From 4f00d2ff96db1c6ee9cb498a39ffd6971f68fc80 Mon Sep 17 00:00:00 2001 From: EricYang Date: Wed, 26 Aug 2020 15:47:04 +0800 Subject: [PATCH 1/5] 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 --- packages/core/src/configuration.ts | 3 +- packages/core/src/interfaces/components.ts | 4 ++ .../core/src/services/scales-cartesian.ts | 10 ++- packages/core/src/services/zoom.ts | 65 +++++++++++++++++++ 4 files changed, 79 insertions(+), 3 deletions(-) diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index 44848794b4..9c3a966f12 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -149,7 +149,8 @@ const axisChart: AxisChartOptions = Tools.merge({}, chart, { zoomBar: { top: { enabled: false, - type: ZoomBarTypes.GRAPH_VIEW + type: ZoomBarTypes.GRAPH_VIEW, + refreshRangeAxisLabel: false } } as ZoomBarsOptions } as AxisChartOptions); diff --git a/packages/core/src/interfaces/components.ts b/packages/core/src/interfaces/components.ts index 5dab21f3eb..81d4a74a49 100644 --- a/packages/core/src/interfaces/components.ts +++ b/packages/core/src/interfaces/components.ts @@ -131,4 +131,8 @@ export interface ZoomBarOptions { * options related to zoom bar data */ data?: Object[]; + /** + * whether keep refreshing range axis label while zoom domain is changing + */ + refreshRangeAxisLabel?: boolean; } diff --git a/packages/core/src/services/scales-cartesian.ts b/packages/core/src/services/scales-cartesian.ts index 4904006ba5..77c1f3ee9e 100644 --- a/packages/core/src/services/scales-cartesian.ts +++ b/packages/core/src/services/scales-cartesian.ts @@ -416,12 +416,18 @@ export class CartesianScales extends Service { let allDataValues; // If the scale is stacked if (axisOptions.stacked) { - const dataValuesGroupedByKeys = this.model.getDataValuesGroupedByKeys(); + const dataValuesGroupedByKeys = this.services.zoom.filterDataForRangeAxisLabel( + this.model.getDataValuesGroupedByKeys(), + true + ); + allDataValues = dataValuesGroupedByKeys.map((dataValues) => sum(values(dataValues) as any) ); } else { - allDataValues = displayData.map((datum) => datum[mapsTo]); + allDataValues = this.services.zoom + .filterDataForRangeAxisLabel(displayData) + .map((datum) => datum[mapsTo]); } if (scaleType !== ScaleTypes.TIME && includeZero) { diff --git a/packages/core/src/services/zoom.ts b/packages/core/src/services/zoom.ts index 659ef4d4e3..5c89e4618c 100644 --- a/packages/core/src/services/zoom.ts +++ b/packages/core/src/services/zoom.ts @@ -1,4 +1,5 @@ // Internal Imports +import { AxisPositions, ScaleTypes } from "../interfaces"; import { Service } from "./service"; import { Tools } from "../tools"; @@ -6,6 +7,41 @@ import { Tools } from "../tools"; import { extent } from "d3-array"; export class Zoom extends Service { + isZoomBarEnabled() { + // CartesianScales service is only available in axis charts + if (!this.services.cartesianScales) { + return false; + } + + // @todo - need to update this if zoom bar in other position (bottom, left, right) is supported + // check configuration + if ( + !Tools.getProperty( + this.model.getOptions(), + "zoomBar", + "top", + "enabled" + ) + ) { + return false; + } + + // @todo - Zoom Bar only supports main axis at BOTTOM axis and time scale for now + this.services.cartesianScales.findDomainAndRangeAxes(); // need to do this before getMainXAxisPosition() + const mainXAxisPosition = this.services.cartesianScales.getMainXAxisPosition(); + const mainXScaleType = Tools.getProperty( + this.model.getOptions(), + "axes", + mainXAxisPosition, + "scaleType" + ); + + return ( + mainXAxisPosition === AxisPositions.BOTTOM && + mainXScaleType === ScaleTypes.TIME + ); + } + // get display data for zoom bar // basically it's sum of value grouped by time getZoomBarData() { @@ -64,4 +100,33 @@ export class Zoom extends Service { extent(zoomBarData, (d: any) => d[domainIdentifier]) ); } + + // filter out data not inside zoom domain + // to get better range value for axis label + filterDataForRangeAxisLabel(displayData: object[], stacked = false) { + const zoomDomain = this.model.get("zoomDomain"); + const isRefreshRangeAxisLabel = Tools.getProperty( + this.model.getOptions(), + "zoomBar", + "top", + "refreshRangeAxisLabel" + ); + if (this.isZoomBarEnabled() && isRefreshRangeAxisLabel && zoomDomain) { + const domainIdentifier = stacked + ? "sharedStackKey" + : this.services.cartesianScales.getDomainIdentifier(); + const filteredData = displayData.filter( + (datum) => + new Date(datum[domainIdentifier]) >= zoomDomain[0] && + new Date(datum[domainIdentifier]) <= zoomDomain[1] + ); + // if no data in zoom domain, use all data to get full range value + // so only return filteredData if length > 0 + if (filteredData.length > 0) { + return filteredData; + } + } + // return original data by default + return displayData; + } } From b9abd4c2abf9c738e059a342cc940cb96f71abde Mon Sep 17 00:00:00 2001 From: EricYang Date: Thu, 27 Aug 2020 09:48:58 +0800 Subject: [PATCH 2/5] refactor: move updateRangeAxis to zoomBarsOptions --- packages/core/src/configuration.ts | 6 +++--- packages/core/src/interfaces/components.ts | 8 ++++---- packages/core/src/services/scales-cartesian.ts | 4 ++-- packages/core/src/services/zoom.ts | 9 ++++----- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index 9c3a966f12..1989384abf 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -149,9 +149,9 @@ const axisChart: AxisChartOptions = Tools.merge({}, chart, { zoomBar: { top: { enabled: false, - type: ZoomBarTypes.GRAPH_VIEW, - refreshRangeAxisLabel: false - } + type: ZoomBarTypes.GRAPH_VIEW + }, + updateRangeAxis: false } as ZoomBarsOptions } as AxisChartOptions); diff --git a/packages/core/src/interfaces/components.ts b/packages/core/src/interfaces/components.ts index 81d4a74a49..6d73a7ff4a 100644 --- a/packages/core/src/interfaces/components.ts +++ b/packages/core/src/interfaces/components.ts @@ -109,6 +109,10 @@ export interface ZoomBarsOptions { * currently only the top position is supported */ top?: ZoomBarOptions; + /** + * whether keep updating range axis in real time while zoom domain is changing + */ + updateRangeAxis?: boolean; } /** @@ -131,8 +135,4 @@ export interface ZoomBarOptions { * options related to zoom bar data */ data?: Object[]; - /** - * whether keep refreshing range axis label while zoom domain is changing - */ - refreshRangeAxisLabel?: boolean; } diff --git a/packages/core/src/services/scales-cartesian.ts b/packages/core/src/services/scales-cartesian.ts index 77c1f3ee9e..5db659dd05 100644 --- a/packages/core/src/services/scales-cartesian.ts +++ b/packages/core/src/services/scales-cartesian.ts @@ -416,7 +416,7 @@ export class CartesianScales extends Service { let allDataValues; // If the scale is stacked if (axisOptions.stacked) { - const dataValuesGroupedByKeys = this.services.zoom.filterDataForRangeAxisLabel( + const dataValuesGroupedByKeys = this.services.zoom.filterDataForRangeAxis( this.model.getDataValuesGroupedByKeys(), true ); @@ -426,7 +426,7 @@ export class CartesianScales extends Service { ); } else { allDataValues = this.services.zoom - .filterDataForRangeAxisLabel(displayData) + .filterDataForRangeAxis(displayData) .map((datum) => datum[mapsTo]); } diff --git a/packages/core/src/services/zoom.ts b/packages/core/src/services/zoom.ts index 5c89e4618c..9c07c13246 100644 --- a/packages/core/src/services/zoom.ts +++ b/packages/core/src/services/zoom.ts @@ -103,15 +103,14 @@ export class Zoom extends Service { // filter out data not inside zoom domain // to get better range value for axis label - filterDataForRangeAxisLabel(displayData: object[], stacked = false) { + filterDataForRangeAxis(displayData: object[], stacked = false) { const zoomDomain = this.model.get("zoomDomain"); - const isRefreshRangeAxisLabel = Tools.getProperty( + const isUpdateRangeAxis = Tools.getProperty( this.model.getOptions(), "zoomBar", - "top", - "refreshRangeAxisLabel" + "updateRangeAxis" ); - if (this.isZoomBarEnabled() && isRefreshRangeAxisLabel && zoomDomain) { + if (this.isZoomBarEnabled() && isUpdateRangeAxis && zoomDomain) { const domainIdentifier = stacked ? "sharedStackKey" : this.services.cartesianScales.getDomainIdentifier(); From 9688034ff3f124008639b3de35559c84dee307c4 Mon Sep 17 00:00:00 2001 From: EricYang Date: Fri, 28 Aug 2020 11:30:55 +0800 Subject: [PATCH 3/5] refactor: use configs object instead of boolean as parameter --- packages/core/src/services/scales-cartesian.ts | 2 +- packages/core/src/services/zoom.ts | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/core/src/services/scales-cartesian.ts b/packages/core/src/services/scales-cartesian.ts index 5db659dd05..41534a9c8c 100644 --- a/packages/core/src/services/scales-cartesian.ts +++ b/packages/core/src/services/scales-cartesian.ts @@ -418,7 +418,7 @@ export class CartesianScales extends Service { if (axisOptions.stacked) { const dataValuesGroupedByKeys = this.services.zoom.filterDataForRangeAxis( this.model.getDataValuesGroupedByKeys(), - true + { stacked: true } ); allDataValues = dataValuesGroupedByKeys.map((dataValues) => diff --git a/packages/core/src/services/zoom.ts b/packages/core/src/services/zoom.ts index 9c07c13246..a5d7589b4c 100644 --- a/packages/core/src/services/zoom.ts +++ b/packages/core/src/services/zoom.ts @@ -103,15 +103,19 @@ export class Zoom extends Service { // filter out data not inside zoom domain // to get better range value for axis label - filterDataForRangeAxis(displayData: object[], stacked = false) { + filterDataForRangeAxis(displayData: object[], configs?: any) { const zoomDomain = this.model.get("zoomDomain"); - const isUpdateRangeAxis = Tools.getProperty( + const mergedConfigs = Object.assign( + { stacked: false }, // default configs + configs + ); + const shouldUpdateRangeAxis = Tools.getProperty( this.model.getOptions(), "zoomBar", "updateRangeAxis" ); - if (this.isZoomBarEnabled() && isUpdateRangeAxis && zoomDomain) { - const domainIdentifier = stacked + if (this.isZoomBarEnabled() && shouldUpdateRangeAxis && zoomDomain) { + const domainIdentifier = mergedConfigs.stacked ? "sharedStackKey" : this.services.cartesianScales.getDomainIdentifier(); const filteredData = displayData.filter( From a224ab3561811cf0d6454093d2fb3af0fe5ab303 Mon Sep 17 00:00:00 2001 From: EricYang Date: Fri, 11 Sep 2020 15:44:35 +0800 Subject: [PATCH 4/5] refactor: move updateWhenZooming option to be under axis option --- packages/core/src/configuration.ts | 3 +-- packages/core/src/interfaces/axis-scales.ts | 4 ++++ packages/core/src/interfaces/components.ts | 4 ---- packages/core/src/services/zoom.ts | 5 +++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index 2181aefb38..23e85f607e 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -154,8 +154,7 @@ const axisChart: AxisChartOptions = Tools.merge({}, chart, { top: { enabled: false, type: ZoomBarTypes.GRAPH_VIEW - }, - updateRangeAxis: false + } } as ZoomBarsOptions } as AxisChartOptions); diff --git a/packages/core/src/interfaces/axis-scales.ts b/packages/core/src/interfaces/axis-scales.ts index 63e05e2f3d..950b6ab77d 100644 --- a/packages/core/src/interfaces/axis-scales.ts +++ b/packages/core/src/interfaces/axis-scales.ts @@ -84,6 +84,10 @@ export interface AxisOptions { values?: any[]; }; truncation?: TruncationOptions; + /** + * whether keep updating axis in real time while zoom domain is changing + */ + updateWhenZooming?: boolean; } /** diff --git a/packages/core/src/interfaces/components.ts b/packages/core/src/interfaces/components.ts index ee32c4b20c..d0e092ca7c 100644 --- a/packages/core/src/interfaces/components.ts +++ b/packages/core/src/interfaces/components.ts @@ -111,10 +111,6 @@ export interface ZoomBarsOptions { * currently only the top position is supported */ top?: ZoomBarOptions; - /** - * whether keep updating range axis in real time while zoom domain is changing - */ - updateRangeAxis?: boolean; } /** diff --git a/packages/core/src/services/zoom.ts b/packages/core/src/services/zoom.ts index a5d7589b4c..0ae316b67d 100644 --- a/packages/core/src/services/zoom.ts +++ b/packages/core/src/services/zoom.ts @@ -111,8 +111,9 @@ export class Zoom extends Service { ); const shouldUpdateRangeAxis = Tools.getProperty( this.model.getOptions(), - "zoomBar", - "updateRangeAxis" + "axes", + this.services.cartesianScales.getMainYAxisPosition(), + "updateWhenZooming" ); if (this.isZoomBarEnabled() && shouldUpdateRangeAxis && zoomDomain) { const domainIdentifier = mergedConfigs.stacked From 2cd37ad112dcf86e38faebf6534fb397ed5225f4 Mon Sep 17 00:00:00 2001 From: EricYang Date: Tue, 6 Oct 2020 11:03:08 +0800 Subject: [PATCH 5/5] refactor: change updateWhenZooming option to zoomBar.updateRangeAxis --- packages/core/src/configuration.ts | 4 ++-- packages/core/src/interfaces/axis-scales.ts | 4 ---- packages/core/src/interfaces/components.ts | 5 ++++- packages/core/src/services/zoom.ts | 5 ++--- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index 430d9ceddf..258fcde783 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -82,7 +82,6 @@ export const ruler: RulerOptions = { enabled: true }; - /** * Tooltip options */ @@ -170,7 +169,8 @@ const axisChart: AxisChartOptions = Tools.merge({}, chart, { top: { enabled: false, type: ZoomBarTypes.GRAPH_VIEW - } + }, + updateRangeAxis: false } as ZoomBarsOptions } as AxisChartOptions); diff --git a/packages/core/src/interfaces/axis-scales.ts b/packages/core/src/interfaces/axis-scales.ts index c4df34fec4..30581b0f47 100644 --- a/packages/core/src/interfaces/axis-scales.ts +++ b/packages/core/src/interfaces/axis-scales.ts @@ -92,10 +92,6 @@ export interface AxisOptions { * is axis visible or not */ visible?: boolean; - /** - * whether keep updating axis in real time while zoom domain is changing - */ - updateWhenZooming?: boolean; } /** diff --git a/packages/core/src/interfaces/components.ts b/packages/core/src/interfaces/components.ts index 4f096e7762..3fa865dfae 100644 --- a/packages/core/src/interfaces/components.ts +++ b/packages/core/src/interfaces/components.ts @@ -101,7 +101,6 @@ export interface RulerOptions { enabled?: boolean; } - export interface BarOptions { width?: number; maxWidth?: number; @@ -124,6 +123,10 @@ export interface ZoomBarsOptions { * currently only the top position is supported */ top?: ZoomBarOptions; + /** + * whether keep updating range axis in real time while zoom domain is changing + */ + updateRangeAxis?: boolean; } /** diff --git a/packages/core/src/services/zoom.ts b/packages/core/src/services/zoom.ts index fb9599dcb9..95f0f94026 100644 --- a/packages/core/src/services/zoom.ts +++ b/packages/core/src/services/zoom.ts @@ -126,9 +126,8 @@ export class Zoom extends Service { ); const shouldUpdateRangeAxis = Tools.getProperty( this.model.getOptions(), - "axes", - this.services.cartesianScales.getMainYAxisPosition(), - "updateWhenZooming" + "zoomBar", + "updateRangeAxis" ); if (this.isZoomBarEnabled() && shouldUpdateRangeAxis && zoomDomain) { const domainIdentifier = mergedConfigs.stacked