Skip to content
This repository was archived by the owner on Nov 25, 2021. It is now read-only.

Commit 85ee546

Browse files
author
Stefan Luger
authored
Merge pull request #7 from datavisyn/sgratzl/graded
add array version + ts interfaces
2 parents 1afed9a + a1e638b commit 85ee546

3 files changed

Lines changed: 154 additions & 17 deletions

File tree

README.md

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Try the demo on [Codepen](https://codepen.io/sluger/pen/YjJKYy).
1414
npm install --save chart.js chartjs-plugin-error-bars
1515
```
1616

17+
1718
## Usage
1819
Datasets must define an `errorBars` object that contains the error bar property key (same as in the used scale) and values `plus` and `minus`. Plus values are always positive, and minus vice versa.
1920

@@ -29,6 +30,29 @@ Datasets must define an `errorBars` object that contains the error bar property
2930
'May': {plus: 35, minus: -14},
3031
'June': {plus: 45, minus: -4}
3132
}, ...
33+
34+
/* or for graded error bars
35+
36+
errorBars: {
37+
'February': [{plus: 15, minus: -34}, {plus: 10, minus: -26}],
38+
'March': [{plus: 5, minus: -24}, {plus: 2, minus: -16}],
39+
'May': [{plus: 35, minus: -14}, {plus: 7, minus: -7}],
40+
'June': [{plus: 45, minus: -4}, {plus: 25, minus: -2}]
41+
}, ...
42+
43+
*/
44+
```
45+
46+
corresponding TypeScript interface
47+
```ts
48+
interface IErrorBars {
49+
[label: string]: IErrorBar | IErrorBar[];
50+
}
51+
52+
interface IErrorBar {
53+
plus: number;
54+
minus: number;
55+
}
3256
```
3357
3458
*Hierarchical scale plugin usage:*
@@ -62,17 +86,23 @@ Find more [Samples](https://github.com/datavisyn/chartjs-plugin-error-bars/tree/
6286
plugins: {
6387
chartJsPluginErrorBars: {
6488
/**
65-
* stroke color
89+
* stroke color, or array of colors
6690
* @default: derived from borderColor
6791
*/
6892
color: '#666',
6993

7094
/**
71-
* bar width in pixel as number or string or bar width in percent based on the barchart bars width (max 100%)
95+
* bar width in pixel as number or string or bar width in percent based on the barchart bars width (max 100%), or array of such definition
7296
* @default 10
7397
*/
7498
width: 10 | '10px' | '60%',
7599

100+
/**
101+
* lineWidth as number, or as string with pixel (px) ending, or array of such definition
102+
* @default 2
103+
*/
104+
lineWidth: 2 | '2px',
105+
76106
/**
77107
* whether to interpet the plus/minus values, relative to the value itself (default) or absolute
78108
* @default false
@@ -85,6 +115,16 @@ Find more [Samples](https://github.com/datavisyn/chartjs-plugin-error-bars/tree/
85115
}
86116
```
87117
118+
corresponding TypeScript interface
119+
```ts
120+
interface IChartJsPluginErrorBarsOptions {
121+
color: string | string[];
122+
width: (string | number) | (string | number)[];
123+
lineWidth: (string | number) | (string | number)[];
124+
absoluteValues: boolean;
125+
}
126+
```
127+
88128
89129
## Building
90130

samples/graded.html

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<!doctype html>
2+
<html>
3+
4+
<head>
5+
<title>Vertical Bar</title>
6+
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.min.js" type></script>
7+
<script src="../build/Plugin.Errorbars.js"></script>
8+
<style>
9+
canvas {
10+
-moz-user-select: none;
11+
-webkit-user-select: none;
12+
-ms-user-select: none;
13+
}
14+
</style>
15+
</head>
16+
17+
<body>
18+
<div id="container" style="width: 75%;">
19+
<canvas id="canvas"></canvas>
20+
</div>
21+
<script>
22+
var color = Chart.helpers.color;
23+
var barChartData = {
24+
labels: ['Value', 'Value 2', 'Value 3', 'Value 4'],
25+
datasets: [{
26+
label: 'Dataset 1',
27+
//backgroundColor: '#d95f02',
28+
borderColor: '#d95f02',
29+
borderWidth: 1,
30+
data: [
31+
50,
32+
-5,
33+
130,
34+
-40
35+
],
36+
errorBars: {
37+
'Value': [{minus: 20, plus: 80}, {minus: 40, plus: 60}],
38+
'Value 2': [{minus: -30, plus: 120}, {minus: -20, plus: 50}]
39+
}
40+
}]
41+
42+
};
43+
44+
window.onload = function () {
45+
var ctx = document.getElementById("canvas").getContext("2d");
46+
window.myBar = new Chart(ctx, {
47+
type: 'bar',
48+
data: barChartData,
49+
options: {
50+
responsive: true,
51+
scales: {
52+
yAxes: [{
53+
ticks: {
54+
beginAtZero: true
55+
}
56+
}]
57+
},
58+
legend: {
59+
position: 'top',
60+
},
61+
title: {
62+
display: true,
63+
text: 'Chart.js Error Bars Plugin'
64+
},
65+
plugins: {
66+
chartJsPluginErrorBars: {
67+
width: '20%',
68+
lineWidth: [2, 4],
69+
color: ['#bcbddc', '#756bb1'],
70+
absoluteValues: true
71+
//color: 'darkgray'
72+
}
73+
}
74+
},
75+
});
76+
};
77+
</script>
78+
</body>
79+
80+
</html>

src/plugin.js

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,17 @@ const defaultOptions = {
88
* @default: derived from borderColor
99
*/
1010
color: undefined,
11+
1112
/**
1213
* with as number, or as string with pixel (px) ending, or as string with percentage (%) ending
1314
*/
1415
width: 10,
1516

17+
/**
18+
* lineWidth as number, or as string with pixel (px) ending, or array of such definition
19+
*/
20+
lineWidth: 2,
21+
1622
/**
1723
* whether the error values are given in absolute values or relative (default)
1824
*/
@@ -68,12 +74,11 @@ const ErrorBarsPlugin = {
6874
* compute error bars width in pixel or percent
6975
* @param chart chartjs instance
7076
* @param horizontal orientation
71-
* @param options plugin options
77+
* @param width plugin option width
7278
* @returns {*} width in pixel as number
7379
* @private
7480
*/
75-
_computeWidth(chart, horizontal, options) {
76-
const width = options.width;
81+
_computeWidth(chart, horizontal, width) {
7782
let widthInPx = width;
7883

7984
try {
@@ -102,7 +107,7 @@ const ErrorBarsPlugin = {
102107
console.error(e);
103108
} finally {
104109
if (Number.isNaN(widthInPx)) {
105-
widthInPx = options.width;
110+
widthInPx = width;
106111
}
107112
}
108113
return widthInPx;
@@ -119,9 +124,10 @@ const ErrorBarsPlugin = {
119124
* @param horizontal orientation
120125
* @private
121126
*/
122-
_drawErrorBar(ctx, model, plus, minus, color, width, horizontal) {
127+
_drawErrorBar(ctx, model, plus, minus, color, lineWidth, width, horizontal) {
123128
ctx.save();
124129
ctx.strokeStyle = color;
130+
ctx.lineWidth = lineWidth;
125131
ctx.beginPath();
126132
if (horizontal) {
127133
ctx.moveTo(minus, model.y - width / 2);
@@ -170,7 +176,10 @@ const ErrorBarsPlugin = {
170176
const horizontal = this._isHorizontal(chart);
171177
const vScale = horizontal ? chart.scales['x-axis-0'] : chart.scales['y-axis-0'];
172178

173-
const errorBarWidth = this._computeWidth(chart, horizontal, options);
179+
const errorBarWidths = (Array.isArray(options.width) ? options.width : [options.width]).map((w) => this._computeWidth(chart, horizontal, w));
180+
const errorBarLineWidths = Array.isArray(options.lineWidth) ? options.lineWidth : [options.lineWidth];
181+
const errorBarColors = Array.isArray(options.color) ? options.color : [options.color];
182+
174183

175184
const ctx = chart.ctx;
176185
ctx.save();
@@ -182,7 +191,7 @@ const ErrorBarsPlugin = {
182191
if (!cur) {
183192
return;
184193
}
185-
let hasLabelProperty = cur.hasOwnProperty(bar.label);
194+
const hasLabelProperty = cur.hasOwnProperty(bar.label);
186195
let errorBarData = null;
187196

188197
// common scale such as categorical
@@ -193,19 +202,27 @@ const ErrorBarsPlugin = {
193202
errorBarData = cur[bar.label.label];
194203
}
195204

196-
// error bar data for the barchart bar or point in linechart
197-
if (errorBarData) {
198-
const errorBarColor = options.color ? options.color : bar.color;
199-
const value = vScale.getRightValue(bar.value);
205+
if (!errorBarData) {
206+
return;
207+
}
208+
209+
const errorBars = Array.isArray(errorBarData) ? errorBarData : [errorBarData];
210+
const value = vScale.getRightValue(bar.value);
200211

201-
const plusValue = options.absoluteValues ? Math.abs(errorBarData.plus) : (value + Math.abs(errorBarData.plus));
202-
const minusValue = options.absoluteValues ? Math.abs(errorBarData.minus) : (value - Math.abs(errorBarData.minus));
212+
errorBars.forEach((errorBar, ei) => {
213+
// error bar data for the barchart bar or point in linechart
214+
const errorBarColor = errorBarColors[ei % errorBarColors.length] ? errorBarColors[ei % errorBarColors.length] : bar.color;
215+
const errorBarLineWidth = errorBarLineWidths[ei % errorBarLineWidths.length];
216+
const errorBarWidth = errorBarWidths[ei % errorBarWidths.length];
217+
218+
const plusValue = options.absoluteValues ? errorBar.plus : (value + Math.abs(errorBar.plus));
219+
const minusValue = options.absoluteValues ? errorBar.minus : (value - Math.abs(errorBar.minus));
203220

204221
const plus = vScale.getPixelForValue(plusValue);
205222
const minus = vScale.getPixelForValue(minusValue);
206223

207-
this._drawErrorBar(ctx, bar, plus, minus, errorBarColor, errorBarWidth, horizontal);
208-
}
224+
this._drawErrorBar(ctx, bar, plus, minus, errorBarColor, errorBarLineWidth, errorBarWidth, horizontal);
225+
});
209226
});
210227
});
211228

0 commit comments

Comments
 (0)