David Pomerenke commited on
Commit
b54f543
·
1 Parent(s): a683732

Add nice cumulative language population plot

Browse files
frontend/src/App.js CHANGED
@@ -7,6 +7,7 @@ import DatasetTable from './components/DatasetTable'
7
  import WorldMap from './components/WorldMap'
8
  import AutoComplete from './components/AutoComplete'
9
  import LanguagePlot from './components/LanguagePlot'
 
10
  import { Carousel } from 'primereact/carousel'
11
 
12
  function App () {
@@ -128,7 +129,8 @@ function App () {
128
  <Carousel
129
  value={[
130
  <WorldMap data={data.countries} />,
131
- <LanguagePlot data={data} />
 
132
  ]}
133
  numScroll={1}
134
  numVisible={1}
 
7
  import WorldMap from './components/WorldMap'
8
  import AutoComplete from './components/AutoComplete'
9
  import LanguagePlot from './components/LanguagePlot'
10
+ import SpeakerPlot from './components/SpeakerPlot'
11
  import { Carousel } from 'primereact/carousel'
12
 
13
  function App () {
 
129
  <Carousel
130
  value={[
131
  <WorldMap data={data.countries} />,
132
+ <LanguagePlot data={data} />,
133
+ <SpeakerPlot data={data} />
134
  ]}
135
  numScroll={1}
136
  numVisible={1}
frontend/src/components/SpeakerPlot.js ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useRef, useEffect } from 'react'
2
+ import * as Plot from '@observablehq/plot'
3
+
4
+ const SpeakerPlot = ({ data }) => {
5
+ const containerRef = useRef()
6
+ const allSpeakers = data.language_table.reduce((sum, curr) => sum + curr.speakers, 0)
7
+ const languages = data.language_table.sort((a, b) => b.speakers - a.speakers).slice(0, 100).reduce((acc, d) => {
8
+ acc.push({
9
+ ...d,
10
+ rank: acc.length + 1,
11
+ cumSpeakers: acc.reduce((sum, curr) => sum + curr.speakers, 0) + d.speakers,
12
+ cumSpeakersPercent: (acc.reduce((sum, curr) => sum + curr.speakers, 0) + d.speakers) / allSpeakers
13
+ })
14
+ return acc
15
+ }, [])
16
+
17
+ useEffect(() => {
18
+ const plot = Plot.plot({
19
+ width: 750,
20
+ height: 500,
21
+ // title: 'Proficiency of Languages by Number of Speakers',
22
+ x: {
23
+ label: 'Languages',
24
+ ticks: [],
25
+ },
26
+ y: {
27
+ label: 'Number of Speakers (millions)',
28
+ },
29
+ color: {
30
+ legend: true,
31
+ domain: ["Speakers", "Cumulative Speakers"],
32
+ range: ["green", "lightgrey"],
33
+ },
34
+ marks: [
35
+ Plot.barY(languages,
36
+ {
37
+ x: "rank",
38
+ y: d => d.cumSpeakers / 1e6,
39
+ fill: d => "Cumulative Speakers",
40
+ sort: { x: 'y' },
41
+ title: d => `The ${d.rank} most spoken languages cover\n${d.cumSpeakersPercent.toLocaleString("en-US", { style: 'percent'})} of all speakers`,
42
+ tip: true // {y: d => d.cumSpeakers / 1e6 * 2}
43
+ }),
44
+ Plot.barY(languages,
45
+ {
46
+ x: "rank",
47
+ y: d => d.speakers / 1e6,
48
+ title: d => `${d.language_name}\n(${d.speakers.toLocaleString("en-US", {notation: 'compact', compactDisplay: 'long'})} speakers)`,
49
+ tip: true,
50
+ fill: d => "Speakers",
51
+ sort: { x: '-y' }
52
+ }),
53
+ Plot.crosshairX(languages, {x: "rank", y: d => d.cumSpeakers / 1e6, textStrokeOpacity: 0, textFillOpacity: 0}),
54
+ Plot.tip(["The 41 most spoken languages cover 80% of all speakers."], {x: 41, y: languages[40].cumSpeakers / 1e6})
55
+ ],
56
+ })
57
+ containerRef.current.append(plot)
58
+ return () => plot.remove()
59
+ }, [])
60
+
61
+ return (
62
+ <div
63
+ ref={containerRef}
64
+ style={{
65
+ width: '100%',
66
+ height: '100%',
67
+ display: 'flex',
68
+ alignItems: 'center',
69
+ justifyContent: 'center',
70
+ }}
71
+ />
72
+ )
73
+ }
74
+
75
+ export default SpeakerPlot