Skip to content

Commit

Permalink
feat(core): create alluvial chart (#1132)
Browse files Browse the repository at this point in the history
* add d3-sankey package

* create enum of all alluvial related events

* create basic alluvial chart

* add alluvial chart options

* create alluvial chart wrapper

* fix linting issues

* define default alluvial configs

* create alluvial react component

* create alluvial angular component

* Add simple alluvial demo under complex charts

* remove skeleton import and comments

* add style for themes

* add logic to add space between node and textbox

* add configs & node group title

* add line event listeners

* declare and export alluvial in ngmodule

* add node event listener

* Add multiple category alluvial demo

* add monochrome option

* add combined monochrome and nodePadding demo

* remove stroke from node rectangles

* Add delay to events to stop flashing behaviour

* add graph traversal to highlight links that pass node

* set minimum node padding to 24

* add units in aria-label and tooltip

* update demo names

* export alluvial chart

* add condition to prevent firefox error

* feat(core): create alluvial chart

closes #871

* filter out unused nodes from rendering

* update debounce for line events

* update debounce for node events

* order complex demos alphabetically

* decrease debounce time

* improve link hover debounce

* exclude legend from alluvial

* fix review changes

* wrap alluvial options in respective key

* improve node debounce highlighting

* deep clone user passed data when creating graph

* remove trailing space in aria-label
  • Loading branch information
Akshat55 committed Sep 15, 2021
1 parent 64380c8 commit 08fa194
Show file tree
Hide file tree
Showing 28 changed files with 1,055 additions and 19 deletions.
34 changes: 34 additions & 0 deletions packages/angular/src/alluvial-chart.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {
Component,
AfterViewInit
} from "@angular/core";

import { BaseChart } from "./base-chart.component";

import { AlluvialChart } from "@carbon/charts";

/**
* Wrapper around `Alluvial` in carbon charts library
*
* Most functions just call their equivalent from the chart library.
*/
@Component({
selector: "ibm-alluvial-chart",
template: ``
})
export class AlluvialChartComponent extends BaseChart implements AfterViewInit {
/**
* Runs after view init to create a chart, attach it to `elementRef` and draw it.
*/
ngAfterViewInit() {
this.chart = new AlluvialChart(
this.elementRef.nativeElement,
{
data: this.data,
options: this.options
}
);

Object.assign(this, this.chart);
}
}
3 changes: 3 additions & 0 deletions packages/angular/src/charts.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { BaseChart } from './base-chart.component';
import { AlluvialChartComponent } from './alluvial-chart.component';
import { AreaChartComponent } from './area-chart.component';
import { StackedAreaChartComponent } from './area-chart-stacked.component';
import { SimpleBarChartComponent } from './bar-chart-simple.component';
Expand Down Expand Up @@ -29,6 +30,7 @@ import { WordCloudChartComponent } from './wordcloud-chart.component';
imports: [CommonModule],
declarations: [
BaseChart,
AlluvialChartComponent,
AreaChartComponent,
StackedAreaChartComponent,
SimpleBarChartComponent,
Expand All @@ -54,6 +56,7 @@ import { WordCloudChartComponent } from './wordcloud-chart.component';
],
exports: [
BaseChart,
AlluvialChartComponent,
AreaChartComponent,
StackedAreaChartComponent,
SimpleBarChartComponent,
Expand Down
1 change: 1 addition & 0 deletions packages/angular/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export * from './tree-chart.component';
export * from './treemap-chart.component';
export * from './circle-pack-chart.component';
export * from './wordcloud-chart.component';
export * from './alluvial-chart.component';

// Diagrams
export * from './diagrams/card-node/card-node.module';
Expand Down
5 changes: 5 additions & 0 deletions packages/core/demo/data/CHART_TYPES.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
export default {
AlluvialChart: {
vanilla: 'AlluvialChart',
angular: 'ibm-alluvial-chart',
vue: 'ccv-alluvial-chart',
},
AreaChart: {
vanilla: 'AreaChart',
angular: 'ibm-area-chart',
Expand Down
134 changes: 134 additions & 0 deletions packages/core/demo/data/alluvial.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
export const alluvialSimpleData = [
{ source: 'A', target: 'X', value: 3 },
{ source: 'A', target: 'Y', value: 5 },
{ source: 'A', target: 'Z', value: 8 },
{ source: 'B', target: 'X', value: 6 },
{ source: 'B', target: 'Y', value: 1 },
{ source: 'B', target: 'Z', value: 7 },
{ source: 'C', target: 'X', value: 5 },
{ source: 'C', target: 'Y', value: 5 },
{ source: 'C', target: 'Z', value: 1 },
];

export const alluvialSimpleOptions = {
title: 'Alluvial',
alluvial: {
units: 'GB',
nodes: [
{ name: 'A', category: 'Start' },
{ name: 'B', category: 'Start' },
{ name: 'C', category: 'Start' },
{ name: 'X', category: 'Finish' },
{ name: 'Y', category: 'Finish' },
{ name: 'Z', category: 'Finish' },
],
},
};

export const alluvialMultipleCategoryOptions = {
title: 'Alluvial (multiple categories)',
alluvial: {
nodes: [
{ name: '1st', category: 'Class' },
{ name: '2nd', category: 'Class' },
{ name: 'Crew', category: 'Class' },
{ name: 'Male', category: 'Sex' },
{ name: 'Female', category: 'Sex' },
{ name: 'Child', category: 'Age' },
{ name: 'Adult', category: 'Age' },
{ name: 'Yes', category: 'Survived' },
{ name: 'No', category: 'Survived' },
],
},
};

export const alluvialMultipleCategoryData = [
{
source: '1st',
target: 'Female',
value: 25,
},
{
source: '1st',
target: 'Male',
value: 35,
},
{
source: '2nd',
target: 'Female',
value: 35,
},
{
source: '2nd',
target: 'Male',
value: 50,
},
{
source: 'Crew',
target: 'Male',
value: 43,
},
{
source: 'Crew',
target: 'Female',
value: 18,
},
{
source: 'Male',
target: 'Child',
value: 38,
},
{
source: 'Male',
target: 'Adult',
value: 90,
},
{
source: 'Female',
target: 'Adult',
value: 52,
},
{
source: 'Female',
target: 'Child',
value: 26,
},
{
source: 'Child',
target: 'Yes',
value: 58,
},
{
source: 'Child',
target: 'No',
value: 6,
},
{
source: 'Adult',
target: 'Yes',
value: 22,
},
{
source: 'Adult',
target: 'No',
value: 120,
},
];

export const alluvialMonochromeData = alluvialSimpleData;

export const alluvialMonochromeOptions = {
title: 'Alluvial (monochrome with custom node padding)',
alluvial: {
nodes: [
{ name: 'A', category: 'Start' },
{ name: 'B', category: 'Start' },
{ name: 'C', category: 'Start' },
{ name: 'X', category: 'Finish' },
{ name: 'Y', category: 'Finish' },
{ name: 'Z', category: 'Finish' },
],
monochrome: true,
nodePadding: 33,
},
};
59 changes: 41 additions & 18 deletions packages/core/demo/data/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import * as toolbarDemos from './toolbar';
import * as wordCloudDemos from './wordcloud';
import * as zoomBarDemos from './zoom-bar';
import * as highScaleDemos from './high-scale';
import * as alluvialDemos from './alluvial';

export * from './area';
export * from './bar';
Expand All @@ -46,6 +47,7 @@ export * from './toolbar';
export * from './wordcloud';
export * from './zoom-bar';
export * from './high-scale';
export * from './alluvial';

import {
createChartSandbox,
Expand Down Expand Up @@ -1060,31 +1062,23 @@ const simpleChartDemos = [

const complexChartDemos = [
{
title: 'Tree',
configs: {
excludeColorPaletteControl: true,
},
title: 'Alluvial',
demos: [
{
data: treeDemos.treeData,
options: treeDemos.dendogramOptions,
chartType: chartTypes.TreeChart,
options: alluvialDemos.alluvialSimpleOptions,
data: alluvialDemos.alluvialSimpleData,
chartType: chartTypes.AlluvialChart,
mainDemo: true,
},
{
data: treeDemos.treeData,
options: treeDemos.treeOptions,
chartType: chartTypes.TreeChart,
options: alluvialDemos.alluvialMultipleCategoryOptions,
data: alluvialDemos.alluvialMultipleCategoryData,
chartType: chartTypes.AlluvialChart,
},
],
},
{
title: 'Treemap',
demos: [
{
data: treemapDemos.treemapData,
options: treemapDemos.treemapOptions,
chartType: chartTypes.TreemapChart,
options: alluvialDemos.alluvialMonochromeOptions,
data: alluvialDemos.alluvialMonochromeData,
chartType: chartTypes.AlluvialChart,
},
],
},
Expand Down Expand Up @@ -1119,6 +1113,35 @@ const complexChartDemos = [
},
],
},
{
title: 'Tree',
configs: {
excludeColorPaletteControl: true,
},
demos: [
{
data: treeDemos.treeData,
options: treeDemos.dendogramOptions,
chartType: chartTypes.TreeChart,
mainDemo: true,
},
{
data: treeDemos.treeData,
options: treeDemos.treeOptions,
chartType: chartTypes.TreeChart,
},
],
},
{
title: 'Treemap',
demos: [
{
data: treemapDemos.treemapData,
options: treemapDemos.treemapOptions,
chartType: chartTypes.TreemapChart,
},
],
},
].map((demoGroup: any) => {
demoGroup.type = DemoGroupTypes.COMPLEX_CHART;

Expand Down
1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"@carbon/utils-position": "1.1.1",
"carbon-components": "10.40.0",
"d3-cloud": "1.2.5",
"d3-sankey": "0.12.3",
"date-fns": "2.8.1",
"dom-to-image": "2.6.0",
"lodash-es": "4.17.21",
Expand Down
50 changes: 50 additions & 0 deletions packages/core/src/charts/alluvial.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Internal Imports
import { Chart } from '../chart';
import * as Configuration from '../configuration';
import { ChartConfig, AlluvialChartOptions } from '../interfaces/index';
import { Tools } from '../tools';

// Components
import {
Alluvial,
// the imports below are needed because of typescript bug (error TS4029)
Tooltip,
Legend,
LayoutComponent,
} from '../components/index';

export class AlluvialChart extends Chart {
constructor(
holder: Element,
chartConfigs: ChartConfig<AlluvialChartOptions>
) {
super(holder, chartConfigs);

// Merge the default options for this chart
// With the user provided options
this.model.setOptions(
Tools.mergeDefaultChartOptions(
Configuration.options.alluvialChart,
chartConfigs.options
)
);

// Initialize data, services, components etc.
this.init(holder, chartConfigs);
}

getComponents() {
// Specify what to render inside the graph-frame
const graphFrameComponents: any = [
new Alluvial(this.model, this.services),
];

const components: any[] = this.getChartComponents(
graphFrameComponents,
{
excludeLegend: true,
}
);
return components;
}
}
1 change: 1 addition & 0 deletions packages/core/src/charts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ export * from './tree';
export * from './treemap';
export * from './circle-pack';
export * from './wordcloud';
export * from './alluvial';

0 comments on commit 08fa194

Please sign in to comment.