diff --git a/src/components/ElectionResultsStackedBar/ElectionResultsStackedBar.stories.tsx b/src/components/ElectionResultsStackedBar/ElectionResultsStackedBar.stories.tsx
index d1560e7..462715c 100644
--- a/src/components/ElectionResultsStackedBar/ElectionResultsStackedBar.stories.tsx
+++ b/src/components/ElectionResultsStackedBar/ElectionResultsStackedBar.stories.tsx
@@ -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,
@@ -118,7 +27,7 @@ export const ExampleWithDiscreteValues = (args: any) => {
};
ExampleWithDiscreteValues.args = {
- results: nationalResultsExample,
+ results: mockCountyCouncilResults,
displayPercentages: false,
};
diff --git a/src/components/ElectionResultsSummarySection/ElectionResultsSummarySection.stories.tsx b/src/components/ElectionResultsSummarySection/ElectionResultsSummarySection.stories.tsx
index 1a279b8..a49d669 100644
--- a/src/components/ElectionResultsSummarySection/ElectionResultsSummarySection.stories.tsx
+++ b/src/components/ElectionResultsSummarySection/ElectionResultsSummarySection.stories.tsx
@@ -3,6 +3,8 @@
import React from "react";
import { ElectionScopeIncompleteResolved } from "../../types/Election";
import {
+ mockCountyCouncilElectionMeta,
+ mockCountyCouncilResults,
mockDiasporaElectionScope,
mockLocalCouncilElectionMeta,
mockLocalityElectionScope,
@@ -37,6 +39,16 @@ export const LocalCouncilElection = () => {
);
};
+export const CountyCouncilElection = () => {
+ return (
+
+ );
+};
+
export const DiasporaElection = () => {
return (
(
meta={meta}
results={results}
headers={tableHeaders}
+ displayVotesAsSeats={!displayPercentages}
/>
)}
{map}
diff --git a/src/components/ElectionResultsSummaryTable/ElectionResultsSummaryTable.stories.tsx b/src/components/ElectionResultsSummaryTable/ElectionResultsSummaryTable.stories.tsx
index 94cb1a2..3622267 100644
--- a/src/components/ElectionResultsSummaryTable/ElectionResultsSummaryTable.stories.tsx
+++ b/src/components/ElectionResultsSummaryTable/ElectionResultsSummaryTable.stories.tsx
@@ -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 {
@@ -24,3 +29,19 @@ SimpleExample.argTypes = {
results: { control: "object" },
header: { control: "object" },
};
+
+export const ExampleWithVotesAsSeats = (args: any) => {
+ return ;
+};
+
+ExampleWithVotesAsSeats.args = {
+ meta: mockCountyCouncilElectionMeta,
+ results: mockCountyCouncilResults,
+ header: { candidate: "Partid", seats: "Mand.", votes: "Voturi", percentage: "%" },
+ displayVotesAsSeats: true,
+};
+
+ExampleWithVotesAsSeats.argTypes = {
+ results: { control: "object" },
+ header: { control: "object" },
+};
diff --git a/src/components/ElectionResultsSummaryTable/ElectionResultsSummaryTable.tsx b/src/components/ElectionResultsSummaryTable/ElectionResultsSummaryTable.tsx
index e2eef57..20e4a50 100644
--- a/src/components/ElectionResultsSummaryTable/ElectionResultsSummaryTable.tsx
+++ b/src/components/ElectionResultsSummaryTable/ElectionResultsSummaryTable.tsx
@@ -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";
@@ -19,6 +19,7 @@ type Props = {
meta: ElectionBallotMeta;
results: ElectionResults;
headers?: ElectionResultsSummaryTableHeaders;
+ displayVotesAsSeats?: boolean;
};
type CellProps = {
@@ -28,10 +29,78 @@ type CellProps = {
const THeadRow = makeTypographyComponent("th", "label");
const TCell = makeTypographyComponent("td", "bodyMedium");
+const headerRowForVotesWithSeats = function (
+ headers:
+ | {
+ candidate?: string;
+ seats?: string;
+ votes?: string;
+ percentage?: string;
+ bar?: string;
+ }
+ | undefined,
+ isReferendum: boolean,
+ hasSeats: boolean,
+ classes: ClassNames,
+) {
+ return (
+
+ {headers?.candidate ?? (isReferendum ? "Opțiune" : "Partid")}
+ {hasSeats && {headers?.seats ?? "Mand."}}
+ {headers?.votes ?? "Voturi"}
+ {headers?.percentage ?? "%"}
+ {headers?.bar ?? ""}
+
+ );
+};
+
+const headerRowForVotesAsSeatsWon = function () {
+ return (
+
+ Partid
+ Mandate
+
+ );
+};
+
+const getRowWithVotesAndSeatsForCandidate = function (
+ hasSeats: boolean,
+ candidate: ElectionResultsCandidate,
+ classes: ClassNames,
+ percentages: number[],
+ index: number,
+ maxFraction: number,
+) {
+ return (
+ <>
+ {hasSeats && {candidate.seats != null && formatGroupedNumber(candidate.seats)}}
+ {formatGroupedNumber(candidate.votes)}
+ {formatPercentage(percentages[index])}
+
+
+ |
+ >
+ );
+};
+
+const getRowWithVotesAsSeatsForCandidate = function (candidate: ElectionResultsCandidate) {
+ return (
+ <>
+ {formatGroupedNumber(candidate.votes)}
+ >
+ );
+};
+
export const ElectionResultsSummaryTable = themable(
"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;
@@ -56,13 +125,9 @@ export const ElectionResultsSummaryTable = themable(
-
- {headers?.candidate ?? (isReferendum ? "Opțiune" : "Partid")}
- {hasSeats && {headers?.seats ?? "Mand."}}
- {headers?.votes ?? "Voturi"}
- {headers?.percentage ?? "%"}
- {headers?.bar ?? ""}
-
+ {displayVotesAsSeats ?? false
+ ? headerRowForVotesAsSeatsWon()
+ : headerRowForVotesWithSeats(headers, isReferendum, hasSeats, classes)}
{results.candidates.map((candidate, index) => (
@@ -71,18 +136,9 @@ export const ElectionResultsSummaryTable = themable(
{candidate.shortName || candidate.name}
- {hasSeats && {candidate.seats != null && formatGroupedNumber(candidate.seats)}}
- {formatGroupedNumber(candidate.votes)}
- {formatPercentage(percentages[index])}
-
-
- |
+ {displayVotesAsSeats ?? false
+ ? getRowWithVotesAsSeatsForCandidate(candidate)
+ : getRowWithVotesAndSeatsForCandidate(hasSeats, candidate, classes, percentages, index, maxFraction)}
))}
diff --git a/src/util/mocks.ts b/src/util/mocks.ts
index 2589f7a..4169add 100644
--- a/src/util/mocks.ts
+++ b/src/util/mocks.ts
@@ -46,6 +46,16 @@ export const mockLocalCouncilElectionMeta: ElectionBallotMeta = {
electionId: 2,
};
+export const mockCountyCouncilElectionMeta: ElectionBallotMeta = {
+ type: "county_council",
+ date: "2016-06-05",
+ title: "Alegeri Locale",
+ ballot: "Consiliul judetean",
+ ballotId: 3,
+ electionId: 3,
+};
+
+
export const mockPresidentialElectionTurnout: ElectionTurnout = {
eligibleVoters: 18217411,
totalVotes: 9086696,
@@ -181,6 +191,98 @@ export const mockResults: ElectionResults = {
],
};
+export const mockCountyCouncilResults = {
+ 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 const mockElectionList = [
{
date: "2019-11-10T00:00:00",