Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions .size-limit.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
},
{
"path": "dist/index.cjs",
"limit": "7.35 kB",
"limit": "7.40 kB",
"import": "{ BarChart }"
},
{
Expand All @@ -18,7 +18,7 @@
},
{
"path": "dist/index.js",
"limit": "7.3 kB",
"limit": "7.4 kB",
"import": "{ BarChart }"
},
{
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ import type {
- [Multi-line labels](http://codesandbox.io/s/github/chartist-js/chartist/main/sandboxes/bar/multiline)
- [Overlapping bars on mobile](http://codesandbox.io/s/github/chartist-js/chartist/main/sandboxes/bar/overlapping-bars)
- [Stacked bar chart](http://codesandbox.io/s/github/chartist-js/chartist/main/sandboxes/bar/stacked)
- [Stacked bar chart with accumulate-relative stack mode](http://codesandbox.io/s/github/chartist-js/chartist/main/sandboxes/bar/stacked-accumulate-relative)
- [Add peak circles using the draw events](http://codesandbox.io/s/github/chartist-js/chartist/main/sandboxes/bar/with-circle-modify-drawing)

</details>
Expand Down
9 changes: 9 additions & 0 deletions sandboxes/bar/stacked-accumulate-relative/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<script defer src="./index.ts"></script>
</head>
<body>
<div id="chart" style="height: 50vh"></div>
</body>
</html>
17 changes: 17 additions & 0 deletions sandboxes/bar/stacked-accumulate-relative/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import 'chartist/dist/index.css';
import { BarChart } from 'chartist';

new BarChart(
'#chart',
{
labels: ['Monday', 'Tuesday', 'Wednesday', 'Thursday'],
series: [
[5, 4, -3, -5],
[5, -4, 3, -5]
]
},
{
stackBars: true,
stackMode: 'accumulate-relative'
}
);
8 changes: 8 additions & 0 deletions sandboxes/bar/stacked-accumulate-relative/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "bar-stacked",
"description": "Stacked bar chart with accumulate-relative stack mode",
"main": "index.ts",
"dependencies": {
"chartist": "^1.0.0"
}
}
6 changes: 6 additions & 0 deletions sandboxes/bar/stacked-accumulate-relative/sandbox.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"infiniteLoopProtection": true,
"hardReloadOnChange": true,
"view": "browser",
"template": "parcel"
}
21 changes: 21 additions & 0 deletions src/charts/BarChart/BarChart.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -424,3 +424,24 @@ export function PeakCircles() {

return root;
}

export function AccumulateRelativeStack() {
const root = document.createElement('div');

new BarChart(
root,
{
labels: ['Monday', 'Tuesday', 'Wednesday', 'Thursday'],
series: [
[5, 4, -3, -5],
[5, -4, 3, -5]
]
},
{
stackBars: true,
stackMode: 'accumulate-relative'
}
);

return root;
}
39 changes: 26 additions & 13 deletions src/charts/BarChart/BarChart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,9 @@ const defaultOptions = {
seriesBarDistance: 15,
// If set to true this property will cause the series bars to be stacked. Check the `stackMode` option for further stacking options.
stackBars: false,
// If set to 'overlap' this property will force the stacked bars to draw from the zero line.
// If set to true this property will force the stacked bars to draw from the zero line.
// If set to 'accumulate' this property will form a total for each series point. This will also influence the y-axis and the overall bounds of the chart. In stacked mode the seriesBarDistance property will have no effect.
// If set to 'accumulate-relative' positive and negative values will be handled separately.
stackMode: 'accumulate' as const,
// Inverts the axes of the bar chart in order to draw a horizontal bar chart. Be aware that you also need to invert your axis settings as the Y Axis will now display the labels and the X Axis the values.
horizontalBars: false,
Expand Down Expand Up @@ -344,8 +345,13 @@ export class BarChart extends BaseChart<BarChartEventsTypes> {
const zeroPoint = options.horizontalBars
? chartRect.x1 + valueAxis.projectValue(0)
: chartRect.y1 - valueAxis.projectValue(0);
const isAccumulateStackMode = options.stackMode === 'accumulate';
const isAccumulateRelativeStackMode =
options.stackMode === 'accumulate-relative';
// Used to track the screen coordinates of stacked bars
const stackedBarValues: number[] = [];
const posStackedBarValues: number[] = [];
const negStackedBarValues: number[] = [];
let stackedBarValues = posStackedBarValues;

labelAxis.createGridAndLabels(
gridGroup,
Expand Down Expand Up @@ -428,6 +434,8 @@ export class BarChart extends BaseChart<BarChartEventsTypes> {
);

normalizedData.series[seriesIndex].forEach((value, valueIndex) => {
const valueX = safeHasProperty(value, 'x') && value.x;
const valueY = safeHasProperty(value, 'y') && value.y;
let labelAxisValueIndex;
// We need to set labelAxisValueIndex based on some options combinations
if (options.distributeSeries && !options.stackBars) {
Expand All @@ -450,14 +458,14 @@ export class BarChart extends BaseChart<BarChartEventsTypes> {
x:
chartRect.x1 +
valueAxis.projectValue(
safeHasProperty(value, 'x') ? value.x : 0,
valueX || 0,
valueIndex,
normalizedData.series[seriesIndex]
),
y:
chartRect.y1 -
labelAxis.projectValue(
safeHasProperty(value, 'y') ? value.y : 0,
valueY || 0,
labelAxisValueIndex,
normalizedData.series[seriesIndex]
)
Expand All @@ -467,14 +475,14 @@ export class BarChart extends BaseChart<BarChartEventsTypes> {
x:
chartRect.x1 +
labelAxis.projectValue(
safeHasProperty(value, 'x') ? value.x : 0,
valueX || 0,
labelAxisValueIndex,
normalizedData.series[seriesIndex]
),
y:
chartRect.y1 -
valueAxis.projectValue(
safeHasProperty(value, 'y') ? value.y : 0,
valueY || 0,
valueIndex,
normalizedData.series[seriesIndex]
)
Expand All @@ -500,6 +508,14 @@ export class BarChart extends BaseChart<BarChartEventsTypes> {
(options.horizontalBars ? -1 : 1);
}

// distinguish between positive and negative values in relative stack mode
if (isAccumulateRelativeStackMode) {
stackedBarValues =
valueY >= 0 || valueX >= 0
? posStackedBarValues
: negStackedBarValues;
}

// Enter value in stacked bar values used to remember previous screen value for stacking up bars
const previousStack = stackedBarValues[valueIndex] || zeroPoint;
stackedBarValues[valueIndex] =
Expand All @@ -517,7 +533,9 @@ export class BarChart extends BaseChart<BarChartEventsTypes> {

if (
options.stackBars &&
(options.stackMode === 'accumulate' || !options.stackMode)
(isAccumulateStackMode ||
isAccumulateRelativeStackMode ||
!options.stackMode)
) {
// Stack mode: accumulate (default)
// If bars are stacked we use the stackedBarValues reference and otherwise base all bars off the zero line
Expand Down Expand Up @@ -558,12 +576,7 @@ export class BarChart extends BaseChart<BarChartEventsTypes> {
const bar = seriesElement
.elem('line', positions, options.classNames.bar)
.attr({
'ct:value': [
safeHasProperty(value, 'x') && value.x,
safeHasProperty(value, 'y') && value.y
]
.filter(isNumeric)
.join(','),
'ct:value': [valueX, valueY].filter(isNumeric).join(','),
'ct:meta': serialize(metaData)
});

Expand Down
5 changes: 3 additions & 2 deletions src/charts/BarChart/BarChart.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@ export interface BarChartOptions<
*/
stackBars?: boolean;
/**
* If set to 'overlap' this property will force the stacked bars to draw from the zero line.
* If set to true this property will force the stacked bars to draw from the zero line.
* If set to 'accumulate' this property will form a total for each series point. This will also influence the y-axis and the overall bounds of the chart. In stacked mode the seriesBarDistance property will have no effect.
* If set to 'accumulate-relative' positive and negative values will be handled separately.
*/
stackMode?: 'accumulate' | boolean;
stackMode?: 'accumulate' | 'accumulate-relative' | boolean;
/**
* Inverts the axes of the bar chart in order to draw a horizontal bar chart. Be aware that you also need to invert your axis settings as the Y Axis will now display the labels and the X Axis the values.
*/
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.