From 00c61fffb35c2c5ed82573486f090bf9b7388cb0 Mon Sep 17 00:00:00 2001 From: Marc Sommerhalder Date: Thu, 27 Apr 2017 10:39:54 +0200 Subject: [PATCH 01/15] Use new PartyResult fields #98 --- HISTORY.rst | 4 ++ docs/format_election_de.md | 10 ++- docs/format_election_en.md | 9 ++- docs/format_election_fr.md | 10 ++- docs/format_election_it.md | 9 ++- docs/format_election_rm.md | 9 ++- docs/open_data_de.md | 7 +- docs/open_data_en.md | 3 + docs/open_data_fr.md | 3 + docs/open_data_it.md | 3 + docs/open_data_rm.md | 4 ++ .../election_day/formats/election/__init__.py | 64 ++++++++++++++----- onegov/election_day/tests/__init__.py | 9 +-- .../election_day/tests/test_election_views.py | 5 +- onegov/election_day/views/election/data.py | 14 +++- onegov/election_day/views/election/parties.py | 61 ++++++------------ 16 files changed, 142 insertions(+), 82 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index e2ad21f6..9e128fb7 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,5 +1,9 @@ Changelog --------- + +- Improves party results. + [msom] + 1.8.5 (2017-04-26) ~~~~~~~~~~~~~~~~~~~ diff --git a/docs/format_election_de.md b/docs/format_election_de.md index ebaae23d..4fda4ce5 100644 --- a/docs/format_election_de.md +++ b/docs/format_election_de.md @@ -297,9 +297,13 @@ Es werden folgende Spalten ausgewertet und sollten vorhanden sein: Name|Beschreibung ---|--- -`Partei`|Der Name der Partei. -`Stimmen`|Die Anzahl Stimmen. -`Sitze`|Die Anzahl Sitze. +`year`|Das Jahr der Wahl. +`total_votes`|Die Gesamtanzahl der Stimmen der Wahl. +`name`|Der Name der Partei. +`color`|Die Farbe der Partei. +`mandates`|Die Anzahl Mandate der Partei. +`votes`|Die Anzahl Stimmen der Partei. + ### Template diff --git a/docs/format_election_en.md b/docs/format_election_en.md index 8fe3d1be..7df8db09 100644 --- a/docs/format_election_en.md +++ b/docs/format_election_en.md @@ -296,9 +296,12 @@ The following columns will be evaluated and should exist: Name|Description ---|--- -`Partei`|The name of the party. -`Stimmen`|The number of votes. -`Sitze`|The number of mandates. +`year`|The year of the election. +`total_votes`|The total votes of the election. +`name`|The name of the party. +`color`|The color of the party. +`mandates`|The number of mandates. +`votes`|The number of votes. ### Template diff --git a/docs/format_election_fr.md b/docs/format_election_fr.md index c7308796..d7da826d 100644 --- a/docs/format_election_fr.md +++ b/docs/format_election_fr.md @@ -297,9 +297,13 @@ The following columns will be evaluated and should exist: Nom|Description ---|--- -`Partei`|The name of the party. -`Stimmen`|The number of votes. -`Sitze`|The number of mandates. +`year`|The year of the election. +`total_votes`|The total votes of the election. +`name`|The name of the party. +`color`|The color of the party. +`mandates`|The number of mandates. +`votes`|The number of votes. + ### Template diff --git a/docs/format_election_it.md b/docs/format_election_it.md index a15bdd6d..40087d24 100644 --- a/docs/format_election_it.md +++ b/docs/format_election_it.md @@ -297,9 +297,12 @@ The following columns will be evaluated and should exist: Nome|Descrizione ---|--- -`Partei`|The name of the party. -`Stimmen`|The number of votes. -`Sitze`|The number of mandates. +`year`|The year of the election. +`total_votes`|The total votes of the election. +`name`|The name of the party. +`color`|The color of the party. +`mandates`|The number of mandates. +`votes`|The number of votes. ### Template diff --git a/docs/format_election_rm.md b/docs/format_election_rm.md index ed5d575b..4b70a189 100644 --- a/docs/format_election_rm.md +++ b/docs/format_election_rm.md @@ -298,9 +298,12 @@ The following columns will be evaluated and should exist: Num|Descripziun ---|--- -`Partei`|The name of the party. -`Stimmen`|The number of votes. -`Sitze`|The number of mandates. +`year`|The year of the election. +`total_votes`|The total votes of the election. +`name`|The name of the party. +`color`|The color of the party. +`mandates`|The number of mandates. +`votes`|The number of votes. ### Template diff --git a/docs/open_data_de.md b/docs/open_data_de.md index a2f15195..e990457a 100644 --- a/docs/open_data_de.md +++ b/docs/open_data_de.md @@ -113,9 +113,12 @@ Die Rohdaten sind als CSV verfügbar. Die folgenden Felder sind enthalten: Name|Description ---|--- +`year`|Das Jahr der Wahl. +`total_votes`|Die Gesamtanzahl der Stimmen der Wahl. `name`|Der Name der Partei. -`mandates`|Die Anzahl gewonnener Sitze. -`votes`|Die Anzahl erhaltener Stimmen. +`color`|Die Farbe der Partei. +`mandates`|Die Anzahl Mandate der Partei. +`votes`|Die Anzahl Stimmen der Partei. ## Abstimmungsresultate diff --git a/docs/open_data_en.md b/docs/open_data_en.md index 2e6ed9c2..77cf50ad 100644 --- a/docs/open_data_en.md +++ b/docs/open_data_en.md @@ -114,7 +114,10 @@ The raw data is available as CSV. The following fields are included: Name|Description ---|--- +`year`|The year of the election. +`total_votes`|The total votes of the election. `name`|The name of the party. +`color`|The color of the party. `mandates`|The number of mandates. `votes`|The number of votes. diff --git a/docs/open_data_fr.md b/docs/open_data_fr.md index 4b492d0a..7100c739 100644 --- a/docs/open_data_fr.md +++ b/docs/open_data_fr.md @@ -114,7 +114,10 @@ The raw data is available as CSV. The following fields are included: Name|Description ---|--- +`year`|The year of the election. +`total_votes`|The total votes of the election. `name`|The name of the party. +`color`|The color of the party. `mandates`|The number of mandates. `votes`|The number of votes. diff --git a/docs/open_data_it.md b/docs/open_data_it.md index 0cc8ab61..2abdaf2e 100644 --- a/docs/open_data_it.md +++ b/docs/open_data_it.md @@ -114,7 +114,10 @@ The raw data is available as CSV. The following fields are included: Name|Description ---|--- +`year`|The year of the election. +`total_votes`|The total votes of the election. `name`|The name of the party. +`color`|The color of the party. `mandates`|The number of mandates. `votes`|The number of votes. diff --git a/docs/open_data_rm.md b/docs/open_data_rm.md index 8bfbd1ed..8f401330 100644 --- a/docs/open_data_rm.md +++ b/docs/open_data_rm.md @@ -116,9 +116,13 @@ The raw data is available as CSV. The following fields are included: Name|Description ---|--- +`year`|The year of the election. +`total_votes`|The total votes of the election. `name`|The name of the party. +`color`|The color of the party. `mandates`|The number of mandates. `votes`|The number of votes. + ## Resultats da la votaziun ### Resultats elavurads diff --git a/onegov/election_day/formats/election/__init__.py b/onegov/election_day/formats/election/__init__.py index 625b3c6c..0dcb9524 100644 --- a/onegov/election_day/formats/election/__init__.py +++ b/onegov/election_day/formats/election/__init__.py @@ -1,9 +1,20 @@ from onegov.ballot import PartyResult from onegov.election_day import _ from onegov.election_day.formats import FileImportError, load_csv +from re import match from sqlalchemy.orm import object_session +HEADERS = [ + 'year', + 'total_votes', + 'name', + 'color', + 'mandates', + 'votes', +] + + def clear_election(election): election.counted_entities = 0 election.total_entities = 0 @@ -30,40 +41,59 @@ def import_party_results_file(election, file, mimetype): """ - party_results = [] - filename = _("Party results") errors = [] + party_results = {} + totals = {} # The party results file has one party per line if file and mimetype: - csv, error = load_csv( - file, mimetype, expected_headers=['Partei', 'Sitze', 'Stimmen'], - filename=filename - ) + csv, error = load_csv(file, mimetype, expected_headers=HEADERS) if error: errors.append(error) else: for line in csv.lines: try: - name = line.partei or '' - mandates = int(line.sitze or 0) - votes = int(line.stimmen or 0) - except ValueError: + year = int(line.year or election.date.year) + total_votes = int(line.total_votes or 0) + name = line.name or '' + color = line.color or ( + '#0571b0' if year == election.date.year else '#999999' + ) + mandates = int(line.mandates or 0) + votes = int(line.votes or 0) + assert all((year, total_votes, name, color)) + assert match(r'^#[0-9A-Fa-f]{6}$', color) + assert totals.get(year, total_votes) == total_votes + except (ValueError, AssertionError): errors.append( FileImportError( error=_("Invalid values"), line=line.rownumber, - filename=filename ) ) else: - party_results.append( - PartyResult( + key = '{}/{}'.format(name, year) + totals[year] = total_votes + + if key in party_results: + errors.append( + FileImportError( + error=_( + "${name} was found twice", + mapping={'name': key} + ), + line=line.rownumber, + ) + ) + else: + party_results[key] = PartyResult( + year=year, + total_votes=total_votes, name=name, - votes=votes, - number_of_mandates=mandates + color=color, + number_of_mandates=mandates, + votes=votes ) - ) if errors: return errors @@ -72,7 +102,7 @@ def import_party_results_file(election, file, mimetype): for result in election.party_results: session.delete(result) - for result in party_results: + for result in party_results.values(): election.party_results.append(result) return diff --git a/onegov/election_day/tests/__init__.py b/onegov/election_day/tests/__init__.py index aa7da641..547c73a7 100644 --- a/onegov/election_day/tests/__init__.py +++ b/onegov/election_day/tests/__init__.py @@ -220,11 +220,12 @@ def upload_proporz_election(client, create=True, canton='gr'): def upload_party_results(client, create=True, canton='gr'): csv_parties = ( - "Partei,Sitze,Stimmen\n" - "BDP,1,60387\n" - "CVP,1,49117\n" - "FDP,0,35134\n" + "year,total_votes,name,color,mandates,votes\n" + "2015,11270,BDP,,1,60387\n" + "2015,11270,CVP,,1,49117\n" + "2015,11270,FDP,,0,35134\n" ).encode('utf-8') + upload = client.get('/election/proporz-election/upload-party-results') upload.form['parties'] = Upload('parties.csv', csv_parties, 'text/plain') upload = upload.form.submit() diff --git a/onegov/election_day/tests/test_election_views.py b/onegov/election_day/tests/test_election_views.py index 3a6bf5cb..35243532 100644 --- a/onegov/election_day/tests/test_election_views.py +++ b/onegov/election_day/tests/test_election_views.py @@ -157,7 +157,10 @@ def test_view_election_parties(election_day_app_gr): export = client.get('/election/proporz-election/data-parties').text assert export == ( - 'name,votes,mandates\r\nBDP,60387,1\r\nCVP,49117,1\r\nFDP,35134,0\r\n' + "year,total_votes,name,color,mandates,votes\r\n" + "2015,11270,BDP,#0571b0,1,60387\r\n" + "2015,11270,CVP,#0571b0,1,49117\r\n" + "2015,11270,FDP,#0571b0,0,35134\r\n" ) diff --git a/onegov/election_day/views/election/data.py b/onegov/election_day/views/election/data.py index acaa7c73..6731f373 100644 --- a/onegov/election_day/views/election/data.py +++ b/onegov/election_day/views/election/data.py @@ -1,6 +1,7 @@ from collections import OrderedDict from morepath.request import Response from onegov.ballot import Election +from onegov.ballot import PartyResult from onegov.core.csv import convert_list_of_dicts_to_csv from onegov.core.csv import convert_list_of_dicts_to_xlsx from onegov.core.security import Public @@ -73,13 +74,20 @@ def view_election_parties_data_as_csv(self, request): def add_last_modified(response): add_last_modified_header(response, self.last_result_change) - self.party_results + results = self.party_results.order_by( + PartyResult.year.desc(), + PartyResult.name + ) + rows = [] - for result in self.party_results: + for result in results: row = OrderedDict() + row['year'] = result.year + row['total_votes'] = result.total_votes row['name'] = result.name - row['votes'] = result.votes + row['color'] = result.color row['mandates'] = result.number_of_mandates + row['votes'] = result.votes rows.append(row) return convert_list_of_dicts_to_csv(rows) diff --git a/onegov/election_day/views/election/parties.py b/onegov/election_day/views/election/parties.py index 1d169ff1..2d086002 100644 --- a/onegov/election_day/views/election/parties.py +++ b/onegov/election_day/views/election/parties.py @@ -1,5 +1,6 @@ from morepath.request import Response from onegov.ballot import Election +from onegov.ballot import PartyResult from onegov.core.security import Public from onegov.election_day import ElectionDayApp from onegov.election_day.layout import DefaultLayout, ElectionsLayout @@ -14,48 +15,28 @@ def get_party_results(election): if election.type != 'proporz' or not election.party_results.first(): return [], {} - year = str(election.date.year) - years = [year] - total_votes = election.accounted_votes - parties = { - party.name: { - year: { - 'mandates': party.number_of_mandates, - 'votes': { - 'total': party.votes, - 'permille': int( - round(1000 * (party.votes / (total_votes or 1))) - ) - } - } + session = object_session(election) + + # Get the totals votes per year + query = session.query(PartyResult.year, PartyResult.total_votes) + query = query.filter(PartyResult.election_id == election.id).distinct() + totals = dict(query) + years = sorted((str(key) for key in totals.keys()), reverse=True) + + parties = {} + for result in election.party_results: + party = parties.setdefault(result.name, {}) + year = party.setdefault(str(result.year), {}) + year['color'] = result.color + year['mandates'] = result.number_of_mandates + year['votes'] = { + 'total': result.votes, + 'permille': int( + round(1000 * (result.votes / (totals.get(result.year) or 1))) + ) } - for party in election.party_results - } - - historical = object_session(election).query(Election) - historical = historical.filter( - Election.type == 'proporz', - Election.domain == election.domain, - Election.number_of_mandates == election.number_of_mandates, - Election.date < election.date - ) - for past_election in historical: - year = str(past_election.date.year) - years.append(year) - total_votes = election.accounted_votes - for party in past_election.party_results: - if party.name not in parties: - parties[party.name] = {} - parties[party.name][year] = { - 'mandates': party.number_of_mandates, - 'votes': { - 'total': party.votes, - 'permille': int(round(1000 * party.votes / total_votes)) - } - } - - return sorted(set(years)), parties + return years, parties def get_party_deltas(election, years, parties): From 7e51cf8a6e2fa815aafba6a8e63accf3135395bf Mon Sep 17 00:00:00 2001 From: Marc Sommerhalder Date: Wed, 31 May 2017 11:40:39 +0200 Subject: [PATCH 02/15] Update party results template --- docs/templates/election_party_results.csv | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/templates/election_party_results.csv b/docs/templates/election_party_results.csv index af868ab9..fd080a4b 100644 --- a/docs/templates/election_party_results.csv +++ b/docs/templates/election_party_results.csv @@ -1,2 +1,12 @@ -Partei,Stimmen,Sitze -BDP,60387,1 +name,color,year,total_votes,votes,mandates +AL,#a74c97,2017,0,0,0 +BDP,#efb52c,2017,0,0,0 +CVP,#ff6300,2017,0,0,0 +EDU,#7f6b65,2017,0,0,0 +EVP,#e3c700,2017,0,0,0 +FDP,#4068c8,2017,0,0,0 +GLP,#aeca00,2017,0,0,0 +Grüne,#4abb3e,2017,0,0,0 +Piraten,#333333,2017,0,0,0 +SP,#db3c27,2017,0,0,0 +SVP,#3f841a,2017,0,0,0 From b2c72a318d0ec7293e991c8b2f029f8559310322 Mon Sep 17 00:00:00 2001 From: Marc Sommerhalder Date: Wed, 31 May 2017 11:45:44 +0200 Subject: [PATCH 03/15] Colorize the parties chart --- .../assets/js/d3.chart.grouped.js | 4 ++++ .../de_CH/LC_MESSAGES/onegov.election_day.po | 22 +++++++++---------- .../fr_CH/LC_MESSAGES/onegov.election_day.po | 22 +++++++++---------- .../it_CH/LC_MESSAGES/onegov.election_day.po | 22 +++++++++---------- .../rm_CH/LC_MESSAGES/onegov.election_day.po | 22 +++++++++---------- .../templates/election/parties.pt | 2 +- onegov/election_day/views/election/parties.py | 4 +++- 7 files changed, 48 insertions(+), 50 deletions(-) diff --git a/onegov/election_day/assets/js/d3.chart.grouped.js b/onegov/election_day/assets/js/d3.chart.grouped.js index de57e1c5..7bbdb4c4 100644 --- a/onegov/election_day/assets/js/d3.chart.grouped.js +++ b/onegov/election_day/assets/js/d3.chart.grouped.js @@ -163,7 +163,11 @@ return height - options.axisHeight - scale.y.back(d.value.back) + 1; }) .style('fill', function(d) { + if (d.color) return d.color; return d.active ? options.colorActive : options.colorInactive; + }) + .style('fill-opacity', function(d) { + if (d.color && !d.active) return 0.3; }); // ... front diff --git a/onegov/election_day/locale/de_CH/LC_MESSAGES/onegov.election_day.po b/onegov/election_day/locale/de_CH/LC_MESSAGES/onegov.election_day.po index 84cd2484..fa618da3 100644 --- a/onegov/election_day/locale/de_CH/LC_MESSAGES/onegov.election_day.po +++ b/onegov/election_day/locale/de_CH/LC_MESSAGES/onegov.election_day.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE 1.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-05-29 15:10+0200\n" +"POT-Creation-Date: 2017-05-31 11:42+0200\n" "PO-Revision-Date: 2017-05-29 15:11+0200\n" "Last-Translator: Denis Krienbühl \n" "Language-Team: German\n" @@ -128,12 +128,13 @@ msgstr "Ungültige Listenverbindungsdaten" msgid "No data found" msgstr "Keine Daten gefunden" -msgid "Party results" -msgstr "Parteiresultate" - msgid "Invalid values" msgstr "Ungültige Werte" +#, python-format +msgid "${name} was found twice" +msgstr "${name} kommt zweimal vor" + msgid "Elected Candidates" msgstr "Gewählte Kandidierende" @@ -143,10 +144,6 @@ msgstr "Unbekannter Kandidierender" msgid "Invalid id" msgstr "Ungültige ID" -#, python-format -msgid "${name} was found twice" -msgstr "${name} kommt zweimal vor" - msgid "Could not read the elegible voters" msgstr "Konnte 'Stimmberechtigte' nicht lesen" @@ -231,6 +228,9 @@ msgstr "Dateiformat" msgid "Complete" msgstr "Komplett ausgezählt" +msgid "Party results" +msgstr "Parteiresultate" + msgid "Proposal / Results" msgstr "Vorlage / Resultate" @@ -582,15 +582,13 @@ msgstr "" #. Default: The diagram shows the votes and mandates of the parties. The rimmed #. bars (left scale) correspond to the number of seats, the colored bars (right -#. scale) to the voices (percentages). The results of earlier elections are -#. grayed out. +#. scale) to the voices (percentages). #. msgid "figcaption_parties" msgstr "" "Das Diagramm zeigt die gewonnen Stimmen und Sitze der Parteien. Die " "umrandeten Balken (linke Skala) entsprechen den Anzahl Sitzen, die " -"eingefärbten Balken (rechte Skala) den Stimmanteilen in Prozent. Ergebnisse " -"früherer Wahlen sind grau eingefärbt." +"eingefärbten Balken (rechte Skala) den Stimmanteilen in Prozent." msgid "Party" msgstr "Partei" diff --git a/onegov/election_day/locale/fr_CH/LC_MESSAGES/onegov.election_day.po b/onegov/election_day/locale/fr_CH/LC_MESSAGES/onegov.election_day.po index 71511eff..62126829 100644 --- a/onegov/election_day/locale/fr_CH/LC_MESSAGES/onegov.election_day.po +++ b/onegov/election_day/locale/fr_CH/LC_MESSAGES/onegov.election_day.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-05-29 15:10+0200\n" +"POT-Creation-Date: 2017-05-31 11:42+0200\n" "PO-Revision-Date: 2017-05-29 15:12+0200\n" "Last-Translator: Fabian Reinhard \n" "Language-Team: \n" @@ -128,12 +128,13 @@ msgstr "Valeurs de connexion de liste non valides" msgid "No data found" msgstr "Pas de données trouvées" -msgid "Party results" -msgstr "Résultats des partis" - msgid "Invalid values" msgstr "Valeurs non valides" +#, python-format +msgid "${name} was found twice" +msgstr "${name} a été trouvé en double" + msgid "Elected Candidates" msgstr "Candidats élus" @@ -143,10 +144,6 @@ msgstr "Candidat inconnu" msgid "Invalid id" msgstr "Mauvaise référence" -#, python-format -msgid "${name} was found twice" -msgstr "${name} a été trouvé en double" - msgid "Could not read the elegible voters" msgstr "Impossible de connaître les électeurs valides" @@ -231,6 +228,9 @@ msgstr "Format de fichier" msgid "Complete" msgstr "Terminé" +msgid "Party results" +msgstr "Résultats des partis" + msgid "Proposal / Results" msgstr "Objet de la votation / Résultats" @@ -580,15 +580,13 @@ msgstr "" #. Default: The diagram shows the votes and mandates of the parties. The rimmed #. bars (left scale) correspond to the number of seats, the colored bars (right -#. scale) to the voices (percentages). The results of earlier elections are -#. grayed out. +#. scale) to the voices (percentages). #. msgid "figcaption_parties" msgstr "" "Le diagramme montre les votes et les mandats des partis. Les barres à rebord " "(échelle de gauche) correspondent au nombre de sièges, les barres colorées " -"(échelle de droite) aux voix (pourcentages). Les résultats des précédentes " -"élections sont grisés." +"(échelle de droite) aux voix (pourcentages)." msgid "Party" msgstr "Parti" diff --git a/onegov/election_day/locale/it_CH/LC_MESSAGES/onegov.election_day.po b/onegov/election_day/locale/it_CH/LC_MESSAGES/onegov.election_day.po index 62d330ef..6e35c84a 100644 --- a/onegov/election_day/locale/it_CH/LC_MESSAGES/onegov.election_day.po +++ b/onegov/election_day/locale/it_CH/LC_MESSAGES/onegov.election_day.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-05-29 15:10+0200\n" +"POT-Creation-Date: 2017-05-31 11:42+0200\n" "PO-Revision-Date: 2017-05-29 15:12+0200\n" "Last-Translator: Fabian Reinhard \n" "Language-Team: \n" @@ -128,12 +128,13 @@ msgstr "Valori della lista delle connessioni non validi" msgid "No data found" msgstr "Nessun dato trovato" -msgid "Party results" -msgstr "Risultati del partito" - msgid "Invalid values" msgstr "Valori non validi" +#, python-format +msgid "${name} was found twice" +msgstr "${name} figura due volte" + msgid "Elected Candidates" msgstr "Candidati eletti" @@ -143,10 +144,6 @@ msgstr "Candidato non conosciuto" msgid "Invalid id" msgstr "ID non valido" -#, python-format -msgid "${name} was found twice" -msgstr "${name} figura due volte" - msgid "Could not read the elegible voters" msgstr "Impossibile leggere 'Aventi diritto di voto'" @@ -231,6 +228,9 @@ msgstr "Formato del file" msgid "Complete" msgstr "Completo" +msgid "Party results" +msgstr "Risultati del partito" + msgid "Proposal / Results" msgstr "Oggetto della votazione / Risultati" @@ -579,15 +579,13 @@ msgstr "" #. Default: The diagram shows the votes and mandates of the parties. The rimmed #. bars (left scale) correspond to the number of seats, the colored bars (right -#. scale) to the voices (percentages). The results of earlier elections are -#. grayed out. +#. scale) to the voices (percentages). #. msgid "figcaption_parties" msgstr "" "Il diagramma mostra i voti e i mandati dei partiti. Le barre cerchiate " "(scala a sinistra) corrispondono al numero dei seggi, le barre colorate " -"(scala a destra) alle voci (percentuali). I risultati delle elezioni " -"anticipate sono disabilitati." +"(scala a destra) alle voci (percentuali)." msgid "Party" msgstr "Partito" diff --git a/onegov/election_day/locale/rm_CH/LC_MESSAGES/onegov.election_day.po b/onegov/election_day/locale/rm_CH/LC_MESSAGES/onegov.election_day.po index c6588e4f..f3f9abe9 100644 --- a/onegov/election_day/locale/rm_CH/LC_MESSAGES/onegov.election_day.po +++ b/onegov/election_day/locale/rm_CH/LC_MESSAGES/onegov.election_day.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-05-29 15:10+0200\n" +"POT-Creation-Date: 2017-05-31 11:42+0200\n" "PO-Revision-Date: 2017-05-29 14:04+0200\n" "Last-Translator: Fabian Reinhard \n" "Language-Team: \n" @@ -128,12 +128,13 @@ msgstr "Datas nunvalaivlas da colliaziuns da glistas" msgid "No data found" msgstr "Chattà naginas datas" -msgid "Party results" -msgstr "Resultats da las partidas" - msgid "Invalid values" msgstr "Valurs nunvalaivlas" +#, python-format +msgid "${name} was found twice" +msgstr "${name} è avant maun duas giadas" + msgid "Elected Candidates" msgstr "Candidat(a)s elegid(a)s" @@ -143,10 +144,6 @@ msgstr "Candidat(a) nunenconuschent(a)" msgid "Invalid id" msgstr "ID nunvalaivel" -#, python-format -msgid "${name} was found twice" -msgstr "${name} è avant maun duas giadas" - msgid "Could not read the elegible voters" msgstr "I n'è betg stà pussaivel da leger las persunas cun dretg da votar" @@ -231,6 +228,9 @@ msgstr "Format da la datoteca" msgid "Complete" msgstr "Resultat eruì cumplettamain" +msgid "Party results" +msgstr "Resultats da las partidas" + msgid "Proposal / Results" msgstr "Project da votaziun / Resultats" @@ -582,15 +582,13 @@ msgstr "" #. Default: The diagram shows the votes and mandates of the parties. The rimmed #. bars (left scale) correspond to the number of seats, the colored bars (right -#. scale) to the voices (percentages). The results of earlier elections are -#. grayed out. +#. scale) to the voices (percentages). #. msgid "figcaption_parties" msgstr "" "Il diagram mussa las vuschs gudagnadas ed ils sezs da las partidas. Las " "travs cun ur (scala sanestra) correspundan al dumber da sezs, las travs " -"coluradas (scala dretga) a las quotas da vuschs en pertschients. Ils " -"resultats d'anteriuras elecziuns èn colurads en grischs." +"coluradas (scala dretga) a las quotas da vuschs en pertschients." msgid "Party" msgstr "Partida" diff --git a/onegov/election_day/templates/election/parties.pt b/onegov/election_day/templates/election/parties.pt index 9938b720..d24c067c 100644 --- a/onegov/election_day/templates/election/parties.pt +++ b/onegov/election_day/templates/election/parties.pt @@ -31,7 +31,7 @@
The diagram shows the votes and mandates of the parties. The rimmed bars (left scale) correspond to the number of seats, the colored bars (right scale) - to the voices (percentages). The results of earlier elections are grayed out. + to the voices (percentages).
diff --git a/onegov/election_day/views/election/parties.py b/onegov/election_day/views/election/parties.py index b3d9de41..99504338 100644 --- a/onegov/election_day/views/election/parties.py +++ b/onegov/election_day/views/election/parties.py @@ -97,6 +97,7 @@ def view_election_parties_data(self, request): front = parties[party].get(year, {}).get('mandates', 0) back = parties[party].get(year, {}).get('votes', {}) back = back.get('permille', 0) / 10.0 + color = parties[party].get(year, {}).get('color', '#999999') results.append({ 'group': party, 'item': year, @@ -104,7 +105,8 @@ def view_election_parties_data(self, request): 'front': front, 'back': back, }, - 'active': year == str(self.date.year) + 'active': year == str(self.date.year), + 'color': color }) return { From 1dafcf26b7ba64221fa2dbb46495eefb04ea400e Mon Sep 17 00:00:00 2001 From: Marc Sommerhalder Date: Wed, 31 May 2017 11:46:28 +0200 Subject: [PATCH 04/15] Reverse the order of the historical party results --- onegov/election_day/views/election/parties.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onegov/election_day/views/election/parties.py b/onegov/election_day/views/election/parties.py index 99504338..27bd3be7 100644 --- a/onegov/election_day/views/election/parties.py +++ b/onegov/election_day/views/election/parties.py @@ -21,7 +21,7 @@ def get_party_results(election): query = session.query(PartyResult.year, PartyResult.total_votes) query = query.filter(PartyResult.election_id == election.id).distinct() totals = dict(query) - years = sorted((str(key) for key in totals.keys()), reverse=True) + years = sorted((str(key) for key in totals.keys())) parties = {} for result in election.party_results: From 7bb5f9b19f11c374ac13a3679337929b02a8a985 Mon Sep 17 00:00:00 2001 From: Marc Sommerhalder Date: Wed, 31 May 2017 12:57:07 +0200 Subject: [PATCH 05/15] Hide inactive (grouped) bars for small screens --- .../assets/js/d3.chart.grouped.js | 45 ++++++++++++++----- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/onegov/election_day/assets/js/d3.chart.grouped.js b/onegov/election_day/assets/js/d3.chart.grouped.js index 7bbdb4c4..7c2d4d47 100644 --- a/onegov/election_day/assets/js/d3.chart.grouped.js +++ b/onegov/election_day/assets/js/d3.chart.grouped.js @@ -34,6 +34,22 @@ if (params.interactive) interactive = params.interactive; } + var updateScales = function(scale) { + // Adjusts the x/dx scales to the current width. If there is not + // enough space to show all bars, layout all bars of one group + // to the same position. + scale.x.rangeRoundPoints([0, width], 1.0); + scale.simple = (width < data.groups.length * data.labels.length * options.barOuterWidth * 1.2); + if (scale.simple) { + scale.dx.range([-options.barOuterWidth/2]); + } else { + scale.dx.rangeRoundBands([ + -(data.labels.length * options.barOuterWidth)/2, + (data.labels.length * options.barOuterWidth)/2 + ]); + } + }; + var chart = function(container) { // Try to read a default width from the container if none is given @@ -64,7 +80,8 @@ y: { front: d3.scale.linear().range([height - options.axisHeight, 0]), back: d3.scale.linear().range([height - options.axisHeight, 0]) - } + }, + simple: false }; var axis = {front: null, back: null, all: null}; @@ -74,17 +91,11 @@ if (data.results && data.labels && data.groups && data.maximum && data.axis_units) { // Adjust the scales - scale.x.domain(data.groups).rangeRoundPoints([0, width], 1.0); - scale.dx - .domain(data.labels) - .rangeRoundBands( - [ - -(data.labels.length * options.barOuterWidth)/2, - (data.labels.length * options.barOuterWidth)/2 - ] - ); + scale.x.domain(data.groups); + scale.dx.domain(data.labels); scale.y.front.domain([0, data.maximum.front]); scale.y.back.domain([0, data.maximum.back]); + updateScales(scale); // Add the labels label = canvas.selectAll('.label') @@ -156,6 +167,9 @@ .attr('class', 'bar back') .attr('transform', function(d) { return 'translate(' + (scale.x(d.group) + scale.dx(d.item)) + ',' + scale.y.back(d.value.back) + ')'; + }) + .attr('visibility', function(d) { + return (scale.simple && !d.active) ? 'hidden' : 'visible'; }); bar.back.append('rect') .attr('width', options.barInnerWidth) @@ -177,6 +191,9 @@ .attr('class', 'bar front') .attr('transform', function(d) { return 'translate(' + (scale.x(d.group) + scale.dx(d.item) + 1) + ',' + scale.y.front(d.value.front) + ')'; + }) + .attr('visibility', function(d) { + return (scale.simple && !d.active) ? 'hidden' : 'visible'; }); bar.front.append('rect') .attr('width', options.barInnerWidth - 2) @@ -267,7 +284,13 @@ // Resize width = $(container).width() - margin.left - margin.right; svg.attr('width', width + margin.left + margin.right); - scale.x.rangeRoundPoints([0, width], 1.0); + updateScales(scale); + bar.front.attr('visibility', function(d) { + return (scale.simple && !d.active) ? 'hidden' : 'visible'; + }); + bar.back.attr('visibility', function(d) { + return (scale.simple && !d.active) ? 'hidden' : 'visible'; + }); label.attr('transform', function(d) { return 'translate(' + scale.x(d) + ',' + height + ')'; From 03075dc11cac4e509396cc148ef610764946729a Mon Sep 17 00:00:00 2001 From: Marc Sommerhalder Date: Wed, 31 May 2017 12:57:36 +0200 Subject: [PATCH 06/15] Show inactive (grouped) bars as dashed boxes --- onegov/election_day/assets/js/d3.chart.grouped.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/onegov/election_day/assets/js/d3.chart.grouped.js b/onegov/election_day/assets/js/d3.chart.grouped.js index 7c2d4d47..eb16a8cc 100644 --- a/onegov/election_day/assets/js/d3.chart.grouped.js +++ b/onegov/election_day/assets/js/d3.chart.grouped.js @@ -202,6 +202,9 @@ }) .attr('fill-opacity', 0.0) .attr('stroke', '#000') + .attr('stroke-dasharray', function(d) { + return d.active ? 'initial' : '1 1'; + }) .attr('stroke-width', 2); bar.front.each(function(d) { if (data.maximum.front / data.groups.length < 5) { From 5063578273c4418b33ccd683bd80a86c4c02b1a6 Mon Sep 17 00:00:00 2001 From: Marc Sommerhalder Date: Wed, 31 May 2017 13:30:30 +0200 Subject: [PATCH 07/15] Visually improve grouped bar charts --- .../assets/js/d3.chart.grouped.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/onegov/election_day/assets/js/d3.chart.grouped.js b/onegov/election_day/assets/js/d3.chart.grouped.js index eb16a8cc..e5eec7d3 100644 --- a/onegov/election_day/assets/js/d3.chart.grouped.js +++ b/onegov/election_day/assets/js/d3.chart.grouped.js @@ -190,34 +190,37 @@ .enter().append('g') .attr('class', 'bar front') .attr('transform', function(d) { - return 'translate(' + (scale.x(d.group) + scale.dx(d.item) + 1) + ',' + scale.y.front(d.value.front) + ')'; + return 'translate(' + (scale.x(d.group) + scale.dx(d.item)) + ',' + scale.y.front(d.value.front) + ')'; }) .attr('visibility', function(d) { return (scale.simple && !d.active) ? 'hidden' : 'visible'; }); bar.front.append('rect') - .attr('width', options.barInnerWidth - 2) + .attr('width', options.barInnerWidth - 1) .attr('height', function(d) { return height - options.axisHeight - scale.y.front(d.value.front) + 1; }) .attr('fill-opacity', 0.0) .attr('stroke', '#000') .attr('stroke-dasharray', function(d) { - return d.active ? 'initial' : '1 1'; + return d.active ? 'initial' : '2 2'; }) - .attr('stroke-width', 2); + .attr('stroke-width', 1); bar.front.each(function(d) { if (data.maximum.front / data.groups.length < 5) { var value = 0; for (value = 1; value < d.value.front; ++value) { var y = scale.y.front(value) - scale.y.front(d.value.front); d3.select(this).append('line') - .attr('x1', 2) + .attr('x1', 0) .attr('y1', y) - .attr('x2', options.barInnerWidth - 4) + .attr('x2', options.barInnerWidth - 1) .attr('y2', y) - .attr('stroke-width', 2) - .attr('stroke', '#000'); + .attr('stroke', '#000') + .attr('stroke-dasharray', function(d) { + return d.active ? 'initial' : '2 2'; + }) + .attr('stroke-width', 1); } } }); From cc6a5e517d61ae62b228273085761550aa4997e0 Mon Sep 17 00:00:00 2001 From: Marc Sommerhalder Date: Wed, 31 May 2017 13:40:50 +0200 Subject: [PATCH 08/15] Fix resizing of grouped bar chart diagramm --- onegov/election_day/assets/js/d3.chart.grouped.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onegov/election_day/assets/js/d3.chart.grouped.js b/onegov/election_day/assets/js/d3.chart.grouped.js index e5eec7d3..668d13c9 100644 --- a/onegov/election_day/assets/js/d3.chart.grouped.js +++ b/onegov/election_day/assets/js/d3.chart.grouped.js @@ -305,7 +305,7 @@ return 'translate(' + (width - options.tickWidth) + ',0)'; }); bar.front.attr('transform', function(d) { - return 'translate(' + (scale.x(d.group) + scale.dx(d.item) + 1) + ',' + scale.y.front(d.value.front) + ')'; + return 'translate(' + (scale.x(d.group) + scale.dx(d.item)) + ',' + scale.y.front(d.value.front) + ')'; }); bar.back.attr('transform', function(d) { return 'translate(' + (scale.x(d.group) + scale.dx(d.item)) + ',' + scale.y.back(d.value.back) + ')'; From ded69b1f0bb4be8f417f09c1a09d2e442ace3d66 Mon Sep 17 00:00:00 2001 From: Marc Sommerhalder Date: Wed, 31 May 2017 13:49:22 +0200 Subject: [PATCH 09/15] Only allow to upload party results if the election is completed --- onegov/election_day/templates/manage/elections.pt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onegov/election_day/templates/manage/elections.pt b/onegov/election_day/templates/manage/elections.pt index 90bae73e..05be4c47 100644 --- a/onegov/election_day/templates/manage/elections.pt +++ b/onegov/election_day/templates/manage/elections.pt @@ -57,7 +57,7 @@
  • Upload results
  • -
  • +
  • Upload party results
  • From e24edb32e9fb48e46600cead389b16fa248d6fab Mon Sep 17 00:00:00 2001 From: Marc Sommerhalder Date: Wed, 31 May 2017 15:04:44 +0200 Subject: [PATCH 10/15] Update tests --- .../election_day/tests/test_election_views.py | 170 +++++++----------- 1 file changed, 63 insertions(+), 107 deletions(-) diff --git a/onegov/election_day/tests/test_election_views.py b/onegov/election_day/tests/test_election_views.py index c7992663..b9749067 100644 --- a/onegov/election_day/tests/test_election_views.py +++ b/onegov/election_day/tests/test_election_views.py @@ -107,6 +107,7 @@ def test_view_election_parties(election_day_app_gr): client.get('/locale/de_CH').follow() login(client) + # Majorz election upload_majorz_election(client) main = client.get('/election/majorz-election/parties') @@ -119,6 +120,7 @@ def test_view_election_parties(election_day_app_gr): assert chart.status_code == 200 assert '/election/majorz-election/parties' in chart + # Proporz election upload_proporz_election(client) upload_party_results(client) @@ -144,115 +146,69 @@ def test_view_election_parties(election_day_app_gr): "2015,11270,FDP,#0571b0,0,35134\r\n" ) + # Historical data + csv_parties = ( + "year,total_votes,name,color,mandates,votes\r\n" + "2015,60000,BDP,#efb52c,1,10000\r\n" + "2015,60000,CVP,#ff6300,1,30000\r\n" + "2015,60000,FDP,#4068c8,0,20000\r\n" + "2011,40000,BDP,#efb52c,1,1000\r\n" + "2011,40000,CVP,#ff6300,1,15000\r\n" + "2011,40000,FDP,#4068c8,1,10000\r\n" + ).encode('utf-8') + + upload = client.get('/election/proporz-election/upload-party-results') + upload.form['parties'] = Upload('parties.csv', csv_parties, 'text/plain') + upload = upload.form.submit() + assert "erfolgreich hochgeladen" in upload -def test_view_election_parties_historical(election_day_app_gr): - client = Client(election_day_app_gr) - client.get('/locale/de_CH').follow() - login(client) + parties = client.get('/election/proporz-election/parties-data').json + assert parties['groups'] == ['BDP', 'CVP', 'FDP'] + assert parties['labels'] == ['2011', '2015'] + assert parties['maximum']['back'] == 100 + assert parties['maximum']['front'] == 5 + assert parties['results'] - for id, year, domain, mandates, results in ( - ('e1', 2014, 'federation', 5, 'BDP,153,5\r\nCVP,1,0\r\n'), - ('e2', 2015, 'federation', 5, 'BDP,123,4\r\nCVP,31,1\r\n'), - ('e3', 2016, 'federation', 5, 'BDP,92,3\r\nCVP,62,2\r\n'), - ('e4', 2013, 'federation', 4, 'BDP,62,2\r\nCVP,62,2\r\n'), - ('e5', 2012, 'canton', 5, 'BDP,92,3\r\nCVP,62,2\r\n') - ): - new = client.get('/manage/elections/new-election') - new.form['election_de'] = id - new.form['date'] = date(year, 1, 1) - new.form['mandates'] = mandates - new.form['election_type'] = 'proporz' - new.form['domain'] = domain - new.form.submit() - - csv = ( - "Anzahl Sitze," - "Wahlkreis-Nr," - "Wahlkreisbezeichnung," - "Stimmberechtigte," - "Wahlzettel," - "Ungültige Wahlzettel," - "Leere Wahlzettel," - "Leere Stimmen," - "Listen-Nr," - "Parteibezeichnung," - "HLV-Nr," - "ULV-Nr," - "Anzahl Sitze Liste," - "Unveränderte Wahlzettel Liste," - "Veränderte Wahlzettel Liste," - "Kandidatenstimmen unveränderte Wahlzettel," - "Zusatzstimmen unveränderte Wahlzettel," - "Kandidatenstimmen veränderte Wahlzettel," - "Zusatzstimmen veränderte Wahlzettel," - "Kandidaten-Nr," - "Gewählt," - "Name," - "Vorname," - "Stimmen unveränderte Wahlzettel," - "Stimmen veränderte Wahlzettel," - "Stimmen Total aus Wahlzettel," - "01 FDP," - "02 CVP," - " Anzahl Gemeinden\n" - "{},3503,Mutten,56,32,1,0,1,1,FDP,1,1,0,0,0,0,0,8,0,101," - "nicht gewählt,Casanova,Angela,0,0,0,0,1,1 von 125\n" - "{},3503,Mutten,56,32,1,0,1,2,CVP,1,2,0,1,0,5,0,0,0,201," - "nicht gewählt,Caluori,Corina,1,0,1,2,0,1 von 125\n".format( - mandates, mandates - ) - ).encode('utf-8') - csv_parties = ("Partei,Stimmen,Sitze\n" + results).encode('utf-8') - - mime = 'text/plain' - upload = client.get('/election/{}/upload'.format(id)).follow() - upload.form['file_format'] = 'sesam' - upload.form['results'] = Upload('data.csv', csv, mime) - upload = upload.form.submit() - assert "Ihre Resultate wurden erfolgreich hochgeladen" in upload - - upload = client.get('/election/{}/upload-party-results'.format(id)) - upload.form['parties'] = Upload('parties.csv', csv_parties, mime) - upload = upload.form.submit() - assert "Ihre Resultate wurden erfolgreich hochgeladen" in upload - - export = client.get('/election/{}/data-parties'.format(id)).text - assert results in export - - e1 = client.get('/election/e1/parties-data').json - e2 = client.get('/election/e2/parties-data').json - e3 = client.get('/election/e3/parties-data').json - e4 = client.get('/election/e4/parties-data').json - e5 = client.get('/election/e5/parties-data').json - - assert e1['groups'] == ['BDP', 'CVP'] - assert e2['groups'] == ['BDP', 'CVP'] - assert e3['groups'] == ['BDP', 'CVP'] - assert e4['groups'] == ['BDP', 'CVP'] - assert e5['groups'] == ['BDP', 'CVP'] - - assert e1['labels'] == ['2014'] - assert e2['labels'] == ['2014', '2015'] - assert e3['labels'] == ['2014', '2015', '2016'] - assert e4['labels'] == ['2013'] - assert e5['labels'] == ['2012'] - - e1 = client.get('/election/e1/parties') - e2 = client.get('/election/e2/parties') - e3 = client.get('/election/e3/parties') - e4 = client.get('/election/e4/parties') - e5 = client.get('/election/e5/parties') - - assert 'Differenz' not in e1 - assert 'Differenz' in e2 - assert 'Differenz' in e3 - assert 'Differenz' not in e4 - assert 'Differenz' not in e5 - - assert '-19.5%' in e2 - assert '19.5%' in e2 - assert '-20.2%' in e3 - assert '20.2%' in e3 + parties = { + '{}-{}'.format(party['item'], party['group']): party + for party in parties['results'] + } + assert parties['2011-BDP']['color'] == '#efb52c' + assert parties['2015-BDP']['color'] == '#efb52c' + assert parties['2011-CVP']['color'] == '#ff6300' + assert parties['2015-CVP']['color'] == '#ff6300' + assert parties['2011-FDP']['color'] == '#4068c8' + assert parties['2015-FDP']['color'] == '#4068c8' + + assert parties['2011-BDP']['active'] == False + assert parties['2011-CVP']['active'] == False + assert parties['2011-FDP']['active'] == False + assert parties['2015-BDP']['active'] == True + assert parties['2015-CVP']['active'] == True + assert parties['2015-FDP']['active'] == True + + assert parties['2011-BDP']['value']['front'] == 1 + assert parties['2011-CVP']['value']['front'] == 1 + assert parties['2011-FDP']['value']['front'] == 1 + assert parties['2015-BDP']['value']['front'] == 1 + assert parties['2015-CVP']['value']['front'] == 1 + assert parties['2015-FDP']['value']['front'] == 0 + + assert parties['2011-BDP']['value']['back'] == 2.5 + assert parties['2011-CVP']['value']['back'] == 37.5 + assert parties['2011-FDP']['value']['back'] == 25 + assert parties['2015-BDP']['value']['back'] == 16.7 + assert parties['2015-CVP']['value']['back'] == 50 + assert parties['2015-FDP']['value']['back'] == 33.3 + + results = client.get('/election/proporz-election/parties').text + assert all(( + value in results + for value in ('2.5%', '37.5%', '25%', '16.7%', '50%', '33.3%') + )) + + export = client.get('/election/proporz-election/data-parties').text + assert export.encode('utf-8') == csv_parties def test_view_election_connections(election_day_app_gr): From ace17b431b7eebd80236f30713607f406ce6e84c Mon Sep 17 00:00:00 2001 From: Marc Sommerhalder Date: Wed, 31 May 2017 15:35:24 +0200 Subject: [PATCH 11/15] Update test --- onegov/election_day/tests/test_election_views.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/onegov/election_day/tests/test_election_views.py b/onegov/election_day/tests/test_election_views.py index b9749067..3add417b 100644 --- a/onegov/election_day/tests/test_election_views.py +++ b/onegov/election_day/tests/test_election_views.py @@ -202,10 +202,17 @@ def test_view_election_parties(election_day_app_gr): assert parties['2015-FDP']['value']['back'] == 33.3 results = client.get('/election/proporz-election/parties').text - assert all(( - value in results - for value in ('2.5%', '37.5%', '25%', '16.7%', '50%', '33.3%') - )) + assert '2.5%' in results + assert '16.7%' in results + assert '14.2%' in results + + assert '37.5%' in results + assert '50.0%' in results + assert '12.5%' in results + + assert '25.0%' in results + assert '33.3%' in results + assert '8.3%' in results export = client.get('/election/proporz-election/data-parties').text assert export.encode('utf-8') == csv_parties From 7ad75129be9b0481e8e4e5f47a0bfe6b40c0a056 Mon Sep 17 00:00:00 2001 From: Marc Sommerhalder Date: Wed, 31 May 2017 15:36:11 +0200 Subject: [PATCH 12/15] Update test --- onegov/election_day/tests/test_election_views.py | 1 - 1 file changed, 1 deletion(-) diff --git a/onegov/election_day/tests/test_election_views.py b/onegov/election_day/tests/test_election_views.py index 3add417b..3ac8de46 100644 --- a/onegov/election_day/tests/test_election_views.py +++ b/onegov/election_day/tests/test_election_views.py @@ -1,4 +1,3 @@ -from datetime import date from freezegun import freeze_time from onegov.election_day.tests import login from onegov.election_day.tests import upload_majorz_election From bc04f7c1c6356afa12ce44263593595adb384d30 Mon Sep 17 00:00:00 2001 From: Marc Sommerhalder Date: Thu, 1 Jun 2017 07:25:03 +0200 Subject: [PATCH 13/15] Update dependencies --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 028314c9..8c1c0ed5 100644 --- a/setup.py +++ b/setup.py @@ -37,7 +37,7 @@ def get_long_description(): 'cached_property', 'cssmin', 'onegov.core>=0.40.1', - 'onegov.ballot>=1.4.0', + 'onegov.ballot>=1.5.0', 'onegov.form>=0.12.0', 'onegov.foundation>=0.0.4', 'onegov.shared>=0.2.0', From 1613821c530b12f51efc2a2be0df37d39a3fc4ed Mon Sep 17 00:00:00 2001 From: Marc Sommerhalder Date: Thu, 1 Jun 2017 14:57:43 +0200 Subject: [PATCH 14/15] Fix floating point issues in grouped bar charts --- onegov/election_day/assets/js/d3.chart.grouped.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/onegov/election_day/assets/js/d3.chart.grouped.js b/onegov/election_day/assets/js/d3.chart.grouped.js index 668d13c9..9892b7fa 100644 --- a/onegov/election_day/assets/js/d3.chart.grouped.js +++ b/onegov/election_day/assets/js/d3.chart.grouped.js @@ -41,7 +41,7 @@ scale.x.rangeRoundPoints([0, width], 1.0); scale.simple = (width < data.groups.length * data.labels.length * options.barOuterWidth * 1.2); if (scale.simple) { - scale.dx.range([-options.barOuterWidth/2]); + scale.dx.range([-Math.round(options.barOuterWidth/2)]); } else { scale.dx.rangeRoundBands([ -(data.labels.length * options.barOuterWidth)/2, @@ -78,8 +78,8 @@ x: d3.scale.ordinal(), dx: d3.scale.ordinal(), y: { - front: d3.scale.linear().range([height - options.axisHeight, 0]), - back: d3.scale.linear().range([height - options.axisHeight, 0]) + front: d3.scale.linear().rangeRound([height - options.axisHeight, 0]), + back: d3.scale.linear().rangeRound([height - options.axisHeight, 0]) }, simple: false }; @@ -166,7 +166,7 @@ .enter().append('g') .attr('class', 'bar back') .attr('transform', function(d) { - return 'translate(' + (scale.x(d.group) + scale.dx(d.item)) + ',' + scale.y.back(d.value.back) + ')'; + return 'translate(' + Math.round(scale.x(d.group) + scale.dx(d.item)) + ',' + scale.y.back(d.value.back) + ')'; }) .attr('visibility', function(d) { return (scale.simple && !d.active) ? 'hidden' : 'visible'; @@ -190,7 +190,7 @@ .enter().append('g') .attr('class', 'bar front') .attr('transform', function(d) { - return 'translate(' + (scale.x(d.group) + scale.dx(d.item)) + ',' + scale.y.front(d.value.front) + ')'; + return 'translate(' + Math.round(scale.x(d.group) + scale.dx(d.item)) + ',' + scale.y.front(d.value.front) + ')'; }) .attr('visibility', function(d) { return (scale.simple && !d.active) ? 'hidden' : 'visible'; @@ -305,10 +305,10 @@ return 'translate(' + (width - options.tickWidth) + ',0)'; }); bar.front.attr('transform', function(d) { - return 'translate(' + (scale.x(d.group) + scale.dx(d.item)) + ',' + scale.y.front(d.value.front) + ')'; + return 'translate(' + Math.round(scale.x(d.group) + scale.dx(d.item)) + ',' + scale.y.front(d.value.front) + ')'; }); bar.back.attr('transform', function(d) { - return 'translate(' + (scale.x(d.group) + scale.dx(d.item)) + ',' + scale.y.back(d.value.back) + ')'; + return 'translate(' + Math.round(scale.x(d.group) + scale.dx(d.item)) + ',' + scale.y.back(d.value.back) + ')'; }); } }); From 07d11ec931fd9b8fc54dd350b6402e1775c7c157 Mon Sep 17 00:00:00 2001 From: Marc Sommerhalder Date: Thu, 1 Jun 2017 15:05:05 +0200 Subject: [PATCH 15/15] Update tests --- .../__snapshots__/d3.chart.grouped.js.snap | 12 ++++++------ .../assets/js/__tests__/d3.chart.grouped.js | 14 +++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/onegov/election_day/assets/js/__tests__/__snapshots__/d3.chart.grouped.js.snap b/onegov/election_day/assets/js/__tests__/__snapshots__/d3.chart.grouped.js.snap index 8288f74c..35b2aff5 100644 --- a/onegov/election_day/assets/js/__tests__/__snapshots__/d3.chart.grouped.js.snap +++ b/onegov/election_day/assets/js/__tests__/__snapshots__/d3.chart.grouped.js.snap @@ -1,15 +1,15 @@ exports[`Grouped bar chart doesn't render a svg with missing parameters 1`] = `""`; -exports[`Grouped bar chart renders a svg @1 1`] = `"ABBCCCDDDDEEEEEFFFFFFGGGGGGG100f100bA (1000): 0f / 0bA (2000): 0f / 0bA (3000): 0f / 0bBB (1000): 1f / 1bBB (2000): 1f / 1bBB (3000): 1f / 1bCCC (1000): 10f / 10bCCC (2000): 10f / 10bCCC (3000): 10f / 10bDDDD (1000): 25f / 30bDDDD (2000): 25f / 30bDDDD (3000): 25f / 30bEEEEE (1000): 50f / 40bEEEEE (2000): 50f / 40bEEEEE (3000): 50f / 40bFFFFFF (1000): 100f / 100bFFFFFF (2000): 100f / 100bFFFFFF (3000): 100f / 100bGGGGGGG (1000): 85.1f / 85.7bGGGGGGG (2000): 85.1f / 85.7bGGGGGGG (3000): 85.1f / 85.7bA (1000): 0f / 0bA (2000): 0f / 0bA (3000): 0f / 0bBB (1000): 1f / 1bBB (2000): 1f / 1bBB (3000): 1f / 1bCCC (1000): 10f / 10bCCC (2000): 10f / 10bCCC (3000): 10f / 10bDDDD (1000): 25f / 30bDDDD (2000): 25f / 30bDDDD (3000): 25f / 30bEEEEE (1000): 50f / 40bEEEEE (2000): 50f / 40bEEEEE (3000): 50f / 40bFFFFFF (1000): 100f / 100bFFFFFF (2000): 100f / 100bFFFFFF (3000): 100f / 100bGGGGGGG (1000): 85.1f / 85.7bGGGGGGG (2000): 85.1f / 85.7bGGGGGGG (3000): 85.1f / 85.7b"`; +exports[`Grouped bar chart renders a svg @1 1`] = `"ABBCCCDDDDEEEEEFFFFFFGGGGGGG100f100bA (1000): 0f / 0bA (2000): 0f / 0bA (3000): 0f / 0bBB (1000): 1f / 1bBB (2000): 1f / 1bBB (3000): 1f / 1bCCC (1000): 10f / 10bCCC (2000): 10f / 10bCCC (3000): 10f / 10bDDDD (1000): 25f / 30bDDDD (2000): 25f / 30bDDDD (3000): 25f / 30bEEEEE (1000): 50f / 40bEEEEE (2000): 50f / 40bEEEEE (3000): 50f / 40bFFFFFF (1000): 100f / 100bFFFFFF (2000): 100f / 100bFFFFFF (3000): 100f / 100bGGGGGGG (1000): 85.1f / 85.7bGGGGGGG (2000): 85.1f / 85.7bGGGGGGG (3000): 85.1f / 85.7bA (1000): 0f / 0bA (2000): 0f / 0bA (3000): 0f / 0bBB (1000): 1f / 1bBB (2000): 1f / 1bBB (3000): 1f / 1bCCC (1000): 10f / 10bCCC (2000): 10f / 10bCCC (3000): 10f / 10bDDDD (1000): 25f / 30bDDDD (2000): 25f / 30bDDDD (3000): 25f / 30bEEEEE (1000): 50f / 40bEEEEE (2000): 50f / 40bEEEEE (3000): 50f / 40bFFFFFF (1000): 100f / 100bFFFFFF (2000): 100f / 100bFFFFFF (3000): 100f / 100bGGGGGGG (1000): 85.1f / 85.7bGGGGGGG (2000): 85.1f / 85.7bGGGGGGG (3000): 85.1f / 85.7b"`; -exports[`Grouped bar chart renders a svg @200 1`] = `"ABBCCCDDDDEEEEEFFFFFFGGGGGGG100f100bA (1000): 0f / 0bA (2000): 0f / 0bA (3000): 0f / 0bBB (1000): 1f / 1bBB (2000): 1f / 1bBB (3000): 1f / 1bCCC (1000): 10f / 10bCCC (2000): 10f / 10bCCC (3000): 10f / 10bDDDD (1000): 25f / 30bDDDD (2000): 25f / 30bDDDD (3000): 25f / 30bEEEEE (1000): 50f / 40bEEEEE (2000): 50f / 40bEEEEE (3000): 50f / 40bFFFFFF (1000): 100f / 100bFFFFFF (2000): 100f / 100bFFFFFF (3000): 100f / 100bGGGGGGG (1000): 85.1f / 85.7bGGGGGGG (2000): 85.1f / 85.7bGGGGGGG (3000): 85.1f / 85.7bA (1000): 0f / 0bA (2000): 0f / 0bA (3000): 0f / 0bBB (1000): 1f / 1bBB (2000): 1f / 1bBB (3000): 1f / 1bCCC (1000): 10f / 10bCCC (2000): 10f / 10bCCC (3000): 10f / 10bDDDD (1000): 25f / 30bDDDD (2000): 25f / 30bDDDD (3000): 25f / 30bEEEEE (1000): 50f / 40bEEEEE (2000): 50f / 40bEEEEE (3000): 50f / 40bFFFFFF (1000): 100f / 100bFFFFFF (2000): 100f / 100bFFFFFF (3000): 100f / 100bGGGGGGG (1000): 85.1f / 85.7bGGGGGGG (2000): 85.1f / 85.7bGGGGGGG (3000): 85.1f / 85.7b"`; +exports[`Grouped bar chart renders a svg @200 1`] = `"ABBCCCDDDDEEEEEFFFFFFGGGGGGG100f100bA (1000): 0f / 0bA (2000): 0f / 0bA (3000): 0f / 0bBB (1000): 1f / 1bBB (2000): 1f / 1bBB (3000): 1f / 1bCCC (1000): 10f / 10bCCC (2000): 10f / 10bCCC (3000): 10f / 10bDDDD (1000): 25f / 30bDDDD (2000): 25f / 30bDDDD (3000): 25f / 30bEEEEE (1000): 50f / 40bEEEEE (2000): 50f / 40bEEEEE (3000): 50f / 40bFFFFFF (1000): 100f / 100bFFFFFF (2000): 100f / 100bFFFFFF (3000): 100f / 100bGGGGGGG (1000): 85.1f / 85.7bGGGGGGG (2000): 85.1f / 85.7bGGGGGGG (3000): 85.1f / 85.7bA (1000): 0f / 0bA (2000): 0f / 0bA (3000): 0f / 0bBB (1000): 1f / 1bBB (2000): 1f / 1bBB (3000): 1f / 1bCCC (1000): 10f / 10bCCC (2000): 10f / 10bCCC (3000): 10f / 10bDDDD (1000): 25f / 30bDDDD (2000): 25f / 30bDDDD (3000): 25f / 30bEEEEE (1000): 50f / 40bEEEEE (2000): 50f / 40bEEEEE (3000): 50f / 40bFFFFFF (1000): 100f / 100bFFFFFF (2000): 100f / 100bFFFFFF (3000): 100f / 100bGGGGGGG (1000): 85.1f / 85.7bGGGGGGG (2000): 85.1f / 85.7bGGGGGGG (3000): 85.1f / 85.7b"`; -exports[`Grouped bar chart renders a svg @500 1`] = `"ABBCCCDDDDEEEEEFFFFFFGGGGGGG100f100bA (1000): 0f / 0bA (2000): 0f / 0bA (3000): 0f / 0bBB (1000): 1f / 1bBB (2000): 1f / 1bBB (3000): 1f / 1bCCC (1000): 10f / 10bCCC (2000): 10f / 10bCCC (3000): 10f / 10bDDDD (1000): 25f / 30bDDDD (2000): 25f / 30bDDDD (3000): 25f / 30bEEEEE (1000): 50f / 40bEEEEE (2000): 50f / 40bEEEEE (3000): 50f / 40bFFFFFF (1000): 100f / 100bFFFFFF (2000): 100f / 100bFFFFFF (3000): 100f / 100bGGGGGGG (1000): 85.1f / 85.7bGGGGGGG (2000): 85.1f / 85.7bGGGGGGG (3000): 85.1f / 85.7bA (1000): 0f / 0bA (2000): 0f / 0bA (3000): 0f / 0bBB (1000): 1f / 1bBB (2000): 1f / 1bBB (3000): 1f / 1bCCC (1000): 10f / 10bCCC (2000): 10f / 10bCCC (3000): 10f / 10bDDDD (1000): 25f / 30bDDDD (2000): 25f / 30bDDDD (3000): 25f / 30bEEEEE (1000): 50f / 40bEEEEE (2000): 50f / 40bEEEEE (3000): 50f / 40bFFFFFF (1000): 100f / 100bFFFFFF (2000): 100f / 100bFFFFFF (3000): 100f / 100bGGGGGGG (1000): 85.1f / 85.7bGGGGGGG (2000): 85.1f / 85.7bGGGGGGG (3000): 85.1f / 85.7b"`; +exports[`Grouped bar chart renders a svg @500 1`] = `"ABBCCCDDDDEEEEEFFFFFFGGGGGGG100f100bA (1000): 0f / 0bA (2000): 0f / 0bA (3000): 0f / 0bBB (1000): 1f / 1bBB (2000): 1f / 1bBB (3000): 1f / 1bCCC (1000): 10f / 10bCCC (2000): 10f / 10bCCC (3000): 10f / 10bDDDD (1000): 25f / 30bDDDD (2000): 25f / 30bDDDD (3000): 25f / 30bEEEEE (1000): 50f / 40bEEEEE (2000): 50f / 40bEEEEE (3000): 50f / 40bFFFFFF (1000): 100f / 100bFFFFFF (2000): 100f / 100bFFFFFF (3000): 100f / 100bGGGGGGG (1000): 85.1f / 85.7bGGGGGGG (2000): 85.1f / 85.7bGGGGGGG (3000): 85.1f / 85.7bA (1000): 0f / 0bA (2000): 0f / 0bA (3000): 0f / 0bBB (1000): 1f / 1bBB (2000): 1f / 1bBB (3000): 1f / 1bCCC (1000): 10f / 10bCCC (2000): 10f / 10bCCC (3000): 10f / 10bDDDD (1000): 25f / 30bDDDD (2000): 25f / 30bDDDD (3000): 25f / 30bEEEEE (1000): 50f / 40bEEEEE (2000): 50f / 40bEEEEE (3000): 50f / 40bFFFFFF (1000): 100f / 100bFFFFFF (2000): 100f / 100bFFFFFF (3000): 100f / 100bGGGGGGG (1000): 85.1f / 85.7bGGGGGGG (2000): 85.1f / 85.7bGGGGGGG (3000): 85.1f / 85.7b"`; -exports[`Grouped bar chart renders a svg @700 1`] = `"ABBCCCDDDDEEEEEFFFFFFGGGGGGG100f100bA (1000): 0f / 0bA (2000): 0f / 0bA (3000): 0f / 0bBB (1000): 1f / 1bBB (2000): 1f / 1bBB (3000): 1f / 1bCCC (1000): 10f / 10bCCC (2000): 10f / 10bCCC (3000): 10f / 10bDDDD (1000): 25f / 30bDDDD (2000): 25f / 30bDDDD (3000): 25f / 30bEEEEE (1000): 50f / 40bEEEEE (2000): 50f / 40bEEEEE (3000): 50f / 40bFFFFFF (1000): 100f / 100bFFFFFF (2000): 100f / 100bFFFFFF (3000): 100f / 100bGGGGGGG (1000): 85.1f / 85.7bGGGGGGG (2000): 85.1f / 85.7bGGGGGGG (3000): 85.1f / 85.7bA (1000): 0f / 0bA (2000): 0f / 0bA (3000): 0f / 0bBB (1000): 1f / 1bBB (2000): 1f / 1bBB (3000): 1f / 1bCCC (1000): 10f / 10bCCC (2000): 10f / 10bCCC (3000): 10f / 10bDDDD (1000): 25f / 30bDDDD (2000): 25f / 30bDDDD (3000): 25f / 30bEEEEE (1000): 50f / 40bEEEEE (2000): 50f / 40bEEEEE (3000): 50f / 40bFFFFFF (1000): 100f / 100bFFFFFF (2000): 100f / 100bFFFFFF (3000): 100f / 100bGGGGGGG (1000): 85.1f / 85.7bGGGGGGG (2000): 85.1f / 85.7bGGGGGGG (3000): 85.1f / 85.7b"`; +exports[`Grouped bar chart renders a svg @700 1`] = `"ABBCCCDDDDEEEEEFFFFFFGGGGGGG100f100bA (1000): 0f / 0bA (2000): 0f / 0bA (3000): 0f / 0bBB (1000): 1f / 1bBB (2000): 1f / 1bBB (3000): 1f / 1bCCC (1000): 10f / 10bCCC (2000): 10f / 10bCCC (3000): 10f / 10bDDDD (1000): 25f / 30bDDDD (2000): 25f / 30bDDDD (3000): 25f / 30bEEEEE (1000): 50f / 40bEEEEE (2000): 50f / 40bEEEEE (3000): 50f / 40bFFFFFF (1000): 100f / 100bFFFFFF (2000): 100f / 100bFFFFFF (3000): 100f / 100bGGGGGGG (1000): 85.1f / 85.7bGGGGGGG (2000): 85.1f / 85.7bGGGGGGG (3000): 85.1f / 85.7bA (1000): 0f / 0bA (2000): 0f / 0bA (3000): 0f / 0bBB (1000): 1f / 1bBB (2000): 1f / 1bBB (3000): 1f / 1bCCC (1000): 10f / 10bCCC (2000): 10f / 10bCCC (3000): 10f / 10bDDDD (1000): 25f / 30bDDDD (2000): 25f / 30bDDDD (3000): 25f / 30bEEEEE (1000): 50f / 40bEEEEE (2000): 50f / 40bEEEEE (3000): 50f / 40bFFFFFF (1000): 100f / 100bFFFFFF (2000): 100f / 100bFFFFFF (3000): 100f / 100bGGGGGGG (1000): 85.1f / 85.7bGGGGGGG (2000): 85.1f / 85.7bGGGGGGG (3000): 85.1f / 85.7b"`; -exports[`Grouped bar chart renders a svg @2000 1`] = `"ABBCCCDDDDEEEEEFFFFFFGGGGGGG100f100bA (1000): 0f / 0bA (2000): 0f / 0bA (3000): 0f / 0bBB (1000): 1f / 1bBB (2000): 1f / 1bBB (3000): 1f / 1bCCC (1000): 10f / 10bCCC (2000): 10f / 10bCCC (3000): 10f / 10bDDDD (1000): 25f / 30bDDDD (2000): 25f / 30bDDDD (3000): 25f / 30bEEEEE (1000): 50f / 40bEEEEE (2000): 50f / 40bEEEEE (3000): 50f / 40bFFFFFF (1000): 100f / 100bFFFFFF (2000): 100f / 100bFFFFFF (3000): 100f / 100bGGGGGGG (1000): 85.1f / 85.7bGGGGGGG (2000): 85.1f / 85.7bGGGGGGG (3000): 85.1f / 85.7bA (1000): 0f / 0bA (2000): 0f / 0bA (3000): 0f / 0bBB (1000): 1f / 1bBB (2000): 1f / 1bBB (3000): 1f / 1bCCC (1000): 10f / 10bCCC (2000): 10f / 10bCCC (3000): 10f / 10bDDDD (1000): 25f / 30bDDDD (2000): 25f / 30bDDDD (3000): 25f / 30bEEEEE (1000): 50f / 40bEEEEE (2000): 50f / 40bEEEEE (3000): 50f / 40bFFFFFF (1000): 100f / 100bFFFFFF (2000): 100f / 100bFFFFFF (3000): 100f / 100bGGGGGGG (1000): 85.1f / 85.7bGGGGGGG (2000): 85.1f / 85.7bGGGGGGG (3000): 85.1f / 85.7b"`; +exports[`Grouped bar chart renders a svg @2000 1`] = `"ABBCCCDDDDEEEEEFFFFFFGGGGGGG100f100bA (1000): 0f / 0bA (2000): 0f / 0bA (3000): 0f / 0bBB (1000): 1f / 1bBB (2000): 1f / 1bBB (3000): 1f / 1bCCC (1000): 10f / 10bCCC (2000): 10f / 10bCCC (3000): 10f / 10bDDDD (1000): 25f / 30bDDDD (2000): 25f / 30bDDDD (3000): 25f / 30bEEEEE (1000): 50f / 40bEEEEE (2000): 50f / 40bEEEEE (3000): 50f / 40bFFFFFF (1000): 100f / 100bFFFFFF (2000): 100f / 100bFFFFFF (3000): 100f / 100bGGGGGGG (1000): 85.1f / 85.7bGGGGGGG (2000): 85.1f / 85.7bGGGGGGG (3000): 85.1f / 85.7bA (1000): 0f / 0bA (2000): 0f / 0bA (3000): 0f / 0bBB (1000): 1f / 1bBB (2000): 1f / 1bBB (3000): 1f / 1bCCC (1000): 10f / 10bCCC (2000): 10f / 10bCCC (3000): 10f / 10bDDDD (1000): 25f / 30bDDDD (2000): 25f / 30bDDDD (3000): 25f / 30bEEEEE (1000): 50f / 40bEEEEE (2000): 50f / 40bEEEEE (3000): 50f / 40bFFFFFF (1000): 100f / 100bFFFFFF (2000): 100f / 100bFFFFFF (3000): 100f / 100bGGGGGGG (1000): 85.1f / 85.7bGGGGGGG (2000): 85.1f / 85.7bGGGGGGG (3000): 85.1f / 85.7b"`; -exports[`Grouped bar chart renders a svg with wrong more groups and labels as in the data 1`] = `"ABBCCCDDDDEEEEEFFFFFFGGGGGGG100f100bA (1000): 0f / 0bA (2000): 0f / 0bBB (1000): 1f / 1bBB (2000): 1f / 1bCCC (1000): 10f / 10bCCC (2000): 10f / 10bDDDD (1000): 25f / 30bDDDD (2000): 25f / 30bA (1000): 0f / 0bA (2000): 0f / 0bBB (1000): 1f / 1bBB (2000): 1f / 1bCCC (1000): 10f / 10bCCC (2000): 10f / 10bDDDD (1000): 25f / 30bDDDD (2000): 25f / 30b"`; +exports[`Grouped bar chart renders a svg with more groups and labels as in the data 1`] = `"ABBCCCDDDDEEEEEFFFFFFGGGGGGG100f100bA (1000): 0f / 0bA (2000): 0f / 0bBB (1000): 1f / 1bBB (2000): 1f / 1bCCC (1000): 10f / 10bCCC (2000): 10f / 10bDDDD (1000): 25f / 30bDDDD (2000): 25f / 30bA (1000): 0f / 0bA (2000): 0f / 0bBB (1000): 1f / 1bBB (2000): 1f / 1bCCC (1000): 10f / 10bCCC (2000): 10f / 10bDDDD (1000): 25f / 30bDDDD (2000): 25f / 30b"`; exports[`Grouped bar chart renders an empty svg with no data 1`] = `""`; diff --git a/onegov/election_day/assets/js/__tests__/d3.chart.grouped.js b/onegov/election_day/assets/js/__tests__/d3.chart.grouped.js index b173b42d..88dba207 100644 --- a/onegov/election_day/assets/js/__tests__/d3.chart.grouped.js +++ b/onegov/election_day/assets/js/__tests__/d3.chart.grouped.js @@ -12,12 +12,12 @@ const results = [ {"active": false, "group": "CCC", "value": {"front": 10, "back": 10}, "item": "1000"}, {"active": true, "group": "CCC", "value": {"front": 10, "back": 10}, "item": "2000"}, {"active": false, "group": "CCC", "value": {"front": 10, "back": 10}, "item": "3000"}, - {"active": false, "group": "DDDD", "value": {"front": 25, "back": 30}, "item": "1000"}, - {"active": true, "group": "DDDD", "value": {"front": 25, "back": 30}, "item": "2000"}, - {"active": false, "group": "DDDD", "value": {"front": 25, "back": 30}, "item": "3000"}, - {"active": false, "group": "EEEEE", "value": {"front": 50, "back": 40}, "item": "1000"}, - {"active": true, "group": "EEEEE", "value": {"front": 50, "back": 40}, "item": "2000"}, - {"active": false, "group": "EEEEE", "value": {"front": 50, "back": 40}, "item": "3000"}, + {"active": false, "group": "DDDD", "value": {"front": 25, "back": 30}, "item": "1000", "color": "#ff6300"}, + {"active": true, "group": "DDDD", "value": {"front": 25, "back": 30}, "item": "2000", "color": "#ff6300"}, + {"active": false, "group": "DDDD", "value": {"front": 25, "back": 30}, "item": "3000", "color": "#ff6300"}, + {"active": false, "group": "EEEEE", "value": {"front": 50, "back": 40}, "item": "1000", "color": "#4068c8"}, + {"active": true, "group": "EEEEE", "value": {"front": 50, "back": 40}, "item": "2000", "color": "#4068c8"}, + {"active": false, "group": "EEEEE", "value": {"front": 50, "back": 40}, "item": "3000", "color": "#4068c8"}, {"active": false, "group": "FFFFFF", "value": {"front": 100, "back": 100}, "item": "1000"}, {"active": true, "group": "FFFFFF", "value": {"front": 100, "back": 100}, "item": "2000"}, {"active": false, "group": "FFFFFF", "value": {"front": 100, "back": 100}, "item": "3000"}, @@ -130,7 +130,7 @@ describe('Grouped bar chart', () => { expect(chart.width()).toBe(2000); }); - it('renders a svg with wrong more groups and labels as in the data', () => { + it('renders a svg with more groups and labels as in the data', () => { var document = jsdom.jsdom(); var chart = groupedChart({ width: 700,