Use getDerivedState for Chart (and kick the can...) (#1320)
* Use getDerivedState for Chart (and kick the can...) * Update Doughnut.tsx * Update HorizBar.tsx
This commit is contained in:
parent
073ffb5ef9
commit
e7dbb1a0ca
@ -33,6 +33,11 @@ export default class ChartDoughnut extends React.PureComponent<Props> {
|
||||
render () {
|
||||
const { className, size = 100, style, values } = this.props;
|
||||
|
||||
// FIXME Classic case of kicking the can down the road, i.e. don't expend energy
|
||||
// when stuff are not used. This was replaced by the HorizBar as the only Chart
|
||||
// in actual use (by Referendum). However the below is not optimal, and gets re-
|
||||
// calculated on each render. If this component is put back in use, look at
|
||||
// getDerivedStateFromProps in HorizBar (the logic is the same for chartData)
|
||||
const options = values.reduce((options, { colors: [normalColor = '#00f', hoverColor], label, value }) => {
|
||||
options.colorNormal.push(normalColor);
|
||||
options.colorHover.push(hoverColor || normalColor);
|
||||
|
||||
@ -21,33 +21,64 @@ type Props = BareProps & {
|
||||
values: Array<Value>
|
||||
};
|
||||
|
||||
type Options = {
|
||||
colorNormal: Array<string>,
|
||||
colorHover: Array<string>,
|
||||
data: Array<number>,
|
||||
labels: Array<string>
|
||||
type State = {
|
||||
chartData?: ChartJs.ChartData,
|
||||
chartOptions?: ChartJs.ChartOptions,
|
||||
valuesStr?: string
|
||||
};
|
||||
|
||||
const alphaColor = (hexColor: string): string =>
|
||||
ChartJs.helpers.color(hexColor).alpha(0.65).rgbString();
|
||||
|
||||
export default class ChartHorizBar extends React.PureComponent<Props> {
|
||||
render () {
|
||||
const { aspectRatio = 4, className, style, values } = this.props;
|
||||
export default class ChartHorizBar extends React.PureComponent<Props, State> {
|
||||
state: State = {};
|
||||
|
||||
const options = values.reduce((options, { colors: [normalColor = '#00f', hoverColor], label, value }) => {
|
||||
options.colorNormal.push(alphaColor(normalColor));
|
||||
options.colorHover.push(alphaColor(hoverColor || normalColor));
|
||||
options.data.push(bnToBn(value).toNumber());
|
||||
options.labels.push(label);
|
||||
static getDerivedStateFromProps ({ aspectRatio = 4, values }: Props, prevState: State) {
|
||||
const valuesStr = JSON.stringify(values);
|
||||
|
||||
return options;
|
||||
if (valuesStr === prevState.valuesStr) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const chartData = values.reduce((data, { colors: [normalColor = '#00f', hoverColor], label, value }) => {
|
||||
const dataset = data.datasets[0];
|
||||
|
||||
dataset.backgroundColor.push(alphaColor(normalColor));
|
||||
dataset.hoverBackgroundColor.push(alphaColor(hoverColor || normalColor));
|
||||
dataset.data.push(bnToBn(value).toNumber());
|
||||
data.labels.push(label);
|
||||
|
||||
return data;
|
||||
}, {
|
||||
colorNormal: [],
|
||||
colorHover: [],
|
||||
data: [],
|
||||
labels: []
|
||||
} as Options);
|
||||
labels: [] as Array<string>,
|
||||
datasets: [{
|
||||
data: [] as Array<number>,
|
||||
backgroundColor: [] as Array<string>,
|
||||
hoverBackgroundColor: [] as Array<string>
|
||||
}]
|
||||
});
|
||||
|
||||
return {
|
||||
chartData,
|
||||
chartOptions: {
|
||||
// width/height by default this is "1", i.e. a square box
|
||||
aspectRatio,
|
||||
// no need for the legend, expect the labels contain everything
|
||||
legend: {
|
||||
display: false
|
||||
}
|
||||
},
|
||||
valuesStr
|
||||
};
|
||||
}
|
||||
|
||||
render () {
|
||||
const { className, style } = this.props;
|
||||
const { chartData, chartOptions } = this.state;
|
||||
|
||||
if (!chartData) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
@ -55,22 +86,8 @@ export default class ChartHorizBar extends React.PureComponent<Props> {
|
||||
style={style}
|
||||
>
|
||||
<HorizontalBar
|
||||
data={{
|
||||
labels: options.labels,
|
||||
datasets: [{
|
||||
data: options.data,
|
||||
backgroundColor: options.colorNormal,
|
||||
hoverBackgroundColor: options.colorHover
|
||||
}]
|
||||
}}
|
||||
options={{
|
||||
// width/height by default this is "1", i.e. a square box
|
||||
aspectRatio,
|
||||
// no need for the legend, expect the labels contain everything
|
||||
legend: {
|
||||
display: false
|
||||
}
|
||||
}}
|
||||
data={chartData}
|
||||
options={chartOptions}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user