Skip to content

Commit

Permalink
Merge branch 'main' into zefirka/screenshot-testing
Browse files Browse the repository at this point in the history
  • Loading branch information
zefirka committed Jul 31, 2023
2 parents 87531ec + cde50ca commit 1f0a046
Show file tree
Hide file tree
Showing 10 changed files with 266 additions and 53 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
### master

## [3.7.2](https://github.com/gravity-ui/yagr/compare/v3.7.1...v3.7.2) (2023-07-31)


### Bug Fixes

* fixed series update ([#117](https://github.com/gravity-ui/yagr/issues/117)) ([d5afe05](https://github.com/gravity-ui/yagr/commit/d5afe05d4ba4d8e9598496149b3209bcefc8213f))

## [3.7.1](https://github.com/gravity-ui/yagr/compare/v3.7.0...v3.7.1) (2023-07-28)


### Bug Fixes

* fixed hooks update ([#113](https://github.com/gravity-ui/yagr/issues/113)) ([9272e5e](https://github.com/gravity-ui/yagr/commit/9272e5e7016b5a7ef781c8c2c5e1c60b97a70b5f))

## [3.7.0](https://github.com/gravity-ui/yagr/compare/v3.6.1...v3.7.0) (2023-07-24)


Expand Down
102 changes: 102 additions & 0 deletions demo/examples/tooltip-updates.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<html>
<head>
<title>Yagr:: Dynamic Updates</title>
<script src="../../dist/yagr.iife.js"></script>
<link rel="stylesheet" href="../../dist/index.css" />
<style>
.container {
margin-bottom: 26px;
height: 400px;
width: 100%;
}
.grid {
height: 450px;
display: flex;
width: 100%;
flex-direction: row;
justify-content: space-between;
}
</style>
</head>
<body>
<h1>Tooltip updates</h1>
<div class="grid">
<div class="container">
<div id="chart1"></div>
<button id="updateData">Data</button>
<button id="updateConfig">Config</button>
</div>
<div class="container" id="cnt2">
<div id="chart2"></div>
<button id="updateSeries">Series</button>
</div>

<script>


const yagr = new Yagr(chart1, {
title: {text: 'Tooltip updates'},
timeline: new Array(20).fill().map((_, i) => i * 1000),
legend: {
show: true,
},
tooltip: {
value: (x) => x + ' in line'
},
series: [
{data: new Array(20).fill().map((_, i) => Math.random() * 6), color: 'red', id: '1'},
{data: new Array(20).fill().map((_, i) => Math.random() * 6), color: 'orange', id: '2'},
],
});

window.updateData.onclick = () => {
yagr.setConfig({
chart: {
series: {
type: 'area'
}
},
series: [
{data: new Array(20).fill().map((_, i) => Math.random() * 6), color: 'blue', id: '1'},
{data: new Array(20).fill().map((_, i) => Math.random() * 6), color: 'green', id: '2'},
],
scales: {
y: {
stacking: true
}
}
});
};

window.updateConfig.onclick = () => {
yagr.setConfig({
tooltip: {
value: (x) => x + ' in stack',
sum: true,
}
})
};

const yagr2 = new Yagr(chart2, {
title: {text: 'Series updates'},
timeline: new Array(20).fill().map((_, i) => i * 1000),
tooltip: {
value: (x) => x + ' in line',
boundClassName: '#cnt2',
},
series: [
{data: new Array(20).fill().map((_, i) => Math.random() * 6), color: 'red', id: '1', formatter: (x) => x + ' format 1' },
],
});

window.updateSeries.onclick = () => {
yagr2.setConfig({
series: [
{data: new Array(20).fill().map((_, i) => Math.random() * 6), color: 'red', id: '1', formatter: (x) => x + ' format 2' },
],
});
};

</script>
</body>
</html>
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@gravity-ui/yagr",
"version": "3.7.0",
"version": "3.7.2",
"description": "High level wrapper for uPlot",
"keywords": [
"canvas",
Expand Down
2 changes: 2 additions & 0 deletions src/YagrCore/locale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ const LOCALIZATIONS: Record<string, Record<string, string>> = {
sum: 'Сумма',
scale: 'Шкала',
series: 'Линия',
weekend: 'Выходной',
},
en: {
'hide-all': 'Hide all',
'show-all': 'Show all',
sum: 'Total',
scale: 'Scale',
series: 'Series',
weekend: 'Weekend',
},
};

Expand Down
115 changes: 66 additions & 49 deletions src/YagrCore/mixins/create-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,69 @@ import {configureAxes} from '../utils/axes';
import {getPaddingByAxes} from '../utils/chart';
import {DrawOrderKey} from '../utils/types';

const uHooks: Record<string, (u: uPlot) => void> = {};

function setIfNotSet(hooks: uPlot.Hooks.Arrays[keyof uPlot.Hooks.Arrays], fn: (u: uPlot) => void) {
for (const hook of hooks || []) {
if (hook === fn) {
return;
}
}
hooks?.push(fn);
}

export class CreateUplotOptionsMixin<T extends MinimalValidConfig> {
initMixin(this: Yagr) {
uHooks.onDraw = () => {
if (this.state.stage === 'listen') {
return;
}
this.state.stage = 'listen';
this.execHooks('stage', {chart: this, stage: this.state.stage});
const renderTime = performance.now() - this._startTime;
this._meta.renderTime = renderTime;
this.execHooks('load', {
chart: this,
meta: this._meta as YagrMeta,
});
};

uHooks.ready = () => {
const initTime = performance.now() - this._startTime;
this._meta.initTime = initTime;
this.execHooks('inited', {
chart: this,
meta: {
initTime,
},
});
};
uHooks.drawClear = (u: uPlot) => {
const {ctx} = u;
ctx.save();
ctx.fillStyle = this.utils.theme.BACKGROUND;
ctx.fillRect(
DEFAULT_CANVAS_PIXEL_RATIO,
DEFAULT_CANVAS_PIXEL_RATIO,
u.width * DEFAULT_CANVAS_PIXEL_RATIO - 2 * DEFAULT_CANVAS_PIXEL_RATIO,
u.height * DEFAULT_CANVAS_PIXEL_RATIO - 2 * DEFAULT_CANVAS_PIXEL_RATIO,
);
ctx.restore();
};
uHooks.setSelect = (u: uPlot) => {
const {left, width} = u.select;
const [_from, _to] = [u.posToVal(left, DEFAULT_X_SCALE), u.posToVal(left + width, DEFAULT_X_SCALE)];
const {timeMultiplier = 1} = this.config.chart || {};

this.execHooks('onSelect', {
from: Math.ceil(_from / timeMultiplier),
to: Math.ceil(_to / timeMultiplier),
chart: this,
});
u.setSelect({width: 0, height: 0, top: 0, left: 0}, false);
};
}

/**
* @internal
* @param reOpt If in reOpt cycle (e.g. batch update), then won't reinit hooks.
Expand Down Expand Up @@ -150,55 +212,10 @@ export class CreateUplotOptionsMixin<T extends MinimalValidConfig> {
options.hooks.drawClear = options.hooks.drawClear || [];
options.hooks.setSelect = options.hooks.setSelect || [];

if (!reOpt) {
options.hooks.draw.push(() => {
if (this.state.stage === 'listen') {
return;
}
this.state.stage = 'listen';
this.execHooks('stage', {chart: this, stage: this.state.stage});
const renderTime = performance.now() - this._startTime;
this._meta.renderTime = renderTime;
this.execHooks('load', {
chart: this,
meta: this._meta as YagrMeta,
});
});
options.hooks.ready.push(() => {
const initTime = performance.now() - this._startTime;
this._meta.initTime = initTime;
this.execHooks('inited', {
chart: this,
meta: {
initTime,
},
});
});
options.hooks.drawClear.push((u: uPlot) => {
const {ctx} = u;
ctx.save();
ctx.fillStyle = this.utils.theme.BACKGROUND;
ctx.fillRect(
DEFAULT_CANVAS_PIXEL_RATIO,
DEFAULT_CANVAS_PIXEL_RATIO,
u.width * DEFAULT_CANVAS_PIXEL_RATIO - 2 * DEFAULT_CANVAS_PIXEL_RATIO,
u.height * DEFAULT_CANVAS_PIXEL_RATIO - 2 * DEFAULT_CANVAS_PIXEL_RATIO,
);
ctx.restore();
});
options.hooks.setSelect.push((u: uPlot) => {
const {left, width} = u.select;
const [_from, _to] = [u.posToVal(left, DEFAULT_X_SCALE), u.posToVal(left + width, DEFAULT_X_SCALE)];
const {timeMultiplier = 1} = chart;

this.execHooks('onSelect', {
from: Math.ceil(_from / timeMultiplier),
to: Math.ceil(_to / timeMultiplier),
chart: this,
});
u.setSelect({width: 0, height: 0, top: 0, left: 0}, false);
});
}
setIfNotSet(options.hooks.draw, uHooks.onDraw);
setIfNotSet(options.hooks.ready, uHooks.ready);
setIfNotSet(options.hooks.drawClear, uHooks.drawClear);
setIfNotSet(options.hooks.setSelect, uHooks.setSelect);

options.drawOrder = chart.appearance?.drawOrder
? (chart.appearance?.drawOrder.filter(
Expand Down
3 changes: 3 additions & 0 deletions src/YagrCore/utils/series.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,7 @@ export const overrideSeriesInUpdate = (dest: Series, source: Series) => {
dest.lineColor = source.lineColor ?? dest.lineColor;
dest.lineWidth = source.lineWidth ?? dest.lineWidth;
dest.stroke = source.stroke ?? dest.stroke;
dest.getFocusedColor = source.getFocusedColor ?? dest.getFocusedColor;
dest.formatter = source.formatter ?? dest.formatter;
dest.paths = source.paths ?? dest.paths;
};
15 changes: 14 additions & 1 deletion src/plugins/weekends/weekends.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,28 @@ import type Yagr from '../../index';
export interface WeekendsPluginOptions {
color?: string;
predicate?: (timestamp: number) => boolean;
label?: string;
}

const DEFAULT_WEEKEND_COLOR = 'rgb(250, 255, 0, 0.38)';


declare module '../../types' {
interface PBandConfig {
label?: string;
}

interface PLineConfig {
label?: string;
}
}

/**
* This plugin highlights weekend ranges using native PlotLines plugin
*/
export default function WeekendsPlugin({
color = DEFAULT_WEEKEND_COLOR,
label,
predicate,
}: WeekendsPluginOptions = {}): YagrPlugin {
return (yagr: Yagr) => {
Expand Down Expand Up @@ -46,7 +59,7 @@ export default function WeekendsPlugin({
scale: 'x',
value: val,
color,
label: 'Weekend',
label: label ?? yagr.utils.i18n('weekend')
})),
);

Expand Down
19 changes: 19 additions & 0 deletions tests/units/plugins/plotlines.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {PlotLineConfig} from '../../../src';
import Yagr from '../../../src/YagrCore';

const DEFAULT_CONFIG = {
Expand Down Expand Up @@ -64,5 +65,23 @@ describe('plotlines', () => {
y.plugins.plotLines?.clear();
expect(y.plugins.plotLines?.get()).toEqual([]);
});

it('should add and remove plotLines', () => {
const pl: PlotLineConfig[] = [{value: [1, 2], color: 'green', scale: 'y', id: '1'}];
y.plugins.plotLines?.add(pl);
expect(y.plugins.plotLines?.get()).toEqual(pl);
y.plugins.plotLines?.remove(pl);
expect(y.plugins.plotLines?.get()).toEqual([]);
});

it('should update plotLines', () => {
const pl: PlotLineConfig[] = [{value: [1, 2], color: 'green', scale: 'y', id: '1'}];
y.plugins.plotLines?.add(pl);
expect(y.plugins.plotLines?.get()).toEqual(pl);

const pl2: PlotLineConfig[] = [{value: [1, 2], color: 'green', scale: 'y', id: '2'}];
y.plugins.plotLines?.update(pl2);
expect(y.plugins.plotLines?.get()).toEqual(pl2);
});
});
});
Loading

0 comments on commit 1f0a046

Please sign in to comment.