Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show pre-selected data groups #639

Merged
merged 51 commits into from
Jul 7, 2020
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
3c327c5
Add selectedGroups option
May 25, 2020
a013589
Bind selectedGroups with legend and dataGroups
May 25, 2020
0f2b92d
Merge branch 'master' of https://github.com/carbon-design-system/carb…
May 25, 2020
45e73cc
improvement: move selectedGroup under data option
May 26, 2020
88184e5
refactor: update selectedGroup position
May 27, 2020
f7ac630
improvement: grab options from getOptions
May 28, 2020
8b57817
improvement: fix naming and update comments
May 28, 2020
e0b9f2b
Merge branch 'master' into selectedGroups
theiliad May 29, 2020
e71381e
Merge branch 'master' of https://github.com/carbon-design-system/carb…
Jun 2, 2020
1cc3cbe
Merge branch 'selectedGroups' of git://github.com/sophiiae/carbon-cha…
Jun 2, 2020
963ad97
improvement: simplify the code
Jun 4, 2020
01b1be0
Merge branch 'master' of https://github.com/carbon-design-system/carb…
Jun 4, 2020
96b454b
Merge branch 'master' of https://github.com/carbon-design-system/carb…
Jun 5, 2020
00c969e
improvement: remove updateSelectedGroups
Jun 8, 2020
f0857e2
fix: remove updateSelectedGroups from legend
Jun 8, 2020
534cb62
Merge branch 'master' of https://github.com/carbon-design-system/carb…
Jun 9, 2020
6486a72
Merge branch 'master' of https://github.com/carbon-design-system/carb…
Jun 10, 2020
9a5880d
Merge branch 'master' into selectedGroups
theiliad Jun 11, 2020
fd88f3d
Merge branch 'master' of https://github.com/carbon-design-system/carb…
Jun 11, 2020
5c1700e
Merge branch 'selectedGroups' of https://github.com/sophiiae/carbon-c…
Jun 11, 2020
b5e050a
Merge branch 'master' of https://github.com/carbon-design-system/carb…
Jun 13, 2020
3f1f8e8
Merge branch 'master' of https://github.com/carbon-design-system/carb…
Jun 22, 2020
88fee02
test: add unit test for setting up selectedGroups
Jun 22, 2020
190fb67
test: modify unit test
Jun 22, 2020
e5cab17
test: renaming
Jun 22, 2020
63c9966
test: revise unit test
Jun 23, 2020
46f378a
test: update test description
Jun 23, 2020
b948159
style: revise the comment for selectedGroup
Jun 23, 2020
35cd830
Merge branch 'master' of https://github.com/carbon-design-system/carb…
Jun 24, 2020
a8a1a4b
test: update test
Jun 24, 2020
6168334
test: simplify the test code
Jun 24, 2020
bd22d0a
style: format the code
Jun 24, 2020
79cf257
test: add more tests
Jun 25, 2020
3b11c8e
Merge branch 'master' of https://github.com/carbon-design-system/carb…
Jun 25, 2020
efdeaa0
test: remove tests for events
Jun 25, 2020
d458da2
test: remove async function
Jun 25, 2020
9315f31
fix: fix check mark position issue and add demos
Jun 25, 2020
d334d6d
fix: fix multiple check marks bug
Jun 26, 2020
05e5c20
Merge branch 'master' of https://github.com/carbon-design-system/carb…
Jun 26, 2020
a2fce6d
fix: fix chart shrinks between legend click for selected groups
Jun 29, 2020
246f179
fix: fix legend height change with first legend click
Jun 29, 2020
4f2233d
fix: fix demo broken
Jun 30, 2020
af678c4
Merge branch 'master' of https://github.com/carbon-design-system/carb…
Jun 30, 2020
e1a911d
refactor: renaming
Jul 2, 2020
c3e86eb
refactor: get legend height
Jul 2, 2020
16056cc
remove semicolon
Jul 2, 2020
2606182
fix: fix data domain
Jul 6, 2020
647926e
Merge branch 'selectedGroups' of https://github.com/sophiiae/carbon-c…
Jul 6, 2020
5c942d3
refactor: rename the demo
Jul 6, 2020
a85684d
fix: fix angular and react height issue
Jul 6, 2020
2578d9f
Merge branch 'master' into selectedGroups
theiliad Jul 7, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions packages/core/demo/data/bar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
10 changes: 10 additions & 0 deletions packages/core/demo/data/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,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,
Expand Down Expand Up @@ -377,6 +382,11 @@ let allDemoGroups = [
data: lineDemos.lineData,
chartType: chartTypes.LineChart,
},
{
options: lineDemos.lineSelectedGroupsOptions,
data: lineDemos.lineData,
chartType: chartTypes.LineChart,
},
{
options: lineDemos.lineTimeSeriesRotatedTicksOptions,
data: lineDemos.lineTimeSeriesDataRotatedTicks,
Expand Down
21 changes: 20 additions & 1 deletion packages/core/demo/data/line.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand All @@ -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 },
Expand Down
24 changes: 18 additions & 6 deletions packages/core/src/components/essentials/legend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,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;
Expand Down Expand Up @@ -208,14 +211,24 @@ export class Legend extends Component {
legendItem
.select("text")
.attr("x", startingPoint + spaceNeededForCheckbox)
.attr("y", yOffset + yPosition + 2);
.attr("y", yOffset + yPosition + 3);

lastYPosition = yPosition;

// Test if legendItems are placed in the correct direction
const testHorizontal = (!legendOrientation ||
sophiiae marked this conversation as resolved.
Show resolved Hide resolved
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 &&
legendItem.select("g.check").empty()
if (hasDeactivatedItems &&
legendItem.select("g.check").empty() &&
hasCorrectLegendDirection
) {
legendItem.append("g").classed("check", true).html(`
<svg focusable="false" preserveAspectRatio="xMidYMid meet"
Expand Down Expand Up @@ -273,7 +286,6 @@ export class Legend extends Component {

// Configs
const checkboxRadius = options.legend.checkbox.radius;

const hoveredItem = select(this);
hoveredItem
.append("rect")
Expand Down
9 changes: 9 additions & 0 deletions packages/core/src/components/layout/layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,15 @@ export class LayoutComponent extends Component {
select(this),
{ useBBox: true }
);

if (d.data.id === "legend") {
const svgSize = DOMUtils.getSVGElementSize(
select(this),
{ useAttrs: true }
);
matchingSVGDimensions.height = svgSize.height;
};
sophiiae marked this conversation as resolved.
Show resolved Hide resolved

if (growth === LayoutGrowth.PREFERRED) {
const matchingSVGWidth = horizontal
? matchingSVGDimensions.width
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ const chart: BaseChartOptions = {
},
data: {
groupMapsTo: "group",
loading: false
loading: false,
selectedGroups: []
},
color: {
scale: null
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/interfaces/charts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ export interface BaseChartOptions {
* used to simulate data loading
*/
loading?: Boolean;
/**
* 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[];
};
/**
* options related to color scales
Expand Down
60 changes: 55 additions & 5 deletions packages/core/src/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 allDataFromDomain = this.getAllDataFromDomain();

return allDataFromDomain.filter((datum) => {
const group = dataGroups.find(
(group) => group.name === datum[groupMapsTo]
);
Expand Down Expand Up @@ -338,6 +355,22 @@ export class ChartModel {
});
}

// Updates selected groups
const updatedActiveItems = dataGroups.filter(group => group.status === ACTIVE);
const options = this.getOptions();

const hasUpdatedDeactivatedItems = dataGroups.some(
group => group.status === DISABLED
);

// If there are deactivated items, map the item name into selected groups
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
Expand Down Expand Up @@ -478,15 +511,32 @@ 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 options = this.getOptions();

const uniqueDataGroups = map(
data,
(datum) => datum[groupMapsTo]
).keys();
return uniqueDataGroups.map((groupName) => ({

// 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: ACTIVE
status: getStatus(groupName)
}));
}

Expand Down
56 changes: 56 additions & 0 deletions packages/core/src/selectedGroups.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
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("selected legend labels", () => {
it("should match the selected groups provided in options", function (done) {
const sampleSelectedGroups = ["Dataset 1", "Dataset 3"];

const chartEventsService = this.chart.services.events;

const renderCb = () => {
// Remove render event listener
chartEventsService.removeEventListener(
Events.Chart.RENDER_FINISHED,
renderCb
);

const selectedLegendLabels = select(
`g.${settings.prefix}--${options.chart.style.prefix}--legend`
)
.selectAll("g.legend-item.active > text")
.nodes()
.map((item) => item["innerHTML"]);

expect(selectedLegendLabels).toEqual(sampleSelectedGroups);

done();
};

// Add event listener for when chart render is finished
chartEventsService.addEventListener(
Events.Chart.RENDER_FINISHED,
renderCb
);
});
});

afterEach(function () {
this.testEnvironment.destroy();
});
});
3 changes: 2 additions & 1 deletion packages/core/src/services/scales-cartesian.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ export class CartesianScales extends Service {
return [];
}

const allDataFromDomain = this.model.getAllDataFromDomain();
const displayData = this.model.getDisplayData();
const { mapsTo, percentage } = axisOptions;

Expand Down Expand Up @@ -368,7 +369,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) {
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/tests/test-environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down