Skip to content

Commit

Permalink
Updated the table to use the votes as seats
Browse files Browse the repository at this point in the history
  • Loading branch information
mmircea16 committed Nov 1, 2020
1 parent aa341c4 commit 670819f
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 116 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,100 +2,9 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */

import React from "react";
import { mockResults } from "../../util/mocks";
import { mockResults, mockCountyCouncilResults } from "../../util/mocks";
import { ElectionResultsStackedBar } from "./ElectionResultsStackedBar";

const nationalResultsExample = {
eligibleVoters: 18466219,
totalVotes: 8419716,
validVotes: 7937514,
nullVotes: 482202,
totalSeats: 0,
candidates: [
{
name: "Partidul Social Democrat",
partyColor: "#FF0000",
partyLogo: "https://rezultatevot-media.s3.eu-central-1.amazonaws.com/v2/Logo__Partidul+Social+Democrat.jpg",
votes: 16,
seats: 0,
totalSeats: 0,
},
{
name: "Partidul Național Liberal",
partyColor: "#F8DD1B",
partyLogo: "https://rezultatevot-media.s3.eu-central-1.amazonaws.com/v2/Logo__Partidul+Na%C8%9Bional+Liberal.jpg",
votes: 15,
seats: 0,
totalSeats: 0,
},
{
name: "UNIUNEA DEMOCRATA MAGHIARA DIN ROMANIA",
partyColor: "#007300",
partyLogo:
"https://rezultatevot-media.s3.eu-central-1.amazonaws.com/v2/Logo__Uniunea+Democrat%C4%83+a+Maghiarilor+din+Rom%C3%A2nia.jpg",
votes: 4,
seats: 0,
totalSeats: 0,
},
{
name: "ALIANȚA ELECTORALĂ ALIANȚA PENTRU MODERNIZAREA NEAMȚULUI 2020",
shortName: "A. ELECTORALĂ PENTRU MODERNIZAREA NEAMȚULUI 2020",
partyColor: "#808080",
votes: 1,
seats: 0,
totalSeats: 0,
},
{
name: "ALIANȚA PNL USR PLUS",
shortName: "A. PNL USR PLUS",
partyColor: "#808080",
votes: 1,
seats: 0,
totalSeats: 0,
},
{
name: "ALIANȚA PENTRU BISTRIȚA-NĂSĂUD",
shortName: "A. NĂSĂUD",
partyColor: "#808080",
votes: 1,
seats: 0,
totalSeats: 0,
},
{
name: "INDEPENDENT",
shortName: "INDEPENDENT",
partyColor: "#808080",
votes: 1,
seats: 0,
totalSeats: 0,
},
{
name: "ALIANTA ELECTORALA PSD+ALDE DOLJ",
partyColor: "#808080",
votes: 1,
seats: 0,
totalSeats: 0,
},
{
name: "ALIANȚA PSD-PRO BUZĂU",
shortName: "A. PRO BUZĂU",
partyColor: "#808080",
votes: 1,
seats: 0,
totalSeats: 0,
},
{
name:
"ALIANȚA PARTIDUL NAȚIONAL LIBERAL - UNIUNEA SALVAȚI ROMÂNIA - PARTIDUL LIBERTATE, UNITATE ȘI SOLIDARITATE (PNL-USR-PLUS)",
shortName: "A. UNIUNEA SALVAȚI ROMÂNIA - PARTIDUL LIBERTATE, UNITATE ȘI SOLIDARITATE (PNL-USR-PLUS)",
partyColor: "#808080",
votes: 1,
seats: 0,
totalSeats: 0,
},
],
};

export default {
title: "Election results stacked bar",
component: ElectionResultsStackedBar,
Expand All @@ -118,7 +27,7 @@ export const ExampleWithDiscreteValues = (args: any) => {
};

ExampleWithDiscreteValues.args = {
results: nationalResultsExample,
results: mockCountyCouncilResults,
displayPercentages: false,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import React from "react";
import { ElectionScopeIncompleteResolved } from "../../types/Election";
import {
mockCountyCouncilElectionMeta,
mockCountyCouncilResults,
mockDiasporaElectionScope,
mockLocalCouncilElectionMeta,
mockLocalityElectionScope,
Expand Down Expand Up @@ -37,6 +39,16 @@ export const LocalCouncilElection = () => {
);
};

export const CountyCouncilElection = () => {
return (
<ElectionResultsSummarySection
scope={mockNationalElectionScope}
meta={mockCountyCouncilElectionMeta}
results={mockCountyCouncilResults}
/>
);
};

export const DiasporaElection = () => {
return (
<ElectionResultsSummarySection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ export const ElectionResultsSummarySection = themable<Props>(
meta={meta}
results={results}
headers={tableHeaders}
displayVotesAsSeats={!displayPercentages}
/>
)}
{map}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
/* eslint-disable @typescript-eslint/no-explicit-any */

import React from "react";
import { mockLocalCouncilElectionMeta, mockResults } from "../../util/mocks";
import {
mockCountyCouncilElectionMeta,
mockCountyCouncilResults,
mockLocalCouncilElectionMeta,
mockResults,
} from "../../util/mocks";
import { ElectionResultsSummaryTable } from "./ElectionResultsSummaryTable";

export default {
Expand All @@ -24,3 +29,19 @@ SimpleExample.argTypes = {
results: { control: "object" },
header: { control: "object" },
};

export const ExampleWithVotesAsSeats = (args: any) => {
return <ElectionResultsSummaryTable {...args} />;
};

ExampleWithVotesAsSeats.args = {
meta: mockCountyCouncilElectionMeta,
results: mockCountyCouncilResults,
header: { candidate: "Partid", seats: "Mand.", votes: "Voturi", percentage: "%" },
displayVotesAsSeats: true,
};

ExampleWithVotesAsSeats.argTypes = {
results: { control: "object" },
header: { control: "object" },
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";
import { electionHasSeats, ElectionBallotMeta, ElectionResults } from "../../types/Election";
import { themable } from "../../hooks/theme";
import { electionHasSeats, ElectionBallotMeta, ElectionResults, ElectionResultsCandidate } from "../../types/Election";
import { ClassNames, themable } from "../../hooks/theme";
import { DivBody, Heading3, makeTypographyComponent } from "../Typography/Typography";
import { lightFormat, parseISO } from "date-fns";
import { electionCandidateColor, formatGroupedNumber, formatPercentage, fractionOf } from "../../util/format";
Expand All @@ -19,6 +19,7 @@ type Props = {
meta: ElectionBallotMeta;
results: ElectionResults;
headers?: ElectionResultsSummaryTableHeaders;
displayVotesAsSeats?: boolean;
};

type CellProps = {
Expand All @@ -28,10 +29,78 @@ type CellProps = {
const THeadRow = makeTypographyComponent("th", "label");
const TCell = makeTypographyComponent<CellProps>("td", "bodyMedium");

const headerRowForVotesWithSeats = function (
headers:
| {
candidate?: string;
seats?: string;
votes?: string;
percentage?: string;
bar?: string;
}
| undefined,
isReferendum: boolean,
hasSeats: boolean,
classes: ClassNames,
) {
return (
<tr>
<THeadRow>{headers?.candidate ?? (isReferendum ? "Opțiune" : "Partid")}</THeadRow>
{hasSeats && <THeadRow>{headers?.seats ?? "Mand."}</THeadRow>}
<THeadRow>{headers?.votes ?? "Voturi"}</THeadRow>
<THeadRow className={classes.percentage}>{headers?.percentage ?? "%"}</THeadRow>
<THeadRow>{headers?.bar ?? ""}</THeadRow>
</tr>
);
};

const headerRowForVotesAsSeatsWon = function () {
return (
<tr>
<THeadRow>Partid</THeadRow>
<THeadRow>Mandate</THeadRow>
</tr>
);
};

const getRowWithVotesAndSeatsForCandidate = function (
hasSeats: boolean,
candidate: ElectionResultsCandidate,
classes: ClassNames,
percentages: number[],
index: number,
maxFraction: number,
) {
return (
<>
{hasSeats && <TCell>{candidate.seats != null && formatGroupedNumber(candidate.seats)}</TCell>}
<TCell>{formatGroupedNumber(candidate.votes)}</TCell>
<TCell className={classes.percentage}>{formatPercentage(percentages[index])}</TCell>
<td className={classes.barContainer}>
<div
className={classes.bar}
style={{
width: `${100 * fractionOf(percentages[index], maxFraction)}%`,
backgroundColor: electionCandidateColor(candidate),
}}
/>
</td>
</>
);
};

const getRowWithVotesAsSeatsForCandidate = function (candidate: ElectionResultsCandidate) {
return (
<>
<TCell>{formatGroupedNumber(candidate.votes)}</TCell>
</>
);
};

export const ElectionResultsSummaryTable = themable<Props>(
"ElectionResultsSummaryTable",
cssClasses,
)(({ classes, results, meta, headers }) => {
)(({ classes, results, meta, headers, displayVotesAsSeats }) => {
const hasSeats = electionHasSeats(meta.type, results);
const isReferendum = meta.type === "referendum";
const percentageBasis = isReferendum ? results.eligibleVoters ?? 0 : results.validVotes;
Expand All @@ -56,13 +125,9 @@ export const ElectionResultsSummaryTable = themable<Props>(
<div className={classes.tableContainer}>
<table className={classes.table}>
<thead>
<tr>
<THeadRow>{headers?.candidate ?? (isReferendum ? "Opțiune" : "Partid")}</THeadRow>
{hasSeats && <THeadRow>{headers?.seats ?? "Mand."}</THeadRow>}
<THeadRow>{headers?.votes ?? "Voturi"}</THeadRow>
<THeadRow className={classes.percentage}>{headers?.percentage ?? "%"}</THeadRow>
<THeadRow>{headers?.bar ?? ""}</THeadRow>
</tr>
{displayVotesAsSeats ?? false
? headerRowForVotesAsSeatsWon()
: headerRowForVotesWithSeats(headers, isReferendum, hasSeats, classes)}
</thead>
<tbody>
{results.candidates.map((candidate, index) => (
Expand All @@ -71,18 +136,9 @@ export const ElectionResultsSummaryTable = themable<Props>(
<ColoredSquare color={electionCandidateColor(candidate)} className={classes.square} />
{candidate.shortName || candidate.name}
</TCell>
{hasSeats && <TCell>{candidate.seats != null && formatGroupedNumber(candidate.seats)}</TCell>}
<TCell>{formatGroupedNumber(candidate.votes)}</TCell>
<TCell className={classes.percentage}>{formatPercentage(percentages[index])}</TCell>
<td className={classes.barContainer}>
<div
className={classes.bar}
style={{
width: `${100 * fractionOf(percentages[index], maxFraction)}%`,
backgroundColor: electionCandidateColor(candidate),
}}
/>
</td>
{displayVotesAsSeats ?? false
? getRowWithVotesAsSeatsForCandidate(candidate)
: getRowWithVotesAndSeatsForCandidate(hasSeats, candidate, classes, percentages, index, maxFraction)}
</tr>
))}
</tbody>
Expand Down
Loading

0 comments on commit 670819f

Please sign in to comment.