Skip to content

Commit

Permalink
fix: react and refs (#109)
Browse files Browse the repository at this point in the history
* fixed react component
* fix: fixed data refs plugin and react component
  • Loading branch information
zefirka authored Jul 21, 2023
1 parent 32267ce commit de8058d
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 100 deletions.
2 changes: 1 addition & 1 deletion src/YagrCore/mixins/transform-series.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export class TransformSeriesMixin<T extends MinimalValidConfig> {
empty = false;

if (scaleConfig.normalize) {
const sum = getSumByIdx(series, this.options.series, idx, scale);
const sum = getSumByIdx(this.options.series, idx, scale);
value = sum && (value / sum) * (scaleConfig.normalizeBase || 100);

serieOptions.normalizedData = serieOptions.normalizedData || [];
Expand Down
11 changes: 6 additions & 5 deletions src/YagrCore/utils/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,18 @@ export const findInRange = (section: TooltipSection, value: number, stickToRange
};

/* Gets sum of all values of given data index by all series */
export const getSumByIdx = (series: DataSeriesExtended[], seriesOptions: Series[], idx: number, scale: string) => {
export const getSumByIdx = (seriesOptions: Series[], idx: number, scale: string) => {
let sum = 0;
let i = 0;
while (i < series.length) {
const serie = series[i];
const opts = seriesOptions[seriesOptions.length - i - 1];
while (i < seriesOptions.length) {
const seriesIdx = seriesOptions.length - i - 1;
const opts = seriesOptions[seriesIdx];
const seriesValues = opts.$c;
i += 1;
if (opts.scale !== scale || opts.show === false) {
continue;
}
const value = serie[idx];
const value = seriesValues[idx];
sum += typeof value === 'number' ? value : 0;
}
return sum;
Expand Down
16 changes: 10 additions & 6 deletions src/plugins/dataRefs/dataRefs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ const DataRef = (opst: DataRefsPluginOptions) => {
calcRefs: (fromIdx: number, toIdx: number, seriesId: string) => {
const seriesIdx = _.state.y2uIdx[seriesId];
const timestamps = _.uplot.data[0].slice(fromIdx, toIdx + 1) as number[];
const values = _.uplot.data[seriesIdx].slice(fromIdx, toIdx + 1) as (number | null)[];
const values = _.uplot.series[seriesIdx].$c.slice(fromIdx, toIdx + 1) as (number | null)[];
const integral = integrate(timestamps, values);
const sum = values.reduce((acc, v) => (acc === null ? 0 : acc + (v || 0)), 0) || 0;
const min = Math.min(...(values.filter((v) => v !== null) as number[]));
Expand Down Expand Up @@ -153,17 +153,21 @@ const DataRef = (opst: DataRefsPluginOptions) => {
};
});

(u.series as Required<Series>[]).forEach(({scale, min, max, sum, count}, sIdx) => {
(u.series as Required<Series>[]).forEach(({scale, $c, count}) => {
if (scale === DEFAULT_X_SCALE) {
return;
}
refs[scale].min = Math.min(refs[scale].min, min);
refs[scale].max = Math.max(refs[scale].max, max);
refs[scale].sum += sum;
const numericValues = $c.filter(
(v) => typeof v === 'number' && v !== null,
) as number[];

refs[scale].min = Math.min(...numericValues, refs[scale].min);
refs[scale].max = Math.max(...numericValues, refs[scale].max);
refs[scale].sum += numericValues.reduce((acc, v) => acc + v, 0);
refs[scale].count += count;
refs[scale].integral += integrate(
u.data[0] as number[],
u.data[sIdx] as DataSeriesExtended,
$c as DataSeriesExtended,
);
});

Expand Down
3 changes: 2 additions & 1 deletion src/react.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ export default React.forwardRef(function YagrReact(

const initChart = React.useCallback(() => {
if (chartRef.current) {
chart.current = new Yagr(chartRef.current, config);
config.hooks = config.hooks || {};
const hooks = config.hooks;

Expand All @@ -61,6 +60,8 @@ export default React.forwardRef(function YagrReact(
selection.push(({from, to}) => onSelect(from, to));
hooks.onSelect = selection;
}

chart.current = new Yagr(chartRef.current, config);
}
}, []);

Expand Down
189 changes: 118 additions & 71 deletions tests/plugins/dataRefs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,95 +2,142 @@ import Yagr from '../../src/YagrCore';
import DataRefs from '../../src/plugins/dataRefs/dataRefs';

describe('DataRefs plugin', () => {
const y = new Yagr(window.document.createElement('div'), {
timeline: [1, 2, 3, 4],
series: [
{data: [1, 2, 3, 4], scale: 'y', id: 'one'},
{data: [3, 3, 3, 3], scale: 'y', id: 'two'},
{data: [5, 6, 7, 8], scale: 'r', id: 'three'},
],
plugins: {
refs: DataRefs({}),
},
});
describe('plain data', () => {
const y = new Yagr(window.document.createElement('div'), {
timeline: [1, 2, 3, 4],
series: [
{data: [1, 2, 3, 4], scale: 'y', id: 'one'},
{data: [3, 3, 3, 3], scale: 'y', id: 'two'},
{data: [5, 6, 7, 8], scale: 'r', id: 'three'},
],
plugins: {
refs: DataRefs({}),
},
});

it('should calc refs for series perScale', async () => {
await new Promise((resolve) => setTimeout(resolve, 100));
expect(y.plugins.refs?.getRefs()).toEqual({
y: {min: 1, max: 4, count: 8, last: null, avg: 2.75, sum: 22, integral: 0.0165},
r: {min: 5, max: 8, count: 4, last: null, avg: 6.5, sum: 26, integral: 0.0195},
it('should calc refs for series perScale', async () => {
await new Promise((resolve) => setTimeout(resolve, 100));
expect(y.plugins.refs?.getRefs()).toEqual({
y: {min: 1, max: 4, count: 8, last: null, avg: 2.75, sum: 22, integral: 0.0165},
r: {min: 5, max: 8, count: 4, last: null, avg: 6.5, sum: 26, integral: 0.0195},
});
});
});

it('should calc refs by idxs', async () => {
await new Promise((resolve) => setTimeout(resolve, 100));
expect(y.plugins.refs?.calcRefs(0, 1, 'one')).toEqual({
min: 1,
max: 2,
count: 2,
avg: 1.5,
last: 2,
sum: 3,
integral: 0.0015,
it('should calc refs by idxs', async () => {
await new Promise((resolve) => setTimeout(resolve, 100));
expect(y.plugins.refs?.calcRefs(0, 1, 'one')).toEqual({
min: 1,
max: 2,
count: 2,
avg: 1.5,
last: 2,
sum: 3,
integral: 0.0015,
});
});
});

it('should calc refs by ranges', async () => {
await new Promise((resolve) => setTimeout(resolve, 100));
expect(y.plugins.refs?.getRefs(0, 1)).toEqual({
y: {
series: {
one: {
min: 1,
max: 2,
count: 2,
avg: 1.5,
sum: 3,
integral: 0.0015,
last: 2,
it('should calc refs by ranges', async () => {
await new Promise((resolve) => setTimeout(resolve, 100));
expect(y.plugins.refs?.getRefs(0, 1)).toEqual({
y: {
series: {
one: {
min: 1,
max: 2,
count: 2,
avg: 1.5,
sum: 3,
integral: 0.0015,
last: 2,
},
two: {
avg: 3,
count: 2,
integral: 0.003,
last: 3,
max: 3,
min: 3,
sum: 6,
},
},
two: {
avg: 3,
count: 2,
integral: 0.003,
last: 3,
total: {
avg: 2.25,
count: 4,
integral: 0.0045000000000000005,
last: null,
max: 3,
min: 3,
sum: 6,
min: 1,
sum: 9,
},
},
total: {
avg: 2.25,
count: 4,
integral: 0.0045000000000000005,
last: null,
max: 3,
min: 1,
sum: 9,
},
},
r: {
series: {
three: {
r: {
series: {
three: {
avg: 5.5,
count: 2,
integral: 0.0055,
last: 6,
max: 6,
min: 5,
sum: 11,
},
},
total: {
avg: 5.5,
count: 2,
integral: 0.0055,
last: 6,
last: null,
max: 6,
min: 5,
sum: 11,
},
},
total: {
avg: 5.5,
count: 2,
integral: 0.0055,
last: null,
max: 6,
min: 5,
sum: 11,
},
});
});
});

describe('stacked data', () => {
const y = new Yagr(window.document.createElement('div'), {
timeline: [1, 2, 3, 4],
scales: {
y: {stacking: true},
},
series: [
{data: [1, 2, 3, 4], scale: 'y', id: 'one'},
{data: [3, 3, 3, 3], scale: 'y', id: 'two'},
],
plugins: {
refs: DataRefs({}),
},
});

it('should calc refs for series perScale', async () => {
await new Promise((resolve) => setTimeout(resolve, 100));
expect(y.plugins.refs?.getRefs()).toEqual({
y: {min: 1, max: 4, count: 8, last: null, avg: 2.75, sum: 22, integral: 0.0165},
});
});

it('should calc refs by idxs', async () => {
await new Promise((resolve) => setTimeout(resolve, 100));
expect(y.plugins.refs?.calcRefs(0, 1, 'one')).toEqual({
min: 1,
max: 2,
count: 2,
avg: 1.5,
last: 2,
sum: 3,
integral: 0.0015,
});
expect(y.plugins.refs?.calcRefs(0, 1, 'two')).toEqual({
min: 3,
max: 3,
count: 2,
avg: 3,
last: 3,
sum: 6,
integral: 0.003,
});
});
});
});
32 changes: 16 additions & 16 deletions tests/utils/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ describe('utils:getSumByIdx', () => {
];
const options = [
{id: 'date'},
{show: true, scale: 'y'},
{show: true, scale: 'y'},
{show: true, scale: 'y'},
] as Series[];
{show: true, scale: 'y', $c: series[0]},
{show: true, scale: 'y', $c: series[1]},
{show: true, scale: 'y', $c: series[2]},
] as unknown as Series[];

expect(getSumByIdx(series, options, 0, 'y')).toBe(600);
expect(getSumByIdx(series, options, 1, 'y')).toBe(60);
expect(getSumByIdx(series, options, 2, 'y')).toBe(6);
expect(getSumByIdx(series, options, 3, 'y')).toBe(0);
expect(getSumByIdx(options, 0, 'y')).toBe(600);
expect(getSumByIdx(options, 1, 'y')).toBe(60);
expect(getSumByIdx(options, 2, 'y')).toBe(6);
expect(getSumByIdx(options, 3, 'y')).toBe(0);
});

it('should sum only visible series by idx', () => {
Expand All @@ -29,14 +29,14 @@ describe('utils:getSumByIdx', () => {
];
const options = [
{id: 'date'},
{show: true, scale: 'y'},
{show: false, scale: 'y'},
{show: true, scale: 'y'},
] as Series[];
{show: true, scale: 'y', $c: series[0]},
{show: false, scale: 'y', $c: series[1]},
{show: true, scale: 'y', $c: series[2]},
] as unknown as Series[];

expect(getSumByIdx(series, options, 0, 'y')).toBe(400);
expect(getSumByIdx(series, options, 1, 'y')).toBe(40);
expect(getSumByIdx(series, options, 2, 'y')).toBe(4);
expect(getSumByIdx(series, options, 3, 'y')).toBe(0);
expect(getSumByIdx(options, 0, 'y')).toBe(400);
expect(getSumByIdx(options, 1, 'y')).toBe(40);
expect(getSumByIdx(options, 2, 'y')).toBe(4);
expect(getSumByIdx(options, 3, 'y')).toBe(0);
});
});

0 comments on commit de8058d

Please sign in to comment.