Skip to content
This repository has been archived by the owner on Aug 17, 2020. It is now read-only.

Commit

Permalink
feat: add download section in mun view
Browse files Browse the repository at this point in the history
Note: the new data file, grouped by date, is a lot bigger: 11MB instead of 4.6MB
(or compressed by gz: 531KB instead of 289KB)
  • Loading branch information
severo committed Apr 15, 2019
1 parent d4650dc commit 0651f63
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 15 deletions.
3 changes: 2 additions & 1 deletion docs/css/main.css

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
<title>Quem bebe agrotóxicos?</title>
<!-- TODO: bundle at build -->
<script defer src="https://bundle.run/fuzzball@1.2.0"></script>
<script defer src="lib/main.pt.js?v=1555282675"></script>
<link rel="stylesheet" href="css/main.css?v=1555282675" />
<script defer src="lib/main.pt.js?v=1555335088"></script>
<link rel="stylesheet" href="css/main.css?v=1555335088" />
</head>
<body>
<section id="page-title" class="hero is-small is-primary cocktail">
Expand Down Expand Up @@ -93,6 +93,7 @@ <h2 class="subtitle is-4">
<footer id="details-footer">
<nav id="to-other-views" class="content"></nav>
<section id="to-article" class="content"></section>
<section id="download" class="content"></section>
<section id="source" class="content"></section>
</footer>
</section>
Expand Down
2 changes: 1 addition & 1 deletion docs/lib/main.pt.js

Large diffs are not rendered by default.

30 changes: 19 additions & 11 deletions src/_javascript/data/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ export const cfg = {
// Published in https://github.com/severo/data_brazil
tests: {
integrityHash:
'sha384-A0apYNqz52d3JYGAxIZ0NAZL62PfXiD0EvxqA79yyqteRm526Thk7HSx4RkbTHmS',
'sha384-HalAFzIfE4ufclJBlandxnRAPt63GUYtQInBVSWYQOFcAZmVXY2BySUcy9QuOIjk',
url:
'https://raw.githubusercontent.com/severo/data_brazil/master/tests_data.json',
'https://raw.githubusercontent.com/severo/data_brazil/master/tests_data.20180415.json',
},
topojson: {
integrityHash:
Expand Down Expand Up @@ -297,20 +297,28 @@ function toFeatures(topojson, key) {
return features;
}

function parseTests(tests, substancesLut) {
function parseTests(testsBySubstanceByDate, substancesLut) {
// Placeholder to compute max
const DETECTED_VALUE = 1e-10;
const keys = Object.keys(tests);
const keys = Object.keys(testsBySubstanceByDate);
return keys.reduce((acc, substanceCode) => {
const test = tests[substanceCode];
const testsByDate = testsBySubstanceByDate[substanceCode];
const dates = Object.keys(testsByDate);
const parsedTestsByDate = dates.map(date => {
return {
date: date,
tests: testsByDate[date].map(str => {
if (str === 'NA') {
return DETECTED_VALUE;
}
return +str;
}),
};
});
const fTest = {
substance: substancesLut[substanceCode],
tests: test.map(str => {
if (str === 'NA') {
return DETECTED_VALUE;
}
return +str;
}),
tests: parsedTestsByDate.map(date => date.tests).flat(),
testsByDate: parsedTestsByDate,
};
fTest.max = fTest.tests.reduce((max, cur) => {
if (cur > max) {
Expand Down
119 changes: 119 additions & 0 deletions src/_javascript/details/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {makeTubesCocktail, makeTubesLimits} from './tubes';
import {MAP2} from '../data';
import {csvFormat} from 'd3-dsv';

//const DETECTED_VALUE = 1e-10;

Expand Down Expand Up @@ -35,6 +36,7 @@ function makeBrazil(parent, dispatcher, view, state) {
.html('{{details.limits.brazil.content}}');
makeLimitsToOtherViews(parent, dispatcher, state);
makeToArticle(parent);
emptyDownload(parent);
makeSource(parent);
} else {
makeHeader(main, '{{details.cocktail.brazil.title}}');
Expand All @@ -44,6 +46,7 @@ function makeBrazil(parent, dispatcher, view, state) {
.html('{{details.cocktail.brazil.content}}');
makeCocktailToOtherViews(parent, dispatcher, state);
makeToArticle(parent);
emptyDownload(parent);
makeSource(parent);
}
}
Expand Down Expand Up @@ -80,6 +83,7 @@ function makeMun(parent, dispatcher, view, state) {
makeLimits(main, dispatcher, state.mun, state.data);
makeLimitsToOtherViews(parent, dispatcher, state);
makeToArticle(parent);
makeDownload(parent, state.mun, state.data);
makeSource(parent);
/*} else if (view === 'substances') {
// init
Expand All @@ -93,6 +97,7 @@ function makeMun(parent, dispatcher, view, state) {
makeCocktail(main, dispatcher, state.mun, state.data);
makeCocktailToOtherViews(parent, dispatcher, state);
makeToArticle(parent);
makeDownload(parent, state.mun, state.data);
makeSource(parent);
}
}
Expand Down Expand Up @@ -387,6 +392,37 @@ function makeToArticle(parent) {
.text('{{details.cocktail.footer.toarticle2}}');
par.append('span').text('{{details.cocktail.footer.toarticle3}}');
}
function emptyDownload(parent, mun, data) {
parent.select('#details-footer #download').html(null);
}
function makeDownload(parent, mun, data) {
const par = parent.select('#details-footer #download').html(null);
const munNameForFilename = mun.properties.deburredName
.replace(/[^a-z0-9]/gi, '_')
.toLowerCase();
par.append('h4').html('{{details.cocktail.footer.download1}}');
const ul = par.append('ul');
const li1 = ul.append('li');
li1
.append('a')
.attr(
'download',
'{{details.csv.dates.filename}}' + munNameForFilename + '.csv'
)
.attr('href', URL.createObjectURL(generateByDateCsvBlob(mun)))
.text('{{details.cocktail.footer.download22}} ' + mun.properties.name);
li1.append('span').text('{{details.cocktail.footer.download23}}');
const li2 = ul.append('li');
li2
.append('a')
.attr(
'download',
'{{details.csv.substances.filename}}' + munNameForFilename + '.csv'
)
.attr('href', URL.createObjectURL(generateBySubstanceCsvBlob(mun, data)))
.text('{{details.cocktail.footer.download32}} ' + mun.properties.name);
li2.append('span').text('{{details.cocktail.footer.download33}}');
}

function makeSource(parent) {
const par = parent.select('#details-footer #source').html(null);
Expand All @@ -413,6 +449,89 @@ function makeSource(parent) {
li2.append('span').text('{{details.cocktail.footer.source33}}');
}

function generateBySubstanceJson(mun, data) {
const EUROPEAN_LIMIT = 0.1;
const json = Object.keys(data.substancesLut)
.sort((key1, key2) => key1.localeCompare(key2, '{{locale}}'))
.map(key => {
const substanceTest = mun.properties.tests.find(
test => test.substance.code === key
);
return {
'{{details.csv.substances.columns.name}}': data.substancesLut[key].name,
'{{details.csv.substances.columns.supbr}}': substanceTest
? substanceTest.tests.filter(
test => test > substanceTest.substance.limit
).length
: 0,
'{{details.csv.substances.columns.supeu}}': substanceTest
? substanceTest.tests.filter(test => test > EUROPEAN_LIMIT).length
: 0,
'{{details.csv.substances.columns.tests}}': substanceTest
? substanceTest.tests.length
: 0,
};
});
return json;
}
function generateBySubstanceCsvBlob(mun, data) {
const orderedColumnNames = [
'{{details.csv.substances.columns.name}}',
'{{details.csv.substances.columns.tests}}',
'{{details.csv.substances.columns.supeu}}',
'{{details.csv.substances.columns.supbr}}',
];
return new Blob(
[csvFormat(generateBySubstanceJson(mun, data), orderedColumnNames)],
{
type: 'text/csv',
}
);
}

function generateByDateJson(mun) {
const resultsByDate = mun.properties.tests.reduce((acc, testsSubstance) => {
testsSubstance.testsByDate.forEach(testsDate => {
if (!(testsDate.date in acc)) {
acc[testsDate.date] = 0;
}
acc[testsDate.date] += testsDate.tests.length;
});
return acc;
}, {});
const dates = Object.keys(resultsByDate).sort(
(date1, date2) => date1 > date2
);
const json = dates.map(date => {
const yearLength = 4;
const monthLength = 2;
const dayLength = 2;
const isoDate =
date.slice(0, yearLength) +
'-' +
date.slice(yearLength, yearLength + monthLength) +
'-' +
date.slice(
yearLength + monthLength,
yearLength + monthLength + dayLength
);
return {
'{{details.csv.dates.columns.date}}': isoDate,
'{{details.csv.dates.columns.number}}': resultsByDate[date],
};
});
return json;
}
function generateByDateCsvBlob(mun) {
const orderedColumnNames = [
'{{details.csv.dates.columns.date}}',
'{{details.csv.dates.columns.number}}',
];
return new Blob([csvFormat(generateByDateJson(mun), orderedColumnNames)], {
type: 'text/csv',
});
}

function startLoading(element) {
element.classed('is-loading', true);
}
Expand Down
1 change: 1 addition & 0 deletions src/_sass/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ html {
}
#to-article {
}
#download,
#source {
margin-top: 4rem;
font-size: 0.7rem;
Expand Down
1 change: 1 addition & 0 deletions src/index.mustache.html
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ <h2 class="subtitle is-4">
<footer id="details-footer">
<nav id="to-other-views" class="content"></nav>
<section id="to-article" class="content"></section>
<section id="download" class="content"></section>
<section id="source" class="content"></section>
</footer>
</section>
Expand Down
25 changes: 25 additions & 0 deletions src/lang/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,24 @@
"goto-brazil": "Voltar para o mapa do Brasil"
},
"details": {
"csv": {
"dates": {
"columns": {
"date": "Data",
"number": "Número de testes realizados"
},
"filename": "testes_por_data_em_"
},
"substances": {
"columns": {
"name": "Agrotóxicos",
"tests": "Testes feitos",
"supeu": "Acima do limite da UE",
"supbr": "Acima do limite do Brasil"
},
"filename": "testes_e_resultados_por_agrótoxico_em_"
}
},
"cocktail": {
"brazil": {
"content": "Agrotóxicos foram detectados na água que abastece mais de 2.300 cidades de 2014 a 2017. Clique no mapa ou digite sua cidade para descobrir quais produtos químicos saíram da sua torneira.",
Expand Down Expand Up @@ -34,6 +52,13 @@
"toarticle1": "Entenda: leia",
"toarticle2": "reportagem sobre a contaminação da água nas cidades",
"toarticle3": ".",
"download1": "Download",
"download21": "",
"download22": "Número de testes realizados por data na cidade de",
"download23": " (CSV).",
"download31": "",
"download32": "Número de testes e resultados por tipo de agrotóxico na cidade de",
"download33": " (CSV).",
"source1": "Fontes",
"source21": "Detecção e concentração de agrotóxicos: ",
"source22": "SISAGUA - Controle Semestral",
Expand Down

0 comments on commit 0651f63

Please sign in to comment.