Skip to content

Add pie chart visualization template#595

Open
skaphan wants to merge 13 commits intoartoonie:mainfrom
skaphan:pie-template-clean
Open

Add pie chart visualization template#595
skaphan wants to merge 13 commits intoartoonie:mainfrom
skaphan:pie-template-clean

Conversation

@skaphan
Copy link

@skaphan skaphan commented Feb 24, 2026

Summary

  • Add embedded pie chart web component with templates and static assets
  • Add pie chart tab icon and nonblocking template for async loading
  • Build pie chart data from processed Graph (respects config filters)
  • Add hidePie setting following hideSankey/hideTabular pattern
  • Pass config options (textForWinner, excludeFinalWinnerAndEliminatedCandidate) to component
  • Initialize pie chart to final round on load
  • Add 32 tests for graphToRCtab converter
  • Fix tooltip positioning (position:fixed + operator precedence fix)

Response to feedback

Matching the candidate colors with the rest of the visualizations

Done.

The data doesn't seem to match the rest of the visualization. I suspect this is because you're reading directly from the JSON without viewing other config options.

Done. The pie chart now reads from the processed Graph (via a new graphToRCtab converter) instead of raw JSON, so it respects all config filters including excludeFinalWinnerAndEliminatedCandidate.

The other visualizations show Undeclared Write-Ins eliminated first but the pie chart hides UWI altogether.

We haven't been doing anything special about this. Not sure what the issue is.

The pie chart doesn't seem to respect any of the configuration options on the upload page (like "How to refer to the winner", "Hide winner because results are preliminary")

Done. textForWinner and excludeFinalWinnerAndEliminatedCandidate are now passed through from the config.

"Use first-round totals for all percentage calculations"

We do this by default. Do you need it to work from active votes if you don't have it this way?

The pie chart shows the first round on page load instead of the last round

Done.

We should have a setting that allows you to hide the Pie chart

Done. Added hidePie model field, config JS variable, settings checkbox, and tab hiding — following the exact hideSankey/hideTabular pattern. Not heavily tested but it's a mechanical copy of the existing pattern.

We should remove the extraneous buttons that don't match the rest of RCVis, like the "one small step" and the description at the bottom

Got rid of the description at the bottom (now behind a showCaptions prop, default false).

I'm going to push back a little on the "one small step" button. It is a useful feature when you're really trying to see what's going on. The animation is a three-phase thing:

  1. Show the transfers that are going to be made
  2. Move them to the candidates those votes are going to be transferred to
  3. Merge them in with those candidates

We can rename or restyle the button, no problem, but I don't think it's helpful to remove it entirely. But for rcvis, it's really up to you. I will say though that without that, for my purposes I'd rather stick with a version that has it.

I'd like at least cursory tests that step through the visualization to ensure it doesn't break in the future

Added 32 tests for the graphToRCtab converter covering: structure validation, tally correctness, eliminations, multi-winner surplus, inactive ballots, no-threshold elections, the excludeFinalWinnerAndEliminatedCandidate flag, and the _stringify helper.

I'd like to run a PageSpeed Insights test to ensure no degradation in loading times

Please do, but be aware that all we're doing is downloading a piece of code that will be cached for the lifetime of the browser instance, so it only has to happen once per browser instance. The only downloading after that will be the parameters (the color map and JSON file) to be visualized.

Add embedded pie chart web component, templates, static assets,
and pie_chart_no_cache setting. Store raw JSON on graph for pie
chart data access.
@skaphan skaphan force-pushed the pie-template-clean branch from 7b29c2d to 5251937 Compare March 4, 2026 17:57
@artoonie
Copy link
Owner

artoonie commented Mar 4, 2026

I haven't looked at the code, but the interface looks great, only a few small things remain:

  1. Matching the candidate colors with the rest of the visualizations
  2. The data doesn't seem to match the rest of the visualization. I suspect this is because you're reading directly from the JSON without viewing other config options. For example, in this JSON, the other visualizations show Undeclared Write-Ins eliminated first but the pie chart hides UWI altogether.
  3. Similarly, the pie chart doesn't seem to respect any of the configuration options on the upload page (like "How to refer to the winner", " Hide winner because results are preliminary", "Use first-round totals for all percentage calculations"
  4. The pie chart shows the first round on page load instead of the last round
  5. We should have a setting that allows you to hide the Pie chart, just like we can hide the tabular and sankey formats. Some jurisdictions want control over which visualizations are visible.
  6. We should remove the extraneous buttons that don't match the rest of RCVis, like the "one small step" and the description at the bottom
  7. I'd like at least cursory tests that step through the visualization to ensure it doesn't break in the future
  8. I'd like to run a PageSpeed Insights test to ensure no degradation in loading times

skaphan added 11 commits March 4, 2026 16:17
The pie chart was the only visualization reading graph._raw_JSON directly,
bypassing config filters like excludeFinalWinnerAndEliminatedCandidate.
New converter in visualizer/pie/graphToRCtab.py builds RCTab-compatible
JSON from the same processed Graph that bar chart and sankey use.

Co-Authored-By: Claude Opus 4.6
- Pass textForWinner and excludeFinalWinnerAndEliminatedCandidate
- Set currentRound to numRounds so pie loads on last round
- Rebuilt standalone component with new props

Co-Authored-By: Claude Opus 4.6
Following the hideSankey/hideTabular pattern: model field, config JS
variable, settings checkbox, and tab hiding in hideTabsBasedOnConfig().

Co-Authored-By: Claude Opus 4.6
Covers structure validation, tally correctness, eliminations, multi-winner
surplus, inactive ballots, no-threshold elections, excludeFinalWinner flag,
and the _stringify helper.

Co-Authored-By: Claude Opus 4.6
Co-Authored-By: Claude Opus 4.6
Use a coprime stride near N/2 to reorder the color palette so that
visually similar colors are spread apart around the pie chart.

Co-Authored-By: Claude Opus 4.6
Replace color scramble with tally interleaving: alternate largest and
smallest candidates so small slices always have a large neighbor,
reducing label overlap. Inactive Ballots always last.

Fix color generation to use actual tally entry count instead of
config.numCandidates, which excluded Inactive Ballots and caused
color wrapping on large elections.

Co-Authored-By: Claude Opus 4.6
Per-round reordering broke D3 pie animation because candidate positions
shifted between rounds. Now the interleave order is stable across all
rounds, just dropping eliminated candidates.

Co-Authored-By: Claude Opus 4.6
Tests pie vistype rendering, embedly redirect, hidePie config toggle,
and cloudflare cache purge including pie URLs. Tests graphToRCtab with
candidate names containing HTML, quotes, and other special characters.

Co-Authored-By: Claude Opus 4.6
@skaphan
Copy link
Author

skaphan commented Mar 6, 2026

Added 7 new tests for the pie chart feature:

testSimple.py (3 new + 1 updated):

  • test_pie_vistype_renders?vistype=pie embedded URL returns 200
  • test_pie_embedly_redirect/vo/{slug}/pie redirects to /ve/{slug}?vistype=pie
  • test_hide_pie_confighidePie toggle propagates to JavaScript config
  • test_cloudflare_purge — expected URLs updated to include pie paths (/vo/{slug}/pie and ?vistype=pie)

testGraphToRCtab.py (4 new in SpecialCharacterTests class):

  • Tests that candidate names with HTML tags, quotes, commas, and other special characters survive the graph-to-RCTab JSON conversion without corruption

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants