Skip to content

Commit 974184c

Browse files
committed
feat: use airbnb linting
1 parent 50272e7 commit 974184c

File tree

11 files changed

+61
-22
lines changed

11 files changed

+61
-22
lines changed

.eslintrc.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ module.exports = {
2323
rules: {
2424
// '@typescript-eslint/explicit-module-boundary-types': 'off',
2525
'@typescript-eslint/no-explicit-any': 'off',
26-
'no-underscore-dangle': 'off',
27-
'max-classes-per-file': 'off',
2826
// '@typescript-eslint/no-non-null-assertion': 'off',
27+
'max-classes-per-file': 'off',
28+
'no-underscore-dangle': 'off',
2929
},
3030
};

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@
1111
/yarn.lock
1212
/.vscode
1313
*.png
14+
*.tgz
1415
*.tsbuildinfo

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,4 @@
2626
"**/.yarn": true,
2727
"**/.pnp.*": true
2828
},
29-
}
29+
}

src/__tests__/createChart.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ function toBuffer(canvas: HTMLCanvasElement) {
1212
canvas.toBlob((b) => {
1313
const file = new FileReader();
1414
file.onload = () => resolve(Buffer.from(file.result as ArrayBuffer));
15+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1516
file.readAsArrayBuffer(b!);
1617
});
1718
});
@@ -22,19 +23,29 @@ export async function expectMatchSnapshot(canvas: HTMLCanvasElement): Promise<vo
2223
expect(image).toMatchImageSnapshot();
2324
}
2425

26+
export interface ChartHelper<TYPE extends ChartType, DATA extends unknown[] = DefaultDataPoint<TYPE>, LABEL = string> {
27+
chart: Chart<TYPE, DATA, LABEL>;
28+
canvas: HTMLCanvasElement;
29+
ctx: CanvasRenderingContext2D;
30+
toMatchImageSnapshot(options?: MatchImageSnapshotOptions): Promise<void>;
31+
}
32+
2533
export default function createChart<
2634
TYPE extends ChartType,
2735
DATA extends unknown[] = DefaultDataPoint<TYPE>,
2836
LABEL = string
29-
>(config: ChartConfiguration<TYPE, DATA, LABEL>, width = 800, height = 600) {
37+
>(config: ChartConfiguration<TYPE, DATA, LABEL>, width = 300, height = 300): ChartHelper<TYPE, DATA, LABEL> {
3038
const canvas = document.createElement('canvas');
3139
canvas.width = width;
3240
canvas.height = height;
3341
defaults.font.family = 'Courier New';
34-
defaults.color = 'transparent';
42+
// defaults.color = 'transparent';
43+
// eslint-disable-next-line no-param-reassign
3544
config.options = {
3645
responsive: false,
37-
animation: false,
46+
animation: {
47+
duration: 1,
48+
},
3849
plugins: {
3950
legend: {
4051
display: false,
@@ -45,6 +56,7 @@ export default function createChart<
4556
},
4657
...(config.options || {}),
4758
} as any;
59+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
4860
const ctx = canvas.getContext('2d')!;
4961

5062
const t = new Chart<TYPE, DATA, LABEL>(ctx, config);

src/controllers/BoxPlotController.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ describe('boxplot', () => {
272272
return chart.toMatchImageSnapshot();
273273
});
274274

275-
test('datastructures', () => {
275+
test('data structures', () => {
276276
const chart = createChart({
277277
type: BoxPlotController.id,
278278
data: {

src/controllers/BoxPlotController.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,16 @@ import patchController from './patchController';
1818
import { boxOptionsKeys } from '../elements/BoxAndWiskers';
1919

2020
export class BoxPlotController extends StatsBase<IBoxPlot, Required<IBoxplotOptions>> {
21+
// eslint-disable-next-line class-methods-use-this
2122
protected _parseStats(value: unknown, config: IBoxplotOptions): IBoxPlot | undefined {
2223
return asBoxPlotStats(value, config);
2324
}
2425

26+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
2527
protected _transformStats<T>(target: any, source: IBoxPlot, mapper: (v: number) => T): void {
2628
super._transformStats(target, source, mapper);
2729
for (const key of ['whiskerMin', 'whiskerMax']) {
30+
// eslint-disable-next-line no-param-reassign
2831
target[key] = mapper(source[key as 'whiskerMin' | 'whiskerMax']);
2932
}
3033
}

src/controllers/ViolinController.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,18 @@ import { interpolateKdeCoords } from '../animation';
1919
import patchController from './patchController';
2020

2121
export class ViolinController extends StatsBase<IViolin, Required<IViolinOptions>> {
22-
protected _parseStats(value: any, config: IViolinOptions) {
22+
// eslint-disable-next-line class-methods-use-this,@typescript-eslint/explicit-module-boundary-types
23+
protected _parseStats(value: any, config: IViolinOptions): IViolin | undefined {
2324
return asViolinStats(value, config);
2425
}
2526

26-
protected _transformStats<T>(target: any, source: IViolin, mapper: (v: number) => T) {
27+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
28+
protected _transformStats<T>(target: any, source: IViolin, mapper: (v: number) => T): void {
2729
super._transformStats(target, source, mapper);
30+
// eslint-disable-next-line no-param-reassign
2831
target.maxEstimate = source.maxEstimate;
2932
if (Array.isArray(source.coords)) {
33+
// eslint-disable-next-line no-param-reassign
3034
target.coords = source.coords.map((c) => ({ ...c, v: mapper(c.v) }));
3135
}
3236
}

src/controllers/__tests__/utils.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { IBoxPlot } from '@sgratzl/boxplots';
1+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
22
import type { BoxPlotDataPoint } from '../BoxPlotController';
33

44
const Months = [
@@ -46,6 +46,7 @@ export class Samples {
4646
return this.randF(min, max)();
4747
}
4848

49+
// eslint-disable-next-line class-methods-use-this
4950
months({ count = 12, section }: { count?: number; section?: number }): string[] {
5051
const values: string[] = [];
5152

@@ -118,6 +119,7 @@ export class Samples {
118119
.map(() => this.numbers({ ...config, count: 50 }) as number[]);
119120
}
120121

122+
// eslint-disable-next-line class-methods-use-this
121123
labels({
122124
min = 0,
123125
max = 100,

src/controllers/base.ts

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { interpolateNumberArray } from '../animation';
33
import { outlierPositioner, patchInHoveredOutlier } from '../tooltip';
44
import { defaultStatsOptions, IBaseOptions, IBaseStats } from '../data';
55

6-
export /* #__PURE__ */ function baseDefaults(keys: string[]) {
6+
export /* #__PURE__ */ function baseDefaults(keys: string[]): Record<string, unknown> {
77
const colorKeys = ['borderColor', 'backgroundColor'].concat(keys.filter((c) => c.endsWith('Color')));
88
return {
99
animations: {
@@ -42,7 +42,7 @@ export /* #__PURE__ */ function baseDefaults(keys: string[]) {
4242
};
4343
}
4444

45-
export function defaultOverrides() {
45+
export function defaultOverrides(): Record<string, unknown> {
4646
return {
4747
plugins: {
4848
tooltips: {
@@ -58,15 +58,18 @@ export function defaultOverrides() {
5858
export abstract class StatsBase<S extends IBaseStats, C extends Required<IBaseOptions>> extends BarController {
5959
declare options: C;
6060

61+
// eslint-disable-next-line class-methods-use-this,@typescript-eslint/explicit-module-boundary-types
6162
protected _transformStats<T>(target: any, source: S, mapper: (v: number) => T): void {
6263
for (const key of ['min', 'max', 'median', 'q3', 'q1', 'mean'] as const) {
6364
const v = source[key];
6465
if (typeof v === 'number') {
66+
// eslint-disable-next-line no-param-reassign
6567
target[key] = mapper(v);
6668
}
6769
}
6870
for (const key of ['outliers', 'items'] as const) {
6971
if (Array.isArray(source[key])) {
72+
// eslint-disable-next-line no-param-reassign
7073
target[key] = source[key].map(mapper);
7174
}
7275
}
@@ -75,20 +78,25 @@ export abstract class StatsBase<S extends IBaseStats, C extends Required<IBaseOp
7578
getMinMax(scale: Scale, canStack?: boolean | undefined): { min: number; max: number } {
7679
const bak = scale.axis;
7780
const config = this.options;
81+
// eslint-disable-next-line no-param-reassign
7882
scale.axis = config.minStats;
7983
const { min } = super.getMinMax(scale, canStack);
84+
// eslint-disable-next-line no-param-reassign
8085
scale.axis = config.maxStats;
8186
const { max } = super.getMinMax(scale, canStack);
87+
// eslint-disable-next-line no-param-reassign
8288
scale.axis = bak;
8389
return { min, max };
8490
}
8591

86-
parsePrimitiveData(meta: ChartMeta, data: any[], start: number, count: number) {
92+
parsePrimitiveData(meta: ChartMeta, data: any[], start: number, count: number): Record<string, unknown>[] {
93+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
8794
const vScale = meta.vScale!;
95+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
8896
const iScale = meta.iScale!;
8997
const labels = iScale.getLabels();
9098
const r = [];
91-
for (let i = 0; i < count; i++) {
99+
for (let i = 0; i < count; i += 1) {
92100
const index = i + start;
93101
const parsed: any = {};
94102
parsed[iScale.axis] = iScale.parse(labels[index], index);
@@ -102,17 +110,18 @@ export abstract class StatsBase<S extends IBaseStats, C extends Required<IBaseOp
102110
return r;
103111
}
104112

105-
parseArrayData(meta: ChartMeta, data: any[], start: number, count: number) {
113+
parseArrayData(meta: ChartMeta, data: any[], start: number, count: number): Record<string, unknown>[] {
106114
return this.parsePrimitiveData(meta, data, start, count);
107115
}
108116

109-
parseObjectData(meta: ChartMeta, data: any[], start: number, count: number) {
117+
parseObjectData(meta: ChartMeta, data: any[], start: number, count: number): Record<string, unknown>[] {
110118
return this.parsePrimitiveData(meta, data, start, count);
111119
}
112120

121+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
113122
protected abstract _parseStats(value: any, options: C): S | undefined;
114123

115-
getLabelAndValue(index: number) {
124+
getLabelAndValue(index: number): { label: string; value: string & { raw: S; hoveredOutlierIndex: number } & S } {
116125
const r = super.getLabelAndValue(index) as any;
117126
const { vScale } = this._cachedMeta;
118127
const parsed = (this.getParsed(index) as unknown) as S;
@@ -125,7 +134,7 @@ export abstract class StatsBase<S extends IBaseStats, C extends Required<IBaseOp
125134
};
126135
this._transformStats(r.value, parsed, (v) => vScale.getLabelForValue(v));
127136
const s = this._toStringStats(r.value);
128-
r.value.toString = function () {
137+
r.value.toString = function toString() {
129138
// custom to string function for the 'value'
130139
if (this.hoveredOutlierIndex >= 0) {
131140
// TODO formatter
@@ -136,20 +145,24 @@ export abstract class StatsBase<S extends IBaseStats, C extends Required<IBaseOp
136145
return r;
137146
}
138147

139-
protected _toStringStats(b: S) {
148+
// eslint-disable-next-line class-methods-use-this
149+
protected _toStringStats(b: S): string {
140150
// TODO formatter
141151
const f = (v: number) => (v == null ? 'NaN' : v.toLocaleString());
142152
return `(min: ${f(b.min)}, 25% quantile: ${f(b.q1)}, median: ${f(b.median)}, mean: ${f(b.mean)}, 75% quantile: ${f(
143153
b.q3
144154
)}, max: ${f(b.max)})`;
145155
}
146156

157+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
147158
updateElement(rectangle: Element, index: number, properties: any, mode: UpdateMode): void {
148159
const reset = mode === 'reset';
149160
const scale = this._cachedMeta.vScale as LinearScale;
150161
const parsed = (this.getParsed(index) as unknown) as S;
151162
const base = scale.getBasePixel();
163+
// eslint-disable-next-line no-param-reassign
152164
properties._datasetIndex = this.index;
165+
// eslint-disable-next-line no-param-reassign
153166
properties._index = index;
154167
this._transformStats(properties, parsed, (v) => (reset ? base : scale.getPixelForValue(v, index)));
155168
super.updateElement(rectangle, index, properties, mode);

src/data.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ export function violinStats(arr: readonly number[], options: IViolinOptions): IV
236236
};
237237
}
238238

239+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
239240
export function asBoxPlotStats(value: any, options: IBoxplotOptions): IBoxPlot | undefined {
240241
if (!value) {
241242
return undefined;
@@ -249,7 +250,9 @@ export function asBoxPlotStats(value: any, options: IBoxplotOptions): IBoxPlot |
249250
Array.isArray(value.items) ? (value.items as number[]).slice().sort((a, b) => a - b) : null,
250251
coef
251252
);
253+
// eslint-disable-next-line no-param-reassign
252254
value.whiskerMin = whiskerMin;
255+
// eslint-disable-next-line no-param-reassign
253256
value.whiskerMax = whiskerMax;
254257
}
255258
return value;
@@ -260,6 +263,7 @@ export function asBoxPlotStats(value: any, options: IBoxplotOptions): IBoxPlot |
260263
return boxplotStats(value, options);
261264
}
262265

266+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
263267
export function asViolinStats(value: any, options: IViolinOptions): IViolin | undefined {
264268
if (!value) {
265269
return undefined;
@@ -273,7 +277,7 @@ export function asViolinStats(value: any, options: IViolinOptions): IViolin | un
273277
return violinStats(value, options);
274278
}
275279

276-
export function rnd(seed = Date.now()) {
280+
export function rnd(seed = Date.now()): () => number {
277281
// Adapted from http://indiegamr.com/generate-repeatable-random-numbers-in-js/
278282
let s = seed;
279283
return () => {

0 commit comments

Comments
 (0)