Skip to content

Commit 54176fc

Browse files
committed
update README
1 parent c8ce80d commit 54176fc

File tree

4 files changed

+153
-93
lines changed

4 files changed

+153
-93
lines changed

README.md

+149-86
Original file line numberDiff line numberDiff line change
@@ -27,57 +27,71 @@ four new types: `boxplot`, `horizontalBoxplot`, `violin`, and `horizontalViolin`
2727

2828
## Config
2929

30-
// TODO
30+
The config can be done on a per dataset `.data.datasets[0].minStats` or for all datasets under the controllers name. e.g., `.options.boxplot.datasets.minStats`.
31+
32+
```ts
33+
interface IBaseOptions {
34+
/**
35+
* statistic measure that should be used for computing the minimal data limit
36+
* @default 'min'
37+
*/
38+
minStats: 'min' | 'q1' | 'whiskerMin';
39+
40+
/**
41+
* statistic measure that should be used for computing the maximal data limit
42+
* @default 'max'
43+
*/
44+
maxStats: 'max' | 'q3' | 'whiskerMax';
45+
46+
/**
47+
* from the R doc: this determines how far the plot ‘whiskers’ extend out from
48+
* the box. If coef is positive, the whiskers extend to the most extreme data
49+
* point which is no more than coef times the length of the box away from the
50+
* box. A value of zero causes the whiskers to extend to the data extremes
51+
* @default 1.5
52+
*/
53+
coef: number;
54+
55+
/**
56+
* the method to compute the quantiles.
57+
*
58+
* 7, 'quantiles': the type-7 method as used by R 'quantiles' method.
59+
* 'hinges' and 'fivenum': the method used by R 'boxplot.stats' method.
60+
* 'linear': the interpolation method 'linear' as used by 'numpy.percentile' function
61+
* 'lower': the interpolation method 'lower' as used by 'numpy.percentile' function
62+
* 'higher': the interpolation method 'higher' as used by 'numpy.percentile' function
63+
* 'nearest': the interpolation method 'nearest' as used by 'numpy.percentile' function
64+
* 'midpoint': the interpolation method 'midpoint' as used by 'numpy.percentile' function
65+
* @default 7
66+
*/
67+
quantiles:
68+
| 7
69+
| 'quantiles'
70+
| 'hinges'
71+
| 'fivenum'
72+
| 'linear'
73+
| 'lower'
74+
| 'higher'
75+
| 'nearest'
76+
| 'midpoint'
77+
| ((sortedArr: number[]) => { min: number; q1: number; median: number; q3: number; max: number });
78+
}
79+
80+
interface IBoxplotOptions extends IBaseOptions {
81+
// no extra options
82+
}
83+
84+
interface IViolinOptions extends IBaseOptions {
85+
/**
86+
* number of points that should be samples of the KDE
87+
* @default 100
88+
*/
89+
points: number;
90+
}
3191

32-
```typescript
3392
interface IChartJSOptions {
3493
boxplot: {
35-
datasets: {
36-
/**
37-
* statistic measure that should be used for computing the minimal data limit
38-
* @default 'min'
39-
*/
40-
minStats: 'min' | 'q1' | 'whiskerMin';
41-
42-
/**
43-
* statistic measure that should be used for computing the maximal data limit
44-
* @default 'max'
45-
*/
46-
maxStats: 'max' | 'q3' | 'whiskerMax';
47-
48-
/**
49-
* from the R doc: this determines how far the plot ‘whiskers’ extend out from
50-
* the box. If coef is positive, the whiskers extend to the most extreme data
51-
* point which is no more than coef times the length of the box away from the
52-
* box. A value of zero causes the whiskers to extend to the data extremes
53-
* @default 1.5
54-
*/
55-
coef: number;
56-
57-
/**
58-
* the method to compute the quantiles.
59-
*
60-
* 7, 'quantiles': the type-7 method as used by R 'quantiles' method.
61-
* 'hinges' and 'fivenum': the method used by R 'boxplot.stats' method.
62-
* 'linear': the interpolation method 'linear' as used by 'numpy.percentile' function
63-
* 'lower': the interpolation method 'lower' as used by 'numpy.percentile' function
64-
* 'higher': the interpolation method 'higher' as used by 'numpy.percentile' function
65-
* 'nearest': the interpolation method 'nearest' as used by 'numpy.percentile' function
66-
* 'midpoint': the interpolation method 'midpoint' as used by 'numpy.percentile' function
67-
* @default 7
68-
*/
69-
quantiles:
70-
| 7
71-
| 'quantiles'
72-
| 'hinges'
73-
| 'fivenum'
74-
| 'linear'
75-
| 'lower'
76-
| 'higher'
77-
| 'nearest'
78-
| 'midpoint'
79-
| ((sortedArr: number[]) => { min: number; q1: number; median: number; q3: number; max: number });
80-
};
94+
datasets: {};
8195
};
8296
}
8397
```
@@ -86,7 +100,7 @@ interface IChartJSOptions {
86100

87101
The boxplot element is called `boxandwhiskers`. The basic options are from the `rectangle` element. The violin element is called `violin` also based on the `rectangle` element.
88102

89-
```typescript
103+
```ts
90104
interface IBaseStyling {
91105
/**
92106
* @default see rectangle
@@ -103,18 +117,27 @@ interface IBaseStyling {
103117
borderColor: string;
104118

105119
/**
106-
* @default null takes the current borderColor
120+
* @default 1
107121
* @scriptable
108122
* @indexable
109123
*/
110-
medianColor: string;
124+
borderWidth: number;
111125

112126
/**
113-
* @default 1
114-
* @scriptable
115-
* @indexable
127+
* item style used to render outliers
128+
* @default circle
116129
*/
117-
borderWidth: number;
130+
outlierStyle:
131+
| 'circle'
132+
| 'triangle'
133+
| 'rect'
134+
| 'rectRounded'
135+
| 'rectRot'
136+
| 'cross'
137+
| 'crossRot'
138+
| 'star'
139+
| 'line'
140+
| 'dash';
118141

119142
/**
120143
* radius used to render outliers
@@ -132,20 +155,17 @@ interface IBaseStyling {
132155
outlierBackgroundColor: string;
133156

134157
/**
135-
* to fill color below the median line of the box
136-
* @default transparent
158+
* @default see rectangle.borderColor
137159
* @scriptable
138160
* @indexable
139161
*/
140-
lowerBackgroundColor: string;
141-
162+
outlierBorderColor: string;
142163
/**
143-
* radius used to render items
144-
* @default 0 so disabled
164+
* @default 1
145165
* @scriptable
146166
* @indexable
147167
*/
148-
itemRadius: number;
168+
outlierBorderWidth: number;
149169

150170
/**
151171
* item style used to render items
@@ -163,25 +183,41 @@ interface IBaseStyling {
163183
| 'line'
164184
| 'dash';
165185

186+
/**
187+
* radius used to render items
188+
* @default 0 so disabled
189+
* @scriptable
190+
* @indexable
191+
*/
192+
itemRadius: number;
193+
166194
/**
167195
* background color for items
168-
* @default see rectangle backgroundColor
196+
* @default see rectangle.backgroundColor
169197
* @scriptable
170198
* @indexable
171199
*/
172200
itemBackgroundColor: string;
173201

174202
/**
175203
* border color for items
176-
* @default see rectangle backgroundColor
204+
* @default see rectangle.borderColor
177205
* @scriptable
178206
* @indexable
179207
*/
180208
itemBorderColor: string;
181209

210+
/**
211+
* border width for items
212+
* @default 0
213+
* @scriptable
214+
* @indexable
215+
*/
216+
itemBorderColor: number;
217+
182218
/**
183219
* padding that is added around the bounding box when computing a mouse hit
184-
* @default 1
220+
* @default 2
185221
* @scriptable
186222
* @indexable
187223
*/
@@ -197,23 +233,33 @@ interface IBaseStyling {
197233
}
198234

199235
interface IBoxPlotStyling extends IBaseStyling {
200-
// no extra styling options
201-
}
236+
/**
237+
* separate color for the median line
238+
* @default 'transparent' takes the current borderColor
239+
* @scriptable
240+
* @indexable
241+
*/
242+
medianColor: string;
202243

203-
interface IViolinStyling extends IBaseStyling {
204244
/**
205-
* number of sample points of the underlying KDE for creating the violin plot
206-
* @default 100
245+
* color the lower half (median-q3) of the box in a different color
246+
* @default 'transparent' takes the current borderColor
247+
* @scriptable
248+
* @indexable
207249
*/
208-
points: number;
250+
lowerBackgroundColor: string;
251+
}
252+
253+
interface IViolinElementStyling extends IBaseStyling {
254+
// no extras
209255
}
210256
```
211257

212258
## Data structure
213259

214260
Both types support that the data is given as an array of numbers `number[]`. The statistics will be automatically computed. In addition, specific summary data structures are supported:
215261

216-
```typescript
262+
```ts
217263
interface IBaseItem {
218264
min: number;
219265
median: number;
@@ -256,24 +302,36 @@ interface IViolinItem extends IBaseItem {
256302

257303
## Tooltips
258304

259-
In order to simplify the customization of the tooltips,
260-
// TODO
261-
262-
```js
263-
arr = {
264-
options: {
265-
tooltips: {
266-
callbacks: {
267-
// TODO
268-
},
269-
},
270-
},
271-
};
305+
In order to simplify the customization of the tooltips the tooltip item given to the tooltip callbacks was improved. The default `toString()` behavior should be fine in most cases. The tooltip item has the following structure:
306+
307+
```ts
308+
interface ITooltipItem {
309+
label: string; // original
310+
value: {
311+
raw: IBoxPlotItem | IViolinItem;
312+
/**
313+
* in case an outlier is hovered this will contains its index
314+
* @default -1
315+
*/
316+
hoveredOutlierRadius: number;
317+
/**
318+
* toString function with a proper default implementation, which is used implicitly
319+
*/
320+
toString(): string;
321+
322+
min: string;
323+
median: string;
324+
max: string;
325+
items?: string[];
326+
327+
//... the formatted version of different attributes IBoxPlotItem or ViolinItem
328+
};
329+
}
272330
```
273331

274332
### ESM and Tree Shaking
275333

276-
The ESM build of the library supports three shaking but having no side effects. As a consequence the chart.js library won't be automatically manipulated nor new controllers automatically registered. One has to manually import and register them.
334+
The ESM build of the library supports tree shaking thus having no side effects. As a consequence the chart.js library won't be automatically manipulated nor new controllers automatically registered. One has to manually import and register them.
277335

278336
```js
279337
import Chart from 'chart.js';
@@ -282,6 +340,11 @@ import { BoxPlot } from '@sgratzl/chartjs-chart-boxplot';
282340
// register controller in chart.js and ensure the defaults are set
283341
BoxPlot.register();
284342
...
343+
344+
new Chart(ctx, {
345+
type: BoxPlot.id,
346+
data: [...],
347+
});
285348
```
286349

287350
## Development Environment

src/elements/base.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ export const baseDefaults = Object.assign({}, defaults.elements.rectangle, {
99
outlierBackgroundColor: defaults.elements.rectangle.backgroundColor,
1010
outlierBorderColor: defaults.elements.rectangle.borderColor,
1111
outlierBorderWidth: 1,
12-
outlierHitRadius: 4,
1312

1413
itemStyle: 'circle',
1514
itemRadius: 0,
@@ -18,6 +17,7 @@ export const baseDefaults = Object.assign({}, defaults.elements.rectangle, {
1817
itemBorderWidth: 0,
1918

2019
hitPadding: 2,
20+
outlierHitRadius: 4,
2121
});
2222

2323
export const baseOptionKeys = [
@@ -55,7 +55,6 @@ export class StatsBase extends Element {
5555
ctx.lineWith = options.itemBorderWidth;
5656
// jitter based on random data
5757
// use the dataset index and index to initialize the random number generator
58-
// TODO
5958
const random = rnd(this._datasetIndex * 1000 + this._index);
6059

6160
const pointOptions = {

src/elements/boxandwhiskers.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { defaults } from 'chart.js';
22
import { StatsBase, baseDefaults, baseOptionKeys } from './base';
33

4-
export const boxOptionsKeys = baseOptionKeys.concat(['medianColor', 'lowerColor']);
4+
export const boxOptionsKeys = baseOptionKeys.concat(['medianColor', 'lowerBackgroundColor']);
55

66
export class BoxAndWiskers extends StatsBase {
77
draw(ctx) {
@@ -198,7 +198,7 @@ export class BoxAndWiskers extends StatsBase {
198198
}
199199
}
200200

201-
BoxAndWiskers._type = 'boxAndWhiskers';
201+
BoxAndWiskers._type = 'boxandwhiskers';
202202
BoxAndWiskers.register = () => {
203203
defaults.set('elements', {
204204
[BoxAndWiskers._type]: Object.assign({}, baseDefaults, {

src/elements/violin.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,7 @@ export class ViolinElement extends StatsBase {
102102
ViolinElement._type = 'violin';
103103
ViolinElement.register = () => {
104104
defaults.set('elements', {
105-
[ViolinElement._type]: Object.assign({}, baseDefaults, {
106-
points: 100,
107-
}),
105+
[ViolinElement._type]: baseDefaults,
108106
});
109107
return ViolinElement;
110108
};

0 commit comments

Comments
 (0)