Skip to content

Commit 070f9e3

Browse files
authored
feat: provide option to refresh range axis label (#766)
* feat: provide option to refresh range axis label - add refreshRangeAxisLabel option (default to false) - add filterDataForRangeAxisLabel() in zoom service to provide data in zoom domain * refactor: move updateRangeAxis to zoomBarsOptions * refactor: use configs object instead of boolean as parameter * refactor: move updateWhenZooming option to be under axis option * refactor: change updateWhenZooming option to zoomBar.updateRangeAxis
1 parent da4c9f4 commit 070f9e3

File tree

4 files changed

+82
-4
lines changed

4 files changed

+82
-4
lines changed

Diff for: packages/core/src/configuration.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,8 @@ const axisChart: AxisChartOptions = Tools.merge({}, chart, {
173173
top: {
174174
enabled: false,
175175
type: ZoomBarTypes.GRAPH_VIEW
176-
}
176+
},
177+
updateRangeAxis: false
177178
} as ZoomBarsOptions
178179
} as AxisChartOptions);
179180

Diff for: packages/core/src/interfaces/components.ts

+4
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ export interface ZoomBarsOptions {
135135
* currently only the top position is supported
136136
*/
137137
top?: ZoomBarOptions;
138+
/**
139+
* whether keep updating range axis in real time while zoom domain is changing
140+
*/
141+
updateRangeAxis?: boolean;
138142
}
139143

140144
/**

Diff for: packages/core/src/services/scales-cartesian.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -416,14 +416,20 @@ export class CartesianScales extends Service {
416416
let allDataValues;
417417
// If the scale is stacked
418418
if (axisOptions.stacked) {
419-
const dataValuesGroupedByKeys = this.model.getDataValuesGroupedByKeys();
419+
const dataValuesGroupedByKeys = this.services.zoom.filterDataForRangeAxis(
420+
this.model.getDataValuesGroupedByKeys(),
421+
{ stacked: true }
422+
);
423+
420424
allDataValues = dataValuesGroupedByKeys.map((dataValues) =>
421425
sum(values(dataValues) as any)
422426
);
423427
} else if (scaleType === ScaleTypes.TIME) {
424428
allDataValues = displayData.map((datum) => +new Date(datum[mapsTo]));
425429
} else {
426-
allDataValues = displayData.map((datum) => datum[mapsTo]);
430+
allDataValues = this.services.zoom
431+
.filterDataForRangeAxis(displayData)
432+
.map((datum) => datum[mapsTo]);
427433
}
428434

429435
if (scaleType !== ScaleTypes.TIME && includeZero) {

Diff for: packages/core/src/services/zoom.ts

+68-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,47 @@
11
// Internal Imports
2+
import { AxisPositions, Events, ScaleTypes } from "../interfaces";
23
import { Service } from "./service";
3-
import { Events } from "../interfaces";
44
import { Tools } from "../tools";
55

66
// D3 imports
77
import { extent } from "d3-array";
88

99
export class Zoom extends Service {
10+
isZoomBarEnabled() {
11+
// CartesianScales service is only available in axis charts
12+
if (!this.services.cartesianScales) {
13+
return false;
14+
}
15+
16+
// @todo - need to update this if zoom bar in other position (bottom, left, right) is supported
17+
// check configuration
18+
if (
19+
!Tools.getProperty(
20+
this.model.getOptions(),
21+
"zoomBar",
22+
"top",
23+
"enabled"
24+
)
25+
) {
26+
return false;
27+
}
28+
29+
// @todo - Zoom Bar only supports main axis at BOTTOM axis and time scale for now
30+
this.services.cartesianScales.findDomainAndRangeAxes(); // need to do this before getMainXAxisPosition()
31+
const mainXAxisPosition = this.services.cartesianScales.getMainXAxisPosition();
32+
const mainXScaleType = Tools.getProperty(
33+
this.model.getOptions(),
34+
"axes",
35+
mainXAxisPosition,
36+
"scaleType"
37+
);
38+
39+
return (
40+
mainXAxisPosition === AxisPositions.BOTTOM &&
41+
mainXScaleType === ScaleTypes.TIME
42+
);
43+
}
44+
1045
// get display data for zoom bar
1146
// basically it's sum of value grouped by time
1247
getZoomBarData() {
@@ -85,4 +120,36 @@ export class Zoom extends Service {
85120
"zoomRatio"
86121
);
87122
}
123+
124+
// filter out data not inside zoom domain
125+
// to get better range value for axis label
126+
filterDataForRangeAxis(displayData: object[], configs?: any) {
127+
const zoomDomain = this.model.get("zoomDomain");
128+
const mergedConfigs = Object.assign(
129+
{ stacked: false }, // default configs
130+
configs
131+
);
132+
const shouldUpdateRangeAxis = Tools.getProperty(
133+
this.model.getOptions(),
134+
"zoomBar",
135+
"updateRangeAxis"
136+
);
137+
if (this.isZoomBarEnabled() && shouldUpdateRangeAxis && zoomDomain) {
138+
const domainIdentifier = mergedConfigs.stacked
139+
? "sharedStackKey"
140+
: this.services.cartesianScales.getDomainIdentifier();
141+
const filteredData = displayData.filter(
142+
(datum) =>
143+
new Date(datum[domainIdentifier]) >= zoomDomain[0] &&
144+
new Date(datum[domainIdentifier]) <= zoomDomain[1]
145+
);
146+
// if no data in zoom domain, use all data to get full range value
147+
// so only return filteredData if length > 0
148+
if (filteredData.length > 0) {
149+
return filteredData;
150+
}
151+
}
152+
// return original data by default
153+
return displayData;
154+
}
88155
}

0 commit comments

Comments
 (0)