Skip to content

Commit

Permalink
feat(core): add support for horizontal bar charts (#415)
Browse files Browse the repository at this point in the history
* feat(core): add support for horizontal bar charts

* add stories for horizontal bar

* add horizontal discrete bar chart

* add vue and angular stories

* update zero-line transition

* Update packages/core/src/components/graphs/bar-stacked.ts

Co-Authored-By: Cal Smith <[email protected]>

* enable switching orientations for grouped bar without duplicating draw logic

* fix lint errors

* draw simple bars in horizontal & vertical orientations

* draw stacked bars regardless of 2D orientation

* add orientation support for time-series stacked bar charts

* use the calculated bar width in all 3 bar types

* add requested PR changes

* fix lint error

* fix lint error

* fix tests

* fix lint error

* fix tests tsconfig issue

* add knobs to all stories

* add requested PR changes

* code style changes

* code style fixes

Co-authored-by: Eliad Moosavi <[email protected]>
Co-authored-by: Cal Smith <[email protected]>
  • Loading branch information
3 people committed Jan 21, 2020
1 parent b4191b3 commit 6a480f0
Show file tree
Hide file tree
Showing 37 changed files with 976 additions and 439 deletions.
84 changes: 84 additions & 0 deletions packages/angular/stories/bar-horizontal.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { storiesOf } from "@storybook/angular";
import { withKnobs, object } from "@storybook/addon-knobs";

import { ChartsModule } from "../src/charts.module";

import {
// Horizontal bar
groupedHorizontalBarOptions,
groupedHorizontalBarData,
simpleHorizontalBarOptions,
simpleHorizontalBarData,
simpleHorizontalBarTimeSeriesOptions,
simpleHorizontalBarTimeSeriesData,
stackedHorizontalBarTimeSeriesOptions,
stackedHorizontalBarTimeSeriesData,
stackedHorizontalBarData,
stackedHorizontalBarOptions,
} from "../../core/demo/demo-data/index";
import { addWidthAndHeight } from "./commons";

const template = barType => `
<ibm-${barType}-bar-chart
class="n-chart"
[data]="data"
[options]="options"
#${barType}BarChart>
</ibm-${barType}-bar-chart>
`;

const stories = storiesOf("Bar (Horizontal)", module).addDecorator(withKnobs);
stories.add(simpleHorizontalBarOptions.title, () => ({
template: template("simple"),
moduleMetadata: {
imports: [ChartsModule]
},
props: {
data: object("Data", simpleHorizontalBarData),
options: object("Options", addWidthAndHeight(simpleHorizontalBarOptions))
}
}));

stories.add(simpleHorizontalBarTimeSeriesOptions.title, () => ({
template: template("simple"),
moduleMetadata: {
imports: [ChartsModule]
},
props: {
data: object("Data", simpleHorizontalBarTimeSeriesData),
options: object("Options", addWidthAndHeight(simpleHorizontalBarTimeSeriesOptions))
}
}));

stories.add(groupedHorizontalBarOptions.title, () => ({
template: template("grouped"),
moduleMetadata: {
imports: [ChartsModule]
},
props: {
data: object("Data", groupedHorizontalBarData),
options: object("Options", addWidthAndHeight(groupedHorizontalBarOptions))
}
}));

stories.add(stackedHorizontalBarOptions.title, () => ({
template: template("stacked"),
moduleMetadata: {
imports: [ChartsModule]
},
props: {
data: object("Data", stackedHorizontalBarData),
options: object("Options", addWidthAndHeight(stackedHorizontalBarOptions))
}
}));

stories.add(stackedHorizontalBarTimeSeriesOptions.title, () => ({
template: template("stacked"),
moduleMetadata: {
imports: [ChartsModule]
},
props: {
data: object("Data", stackedHorizontalBarTimeSeriesData),
options: object("Options", addWidthAndHeight(stackedHorizontalBarTimeSeriesOptions))
}
}));
53 changes: 44 additions & 9 deletions packages/core/demo/chart-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,24 @@ const {
// Bar
groupedBarOptions,
groupedBarData,
groupedHorizontalBarOptions,
groupedHorizontalBarData,
simpleBarOptions,
simpleBarData,
simpleHorizontalBarOptions,
simpleHorizontalBarData,
simpleBarTimeSeriesOptions,
simpleBarTimeSeriesData,
stackedBarData,
simpleHorizontalBarTimeSeriesOptions,
simpleHorizontalBarTimeSeriesData,
stackedBarOptions,
stackedBarData,
stackedHorizontalBarOptions,
stackedHorizontalBarData,
stackedBarTimeSeriesOptions,
stackedBarTimeSeriesData,
stackedHorizontalBarTimeSeriesOptions,
stackedHorizontalBarTimeSeriesData,
// Pie & donut
pieOptions,
pieData,
Expand All @@ -33,16 +43,21 @@ const {
} = require("./demo-data/index");

export const chartTypes = [
{
id: "grouped-bar",
options: groupedBarOptions,
data: groupedBarData
},
{
id: "simple-bar",
options: simpleBarOptions,
data: simpleBarData
},
{
id: "simple-horizontal-bar-time-series",
options: simpleHorizontalBarTimeSeriesOptions,
data: simpleHorizontalBarTimeSeriesData
},
{
id: "simple-horizontal-bar",
options: simpleHorizontalBarOptions,
data: simpleHorizontalBarData
},
{
id: "scatter-time-series",
options: scatterTimeSeriesOptions,
Expand All @@ -54,20 +69,40 @@ export const chartTypes = [
data: scatterData
},
{
id: "simple-bar-time-series",
options: simpleBarTimeSeriesOptions,
data: simpleBarTimeSeriesData
id: "grouped-bar",
options: groupedBarOptions,
data: groupedBarData
},
{
id: "grouped-horizontal-bar",
options: groupedHorizontalBarOptions,
data: groupedHorizontalBarData
},
{
id: "stacked-bar",
options: stackedBarOptions,
data: stackedBarData
},
{
id: "stacked-horizontal-bar",
options: stackedHorizontalBarOptions,
data: stackedHorizontalBarData
},
{
id: "simple-bar-time-series",
options: simpleBarTimeSeriesOptions,
data: simpleBarTimeSeriesData
},
{
id: "stacked-bar-time-series",
options: stackedBarTimeSeriesOptions,
data: stackedBarTimeSeriesData
},
{
id: "stacked-horizontal-bar-time-series",
options: stackedHorizontalBarTimeSeriesOptions,
data: stackedHorizontalBarTimeSeriesData
},
{
id: "pie",
options: pieOptions,
Expand Down
86 changes: 83 additions & 3 deletions packages/core/demo/demo-data/bar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,23 @@ export const groupedBarOptions = {
},
bottom: {
scaleType: "labels",
secondary: true,
secondary: true
}
}
};

// Horizontal Grouped
export const groupedHorizontalBarData = groupedBarData;

export const groupedHorizontalBarOptions = {
title: "Grouped horizontal bar (discrete)",
axes: {
left: {
scaleType: "labels",
primary: true,
},
bottom: {
secondary: true
}
}
};
Expand Down Expand Up @@ -87,11 +103,26 @@ export const simpleBarOptions = {
},
bottom: {
scaleType: "labels",
secondary: true,
secondary: true
}
}
};

// Horizontal Simple
export const simpleHorizontalBarData = simpleBarData;

export const simpleHorizontalBarOptions = {
title: "Simple horizontal bar (discrete)",
axes: {
left: {
primary: true,
scaleType: "labels"
},
bottom: {
secondary: true
}
}
};

export const simpleBarTimeSeriesData = {
labels: ["Qty", "More", "Sold", "Restocking", "Miscellaneous"],
Expand Down Expand Up @@ -140,6 +171,22 @@ export const simpleBarTimeSeriesOptions = {
}
};

// Horizontal simple time series
export const simpleHorizontalBarTimeSeriesOptions = {
title: "Simple horizontal bar (time series)",
axes: {
left: {
scaleType: "time",
primary: true
},
bottom: {
secondary: true
}
}
};

export const simpleHorizontalBarTimeSeriesData = simpleBarTimeSeriesData;

// Stacked bar
export const stackedBarData = {
labels: ["Qty", "More", "Sold", "Restocking", "Misc"],
Expand Down Expand Up @@ -196,11 +243,27 @@ export const stackedBarOptions = {
},
bottom: {
scaleType: "labels",
secondary: true,
secondary: true
}
}
};

// horizontal stacked bar
export const stackedHorizontalBarData = stackedBarData;

export const stackedHorizontalBarOptions = {
title: "Stacked horizontal bar (discrete)",
axes: {
left: {
scaleType: "labels",
primary: true
},
bottom: {
stacked: true,
secondary: true
}
}
};

export const stackedBarTimeSeriesData = {
labels: ["Qty", "More", "Sold", "Restocking", "Misc"],
Expand Down Expand Up @@ -321,3 +384,20 @@ export const stackedBarTimeSeriesOptions = {
}
}
};

// Stacked horizontal bar (time series)
export const stackedHorizontalBarTimeSeriesOptions = {
title: "Stacked horizontal bar (time series)",
axes: {
left: {
primary: true,
scaleType: "time"
},
bottom: {
stacked: true,
secondary: true
}
}
};

export const stackedHorizontalBarTimeSeriesData = stackedBarTimeSeriesData;
2 changes: 1 addition & 1 deletion packages/core/demo/demo-data/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const urlParams = new URLSearchParams(window.location.search);
// Grab "theme" param from query string
let themeToUse = colorPalettes.DEFAULT;
if (urlParams.has("theme") && colorPalettes[urlParams.get("theme")]) {
themeToUse = colorPalettes[urlParams.get("theme")];
themeToUse = colorPalettes[urlParams.get("theme")];
}

export const colors = themeToUse;
2 changes: 0 additions & 2 deletions packages/core/demo/demo-options.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { colorPalettes } from "../src/index";

export const setOrUpdateParam = (name, value) => {
const params = new URLSearchParams(location.search)

Expand Down
8 changes: 6 additions & 2 deletions packages/core/demo/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ const changeDemoData = (chartType: any, chartObj: any) => {
// Function to be used to randomize a value
const randomizeValue = datum => {
const currentVal = datum.value !== undefined ? datum.value : datum;
const firstTry = Math.max(0.85 * currentVal, currentVal * Math.random() * (Math.random() * 5));
let result = currentVal > 0 ? Math.min(3 * currentVal, firstTry) : Math.max(3 * currentVal, firstTry);
let result = Math.random() > 0.5 ? 0.95 * currentVal : 1.05 * currentVal;

if (Math.random() > 0.5
|| chartType.indexOf("stacked") !== -1
Expand Down Expand Up @@ -157,14 +156,19 @@ chartTypes.forEach(type => {
let classToInitialize;
switch (type.id) {
case "simple-bar":
case "simple-horizontal-bar":
case "simple-bar-time-series":
case "simple-horizontal-bar-time-series":
classToInitialize = SimpleBarChart;
break;
case "grouped-bar":
case "grouped-horizontal-bar":
classToInitialize = GroupedBarChart;
break;
case "stacked-bar":
case "stacked-horizontal-bar":
case "stacked-bar-time-series":
case "stacked-horizontal-bar-time-series":
classToInitialize = StackedBarChart;
break;
case "scatter":
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/axis-chart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ import {
} from "./components/index";
import { Tools } from "./tools";

import { Axes, Curves } from "./services/index";
import { CartesianScales, Curves } from "./services/index";

export class AxisChart extends Chart {
services: any = Object.assign(this.services, {
axes: Axes,
cartesianScales: CartesianScales,
curves: Curves
});

Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/charts/bar-grouped.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
Grid,
GroupedBar,
TwoDimensionalAxes,
HorizontalZeroLine,
ZeroLine,
TooltipBar,
// the imports below are needed because of typescript bug (error TS4029)
Tooltip,
Expand Down Expand Up @@ -43,7 +43,7 @@ export class GroupedBarChart extends AxisChart {
new TwoDimensionalAxes(this.model, this.services),
new Grid(this.model, this.services),
new GroupedBar(this.model, this.services),
new HorizontalZeroLine(this.model, this.services)
new ZeroLine(this.model, this.services)
];

const components: any[] = this.getAxisChartComponents(graphFrameComponents);
Expand Down
Loading

0 comments on commit 6a480f0

Please sign in to comment.