diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2019-03-30 12:17:56 +0100 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2019-03-30 12:17:56 +0100 |
| commit | 164b92454f2814e73dee9f673c1de07b715bc424 (patch) | |
| tree | 595a2ae4f2621bed30e339bb795081a0882728f2 /client | |
| parent | ab46c9007b862eb512fe66cc47a325a7a374e20c (diff) | |
pie chart test
Diffstat (limited to 'client')
| -rw-r--r-- | client/applet.js | 6 | ||||
| -rw-r--r-- | client/chart/constants.js | 33 | ||||
| -rw-r--r-- | client/chart/countriesByYear.chart.js (renamed from client/chart/chart.container.js) | 38 | ||||
| -rw-r--r-- | client/chart/index.js | 6 | ||||
| -rw-r--r-- | client/chart/pie.charts.js | 167 |
5 files changed, 211 insertions, 39 deletions
diff --git a/client/applet.js b/client/applet.js index cd73925c..21e1e4fa 100644 --- a/client/applet.js +++ b/client/applet.js @@ -4,7 +4,7 @@ import { Container as FaceSearchContainer } from './faceSearch' import { Container as FaceAnalysisContainer } from './faceAnalysis' import { Container as NameSearchContainer } from './nameSearch' import { Container as DatasetListContainer } from './datasetList' -import { Container as ChartContainer } from './chart' +import { CountriesByYear, PieCharts } from './chart' export default class Applet extends Component { render() { @@ -19,7 +19,9 @@ export default class Applet extends Component { case 'dataset_list': return <DatasetListContainer {...this.props} /> case 'chart': - return <ChartContainer {...this.props} /> + return <CountriesByYear {...this.props} /> + case 'piechart': + return <PieCharts {...this.props} /> default: return <pre style={{ color: '#0f0' }}>{'Megapixels'}</pre> } 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/chart.container.js b/client/chart/countriesByYear.chart.js index aa80100e..c846fd0f 100644 --- a/client/chart/chart.container.js +++ b/client/chart/countriesByYear.chart.js @@ -6,41 +6,9 @@ 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', -] +import { rainbow, colorblindSafeRainbow, topCountryCount, otherCountriesLabel } from './constants' -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 { +class CountriesByYearChart extends Component { render() { const { payload } = this.props const { paper, citations } = payload.data @@ -196,4 +164,4 @@ class ChartContainer extends Component { } } -export default ChartContainer +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 ( + <div className='chart'> + <C3Chart + data={{ + x: 'x', + columns: citationCountsByYear, + type: 'bar', + groups: [ topCountries.concat(otherCountriesLabel) ], + }} + axis={{ + x: { + type: 'category' // this needed to load string x value + }, + y: { + show: false, + }, + y2: { + tick: { + values: ticks, + }, + default: [ 0, maxCitationsInAYear * 286 / 261 ], + show: true, + } + }} + legend={{ + position: 'right' + }} + color={{ + pattern: colorPattern + }} + tooltip={{ + contents: function (d, defaultTitleFormat, defaultValueFormat, color) { + const countriesByYearLookup = years[yearList[d[0].x]] + let countriesByYear = Object.keys(countriesByYearLookup).map(country => [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 [ + "<tr>", + "<td>", + "<span style='background-color:" + color + "' class='swatch'></span>", + country, + "</td>", + "<td>", + total, + "</td>", + "</tr>", + ].join('') + }) + return [ + "<table class='c3-tooltip'>", + ...tableRows, + "</table>", + ].join('') + } + }} + /> + </div> + ) + } +} + +export default PieCharts |
