Skip to content

Commit b276f89

Browse files
Add same axis feature for scatter plot
1 parent 704d14e commit b276f89

File tree

8 files changed

+75
-6
lines changed

8 files changed

+75
-6
lines changed

src/Components/AggregatedDataExplorer.tsx

+8
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ function AggregatedDataExplorer(props: Props) {
5959
selectedCountryOrRegion: regionId,
6060
signatureSolution: undefined,
6161
signatureSolutionForDataList: 'All',
62+
keepAxisSame: false,
6263
};
6364

6465
const [state, dispatch] = useReducer(Reducer, initialState);
@@ -207,6 +208,12 @@ function AggregatedDataExplorer(props: Props) {
207208
payload: verticalBarLayout,
208209
});
209210
};
211+
const updateKeepAxisSame = (d: boolean) => {
212+
dispatch({
213+
type: 'UPDATE_KEEP_AXIS_SAME',
214+
payload: d,
215+
});
216+
};
210217
return (
211218
<div>
212219
<div
@@ -279,6 +286,7 @@ function AggregatedDataExplorer(props: Props) {
279286
updateReverseOrder,
280287
updateBarLayout,
281288
updateSignatureSolutionForDataList,
289+
updateKeepAxisSame,
282290
}}
283291
>
284292
<div

src/Components/CountryVisualization.tsx

+8
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ function CountryVisualization(props: Props) {
9393
disaggregationMetaData.length > 0 ? disaggregationMetaData[0] : undefined,
9494
disaggregationGraphType: 'country',
9595
disaggregationOrder: 'first',
96+
keepAxisSame: false,
9697
};
9798

9899
const [state, dispatch] = useReducer(Reducer, initialState);
@@ -271,6 +272,12 @@ function CountryVisualization(props: Props) {
271272
payload: disaggregationOrder,
272273
});
273274
};
275+
const updateKeepAxisSame = (d: boolean) => {
276+
dispatch({
277+
type: 'UPDATE_KEEP_AXIS_SAME',
278+
payload: d,
279+
});
280+
};
274281
return (
275282
<Context.Provider
276283
// eslint-disable-next-line react/jsx-no-constructed-context-values
@@ -299,6 +306,7 @@ function CountryVisualization(props: Props) {
299306
updateDisaggregationIndicator,
300307
updateDisaggregationGraphType,
301308
updateDisaggregationOrder,
309+
updateKeepAxisSame,
302310
}}
303311
>
304312
<div className='undp-container'>

src/Context/Context.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const Context = createContext<CtxDataType>({
3333
signatureSolution: undefined,
3434
signatureSolutionForDataList: 'All',
3535
showReference: false,
36+
keepAxisSame: false,
3637
updateGraphType: (
3738
_d:
3839
| 'scatterPlot'
@@ -74,6 +75,7 @@ const Context = createContext<CtxDataType>({
7475
| 'Poverty and Inequality'
7576
| 'Resilience',
7677
) => {},
78+
updateKeepAxisSame: (_d: boolean) => {},
7779
});
7880

7981
export default Context;

src/Context/Reducer.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ export default (state: any, action: any) => {
4646
return { ...state, disaggregationGraphType: action.payload };
4747
case 'UPDATE_DISAGGREGATION_ORDER':
4848
return { ...state, disaggregationOrder: action.payload };
49+
case 'UPDATE_KEEP_AXIS_SAME':
50+
return { ...state, keepAxisSame: action.payload };
4951
default:
5052
return { ...state };
5153
}

src/GrapherComponent/ScatterPlot/Graph.tsx

+33-6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import { Delaunay } from 'd3-delaunay';
77
import { scaleOrdinal, scaleLinear, scaleThreshold, scaleSqrt } from 'd3-scale';
88
import minBy from 'lodash.minby';
99
import UNDPColorModule from 'undp-viz-colors';
10+
import flattenDeep from 'lodash.flattendeep';
11+
import min from 'lodash.min';
1012
import { Tooltip } from '../../Components/Tooltip';
1113
import {
1214
CountryGroupDataType,
@@ -47,6 +49,7 @@ export function Graph(props: Props) {
4749
selectedRegions,
4850
selectedIncomeGroups,
4951
selectedCountryGroup,
52+
keepAxisSame,
5053
} = useContext(Context) as CtxDataType;
5154
const [selectedColor, setSelectedColor] = useState<string | undefined>(
5255
undefined,
@@ -103,7 +106,24 @@ export function Graph(props: Props) {
103106
.range([0.25, 30])
104107
.nice()
105108
: undefined;
106-
109+
const xFullArray = flattenDeep(
110+
data.map(d => {
111+
const xIndicatorIndex = d.indicators.findIndex(
112+
el => xIndicatorMetaData.DataKey === el.indicator,
113+
);
114+
const arr = d.indicators[xIndicatorIndex].yearlyData.map(el => el.value);
115+
return arr;
116+
}),
117+
);
118+
const yFullArray = flattenDeep(
119+
data.map(d => {
120+
const yIndicatorIndex = d.indicators.findIndex(
121+
el => yIndicatorMetaData.DataKey === el.indicator,
122+
);
123+
const arr = d.indicators[yIndicatorIndex].yearlyData.map(el => el.value);
124+
return arr;
125+
}),
126+
);
107127
const dataFormatted = orderBy(
108128
data
109129
.map(d => {
@@ -245,7 +265,6 @@ export function Graph(props: Props) {
245265
'radiusValue',
246266
'desc',
247267
);
248-
249268
const refXIndicatorIndex = regionData
250269
? regionData.indicators.findIndex(
251270
el => xIndicatorMetaData.DataKey === el.indicator,
@@ -266,14 +285,18 @@ export function Graph(props: Props) {
266285
: regionData.indicators[refXIndicatorIndex].yearlyData[
267286
regionData.indicators[refXIndicatorIndex].yearlyData.length - 1
268287
]?.value;
269-
const xMaxValue = maxBy(dataFormatted, d => d.xVal)
288+
const xMaxValue = keepAxisSame
289+
? (max(xFullArray) as number)
290+
: maxBy(dataFormatted, d => d.xVal)
270291
? refXVal && showReference
271292
? (maxBy(dataFormatted, d => d.xVal)?.xVal as number) > refXVal
272293
? (maxBy(dataFormatted, d => d.xVal)?.xVal as number)
273294
: refXVal
274295
: (maxBy(dataFormatted, d => d.xVal)?.xVal as number)
275296
: 0;
276-
const xMinValue = minBy(dataFormatted, d => d.xVal)
297+
const xMinValue = keepAxisSame
298+
? (min(xFullArray) as number)
299+
: minBy(dataFormatted, d => d.xVal)
277300
? refXVal && showReference
278301
? (minBy(dataFormatted, d => d.xVal)?.xVal as number) < refXVal
279302
? (minBy(dataFormatted, d => d.xVal)?.xVal as number)
@@ -300,14 +323,18 @@ export function Graph(props: Props) {
300323
: regionData.indicators[refYIndicatorIndex].yearlyData[
301324
regionData.indicators[refYIndicatorIndex].yearlyData.length - 1
302325
]?.value;
303-
const yMaxValue = maxBy(dataFormatted, d => d.yVal)
326+
const yMaxValue = keepAxisSame
327+
? (max(yFullArray) as number)
328+
: maxBy(dataFormatted, d => d.yVal)
304329
? refYVal && showReference
305330
? (maxBy(dataFormatted, d => d.yVal)?.yVal as number) > refYVal
306331
? (maxBy(dataFormatted, d => d.yVal)?.yVal as number)
307332
: refYVal
308333
: (maxBy(dataFormatted, d => d.yVal)?.yVal as number)
309334
: 0;
310-
const yMinValue = minBy(dataFormatted, d => d.yVal)
335+
const yMinValue = keepAxisSame
336+
? (min(yFullArray) as number)
337+
: minBy(dataFormatted, d => d.yVal)
311338
? refYVal && showReference
312339
? (minBy(dataFormatted, d => d.yVal)?.yVal as number) < refYVal
313340
? (minBy(dataFormatted, d => d.yVal)?.yVal as number)

src/GrapherComponent/Settings/ScatterPlotSettings.tsx

+12
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export function ScatterPlotSettings(props: Props) {
3636
yAxisIndicator,
3737
sizeIndicator,
3838
colorIndicator,
39+
keepAxisSame,
3940
showLabel,
4041
showMostRecentData,
4142
selectedCountryOrRegion,
@@ -47,6 +48,7 @@ export function ScatterPlotSettings(props: Props) {
4748
updateShowLabel,
4849
updateShowMostRecentData,
4950
updateShowReference,
51+
updateKeepAxisSame,
5052
} = useContext(Context) as CtxDataType;
5153
const scatterPlotIndicators = indicators.filter(d => !d.IsCategorical);
5254
const sizeIndicators = indicators.filter(d => d.Sizing);
@@ -240,6 +242,16 @@ export function ScatterPlotSettings(props: Props) {
240242
>
241243
Show World/Regional Reference
242244
</Checkbox>
245+
<Checkbox
246+
style={{ margin: 0 }}
247+
className='undp-checkbox'
248+
checked={keepAxisSame}
249+
onChange={e => {
250+
updateKeepAxisSame(e.target.checked);
251+
}}
252+
>
253+
Use same axes to compare between years
254+
</Checkbox>
243255
</div>
244256
</div>
245257
{!selectedCountryOrRegion && countries.length > 1 ? (

src/RegionVisualization/Visualization.tsx

+8
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ function VisualizationEl(props: Props) {
9191
disaggregationMetaData.length > 0 ? disaggregationMetaData[0] : undefined,
9292
disaggregationGraphType: 'global',
9393
disaggregationOrder: 'first',
94+
keepAxisSame: false,
9495
};
9596

9697
const [state, dispatch] = useReducer(Reducer, initialState);
@@ -270,6 +271,12 @@ function VisualizationEl(props: Props) {
270271
payload: disaggregationOrder,
271272
});
272273
};
274+
const updateKeepAxisSame = (d: boolean) => {
275+
dispatch({
276+
type: 'UPDATE_KEEP_AXIS_SAME',
277+
payload: d,
278+
});
279+
};
273280
return (
274281
<Context.Provider
275282
// eslint-disable-next-line react/jsx-no-constructed-context-values
@@ -298,6 +305,7 @@ function VisualizationEl(props: Props) {
298305
updateDisaggregationIndicator,
299306
updateDisaggregationGraphType,
300307
updateDisaggregationOrder,
308+
updateKeepAxisSame,
301309
}}
302310
>
303311
<div>

src/Types.ts

+2
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ export interface CtxDataType {
168168
| 'Governance'
169169
| 'Poverty and Inequality'
170170
| 'Resilience';
171+
keepAxisSame: boolean;
171172
updateGraphType: (
172173
_d:
173174
| 'scatterPlot'
@@ -209,6 +210,7 @@ export interface CtxDataType {
209210
| 'Poverty and Inequality'
210211
| 'Resilience',
211212
) => void;
213+
updateKeepAxisSame: (_d: boolean) => void;
212214
}
213215

214216
export interface CountryListType {

0 commit comments

Comments
 (0)