Skip to content

Commit 59e4870

Browse files
authored
Add excess hydropower credits post (#337)
1 parent dc673e3 commit 59e4870

File tree

7 files changed

+449
-0
lines changed

7 files changed

+449
-0
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import { Box } from 'theme-ui'
2+
import { format } from 'd3-format'
3+
import {
4+
Chart,
5+
Ticks,
6+
TickLabels,
7+
Axis,
8+
AxisLabel,
9+
Bar,
10+
Plot,
11+
Line,
12+
Label,
13+
Grid,
14+
} from '@carbonplan/charts'
15+
16+
const data = {
17+
2009: 2605227,
18+
2010: 4991786,
19+
2011: 7670460,
20+
2012: 11857529,
21+
2013: 8307486,
22+
2014: 5508923,
23+
2015: 5264806,
24+
2016: 3310261,
25+
2017: 3071090,
26+
2018: 5971540,
27+
2019: 9604842,
28+
2020: 19355331,
29+
2021: 43046942,
30+
2022: 33783221,
31+
2023: 37728043,
32+
2024: 15870432,
33+
2025: 6077005,
34+
}
35+
36+
const counts = Object.keys(data).map((k) => [parseInt(k), data[k]])
37+
38+
const Issuances = () => {
39+
const formatter = format('~s')
40+
41+
return (
42+
<Box sx={{ width: '100%', height: ['275px', '350px', '350px', '350px'] }}>
43+
<Chart x={[2008, 2026]} y={[0, 40000000]} padding={{ left: 60 }}>
44+
<Ticks left />
45+
<Ticks
46+
bottom
47+
count={10}
48+
sx={{ display: ['none', 'inherit', 'inherit', 'inherit'] }}
49+
/>
50+
<Ticks
51+
bottom
52+
count={5}
53+
sx={{ display: ['inherit', 'none', 'none', 'none'] }}
54+
/>
55+
<TickLabels left format={formatter} />
56+
<TickLabels
57+
bottom
58+
count={10}
59+
sx={{ display: ['none', 'inherit', 'inherit', 'inherit'] }}
60+
/>
61+
<TickLabels
62+
bottom
63+
count={5}
64+
sx={{ display: ['inherit', 'none', 'none', 'none'] }}
65+
/>
66+
<Axis left bottom />
67+
<Grid
68+
vertical
69+
count={10}
70+
sx={{ display: ['none', 'inherit', 'inherit', 'inherit'] }}
71+
/>
72+
<Grid
73+
vertical
74+
count={5}
75+
sx={{ display: ['inherit', 'none', 'none', 'none'] }}
76+
/>
77+
<AxisLabel left align='left'>
78+
Credits
79+
</AxisLabel>
80+
<AxisLabel bottom>Issuance year</AxisLabel>
81+
<Plot>
82+
<defs>
83+
<pattern
84+
id={`hatch-pattern`}
85+
patternUnits='userSpaceOnUse'
86+
width={1}
87+
height={1}
88+
patternTransform={'rotate(35)'}
89+
>
90+
<Box
91+
as='line'
92+
x1='0'
93+
y1='0'
94+
x2='0'
95+
y2='1'
96+
sx={{
97+
stroke: 'blue',
98+
strokeWidth: 1,
99+
}}
100+
/>
101+
</pattern>
102+
</defs>
103+
<Bar
104+
width={0.7}
105+
data={counts}
106+
color={counts.map((c, i) =>
107+
i === counts.length - 1 ? 'url(#hatch-pattern)' : 'blue'
108+
)}
109+
/>
110+
<Line
111+
data={[
112+
[2019.5, 10],
113+
[2019.5, 40000000],
114+
]}
115+
color={'secondary'}
116+
sx={{ strokeWidth: 1, strokeDasharray: 4 }}
117+
/>
118+
</Plot>
119+
<Label
120+
x={2019.5}
121+
y={40000000}
122+
sx={{ color: 'secondary', mr: 2 }}
123+
align='right'
124+
>
125+
Hydropower Ban
126+
</Label>
127+
</Chart>
128+
</Box>
129+
)
130+
}
131+
132+
export default Issuances
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { useMemo } from 'react'
2+
import { Rect } from '@carbonplan/charts'
3+
4+
import data from './projects-data.json'
5+
6+
const Timeline = ({ activeYears, color, y, years }) => {
7+
const yearData = useMemo(() => {
8+
let hasInactivated
9+
const result = years.reduce((rects, year) => {
10+
const currentRect = rects[rects.length - 1]
11+
const active = activeYears.includes(year)
12+
let status = 'active'
13+
let fill = color
14+
if (!active) {
15+
fill = 'muted'
16+
status = 'inactive'
17+
} else if (hasInactivated) {
18+
fill = 'blue'
19+
status = 'reactivated'
20+
}
21+
22+
if (!currentRect || currentRect.end || currentRect.status !== status) {
23+
rects.push({
24+
start: year,
25+
status,
26+
fill,
27+
})
28+
if (currentRect && currentRect.status !== status) {
29+
currentRect.end = year - 1
30+
}
31+
}
32+
hasInactivated ||= !active
33+
return rects
34+
}, [])
35+
result[result.length - 1].end ||= years[years.length - 1]
36+
return result
37+
}, [activeYears, color, years])
38+
39+
return (
40+
<g>
41+
{yearData.map(({ start, end, fill }) => (
42+
<Rect key={start} x={[start, end + 1]} y={[y, y + 1.25]} color={fill} />
43+
))}
44+
</g>
45+
)
46+
}
47+
48+
const Project = ({ project, y, years }) => {
49+
return (
50+
<>
51+
<Timeline
52+
years={years}
53+
color='blue'
54+
activeYears={data[project].credit_data}
55+
y={y}
56+
/>
57+
</>
58+
)
59+
}
60+
61+
export default Project
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"VCS753": {
3+
"credit_data": [2012, 2021, 2023, 2024]
4+
},
5+
"VCS766": {
6+
"credit_data": [2012, 2021, 2022]
7+
},
8+
"VCS883": {
9+
"credit_data": [2012, 2022, 2023, 2024]
10+
},
11+
"VCS884": {
12+
"credit_data": [2012, 2023]
13+
}
14+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { Box } from 'theme-ui'
2+
import {
3+
Axis,
4+
Chart,
5+
Grid,
6+
Plot,
7+
TickLabels,
8+
Ticks,
9+
Label,
10+
AxisLabel,
11+
} from '@carbonplan/charts'
12+
13+
import Project from './project'
14+
import data from './projects-data.json'
15+
const YEARS = [
16+
2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024,
17+
]
18+
const TICKS = YEARS.filter((d, i) => i % 2 === 0).map((d) => d + 0.5)
19+
20+
const Summary = () => {
21+
return (
22+
<Box sx={{ height: 300 }}>
23+
<Chart x={[2012, 2025]} y={[16, -1]} padding={{ left: 0 }}>
24+
<Axis bottom />
25+
<AxisLabel bottom>Issuance years</AxisLabel>
26+
<Ticks bottom values={TICKS} />
27+
<TickLabels bottom values={TICKS} format={Math.floor} />
28+
<Grid vertical values={YEARS} />
29+
<Plot>
30+
{Object.keys(data).map((project, i) => (
31+
<g key={project}>
32+
<Project
33+
years={YEARS}
34+
key={project}
35+
project={project}
36+
y={(i + 0.25) * 4}
37+
/>
38+
</g>
39+
))}
40+
</Plot>
41+
{Object.keys(data).map((project, i) => (
42+
<Label
43+
key={project}
44+
x={0}
45+
y={(i + 0.25) * 4 - 1}
46+
sx={{
47+
mr: [4, 5, 5, 6],
48+
color: 'primary',
49+
mt: '-5px',
50+
}}
51+
>
52+
{project}
53+
</Label>
54+
))}
55+
56+
{/* {Object.keys(data).map((project, i) => (
57+
<Label
58+
key={project}
59+
x={2013}
60+
y={(i + 0.25) * 4}
61+
sx={{
62+
color: 'secondary',
63+
ml: 2,
64+
mt: '2px',
65+
}}
66+
>
67+
Issuance gap
68+
</Label>
69+
))} */}
70+
</Chart>
71+
</Box>
72+
)
73+
}
74+
export default Summary

0 commit comments

Comments
 (0)