From 164b92454f2814e73dee9f673c1de07b715bc424 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sat, 30 Mar 2019 12:17:56 +0100 Subject: pie chart test --- client/chart/chart.container.js | 199 ---------------------------------- client/chart/constants.js | 33 ++++++ client/chart/countriesByYear.chart.js | 167 ++++++++++++++++++++++++++++ client/chart/index.js | 6 +- client/chart/pie.charts.js | 167 ++++++++++++++++++++++++++++ 5 files changed, 371 insertions(+), 201 deletions(-) delete mode 100644 client/chart/chart.container.js create mode 100644 client/chart/constants.js create mode 100644 client/chart/countriesByYear.chart.js create mode 100644 client/chart/pie.charts.js (limited to 'client/chart') diff --git a/client/chart/chart.container.js b/client/chart/chart.container.js deleted file mode 100644 index aa80100e..00000000 --- a/client/chart/chart.container.js +++ /dev/null @@ -1,199 +0,0 @@ -import React, { Component } from 'react' -import { bindActionCreators } from 'redux' -import { connect } from 'react-redux' -import { toArray } from '../util' -import C3Chart from 'react-c3js' -import 'c3/c3.css' -import './chart.css' - -const rainbow = [ - '#9e0142', - '#d53e4f', - '#f46d43', - '#fdae61', - '#fee08b', - '#ffffbf', - '#e6f598', - '#abdda4', - '#66c2a5', - '#3288bd', - '#5e4fa2', - // '#888888', -] - -const colorblindSafeRainbow = [ - '#a50026', - '#d73027', - '#f46d43', - '#fdae61', - '#fee090', - '#ffffbf', - '#e0f3f8', - '#abd9e9', - '#74add1', - '#4575b4', - '#313695', - // '#888888', -] - -const topCountryCount = 10 - -const otherCountriesLabel = 'Other Countries' - -class ChartContainer extends Component { - render() { - const { payload } = this.props - const { paper, citations } = payload.data - if (!citations.length) return null - const years = {} - const countries = {} - citations.forEach(citation => { - let { year, addresses } = citation - if (!year || !parseInt(year)) return - year = parseInt(year) - years[year] = years[year] || {} - addresses.forEach(address => { - const { country } = address - if (!country) return - if (!(country in countries)) { - countries[country] = 1 - } else { - countries[country] += 1 - } - if (country in years[year]) { - years[year][country] += 1 - } else { - years[year][country] = 1 - countries[country] = true - } - }) - }) - let yearList = Object.keys(years).map(year => parseInt(year)).sort() - for (let i = yearList[0]; i < yearList[-1]; i++) { - if (!(i in years)) { - years[i] = {} - } - } - yearList = Object.keys(years).map(year => parseInt(year)).sort() - - Object.keys(countries).forEach(country => { - yearList.forEach(year => { - if (!(country in years[year])) years[year][country] = 0 - }) - }) - - // figure out the top N countries in the dataset - const countriesByCount = Object.keys(countries).sort((a,b) => countries[b] - countries[a]) - // console.log(countriesByCount) - let topCountries = countriesByCount.slice(0, topCountryCount) - let otherCountries = countriesByCount.slice(topCountryCount) - - let citationCountsByYear = - [ ['x'].concat(yearList.map(year => String(year))) ] - .concat( - topCountries - .map(country => - [country] - .concat( - yearList - .map(year => years[year][country]) - ) - ) - ) - - citationCountsByYear.push( - [otherCountriesLabel].concat( - yearList.map(year => otherCountries.reduce((a,b) => (a + years[year][b]), 0)) - ) - ) - - let maxCitationsInAYear = 0 - let currentSum = 0 - // for each year... - for (let j = 1; j < citationCountsByYear[0].length; j++) { - // for each country - currentSum = 0 - for (let i = 1; i < citationCountsByYear.length; i++) { - currentSum += citationCountsByYear[i][j] - } - maxCitationsInAYear = Math.max(currentSum, maxCitationsInAYear) - } - - let ticks = [] - for (let i = 0; i < maxCitationsInAYear; i += 50) { - ticks.push(i) - } - if (ticks[ticks.length - 1] < maxCitationsInAYear) { - ticks.push('') - } - - const colorPattern = rainbow - - return ( -
- [country, countriesByYearLookup[country]]).sort((a,b) => b[1] - a[1]) - let topCountriesForThisYear = countriesByYear.slice(0, topCountryCount) - let bottomTotal = countriesByYear.slice(topCountryCount).reduce((a,b) => (a + b[1]), 0) - // console.log(topCountriesForThisYear) - topCountriesForThisYear.push([otherCountriesLabel, bottomTotal]) - const tableRows = topCountriesForThisYear.filter(pair => !!pair[1]).map(([country, total]) => { - let colorIndex = topCountries.indexOf(country) - if (colorIndex < 0) colorIndex = colorPattern.length - 1 - const color = colorPattern[ colorIndex ] - return [ - "", - "", - "", - country, - "", - "", - total, - "", - "", - ].join('') - }) - return [ - "", - ...tableRows, - "
", - ].join('') - } - }} - /> -
- ) - } -} - -export default ChartContainer diff --git a/client/chart/constants.js b/client/chart/constants.js new file mode 100644 index 00000000..295b9232 --- /dev/null +++ b/client/chart/constants.js @@ -0,0 +1,33 @@ +export const rainbow = [ + '#9e0142', + '#d53e4f', + '#f46d43', + '#fdae61', + '#fee08b', + '#ffffbf', + '#e6f598', + '#abdda4', + '#66c2a5', + '#3288bd', + '#5e4fa2', + // '#888888', +] + +export const colorblindSafeRainbow = [ + '#a50026', + '#d73027', + '#f46d43', + '#fdae61', + '#fee090', + '#ffffbf', + '#e0f3f8', + '#abd9e9', + '#74add1', + '#4575b4', + '#313695', + // '#888888', +] + +export const topCountryCount = 10 + +export const otherCountriesLabel = 'Other Countries' diff --git a/client/chart/countriesByYear.chart.js b/client/chart/countriesByYear.chart.js new file mode 100644 index 00000000..c846fd0f --- /dev/null +++ b/client/chart/countriesByYear.chart.js @@ -0,0 +1,167 @@ +import React, { Component } from 'react' +import { bindActionCreators } from 'redux' +import { connect } from 'react-redux' +import { toArray } from '../util' +import C3Chart from 'react-c3js' +import 'c3/c3.css' +import './chart.css' + +import { rainbow, colorblindSafeRainbow, topCountryCount, otherCountriesLabel } from './constants' + +class CountriesByYearChart extends Component { + render() { + const { payload } = this.props + const { paper, citations } = payload.data + if (!citations.length) return null + const years = {} + const countries = {} + citations.forEach(citation => { + let { year, addresses } = citation + if (!year || !parseInt(year)) return + year = parseInt(year) + years[year] = years[year] || {} + addresses.forEach(address => { + const { country } = address + if (!country) return + if (!(country in countries)) { + countries[country] = 1 + } else { + countries[country] += 1 + } + if (country in years[year]) { + years[year][country] += 1 + } else { + years[year][country] = 1 + countries[country] = true + } + }) + }) + let yearList = Object.keys(years).map(year => parseInt(year)).sort() + for (let i = yearList[0]; i < yearList[-1]; i++) { + if (!(i in years)) { + years[i] = {} + } + } + yearList = Object.keys(years).map(year => parseInt(year)).sort() + + Object.keys(countries).forEach(country => { + yearList.forEach(year => { + if (!(country in years[year])) years[year][country] = 0 + }) + }) + + // figure out the top N countries in the dataset + const countriesByCount = Object.keys(countries).sort((a,b) => countries[b] - countries[a]) + // console.log(countriesByCount) + let topCountries = countriesByCount.slice(0, topCountryCount) + let otherCountries = countriesByCount.slice(topCountryCount) + + let citationCountsByYear = + [ ['x'].concat(yearList.map(year => String(year))) ] + .concat( + topCountries + .map(country => + [country] + .concat( + yearList + .map(year => years[year][country]) + ) + ) + ) + + citationCountsByYear.push( + [otherCountriesLabel].concat( + yearList.map(year => otherCountries.reduce((a,b) => (a + years[year][b]), 0)) + ) + ) + + let maxCitationsInAYear = 0 + let currentSum = 0 + // for each year... + for (let j = 1; j < citationCountsByYear[0].length; j++) { + // for each country + currentSum = 0 + for (let i = 1; i < citationCountsByYear.length; i++) { + currentSum += citationCountsByYear[i][j] + } + maxCitationsInAYear = Math.max(currentSum, maxCitationsInAYear) + } + + let ticks = [] + for (let i = 0; i < maxCitationsInAYear; i += 50) { + ticks.push(i) + } + if (ticks[ticks.length - 1] < maxCitationsInAYear) { + ticks.push('') + } + + const colorPattern = rainbow + + return ( +
+ [country, countriesByYearLookup[country]]).sort((a,b) => b[1] - a[1]) + let topCountriesForThisYear = countriesByYear.slice(0, topCountryCount) + let bottomTotal = countriesByYear.slice(topCountryCount).reduce((a,b) => (a + b[1]), 0) + // console.log(topCountriesForThisYear) + topCountriesForThisYear.push([otherCountriesLabel, bottomTotal]) + const tableRows = topCountriesForThisYear.filter(pair => !!pair[1]).map(([country, total]) => { + let colorIndex = topCountries.indexOf(country) + if (colorIndex < 0) colorIndex = colorPattern.length - 1 + const color = colorPattern[ colorIndex ] + return [ + "", + "", + "", + country, + "", + "", + total, + "", + "", + ].join('') + }) + return [ + "", + ...tableRows, + "
", + ].join('') + } + }} + /> +
+ ) + } +} + +export default CountriesByYearChart diff --git a/client/chart/index.js b/client/chart/index.js index e9d3322d..27650020 100644 --- a/client/chart/index.js +++ b/client/chart/index.js @@ -1,5 +1,7 @@ -import Container from './chart.container' +import CountriesByYear from './countriesByYear.chart' +import PieCharts from './pie.charts' export { - Container, + CountriesByYear, + PieCharts, } diff --git a/client/chart/pie.charts.js b/client/chart/pie.charts.js new file mode 100644 index 00000000..998d6758 --- /dev/null +++ b/client/chart/pie.charts.js @@ -0,0 +1,167 @@ +import React, { Component } from 'react' +import { bindActionCreators } from 'redux' +import { connect } from 'react-redux' +import { toArray } from '../util' +import C3Chart from 'react-c3js' +import 'c3/c3.css' +import './chart.css' + +import { rainbow, colorblindSafeRainbow, topCountryCount, otherCountriesLabel } from './constants' + +class PieCharts extends Component { + render() { + const { payload } = this.props + const { paper, citations } = payload.data + if (!citations.length) return null + const years = {} + const countries = {} + citations.forEach(citation => { + let { year, addresses } = citation + if (!year || !parseInt(year)) return + year = parseInt(year) + years[year] = years[year] || {} + addresses.forEach(address => { + const { country } = address + if (!country) return + if (!(country in countries)) { + countries[country] = 1 + } else { + countries[country] += 1 + } + if (country in years[year]) { + years[year][country] += 1 + } else { + years[year][country] = 1 + countries[country] = true + } + }) + }) + let yearList = Object.keys(years).map(year => parseInt(year)).sort() + for (let i = yearList[0]; i < yearList[-1]; i++) { + if (!(i in years)) { + years[i] = {} + } + } + yearList = Object.keys(years).map(year => parseInt(year)).sort() + + Object.keys(countries).forEach(country => { + yearList.forEach(year => { + if (!(country in years[year])) years[year][country] = 0 + }) + }) + + // figure out the top N countries in the dataset + const countriesByCount = Object.keys(countries).sort((a,b) => countries[b] - countries[a]) + // console.log(countriesByCount) + let topCountries = countriesByCount.slice(0, topCountryCount) + let otherCountries = countriesByCount.slice(topCountryCount) + + let citationCountsByYear = + [ ['x'].concat(yearList.map(year => String(year))) ] + .concat( + topCountries + .map(country => + [country] + .concat( + yearList + .map(year => years[year][country]) + ) + ) + ) + + citationCountsByYear.push( + [otherCountriesLabel].concat( + yearList.map(year => otherCountries.reduce((a,b) => (a + years[year][b]), 0)) + ) + ) + + let maxCitationsInAYear = 0 + let currentSum = 0 + // for each year... + for (let j = 1; j < citationCountsByYear[0].length; j++) { + // for each country + currentSum = 0 + for (let i = 1; i < citationCountsByYear.length; i++) { + currentSum += citationCountsByYear[i][j] + } + maxCitationsInAYear = Math.max(currentSum, maxCitationsInAYear) + } + + let ticks = [] + for (let i = 0; i < maxCitationsInAYear; i += 50) { + ticks.push(i) + } + if (ticks[ticks.length - 1] < maxCitationsInAYear) { + ticks.push('') + } + + const colorPattern = rainbow + + return ( +
+ [country, countriesByYearLookup[country]]).sort((a,b) => b[1] - a[1]) + let topCountriesForThisYear = countriesByYear.slice(0, topCountryCount) + let bottomTotal = countriesByYear.slice(topCountryCount).reduce((a,b) => (a + b[1]), 0) + // console.log(topCountriesForThisYear) + topCountriesForThisYear.push([otherCountriesLabel, bottomTotal]) + const tableRows = topCountriesForThisYear.filter(pair => !!pair[1]).map(([country, total]) => { + let colorIndex = topCountries.indexOf(country) + if (colorIndex < 0) colorIndex = colorPattern.length - 1 + const color = colorPattern[ colorIndex ] + return [ + "", + "", + "", + country, + "", + "", + total, + "", + "", + ].join('') + }) + return [ + "", + ...tableRows, + "
", + ].join('') + } + }} + /> +
+ ) + } +} + +export default PieCharts -- cgit v1.2.3-70-g09d2