From 3c327c502aff299b564c8c926e18ed74aa4f97da Mon Sep 17 00:00:00 2001 From: Fei Date: Mon, 25 May 2020 16:07:36 -0400 Subject: [PATCH 01/32] Add selectedGroups option --- packages/core/src/configuration.ts | 3 ++- packages/core/src/interfaces/charts.ts | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index cb8919fea6..4ecf779502 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -154,7 +154,8 @@ const chart: BaseChartOptions = { }, color: { scale: null - } + }, + selectedGroups: [] }; /** diff --git a/packages/core/src/interfaces/charts.ts b/packages/core/src/interfaces/charts.ts index c7bb23468d..80e8c59a79 100644 --- a/packages/core/src/interfaces/charts.ts +++ b/packages/core/src/interfaces/charts.ts @@ -97,6 +97,10 @@ export interface BaseChartOptions { */ scale?: object; }; + /** + * options related to pre-selected datasets + */ + selectedGroups?: string[]; } /** From a013589845a8a6255219168cb3c69bf386ea9a85 Mon Sep 17 00:00:00 2001 From: Fei Date: Mon, 25 May 2020 16:08:23 -0400 Subject: [PATCH 02/32] Bind selectedGroups with legend and dataGroups --- .../core/src/components/essentials/legend.ts | 1 + packages/core/src/model.ts | 43 ++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/packages/core/src/components/essentials/legend.ts b/packages/core/src/components/essentials/legend.ts index dc4bda35b5..428b1387e6 100644 --- a/packages/core/src/components/essentials/legend.ts +++ b/packages/core/src/components/essentials/legend.ts @@ -268,6 +268,7 @@ export class Legend extends Component { const clickedItemData = clickedItem.datum() as any; self.model.toggleDataLabel(clickedItemData.name); + self.model.updateSelectedGroups(); }) .on("mouseout", function() { const hoveredItem = select(this); diff --git a/packages/core/src/model.ts b/packages/core/src/model.ts index b08c30155f..debde29ed4 100644 --- a/packages/core/src/model.ts +++ b/packages/core/src/model.ts @@ -286,6 +286,39 @@ export class ChartModel { }); } + /** + * Updates selected datasets + */ + updateSelectedGroups() { + const { ACTIVE, DISABLED } = Configuration.legend.items.status; + const dataGroups = this.getDataGroups(); + const activeItems = dataGroups.filter(group => group.status === ACTIVE); + + const hasDeactivatedItems = dataGroups.some( + group => group.status === DISABLED + ); + + // If there are deactivated items, map the label names into selected datasets + if (hasDeactivatedItems) { + this.state.options.selectedGroups = activeItems.map(activeItem => activeItem.name); + } else { + // If every item is active, clear array + this.state.options.selectedGroups = []; + }; + } + + checkSelectedGroups(uniqueDataGroups: string[]) { + if (this.state.options.selectedGroups.length) { + // check if current groups includes every item in selected groups + const hasSelectedGroups = this.state.options.selectedGroups + .every(groupName => uniqueDataGroups.includes(groupName)); + + if (!hasSelectedGroups) { + this.state.options.selectedGroups = []; + }; + }; + } + /** * Should the data point be filled? * @param group @@ -415,12 +448,18 @@ export class ChartModel { protected generateDataGroups(data) { const { groupMapsTo } = this.getOptions().data; - const { ACTIVE } = Configuration.legend.items.status; + const { ACTIVE, DISABLED } = Configuration.legend.items.status; const uniqueDataGroups = map(data, datum => datum[groupMapsTo]).keys(); + + this.checkSelectedGroups(uniqueDataGroups); + return uniqueDataGroups.map(groupName => ({ name: groupName, - status: ACTIVE + status: !this.state.options.selectedGroups.length || + this.state.options.selectedGroups.includes(groupName) + ? ACTIVE + : DISABLED, })); } From 45e73cc2dea2985a240ca9100dfa35f4d36e0a38 Mon Sep 17 00:00:00 2001 From: Fei Date: Tue, 26 May 2020 10:33:20 -0400 Subject: [PATCH 03/32] improvement: move selectedGroup under data option re #610 --- packages/core/src/configuration.ts | 4 ++-- packages/core/src/interfaces/charts.ts | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index 5e7896c08b..627ea2cbcb 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -151,11 +151,11 @@ const chart: BaseChartOptions = { data: { groupMapsTo: "group", loading: false, + selectedGroups: [] }, color: { scale: null - }, - selectedGroups: [] + } }; /** diff --git a/packages/core/src/interfaces/charts.ts b/packages/core/src/interfaces/charts.ts index e7eeb11eb3..7301a75f9f 100644 --- a/packages/core/src/interfaces/charts.ts +++ b/packages/core/src/interfaces/charts.ts @@ -87,6 +87,10 @@ export interface BaseChartOptions { * used to simulate data loading */ loading?: Boolean; + /** + * options related to pre-selected datasets + */ + selectedGroups?: string[]; }; /** * options related to color scales @@ -97,10 +101,6 @@ export interface BaseChartOptions { */ scale?: object; }; - /** - * options related to pre-selected datasets - */ - selectedGroups?: string[]; } /** From 88184e5c0af1344b9d3018d39c4226f076435f2d Mon Sep 17 00:00:00 2001 From: Fei Date: Wed, 27 May 2020 17:29:51 -0400 Subject: [PATCH 04/32] refactor: update selectedGroup position --- packages/core/src/model.ts | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/packages/core/src/model.ts b/packages/core/src/model.ts index 163a599b92..e2f1ec3c45 100644 --- a/packages/core/src/model.ts +++ b/packages/core/src/model.ts @@ -302,21 +302,21 @@ export class ChartModel { // If there are deactivated items, map the label names into selected datasets if (hasDeactivatedItems) { - this.state.options.selectedGroups = activeItems.map(activeItem => activeItem.name); + this.state.options.data.selectedGroups = activeItems.map(activeItem => activeItem.name); } else { // If every item is active, clear array - this.state.options.selectedGroups = []; + this.state.options.data.selectedGroups = []; }; } checkSelectedGroups(uniqueDataGroups: string[]) { - if (this.state.options.selectedGroups.length) { + if (this.state.options.data.selectedGroups.length) { // check if current groups includes every item in selected groups - const hasSelectedGroups = this.state.options.selectedGroups + const hasSelectedGroups = this.state.options.data.selectedGroups .every(groupName => uniqueDataGroups.includes(groupName)); if (!hasSelectedGroups) { - this.state.options.selectedGroups = []; + this.state.options.data.selectedGroups = []; }; }; } @@ -453,18 +453,21 @@ export class ChartModel { const { ACTIVE, DISABLED } = Configuration.legend.items.status; const uniqueDataGroups = map( - data, + data, (datum) => datum[groupMapsTo] ).keys(); this.checkSelectedGroups(uniqueDataGroups); + const getStatus = (groupName) => { + return (!this.state.options.data.selectedGroups.length || + this.state.options.data.selectedGroups.includes(groupName)) + ? ACTIVE + : DISABLED; + } return uniqueDataGroups.map(groupName => ({ name: groupName, - status: !this.state.options.selectedGroups.length || - this.state.options.selectedGroups.includes(groupName) - ? ACTIVE - : DISABLED, + status: getStatus(groupName) })); } From f7ac6306a520392f6fd7e17ad48414f91904e91f Mon Sep 17 00:00:00 2001 From: Fei Date: Thu, 28 May 2020 10:10:34 -0400 Subject: [PATCH 05/32] improvement: grab options from getOptions --- packages/core/src/model.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/core/src/model.ts b/packages/core/src/model.ts index e2f1ec3c45..a4771e346f 100644 --- a/packages/core/src/model.ts +++ b/packages/core/src/model.ts @@ -295,6 +295,7 @@ export class ChartModel { const { ACTIVE, DISABLED } = Configuration.legend.items.status; const dataGroups = this.getDataGroups(); const activeItems = dataGroups.filter(group => group.status === ACTIVE); + const options = this.getOptions(); const hasDeactivatedItems = dataGroups.some( group => group.status === DISABLED @@ -302,21 +303,22 @@ export class ChartModel { // If there are deactivated items, map the label names into selected datasets if (hasDeactivatedItems) { - this.state.options.data.selectedGroups = activeItems.map(activeItem => activeItem.name); + options.data.selectedGroups = activeItems.map(activeItem => activeItem.name); } else { // If every item is active, clear array - this.state.options.data.selectedGroups = []; + options.data.selectedGroups = []; }; } checkSelectedGroups(uniqueDataGroups: string[]) { - if (this.state.options.data.selectedGroups.length) { + const options = this.getOptions(); + if (options.data.selectedGroups.length) { // check if current groups includes every item in selected groups - const hasSelectedGroups = this.state.options.data.selectedGroups + const hasSelectedGroups = options.data.selectedGroups .every(groupName => uniqueDataGroups.includes(groupName)); if (!hasSelectedGroups) { - this.state.options.data.selectedGroups = []; + options.data.selectedGroups = []; }; }; } @@ -451,6 +453,7 @@ export class ChartModel { protected generateDataGroups(data) { const { groupMapsTo } = this.getOptions().data; const { ACTIVE, DISABLED } = Configuration.legend.items.status; + const options = this.getOptions(); const uniqueDataGroups = map( data, @@ -459,8 +462,8 @@ export class ChartModel { this.checkSelectedGroups(uniqueDataGroups); const getStatus = (groupName) => { - return (!this.state.options.data.selectedGroups.length || - this.state.options.data.selectedGroups.includes(groupName)) + return (!options.data.selectedGroups.length || + options.data.selectedGroups.includes(groupName)) ? ACTIVE : DISABLED; } From 8b578171483819f930dec42646e959c8fb034c7b Mon Sep 17 00:00:00 2001 From: Fei Date: Thu, 28 May 2020 10:23:15 -0400 Subject: [PATCH 06/32] improvement: fix naming and update comments --- packages/core/src/model.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/core/src/model.ts b/packages/core/src/model.ts index a4771e346f..1eac0c5b27 100644 --- a/packages/core/src/model.ts +++ b/packages/core/src/model.ts @@ -289,7 +289,7 @@ export class ChartModel { } /** - * Updates selected datasets + * Updates selected groups */ updateSelectedGroups() { const { ACTIVE, DISABLED } = Configuration.legend.items.status; @@ -301,7 +301,7 @@ export class ChartModel { group => group.status === DISABLED ); - // If there are deactivated items, map the label names into selected datasets + // If there are deactivated items, map the item name into selected groups if (hasDeactivatedItems) { options.data.selectedGroups = activeItems.map(activeItem => activeItem.name); } else { @@ -310,14 +310,18 @@ export class ChartModel { }; } + /** + * Check selected groups with current data groups, clear selected groups if current data groups don't contain every item in selected groups + * @param uniqueDataGroups + */ checkSelectedGroups(uniqueDataGroups: string[]) { const options = this.getOptions(); if (options.data.selectedGroups.length) { // check if current groups includes every item in selected groups - const hasSelectedGroups = options.data.selectedGroups + const hasAllSelectedGroups = options.data.selectedGroups .every(groupName => uniqueDataGroups.includes(groupName)); - if (!hasSelectedGroups) { + if (!hasAllSelectedGroups) { options.data.selectedGroups = []; }; }; @@ -461,6 +465,7 @@ export class ChartModel { ).keys(); this.checkSelectedGroups(uniqueDataGroups); + // Get group status based on items in selected groups const getStatus = (groupName) => { return (!options.data.selectedGroups.length || options.data.selectedGroups.includes(groupName)) From 963ad97417b62849ae65bc7b404e340f1910a5a9 Mon Sep 17 00:00:00 2001 From: Fei Date: Thu, 4 Jun 2020 11:41:26 -0400 Subject: [PATCH 07/32] improvement: simplify the code --- packages/core/src/model.ts | 39 ++++++++++++++------------------------ 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/packages/core/src/model.ts b/packages/core/src/model.ts index 1eac0c5b27..9ba45e6783 100644 --- a/packages/core/src/model.ts +++ b/packages/core/src/model.ts @@ -310,23 +310,6 @@ export class ChartModel { }; } - /** - * Check selected groups with current data groups, clear selected groups if current data groups don't contain every item in selected groups - * @param uniqueDataGroups - */ - checkSelectedGroups(uniqueDataGroups: string[]) { - const options = this.getOptions(); - if (options.data.selectedGroups.length) { - // check if current groups includes every item in selected groups - const hasAllSelectedGroups = options.data.selectedGroups - .every(groupName => uniqueDataGroups.includes(groupName)); - - if (!hasAllSelectedGroups) { - options.data.selectedGroups = []; - }; - }; - } - /** * Should the data point be filled? * @param group @@ -463,16 +446,22 @@ export class ChartModel { data, (datum) => datum[groupMapsTo] ).keys(); - - this.checkSelectedGroups(uniqueDataGroups); - // Get group status based on items in selected groups - const getStatus = (groupName) => { - return (!options.data.selectedGroups.length || - options.data.selectedGroups.includes(groupName)) - ? ACTIVE - : DISABLED; + + // check if selectedGroups can be applied to chart with current data groups + if (options.data.selectedGroups.length) { + const hasAllSelectedGroups = options.data.selectedGroups + .every(groupName => uniqueDataGroups.includes(groupName)); + if (!hasAllSelectedGroups) { + options.data.selectedGroups = []; + }; } + // Get group status based on items in selected groups + const getStatus = (groupName) => + !options.data.selectedGroups.length || options.data.selectedGroups.includes(groupName) + ? ACTIVE + : DISABLED; + return uniqueDataGroups.map(groupName => ({ name: groupName, status: getStatus(groupName) From 00c969ee884dccee51d567eb8077bbabd37e35d4 Mon Sep 17 00:00:00 2001 From: Fei Date: Mon, 8 Jun 2020 14:30:48 -0400 Subject: [PATCH 08/32] improvement: remove updateSelectedGroups --- packages/core/src/model.ts | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/packages/core/src/model.ts b/packages/core/src/model.ts index 9ba45e6783..a41f8911f2 100644 --- a/packages/core/src/model.ts +++ b/packages/core/src/model.ts @@ -277,37 +277,31 @@ export class ChartModel { }); } - // dispatch legend filtering event with the status of all the dataLabels - this.services.events.dispatchEvent(Events.Legend.ITEMS_UPDATE, { - dataGroups, - }); - - // Update model - this.set({ - dataGroups, - }); - } - - /** - * Updates selected groups - */ - updateSelectedGroups() { - const { ACTIVE, DISABLED } = Configuration.legend.items.status; - const dataGroups = this.getDataGroups(); - const activeItems = dataGroups.filter(group => group.status === ACTIVE); + // Updates selected groups + const updatedActiveItems = dataGroups.filter(group => group.status === ACTIVE); const options = this.getOptions(); - const hasDeactivatedItems = dataGroups.some( + const hasUpdatedDeactivatedItems = dataGroups.some( group => group.status === DISABLED ); // If there are deactivated items, map the item name into selected groups - if (hasDeactivatedItems) { - options.data.selectedGroups = activeItems.map(activeItem => activeItem.name); + if (hasUpdatedDeactivatedItems) { + options.data.selectedGroups = updatedActiveItems.map(activeItem => activeItem.name); } else { // If every item is active, clear array options.data.selectedGroups = []; }; + + // dispatch legend filtering event with the status of all the dataLabels + this.services.events.dispatchEvent(Events.Legend.ITEMS_UPDATE, { + dataGroups, + }); + + // Update model + this.set({ + dataGroups, + }); } /** From f0857e2bf30a16487ea846c087844e45d302923a Mon Sep 17 00:00:00 2001 From: Fei Date: Mon, 8 Jun 2020 14:32:39 -0400 Subject: [PATCH 09/32] fix: remove updateSelectedGroups from legend --- packages/core/src/components/essentials/legend.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/core/src/components/essentials/legend.ts b/packages/core/src/components/essentials/legend.ts index 0b8d4541e1..73d398fea9 100644 --- a/packages/core/src/components/essentials/legend.ts +++ b/packages/core/src/components/essentials/legend.ts @@ -268,7 +268,6 @@ export class Legend extends Component { const clickedItemData = clickedItem.datum() as any; self.model.toggleDataLabel(clickedItemData.name); - self.model.updateSelectedGroups(); }) .on("mouseout", function () { const hoveredItem = select(this); From 88fee02bb704ca832ac5cf90abcfd06d6934cc70 Mon Sep 17 00:00:00 2001 From: Fei Date: Mon, 22 Jun 2020 12:13:52 -0400 Subject: [PATCH 10/32] test: add unit test for setting up selectedGroups --- packages/core/src/selectedGroups.spec.ts | 47 +++++++++++++++++++++ packages/core/src/tests/test-environment.ts | 3 ++ 2 files changed, 50 insertions(+) create mode 100644 packages/core/src/selectedGroups.spec.ts diff --git a/packages/core/src/selectedGroups.spec.ts b/packages/core/src/selectedGroups.spec.ts new file mode 100644 index 0000000000..86aa6e0e7c --- /dev/null +++ b/packages/core/src/selectedGroups.spec.ts @@ -0,0 +1,47 @@ +import { TestEnvironment } from "./tests/index"; + +// import the settings for the css prefixes +import settings from "carbon-components/es/globals/js/settings"; + +import { options } from "./configuration"; +import { Events } from "./interfaces"; + +import { select } from "d3-selection"; + +describe("selectedGroups option", () => { + beforeEach(function () { + const testEnvironment = new TestEnvironment(); + testEnvironment.render(); + + this.chart = testEnvironment.getChartReference(); + this.testEnvironment = testEnvironment; + }); + + describe("set default selectedGroups", () => { + it("should match the array length in options", function (done) { + const numberOfSelectedGroup = this.chart.model.getOptions().data.selectedGroups.length; + const chartEventsService = this.chart.services.events; + + const renderCb = () => { + const numberOfActiveLengendItems = select( + `g.${settings.prefix}--${options.chart.style.prefix}--legend` + ).selectAll('g.legend-item > rect.active') + .size(); + + expect(numberOfActiveLengendItems).toEqual(numberOfSelectedGroup); + + done(); + }; + + // Add event listener for when chart render is finished + chartEventsService.addEventListener( + Events.Chart.RENDER_FINISHED, + renderCb + ); + }) + }) + + afterEach(function () { + this.testEnvironment.destroy(); + }); +}) diff --git a/packages/core/src/tests/test-environment.ts b/packages/core/src/tests/test-environment.ts index 84c74ab998..bcc9908b8c 100644 --- a/packages/core/src/tests/test-environment.ts +++ b/packages/core/src/tests/test-environment.ts @@ -10,6 +10,9 @@ import { groupedBarData, groupedBarOptions } from "../../demo/data"; export const data = groupedBarData as ChartData; export const options = Object.assign(groupedBarOptions, { title: "My chart", + data: { + selectedGroups: ['Dataset 1', 'Dataset 3'] + } }) as any; export class TestEnvironment { From 190fb67553bb74d4e087411fd2a13d2531eb7df3 Mon Sep 17 00:00:00 2001 From: Fei Date: Mon, 22 Jun 2020 18:58:58 -0400 Subject: [PATCH 11/32] test: modify unit test --- .../core/src/components/essentials/legend.ts | 7 ++++- packages/core/src/selectedGroups.spec.ts | 28 +++++++++++++++---- packages/core/src/tests/test-environment.ts | 5 +--- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/packages/core/src/components/essentials/legend.ts b/packages/core/src/components/essentials/legend.ts index 73d398fea9..86eca333db 100644 --- a/packages/core/src/components/essentials/legend.ts +++ b/packages/core/src/components/essentials/legend.ts @@ -26,7 +26,10 @@ export class Legend extends Component { const addedLegendItems = legendItems .enter() .append("g") - .classed("legend-item", true); + .classed("legend-item", true) + .classed("active", function (d, i) { + return d.status === options.legend.items.status.ACTIVE; + }); // Configs const checkboxRadius = options.legend.checkbox.radius; @@ -263,9 +266,11 @@ export class Legend extends Component { self.services.events.dispatchEvent(Events.Legend.ITEM_CLICK, { clickedElement: select(this), }); + console.log(select(this)); const clickedItem = select(this); const clickedItemData = clickedItem.datum() as any; + console.log(clickedItemData); self.model.toggleDataLabel(clickedItemData.name); }) diff --git a/packages/core/src/selectedGroups.spec.ts b/packages/core/src/selectedGroups.spec.ts index 86aa6e0e7c..6f821f638e 100644 --- a/packages/core/src/selectedGroups.spec.ts +++ b/packages/core/src/selectedGroups.spec.ts @@ -19,16 +19,34 @@ describe("selectedGroups option", () => { describe("set default selectedGroups", () => { it("should match the array length in options", function (done) { - const numberOfSelectedGroup = this.chart.model.getOptions().data.selectedGroups.length; + const selectedGroups = this.chart.model.getOptions().data.selectedGroups; const chartEventsService = this.chart.services.events; const renderCb = () => { - const numberOfActiveLengendItems = select( + const legendGroup = select( `g.${settings.prefix}--${options.chart.style.prefix}--legend` - ).selectAll('g.legend-item > rect.active') - .size(); + ); - expect(numberOfActiveLengendItems).toEqual(numberOfSelectedGroup); + const numberOfTotalItems = legendGroup + .selectAll('g.legend-item') + .size(); + + const numberOfActiveItems = legendGroup + .selectAll('g.legend-item.active') + .size(); + + const activeLegendNodes = legendGroup + .selectAll('g.legend-item.active > text') + .nodes(); + + const selectedLegend = activeLegendNodes.map(item => item['innerHTML']); + + const preselectedLegendItems = + numberOfTotalItems === numberOfActiveItems + ? [] + : selectedLegend; + + expect(preselectedLegendItems).toEqual(selectedGroups); done(); }; diff --git a/packages/core/src/tests/test-environment.ts b/packages/core/src/tests/test-environment.ts index bcc9908b8c..709513ec87 100644 --- a/packages/core/src/tests/test-environment.ts +++ b/packages/core/src/tests/test-environment.ts @@ -9,10 +9,7 @@ import { groupedBarData, groupedBarOptions } from "../../demo/data"; export const data = groupedBarData as ChartData; export const options = Object.assign(groupedBarOptions, { - title: "My chart", - data: { - selectedGroups: ['Dataset 1', 'Dataset 3'] - } + title: "My chart" }) as any; export class TestEnvironment { From e5cab1791971db15a9b6893185ac598e527fc04c Mon Sep 17 00:00:00 2001 From: Fei Date: Mon, 22 Jun 2020 19:00:54 -0400 Subject: [PATCH 12/32] test: renaming --- packages/core/src/selectedGroups.spec.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/core/src/selectedGroups.spec.ts b/packages/core/src/selectedGroups.spec.ts index 6f821f638e..2743c72490 100644 --- a/packages/core/src/selectedGroups.spec.ts +++ b/packages/core/src/selectedGroups.spec.ts @@ -39,14 +39,14 @@ describe("selectedGroups option", () => { .selectAll('g.legend-item.active > text') .nodes(); - const selectedLegend = activeLegendNodes.map(item => item['innerHTML']); + const selectedLegendLabels = activeLegendNodes.map(item => item['innerHTML']); - const preselectedLegendItems = + const preselectedLegendLabels = numberOfTotalItems === numberOfActiveItems ? [] - : selectedLegend; + : selectedLegendLabels; - expect(preselectedLegendItems).toEqual(selectedGroups); + expect(preselectedLegendLabels).toEqual(selectedGroups); done(); }; From 63c9966352fb6c78b90c14c1fe8cd591598f5581 Mon Sep 17 00:00:00 2001 From: Fei Date: Tue, 23 Jun 2020 16:58:56 -0400 Subject: [PATCH 13/32] test: revise unit test --- .../core/src/components/essentials/legend.ts | 2 - packages/core/src/selectedGroups.spec.ts | 50 +++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/packages/core/src/components/essentials/legend.ts b/packages/core/src/components/essentials/legend.ts index 86eca333db..005c0dc7be 100644 --- a/packages/core/src/components/essentials/legend.ts +++ b/packages/core/src/components/essentials/legend.ts @@ -266,11 +266,9 @@ export class Legend extends Component { self.services.events.dispatchEvent(Events.Legend.ITEM_CLICK, { clickedElement: select(this), }); - console.log(select(this)); const clickedItem = select(this); const clickedItemData = clickedItem.datum() as any; - console.log(clickedItemData); self.model.toggleDataLabel(clickedItemData.name); }) diff --git a/packages/core/src/selectedGroups.spec.ts b/packages/core/src/selectedGroups.spec.ts index 2743c72490..4b7dc7a984 100644 --- a/packages/core/src/selectedGroups.spec.ts +++ b/packages/core/src/selectedGroups.spec.ts @@ -23,6 +23,12 @@ describe("selectedGroups option", () => { const chartEventsService = this.chart.services.events; const renderCb = () => { + // Remove render event listener + chartEventsService.removeEventListener( + Events.Chart.RENDER_FINISHED, + renderCb + ); + const legendGroup = select( `g.${settings.prefix}--${options.chart.style.prefix}--legend` ); @@ -59,6 +65,50 @@ describe("selectedGroups option", () => { }) }) + describe("legend click", () => { + it("should match the selected groups in data options", function (done) { + const chartEventsService = this.chart.services.events; + const dataGroups = this.chart.model.getDataGroups(); + const firstDatasetName = dataGroups[0].name; + + const isOnlySelectedItem = dataGroups[0].status && + dataGroups.filter(group => group.status).length === 1; + + this.chart.model.toggleDataLabel(firstDatasetName); + chartEventsService.removeEventListener(Events.Legend.ITEMS_UPDATE, { + dataGroups + }); + + const renderCb = () => { + // Remove render event listener + chartEventsService.removeEventListener( + Events.Chart.RENDER_FINISHED, + renderCb + ); + const selectedGroups = this.chart.model.getOptions().data.selectedGroups; + + const selectedLegendLabels = []; + + if (!isOnlySelectedItem) { + dataGroups.forEach(dataGroup => { + if (dataGroup.status){ + selectedLegendLabels.push(dataGroup.name); + } + }); + } + expect(selectedLegendLabels).toEqual(selectedGroups); + + done(); + }; + + // Add event listener for when chart render is finished + chartEventsService.addEventListener( + Events.Chart.RENDER_FINISHED, + renderCb + ); + }) + }) + afterEach(function () { this.testEnvironment.destroy(); }); From 46f378a0f5982cd9f4ea4ccd86030266f693b4de Mon Sep 17 00:00:00 2001 From: Fei Date: Tue, 23 Jun 2020 17:14:53 -0400 Subject: [PATCH 14/32] test: update test description --- packages/core/src/selectedGroups.spec.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/core/src/selectedGroups.spec.ts b/packages/core/src/selectedGroups.spec.ts index 4b7dc7a984..b6fba49102 100644 --- a/packages/core/src/selectedGroups.spec.ts +++ b/packages/core/src/selectedGroups.spec.ts @@ -17,8 +17,8 @@ describe("selectedGroups option", () => { this.testEnvironment = testEnvironment; }); - describe("set default selectedGroups", () => { - it("should match the array length in options", function (done) { + describe("selected groups", () => { + it("should match the selected legend labels", function (done) { const selectedGroups = this.chart.model.getOptions().data.selectedGroups; const chartEventsService = this.chart.services.events; @@ -52,7 +52,7 @@ describe("selectedGroups option", () => { ? [] : selectedLegendLabels; - expect(preselectedLegendLabels).toEqual(selectedGroups); + expect(selectedGroups).toEqual(preselectedLegendLabels); done(); }; @@ -65,8 +65,8 @@ describe("selectedGroups option", () => { }) }) - describe("legend click", () => { - it("should match the selected groups in data options", function (done) { + describe("selected groups", () => { + it("should match the legend labels after click event", function (done) { const chartEventsService = this.chart.services.events; const dataGroups = this.chart.model.getDataGroups(); const firstDatasetName = dataGroups[0].name; @@ -96,7 +96,7 @@ describe("selectedGroups option", () => { } }); } - expect(selectedLegendLabels).toEqual(selectedGroups); + expect(selectedGroups).toEqual(selectedLegendLabels); done(); }; From b948159e9d49acb056c978a1031d78bcf69d5d33 Mon Sep 17 00:00:00 2001 From: Fei Date: Tue, 23 Jun 2020 17:24:57 -0400 Subject: [PATCH 15/32] style: revise the comment for selectedGroup --- packages/core/src/interfaces/charts.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/core/src/interfaces/charts.ts b/packages/core/src/interfaces/charts.ts index 383555dde9..1e30ded6a1 100644 --- a/packages/core/src/interfaces/charts.ts +++ b/packages/core/src/interfaces/charts.ts @@ -93,7 +93,8 @@ export interface BaseChartOptions { */ loading?: Boolean; /** - * options related to pre-selected datasets + * options related to pre-selected data groups + * Remains empty if every legend item is active or dataset doesn't have the data groups. */ selectedGroups?: string[]; }; From a8a1a4b70fdda86d17987933f5a44dd41bffbfbf Mon Sep 17 00:00:00 2001 From: Fei Date: Wed, 24 Jun 2020 16:10:34 -0400 Subject: [PATCH 16/32] test: update test --- packages/core/src/selectedGroups.spec.ts | 69 ++------------------- packages/core/src/tests/test-environment.ts | 5 +- 2 files changed, 10 insertions(+), 64 deletions(-) diff --git a/packages/core/src/selectedGroups.spec.ts b/packages/core/src/selectedGroups.spec.ts index b6fba49102..6ff8ff1b9d 100644 --- a/packages/core/src/selectedGroups.spec.ts +++ b/packages/core/src/selectedGroups.spec.ts @@ -19,9 +19,10 @@ describe("selectedGroups option", () => { describe("selected groups", () => { it("should match the selected legend labels", function (done) { - const selectedGroups = this.chart.model.getOptions().data.selectedGroups; const chartEventsService = this.chart.services.events; + const sampleSelectedGroups = ['Dataset 1', 'Dataset 3']; + const renderCb = () => { // Remove render event listener chartEventsService.removeEventListener( @@ -32,71 +33,13 @@ describe("selectedGroups option", () => { const legendGroup = select( `g.${settings.prefix}--${options.chart.style.prefix}--legend` ); - - const numberOfTotalItems = legendGroup - .selectAll('g.legend-item') - .size(); - - const numberOfActiveItems = legendGroup - .selectAll('g.legend-item.active') - .size(); - const activeLegendNodes = legendGroup + const selectedLegendLabels = legendGroup .selectAll('g.legend-item.active > text') - .nodes(); - - const selectedLegendLabels = activeLegendNodes.map(item => item['innerHTML']); - - const preselectedLegendLabels = - numberOfTotalItems === numberOfActiveItems - ? [] - : selectedLegendLabels; - - expect(selectedGroups).toEqual(preselectedLegendLabels); - - done(); - }; - - // Add event listener for when chart render is finished - chartEventsService.addEventListener( - Events.Chart.RENDER_FINISHED, - renderCb - ); - }) - }) - - describe("selected groups", () => { - it("should match the legend labels after click event", function (done) { - const chartEventsService = this.chart.services.events; - const dataGroups = this.chart.model.getDataGroups(); - const firstDatasetName = dataGroups[0].name; - - const isOnlySelectedItem = dataGroups[0].status && - dataGroups.filter(group => group.status).length === 1; - - this.chart.model.toggleDataLabel(firstDatasetName); - chartEventsService.removeEventListener(Events.Legend.ITEMS_UPDATE, { - dataGroups - }); - - const renderCb = () => { - // Remove render event listener - chartEventsService.removeEventListener( - Events.Chart.RENDER_FINISHED, - renderCb - ); - const selectedGroups = this.chart.model.getOptions().data.selectedGroups; - - const selectedLegendLabels = []; + .nodes() + .map(item => item['innerHTML']); - if (!isOnlySelectedItem) { - dataGroups.forEach(dataGroup => { - if (dataGroup.status){ - selectedLegendLabels.push(dataGroup.name); - } - }); - } - expect(selectedGroups).toEqual(selectedLegendLabels); + expect(selectedLegendLabels).toEqual(sampleSelectedGroups); done(); }; diff --git a/packages/core/src/tests/test-environment.ts b/packages/core/src/tests/test-environment.ts index 709513ec87..bcc9908b8c 100644 --- a/packages/core/src/tests/test-environment.ts +++ b/packages/core/src/tests/test-environment.ts @@ -9,7 +9,10 @@ import { groupedBarData, groupedBarOptions } from "../../demo/data"; export const data = groupedBarData as ChartData; export const options = Object.assign(groupedBarOptions, { - title: "My chart" + title: "My chart", + data: { + selectedGroups: ['Dataset 1', 'Dataset 3'] + } }) as any; export class TestEnvironment { From 6168334ae916a29577a4fe29568baf52335901b7 Mon Sep 17 00:00:00 2001 From: Fei Date: Wed, 24 Jun 2020 16:16:29 -0400 Subject: [PATCH 17/32] test: simplify the test code --- packages/core/src/selectedGroups.spec.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/core/src/selectedGroups.spec.ts b/packages/core/src/selectedGroups.spec.ts index 6ff8ff1b9d..3b659acf0d 100644 --- a/packages/core/src/selectedGroups.spec.ts +++ b/packages/core/src/selectedGroups.spec.ts @@ -29,12 +29,10 @@ describe("selectedGroups option", () => { Events.Chart.RENDER_FINISHED, renderCb ); - - const legendGroup = select( - `g.${settings.prefix}--${options.chart.style.prefix}--legend` - ); - const selectedLegendLabels = legendGroup + const selectedLegendLabels = select( + `g.${settings.prefix}--${options.chart.style.prefix}--legend` + ) .selectAll('g.legend-item.active > text') .nodes() .map(item => item['innerHTML']); From bd22d0a62a2bcee3ada5f5e39fcc844c8016acf3 Mon Sep 17 00:00:00 2001 From: Fei Date: Wed, 24 Jun 2020 16:27:49 -0400 Subject: [PATCH 18/32] style: format the code --- packages/core/src/selectedGroups.spec.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/core/src/selectedGroups.spec.ts b/packages/core/src/selectedGroups.spec.ts index 3b659acf0d..b94f94dd26 100644 --- a/packages/core/src/selectedGroups.spec.ts +++ b/packages/core/src/selectedGroups.spec.ts @@ -17,11 +17,11 @@ describe("selectedGroups option", () => { this.testEnvironment = testEnvironment; }); - describe("selected groups", () => { - it("should match the selected legend labels", function (done) { + describe("selected legend labels", () => { + it("should match the selected groups provided in options", function (done) { const chartEventsService = this.chart.services.events; - const sampleSelectedGroups = ['Dataset 1', 'Dataset 3']; + const sampleSelectedGroups = ["Dataset 1", "Dataset 3"]; const renderCb = () => { // Remove render event listener @@ -29,13 +29,13 @@ describe("selectedGroups option", () => { Events.Chart.RENDER_FINISHED, renderCb ); - + const selectedLegendLabels = select( `g.${settings.prefix}--${options.chart.style.prefix}--legend` ) - .selectAll('g.legend-item.active > text') + .selectAll("g.legend-item.active > text") .nodes() - .map(item => item['innerHTML']); + .map((item) => item["innerHTML"]); expect(selectedLegendLabels).toEqual(sampleSelectedGroups); @@ -47,10 +47,10 @@ describe("selectedGroups option", () => { Events.Chart.RENDER_FINISHED, renderCb ); - }) - }) + }); + }); afterEach(function () { this.testEnvironment.destroy(); }); -}) +}); From 79cf2574902ec9453fe352778b19b3636bc161dc Mon Sep 17 00:00:00 2001 From: Fei Date: Thu, 25 Jun 2020 10:58:54 -0400 Subject: [PATCH 19/32] test: add more tests --- packages/core/src/selectedGroups.spec.ts | 113 +++++++++++++++++++- packages/core/src/tests/test-environment.ts | 2 +- 2 files changed, 112 insertions(+), 3 deletions(-) diff --git a/packages/core/src/selectedGroups.spec.ts b/packages/core/src/selectedGroups.spec.ts index b94f94dd26..115a1d2859 100644 --- a/packages/core/src/selectedGroups.spec.ts +++ b/packages/core/src/selectedGroups.spec.ts @@ -20,8 +20,7 @@ describe("selectedGroups option", () => { describe("selected legend labels", () => { it("should match the selected groups provided in options", function (done) { const chartEventsService = this.chart.services.events; - - const sampleSelectedGroups = ["Dataset 1", "Dataset 3"]; + const sampleSelectedGroups = ["Dataset 1"]; const renderCb = () => { // Remove render event listener @@ -50,6 +49,116 @@ describe("selectedGroups option", () => { }); }); + describe("selected groups", () => { + it("should match the legend labels after click unchosen label", function (done) { + const chartEventsService = this.chart.services.events; + const dataGroups = this.chart.model.getDataGroups(); + const sampleSelectedGroups = ["Dataset 1", "Dataset 2"]; + const clickedLabel = "Dataset 2"; + + const updateChart = () => { + // Remove render event listener + chartEventsService.removeEventListener( + Events.Chart.RENDER_FINISHED, + updateChart + ); + + this.chart.model.toggleDataLabel(clickedLabel); + chartEventsService.removeEventListener(Events.Legend.ITEMS_UPDATE, { + dataGroups + }); + + const renderCb = () => { + // Remove render event listener + chartEventsService.removeEventListener( + Events.Chart.RENDER_FINISHED, + renderCb + ); + + const selectedLegendLabels = []; + dataGroups.forEach(dataGroup => { + if (dataGroup.status){ + selectedLegendLabels.push(dataGroup.name); + } + }); + + expect(sampleSelectedGroups).toEqual(selectedLegendLabels); + + done(); + }; + + // Add event listener for when chart render is finished + chartEventsService.addEventListener( + Events.Chart.RENDER_FINISHED, + renderCb + ); + } + + // Remove render event listener + chartEventsService.addEventListener( + Events.Chart.RENDER_FINISHED, + updateChart + ); + }); + }); + + describe("selected groups", () => { + it("should match the legend labels after click chosen label", function (done) { + const chartEventsService = this.chart.services.events; + const dataGroups = this.chart.model.getDataGroups(); + const sampleSelectedGroups = []; + const clickedLabel = "Dataset 1"; + + const updateChart = () => { + // Remove render event listener + chartEventsService.removeEventListener( + Events.Chart.RENDER_FINISHED, + updateChart + ); + + this.chart.model.toggleDataLabel(clickedLabel); + chartEventsService.removeEventListener(Events.Legend.ITEMS_UPDATE, { + dataGroups + }); + + const renderCb = () => { + // Remove render event listener + chartEventsService.removeEventListener( + Events.Chart.RENDER_FINISHED, + renderCb + ); + + const selectedLegendLabels = []; + const hasDeactiveLabel = dataGroups.some(group => !group.status); + + if (hasDeactiveLabel) { + dataGroups.forEach(group => { + if (group.status){ + selectedLegendLabels.push(group.name); + }; + }); + }; + + expect(sampleSelectedGroups).toEqual(selectedLegendLabels); + + done(); + }; + + // Add event listener for when chart render is finished + chartEventsService.addEventListener( + Events.Chart.RENDER_FINISHED, + renderCb + ); + } + + // Remove render event listener + chartEventsService.addEventListener( + Events.Chart.RENDER_FINISHED, + updateChart + ); + }); + }); + afterEach(function () { this.testEnvironment.destroy(); }); diff --git a/packages/core/src/tests/test-environment.ts b/packages/core/src/tests/test-environment.ts index bcc9908b8c..24bc2f8849 100644 --- a/packages/core/src/tests/test-environment.ts +++ b/packages/core/src/tests/test-environment.ts @@ -11,7 +11,7 @@ export const data = groupedBarData as ChartData; export const options = Object.assign(groupedBarOptions, { title: "My chart", data: { - selectedGroups: ['Dataset 1', 'Dataset 3'] + selectedGroups: ['Dataset 1'] } }) as any; From efdeaa0ea7fea8229f2b84cd66fc79f813c3e6d2 Mon Sep 17 00:00:00 2001 From: Fei Date: Thu, 25 Jun 2020 13:55:21 -0400 Subject: [PATCH 20/32] test: remove tests for events --- packages/core/src/selectedGroups.spec.ts | 112 +------------------- packages/core/src/tests/test-environment.ts | 2 +- 2 files changed, 2 insertions(+), 112 deletions(-) diff --git a/packages/core/src/selectedGroups.spec.ts b/packages/core/src/selectedGroups.spec.ts index 115a1d2859..c532f5a51a 100644 --- a/packages/core/src/selectedGroups.spec.ts +++ b/packages/core/src/selectedGroups.spec.ts @@ -20,7 +20,7 @@ describe("selectedGroups option", () => { describe("selected legend labels", () => { it("should match the selected groups provided in options", function (done) { const chartEventsService = this.chart.services.events; - const sampleSelectedGroups = ["Dataset 1"]; + const sampleSelectedGroups = ["Dataset 1", "Dataset 3"]; const renderCb = () => { // Remove render event listener @@ -49,116 +49,6 @@ describe("selectedGroups option", () => { }); }); - describe("selected groups", () => { - it("should match the legend labels after click unchosen label", function (done) { - const chartEventsService = this.chart.services.events; - const dataGroups = this.chart.model.getDataGroups(); - const sampleSelectedGroups = ["Dataset 1", "Dataset 2"]; - const clickedLabel = "Dataset 2"; - - const updateChart = () => { - // Remove render event listener - chartEventsService.removeEventListener( - Events.Chart.RENDER_FINISHED, - updateChart - ); - - this.chart.model.toggleDataLabel(clickedLabel); - chartEventsService.removeEventListener(Events.Legend.ITEMS_UPDATE, { - dataGroups - }); - - const renderCb = () => { - // Remove render event listener - chartEventsService.removeEventListener( - Events.Chart.RENDER_FINISHED, - renderCb - ); - - const selectedLegendLabels = []; - dataGroups.forEach(dataGroup => { - if (dataGroup.status){ - selectedLegendLabels.push(dataGroup.name); - } - }); - - expect(sampleSelectedGroups).toEqual(selectedLegendLabels); - - done(); - }; - - // Add event listener for when chart render is finished - chartEventsService.addEventListener( - Events.Chart.RENDER_FINISHED, - renderCb - ); - } - - // Remove render event listener - chartEventsService.addEventListener( - Events.Chart.RENDER_FINISHED, - updateChart - ); - }); - }); - - describe("selected groups", () => { - it("should match the legend labels after click chosen label", function (done) { - const chartEventsService = this.chart.services.events; - const dataGroups = this.chart.model.getDataGroups(); - const sampleSelectedGroups = []; - const clickedLabel = "Dataset 1"; - - const updateChart = () => { - // Remove render event listener - chartEventsService.removeEventListener( - Events.Chart.RENDER_FINISHED, - updateChart - ); - - this.chart.model.toggleDataLabel(clickedLabel); - chartEventsService.removeEventListener(Events.Legend.ITEMS_UPDATE, { - dataGroups - }); - - const renderCb = () => { - // Remove render event listener - chartEventsService.removeEventListener( - Events.Chart.RENDER_FINISHED, - renderCb - ); - - const selectedLegendLabels = []; - const hasDeactiveLabel = dataGroups.some(group => !group.status); - - if (hasDeactiveLabel) { - dataGroups.forEach(group => { - if (group.status){ - selectedLegendLabels.push(group.name); - }; - }); - }; - - expect(sampleSelectedGroups).toEqual(selectedLegendLabels); - - done(); - }; - - // Add event listener for when chart render is finished - chartEventsService.addEventListener( - Events.Chart.RENDER_FINISHED, - renderCb - ); - } - - // Remove render event listener - chartEventsService.addEventListener( - Events.Chart.RENDER_FINISHED, - updateChart - ); - }); - }); - afterEach(function () { this.testEnvironment.destroy(); }); diff --git a/packages/core/src/tests/test-environment.ts b/packages/core/src/tests/test-environment.ts index 24bc2f8849..e41886b107 100644 --- a/packages/core/src/tests/test-environment.ts +++ b/packages/core/src/tests/test-environment.ts @@ -11,7 +11,7 @@ export const data = groupedBarData as ChartData; export const options = Object.assign(groupedBarOptions, { title: "My chart", data: { - selectedGroups: ['Dataset 1'] + selectedGroups: ["Dataset 1", "Dataset 3"] } }) as any; From d458da2ccb29f169c1529d83c0edfe4131a540a7 Mon Sep 17 00:00:00 2001 From: Fei Date: Thu, 25 Jun 2020 14:29:06 -0400 Subject: [PATCH 21/32] test: remove async function --- packages/core/src/selectedGroups.spec.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/core/src/selectedGroups.spec.ts b/packages/core/src/selectedGroups.spec.ts index c532f5a51a..21411fb043 100644 --- a/packages/core/src/selectedGroups.spec.ts +++ b/packages/core/src/selectedGroups.spec.ts @@ -19,9 +19,10 @@ describe("selectedGroups option", () => { describe("selected legend labels", () => { it("should match the selected groups provided in options", function (done) { - const chartEventsService = this.chart.services.events; const sampleSelectedGroups = ["Dataset 1", "Dataset 3"]; + const chartEventsService = this.chart.services.events; + const renderCb = () => { // Remove render event listener chartEventsService.removeEventListener( From 9315f31c366c5baa28bf4b95ceb27af4eb21cc65 Mon Sep 17 00:00:00 2001 From: Fei Date: Thu, 25 Jun 2020 17:36:40 -0400 Subject: [PATCH 22/32] fix: fix check mark position issue and add demos --- packages/core/demo/data/bar.ts | 38 +++++++++++++++++++ packages/core/demo/data/index.ts | 15 ++++++++ packages/core/demo/data/line.ts | 21 +++++++++- .../core/src/components/essentials/legend.ts | 3 +- 4 files changed, 74 insertions(+), 3 deletions(-) diff --git a/packages/core/demo/data/bar.ts b/packages/core/demo/data/bar.ts index 7e647f5c77..03abc801fd 100644 --- a/packages/core/demo/data/bar.ts +++ b/packages/core/demo/data/bar.ts @@ -74,6 +74,25 @@ export const simpleBarOptions = { }, }; +// Simple bar with selected groups option +export const simpleBarSelectedGroupsData = simpleBarData; + +export const simpleBarSelectedGroupsOptions = { + title: "Simple bar (selected groups)", + data: { + selectedGroups: ["Qty", "Sold", "Misc"] + }, + axes: { + left: { + mapsTo: "value", + }, + bottom: { + mapsTo: "group", + scaleType: "labels", + }, + }, +}; + // Simple bar with long labels export const simpleBarLongLabelData = [ { group: "6591DA8668C339B1B39297C61091E320C35391AB7AFC15B469F96B8A2DD0C231", value: 65000 }, @@ -134,6 +153,25 @@ export const simpleHorizontalBarOptions = { }, }; +export const simpleHorizontalBarSelectedGroupsData = simpleBarData; + +// Horizontal simple with selected groups option +export const simpleHorizontalBarSelectedGroupsOptions = { + title: "Simple horizontal bar (selected groups)", + data: { + selectedGroups: ["Qty", "Sold", "Misc"] + }, + axes: { + left: { + mapsTo: "group", + scaleType: "labels", + }, + bottom: { + mapsTo: "value", + }, + }, +}; + export const simpleHorizontalBarLongLabelOptions = { title: "Simple horizontal bar (truncated labels)", axes: { diff --git a/packages/core/demo/data/index.ts b/packages/core/demo/data/index.ts index 703e459214..146d5cf073 100644 --- a/packages/core/demo/data/index.ts +++ b/packages/core/demo/data/index.ts @@ -141,6 +141,11 @@ let allDemoGroups = [ data: barDemos.simpleBarData, chartType: chartTypes.SimpleBarChart }, + { + options: barDemos.simpleBarSelectedGroupsOptions, + data: barDemos.simpleBarSelectedGroupsData, + chartType: chartTypes.SimpleBarChart + }, { options: barDemos.simpleBarLongLabelOptions, data: barDemos.simpleBarLongLabelData, @@ -222,6 +227,11 @@ let allDemoGroups = [ data: barDemos.simpleHorizontalBarData, chartType: chartTypes.SimpleBarChart }, + { + options: barDemos.simpleHorizontalBarSelectedGroupsOptions, + data: barDemos.simpleHorizontalBarSelectedGroupsData, + chartType: chartTypes.SimpleBarChart + }, { options: barDemos.simpleHorizontalBarLongLabelOptions, data: barDemos.simpleHorizontalBarLongLabelData, @@ -377,6 +387,11 @@ let allDemoGroups = [ data: lineDemos.lineData, chartType: chartTypes.LineChart, }, + { + options: lineDemos.lineSelectedGroupsOptions, + data: lineDemos.lineData, + chartType: chartTypes.LineChart, + }, { options: lineDemos.lineTimeSeriesRotatedTicksOptions, data: lineDemos.lineTimeSeriesDataRotatedTicks, diff --git a/packages/core/demo/data/line.ts b/packages/core/demo/data/line.ts index b57e8fcb3d..2dce51868d 100644 --- a/packages/core/demo/data/line.ts +++ b/packages/core/demo/data/line.ts @@ -85,7 +85,7 @@ export const lineCustomDomainOptions = { title: "2019 Annual Sales Figures", mapsTo: "key", scaleType: "labels", - domain: ['Qty', 'More', 'Misc'] + domain: ["Qty", "More", "Misc"] }, left: { domain: [10000, 50000], @@ -96,6 +96,25 @@ export const lineCustomDomainOptions = { }, }; +export const lineSelectedGroupsOptions = { + title: "Line (selected groups)", + data: { + selectedGroups: ["Dataset 1", "Dataset 3"] + }, + axes: { + bottom: { + title: "2019 Annual Sales Figures", + mapsTo: "key", + scaleType: "labels", + }, + left: { + mapsTo: "value", + title: "Conversion rate", + scaleType: "linear", + }, + }, +}; + export const lineTimeSeriesData = [ { group: "Dataset 1", date: new Date(2019, 0, 1), value: 50000 }, { group: "Dataset 1", date: new Date(2019, 0, 5), value: 65000 }, diff --git a/packages/core/src/components/essentials/legend.ts b/packages/core/src/components/essentials/legend.ts index a3d0c2910d..def47ebcf8 100644 --- a/packages/core/src/components/essentials/legend.ts +++ b/packages/core/src/components/essentials/legend.ts @@ -217,8 +217,7 @@ export class Legend extends Component { // Render checkbox check icon if ( - hasDeactivatedItems && - legendItem.select("g.check").empty() + hasDeactivatedItems ) { legendItem.append("g").classed("check", true).html(` Date: Fri, 26 Jun 2020 14:55:39 -0400 Subject: [PATCH 23/32] fix: fix multiple check marks bug --- packages/core/src/components/essentials/legend.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/core/src/components/essentials/legend.ts b/packages/core/src/components/essentials/legend.ts index def47ebcf8..e621614b4d 100644 --- a/packages/core/src/components/essentials/legend.ts +++ b/packages/core/src/components/essentials/legend.ts @@ -215,9 +215,20 @@ export class Legend extends Component { lastYPosition = yPosition; + // Test if legendItems are placed in the correct direction + const testHorizontal = (!legendOrientation || + legendOrientation === LegendOrientations.HORIZONTAL) && + legendItem.select("rect.checkbox").attr("y") === '0'; + + const testVertical = legendOrientation === LegendOrientations.VERTICAL && + legendItem.select("rect.checkbox").attr("x") === '0'; + + const hasCorrectLegendDirection = testHorizontal || testVertical; + // Render checkbox check icon - if ( - hasDeactivatedItems + if (hasDeactivatedItems && + legendItem.select("g.check").empty() && + hasCorrectLegendDirection ) { legendItem.append("g").classed("check", true).html(` Date: Mon, 29 Jun 2020 10:51:28 -0400 Subject: [PATCH 24/32] fix: fix chart shrinks between legend click for selected groups --- packages/core/demo/data/bar.ts | 57 +++++++------------ packages/core/demo/data/index.ts | 15 ++--- packages/core/src/model.ts | 21 ++++++- .../core/src/services/scales-cartesian.ts | 6 +- 4 files changed, 46 insertions(+), 53 deletions(-) diff --git a/packages/core/demo/data/bar.ts b/packages/core/demo/data/bar.ts index 03abc801fd..c9fc44ebad 100644 --- a/packages/core/demo/data/bar.ts +++ b/packages/core/demo/data/bar.ts @@ -36,6 +36,25 @@ export const groupedBarOptions = { }, }; +export const groupedBarSelectedGroupsData = groupedBarData; + +// Grouped bar with selected groups option +export const groupedBarSelectedGroupsOptions = { + title: "Grouped bar (selected groups)", + data: { + selectedGroups: ["Dataset 1", "Dataset 3"] + }, + axes: { + left: { + mapsTo: "value", + }, + bottom: { + scaleType: "labels", + mapsTo: "key", + }, + }, +}; + // Horizontal Grouped export const groupedHorizontalBarData = groupedBarData; @@ -74,25 +93,6 @@ export const simpleBarOptions = { }, }; -// Simple bar with selected groups option -export const simpleBarSelectedGroupsData = simpleBarData; - -export const simpleBarSelectedGroupsOptions = { - title: "Simple bar (selected groups)", - data: { - selectedGroups: ["Qty", "Sold", "Misc"] - }, - axes: { - left: { - mapsTo: "value", - }, - bottom: { - mapsTo: "group", - scaleType: "labels", - }, - }, -}; - // Simple bar with long labels export const simpleBarLongLabelData = [ { group: "6591DA8668C339B1B39297C61091E320C35391AB7AFC15B469F96B8A2DD0C231", value: 65000 }, @@ -153,25 +153,6 @@ export const simpleHorizontalBarOptions = { }, }; -export const simpleHorizontalBarSelectedGroupsData = simpleBarData; - -// Horizontal simple with selected groups option -export const simpleHorizontalBarSelectedGroupsOptions = { - title: "Simple horizontal bar (selected groups)", - data: { - selectedGroups: ["Qty", "Sold", "Misc"] - }, - axes: { - left: { - mapsTo: "group", - scaleType: "labels", - }, - bottom: { - mapsTo: "value", - }, - }, -}; - export const simpleHorizontalBarLongLabelOptions = { title: "Simple horizontal bar (truncated labels)", axes: { diff --git a/packages/core/demo/data/index.ts b/packages/core/demo/data/index.ts index 146d5cf073..81d3c81fc1 100644 --- a/packages/core/demo/data/index.ts +++ b/packages/core/demo/data/index.ts @@ -141,11 +141,6 @@ let allDemoGroups = [ data: barDemos.simpleBarData, chartType: chartTypes.SimpleBarChart }, - { - options: barDemos.simpleBarSelectedGroupsOptions, - data: barDemos.simpleBarSelectedGroupsData, - chartType: chartTypes.SimpleBarChart - }, { options: barDemos.simpleBarLongLabelOptions, data: barDemos.simpleBarLongLabelData, @@ -181,6 +176,11 @@ let allDemoGroups = [ data: barDemos.groupedBarData, chartType: chartTypes.GroupedBarChart }, + { + options: barDemos.groupedBarSelectedGroupsOptions, + data: barDemos.groupedBarSelectedGroupsData, + chartType: chartTypes.GroupedBarChart + }, { options: barDemos.groupedBarEmptyStateOptions, data: barDemos.groupedBarEmptyStateData, @@ -227,11 +227,6 @@ let allDemoGroups = [ data: barDemos.simpleHorizontalBarData, chartType: chartTypes.SimpleBarChart }, - { - options: barDemos.simpleHorizontalBarSelectedGroupsOptions, - data: barDemos.simpleHorizontalBarSelectedGroupsData, - chartType: chartTypes.SimpleBarChart - }, { options: barDemos.simpleHorizontalBarLongLabelOptions, data: barDemos.simpleHorizontalBarLongLabelData, diff --git a/packages/core/src/model.ts b/packages/core/src/model.ts index 144eac4471..d7ff8e99bf 100644 --- a/packages/core/src/model.ts +++ b/packages/core/src/model.ts @@ -39,12 +39,11 @@ export class ChartModel { this.services = services; } - getDisplayData() { + getAllDataFromDomain() { if (!this.get("data")) { return null; } - const { ACTIVE } = Configuration.legend.items.status; const dataGroups = this.getDataGroups(); // Remove datasets that have been disabled @@ -76,6 +75,24 @@ export class ChartModel { } return displayData.filter((datum) => { + return dataGroups.find( + (group) => group.name === datum[groupMapsTo] + ); + }); + } + + getDisplayData() { + if (!this.get("data")) { + return null; + } + + const { ACTIVE } = Configuration.legend.items.status; + const dataGroups = this.getDataGroups(); + const { groupMapsTo } = this.getOptions().data; + + const allData = this.getAllDataFromDomain(); + + return allData.filter((datum) => { const group = dataGroups.find( (group) => group.name === datum[groupMapsTo] ); diff --git a/packages/core/src/services/scales-cartesian.ts b/packages/core/src/services/scales-cartesian.ts index 5c2d785360..9db2745804 100644 --- a/packages/core/src/services/scales-cartesian.ts +++ b/packages/core/src/services/scales-cartesian.ts @@ -336,7 +336,7 @@ export class CartesianScales extends Service { return []; } - const displayData = this.model.getDisplayData(); + const allDataFromDomain = this.model.getAllDataFromDomain(); const { mapsTo, percentage } = axisOptions; // If domain is specified return that domain @@ -355,7 +355,7 @@ export class CartesianScales extends Service { // If scale is a LABELS scale, return some labels as the domain if (axisOptions && scaleType === ScaleTypes.LABELS) { // Get unique values - return map(displayData, (d) => d[mapsTo]).keys(); + return map(allDataFromDomain, (d) => d[mapsTo]).keys(); } // Get the extent of the domain @@ -368,7 +368,7 @@ export class CartesianScales extends Service { sum(values(dataValues) as any) ); } else { - allDataValues = displayData.map((datum) => datum[mapsTo]); + allDataValues = allDataFromDomain.map((datum) => datum[mapsTo]); } if (scaleType !== ScaleTypes.TIME && includeZero) { From 246f179af162b5bdc2c6ebbe728bdfa32a717d05 Mon Sep 17 00:00:00 2001 From: Fei Date: Mon, 29 Jun 2020 15:56:32 -0400 Subject: [PATCH 25/32] fix: fix legend height change with first legend click --- packages/core/src/components/essentials/legend.ts | 3 +-- packages/core/src/components/layout/layout.ts | 10 +++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/core/src/components/essentials/legend.ts b/packages/core/src/components/essentials/legend.ts index e621614b4d..f24a29c4f9 100644 --- a/packages/core/src/components/essentials/legend.ts +++ b/packages/core/src/components/essentials/legend.ts @@ -211,7 +211,7 @@ export class Legend extends Component { legendItem .select("text") .attr("x", startingPoint + spaceNeededForCheckbox) - .attr("y", yOffset + yPosition + 2); + .attr("y", yOffset + yPosition + 3); lastYPosition = yPosition; @@ -286,7 +286,6 @@ export class Legend extends Component { // Configs const checkboxRadius = options.legend.checkbox.radius; - const hoveredItem = select(this); hoveredItem .append("rect") diff --git a/packages/core/src/components/layout/layout.ts b/packages/core/src/components/layout/layout.ts index cba8a175cf..aefdcfc109 100644 --- a/packages/core/src/components/layout/layout.ts +++ b/packages/core/src/components/layout/layout.ts @@ -158,10 +158,18 @@ export class LayoutComponent extends Component { ) { // Calculate preffered children sizes after internal rendering const growth = Tools.getProperty(d, "data", "growth", "x"); - const matchingSVGDimensions = DOMUtils.getSVGElementSize( + let matchingSVGDimensions = DOMUtils.getSVGElementSize( select(this), { useBBox: true } ); + + if (d.data.id === "legend") { + matchingSVGDimensions = DOMUtils.getSVGElementSize( + select(this), + { useAttrs: true } + ); + } + if (growth === LayoutGrowth.PREFERRED) { const matchingSVGWidth = horizontal ? matchingSVGDimensions.width From 4f2233d3d3016c6e26c5f6a9b1b7b4ff75502581 Mon Sep 17 00:00:00 2001 From: Fei Date: Tue, 30 Jun 2020 18:22:39 -0400 Subject: [PATCH 26/32] fix: fix demo broken --- packages/core/src/services/scales-cartesian.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/core/src/services/scales-cartesian.ts b/packages/core/src/services/scales-cartesian.ts index 9db2745804..2a66bcc8a3 100644 --- a/packages/core/src/services/scales-cartesian.ts +++ b/packages/core/src/services/scales-cartesian.ts @@ -337,6 +337,7 @@ export class CartesianScales extends Service { } const allDataFromDomain = this.model.getAllDataFromDomain(); + const displayData = this.model.getDisplayData(); const { mapsTo, percentage } = axisOptions; // If domain is specified return that domain @@ -355,7 +356,7 @@ export class CartesianScales extends Service { // If scale is a LABELS scale, return some labels as the domain if (axisOptions && scaleType === ScaleTypes.LABELS) { // Get unique values - return map(allDataFromDomain, (d) => d[mapsTo]).keys(); + return map(displayData, (d) => d[mapsTo]).keys(); } // Get the extent of the domain From e1a911db32a105945e0f2f3b11f9f1e09f355f42 Mon Sep 17 00:00:00 2001 From: Fei Date: Thu, 2 Jul 2020 16:48:21 -0400 Subject: [PATCH 27/32] refactor: renaming --- packages/core/src/model.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/src/model.ts b/packages/core/src/model.ts index d7ff8e99bf..58741045fe 100644 --- a/packages/core/src/model.ts +++ b/packages/core/src/model.ts @@ -90,9 +90,9 @@ export class ChartModel { const dataGroups = this.getDataGroups(); const { groupMapsTo } = this.getOptions().data; - const allData = this.getAllDataFromDomain(); + const allDataFromDomain = this.getAllDataFromDomain(); - return allData.filter((datum) => { + return allDataFromDomain.filter((datum) => { const group = dataGroups.find( (group) => group.name === datum[groupMapsTo] ); From c3e86eb9b4009e2ee2721faf980d1d270cae737d Mon Sep 17 00:00:00 2001 From: Fei Date: Thu, 2 Jul 2020 17:19:39 -0400 Subject: [PATCH 28/32] refactor: get legend height --- packages/core/src/components/layout/layout.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/core/src/components/layout/layout.ts b/packages/core/src/components/layout/layout.ts index aefdcfc109..f7689bd318 100644 --- a/packages/core/src/components/layout/layout.ts +++ b/packages/core/src/components/layout/layout.ts @@ -158,17 +158,18 @@ export class LayoutComponent extends Component { ) { // Calculate preffered children sizes after internal rendering const growth = Tools.getProperty(d, "data", "growth", "x"); - let matchingSVGDimensions = DOMUtils.getSVGElementSize( + const matchingSVGDimensions = DOMUtils.getSVGElementSize( select(this), { useBBox: true } ); if (d.data.id === "legend") { - matchingSVGDimensions = DOMUtils.getSVGElementSize( + const svgSize = DOMUtils.getSVGElementSize( select(this), { useAttrs: true } ); - } + matchingSVGDimensions.height = svgSize.height; + }; if (growth === LayoutGrowth.PREFERRED) { const matchingSVGWidth = horizontal From 16056ccefce7e3d966ebacde0ebf434f49d41a6f Mon Sep 17 00:00:00 2001 From: Fei Z Date: Thu, 2 Jul 2020 17:38:40 -0400 Subject: [PATCH 29/32] remove semicolon Co-authored-by: Eliad Moosavi --- packages/core/src/components/layout/layout.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/components/layout/layout.ts b/packages/core/src/components/layout/layout.ts index f7689bd318..2270ae7792 100644 --- a/packages/core/src/components/layout/layout.ts +++ b/packages/core/src/components/layout/layout.ts @@ -169,7 +169,7 @@ export class LayoutComponent extends Component { { useAttrs: true } ); matchingSVGDimensions.height = svgSize.height; - }; + } if (growth === LayoutGrowth.PREFERRED) { const matchingSVGWidth = horizontal From 2606182e1cd491f8fbf1e5acdc35818cfb2c3fce Mon Sep 17 00:00:00 2001 From: Fei Date: Mon, 6 Jul 2020 11:21:19 -0400 Subject: [PATCH 30/32] fix: fix data domain --- packages/core/demo/data/index.ts | 2 +- packages/core/demo/data/line.ts | 23 +++++++++++++++++++ .../core/src/services/scales-cartesian.ts | 3 +-- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/packages/core/demo/data/index.ts b/packages/core/demo/data/index.ts index 81d3c81fc1..1b96b85b94 100644 --- a/packages/core/demo/data/index.ts +++ b/packages/core/demo/data/index.ts @@ -384,7 +384,7 @@ let allDemoGroups = [ }, { options: lineDemos.lineSelectedGroupsOptions, - data: lineDemos.lineData, + data: lineDemos.lineSelectedGroupsData, chartType: chartTypes.LineChart, }, { diff --git a/packages/core/demo/data/line.ts b/packages/core/demo/data/line.ts index 2dce51868d..3dcfceba8f 100644 --- a/packages/core/demo/data/line.ts +++ b/packages/core/demo/data/line.ts @@ -96,6 +96,29 @@ export const lineCustomDomainOptions = { }, }; +export const lineSelectedGroupsData = [ + { group: "Dataset 1", key: "Qty", value: 34200 }, + { group: "Dataset 1", key: "More", value: 23500 }, + { group: "Dataset 1", key: "Sold", value: 53100 }, + { group: "Dataset 1", key: "Restocking", value: 42300 }, + { group: "Dataset 1", key: "Misc", value: 12300 }, + { group: "Dataset 2", key: "Qty", value: 34200 }, + { group: "Dataset 2", key: "More", value: 56000 }, + { group: "Dataset 2", key: "Sold", value: 42300 }, + { group: "Dataset 2", key: "Restocking", value: 21400 }, + { group: "Dataset 2", key: "Misc", value: 0 }, + { group: "Dataset 3", key: "Qty", value: 41200 }, + { group: "Dataset 3", key: "More", value: 18400 }, + { group: "Dataset 3", key: "Sold", value: 34210 }, + { group: "Dataset 3", key: "Restocking", value: 1400 }, + { group: "Dataset 3", key: "Misc", value: 42100 }, + { group: "Dataset 4", key: "Qty", value: 22000 }, + { group: "Dataset 4", key: "More", value: 1200 }, + { group: "Dataset 4", key: "Sold", value: 9000 }, + { group: "Dataset 4", key: "Restocking", value: 24000, audienceSize: 10 }, + { group: "Dataset 4", key: "Misc", value: 3000, audienceSize: 10 }, +]; + export const lineSelectedGroupsOptions = { title: "Line (selected groups)", data: { diff --git a/packages/core/src/services/scales-cartesian.ts b/packages/core/src/services/scales-cartesian.ts index 2a66bcc8a3..5c2d785360 100644 --- a/packages/core/src/services/scales-cartesian.ts +++ b/packages/core/src/services/scales-cartesian.ts @@ -336,7 +336,6 @@ export class CartesianScales extends Service { return []; } - const allDataFromDomain = this.model.getAllDataFromDomain(); const displayData = this.model.getDisplayData(); const { mapsTo, percentage } = axisOptions; @@ -369,7 +368,7 @@ export class CartesianScales extends Service { sum(values(dataValues) as any) ); } else { - allDataValues = allDataFromDomain.map((datum) => datum[mapsTo]); + allDataValues = displayData.map((datum) => datum[mapsTo]); } if (scaleType !== ScaleTypes.TIME && includeZero) { From 5c942d3eb4713d8308d3ec8de8f6e72c9c21f542 Mon Sep 17 00:00:00 2001 From: Fei Date: Mon, 6 Jul 2020 11:44:04 -0400 Subject: [PATCH 31/32] refactor: rename the demo --- packages/core/demo/data/line.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/demo/data/line.ts b/packages/core/demo/data/line.ts index 3dcfceba8f..326ebc8595 100644 --- a/packages/core/demo/data/line.ts +++ b/packages/core/demo/data/line.ts @@ -79,7 +79,7 @@ export const lineLongLabelOptions = { }; export const lineCustomDomainOptions = { - title: "Line (discrete with custom domain)", + title: "Line (discrete with customized domain)", axes: { bottom: { title: "2019 Annual Sales Figures", @@ -179,7 +179,7 @@ export const lineTimeSeriesOptions = { }; export const lineTimeSeriesCustomDomainOptions = { - title: "Line (time series with custom domain)", + title: "Line (time series with customized domain)", axes: { bottom: { title: "2019 Annual Sales Figures", From a85684d5104612b1c87568708713eba5271d5b69 Mon Sep 17 00:00:00 2001 From: Fei Date: Mon, 6 Jul 2020 14:42:19 -0400 Subject: [PATCH 32/32] fix: fix angular and react height issue --- packages/core/src/components/layout/layout.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/core/src/components/layout/layout.ts b/packages/core/src/components/layout/layout.ts index 2270ae7792..4ec84e8441 100644 --- a/packages/core/src/components/layout/layout.ts +++ b/packages/core/src/components/layout/layout.ts @@ -168,7 +168,10 @@ export class LayoutComponent extends Component { select(this), { useAttrs: true } ); - matchingSVGDimensions.height = svgSize.height; + + if (svgSize.height < 40) { + matchingSVGDimensions.height = svgSize.height; + } } if (growth === LayoutGrowth.PREFERRED) {