Compare commits

..

1 Commits

Author SHA1 Message Date
glitch4347 817b25d575 core 0.6.24 8 months ago
  1. 61
      examples/demo.html
  2. 55
      examples/demo_annotation.html
  3. 57
      examples/demo_discrete.html
  4. 57
      examples/demo_formatters.html
  5. 56
      examples/demo_non_discrete.html
  6. 4
      package.json
  7. 380
      src/index.ts
  8. 69
      src/models/bar_annotation.ts
  9. 183
      src/models/bar_group.ts
  10. 99
      src/models/bar_options.ts
  11. 24
      src/models/bar_series.ts
  12. 46
      src/models/bar_state.ts
  13. 143
      src/models/data_processor.ts
  14. 102
      src/types.ts
  15. 356
      yarn.lock

61
examples/demo.html

@ -1,61 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<script src="../dist/index.dev.js" type="text/javascript"></script>
</head>
<body>
<div id="chart" style="width: 50%; height: 500px;"></div>
<script type="text/javascript">
var pod = new ChartwerkBarPod(
document.getElementById('chart'),
[
{ target: 'test11', datapoints: getData(), matchedKey: 'm-1', color: 'red', colorFormatter: (data) => ['green', 'yellow'][data.rowIndex] },
// { target: 'test12', datapoints: [[100, 10], [200, 20], [300, 10]], matchedKey: 'm-1', color: 'green' },
// { target: 'test21', datapoints: [[130, 10], [230, 26], [330, 15]], matchedKey: 'm-2', color: 'yellow'},
// { target: 'test22', datapoints: [[130, 10], [230, 27], [330, 10]], matchedKey: 'm-2', color: 'blue' },
],
{
usePanning: false,
axis: {
x: { format: 'custom', invert: false, valueFormatter: (value) => { return 'L' + value; } },
y: { format: 'custom', invert: false, range: [0, 30], valueFormatter: (value) => { return value + '%'; } }
},
stacked: false,
matching: false,
maxBarWidth: 20,
minBarWidth: 4,
zoomEvents: {
scroll: { zoom: { isActive: false }, pan: { isActive: false } },
},
annotations: [
{ key: 'm-1', color: 'red' },
{ key: 'm-2', color: 'green' }
],
eventsCallbacks: {
zoomIn: (range) => { console.log('range', range) }
},
renderLegend: false,
}
);
console.time('render');
pod.render();
console.timeEnd('render');
function getData() {
return [
[100, 15], [200, 20], [300, 10],
];
}
</script>
</body>
</html>
<style>
.overlay {
fill: black;
}
</style>

55
examples/demo_annotation.html

@ -0,0 +1,55 @@
<!DOCTYPE html>
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<script src="../dist/index.dev.js" type="text/javascript"></script>
</head>
<body>
<div id="chart" style="width: 50%; height: 500px;"></div>
<script type="text/javascript">
var pod = new ChartwerkBarPod(
document.getElementById('chart'),
[
{ target: 'serie1', datapoints: [[100, 10, 20, 5], [180, 15, 30, 5], [300, 20, 35, 15]], color: ['red', 'pink', 'blue'], annotation: { enable: true, color: 'green'} },
{ target: 'serie2', datapoints: [[150, 10, 10], [220, 20, 15], [330, 30, 5]], color: ['green', 'yellow'], annotation: { enable: true, color: 'black' } },
],
{
usePanning: false,
axis: {
x: { format: 'custom', invert: false, valueFormatter: (value) => { return 'L' + value; }, ticksCount: 6, range: [50, 380] },
y: { format: 'custom', invert: false, valueFormatter: (value) => { return value + '%'; }, ticksCount: 8 }
},
zoomEvents: {
scroll: { zoom: { isActive: false }, pan: { isActive: false } },
},
eventsCallbacks: {
zoomIn: (range) => { console.log('range', range) }
},
renderLegend: false,
type: {
['non-discrete']: {
enable: true,
barWidth: {
estimated: { value: 35, type: 'unit' },
max: 30,
min: 10,
}
}
}
}
);
console.time('render');
pod.render();
console.timeEnd('render');
</script>
</body>
</html>
<style>
.overlay {
fill: none;
}
</style>

57
examples/demo_discrete.html

@ -0,0 +1,57 @@
<!DOCTYPE html>
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<script src="../dist/index.dev.js" type="text/javascript"></script>
</head>
<body>
<div id="chart" style="width: 50%; height: 500px;"></div>
<script type="text/javascript">
var pod = new ChartwerkBarPod(
document.getElementById('chart'),
[
{ target: 'serie1', datapoints: [[100, 10, 20, 5], [200, 15, 30, 5], [300, 20, 35, 15]], color: ['red', 'pink', 'blue'] },
{ target: 'serie2', datapoints: [[100, 10, 10], [200, 20, 15], [300, 30, 5]], color: ['green', 'yellow'] },
{ target: 'serie3', datapoints: [[100, -10, 5], [200, -5, -5], [300, -20, 15]], color: ['red', 'pink', 'blue'] },
{ target: 'serie4', datapoints: [[100, 10, 10], [200, 20, 15], [300, 30, 5]], color: ['green', 'yellow'] },
],
{
usePanning: false,
axis: {
x: { format: 'custom', invert: false, valueFormatter: (value) => { return 'L' + value; }, ticksCount: 6 },
y: { format: 'custom', invert: false, valueFormatter: (value) => { return value + '%'; }, ticksCount: 8 }
},
zoomEvents: {
scroll: { zoom: { isActive: false }, pan: { isActive: false } },
},
eventsCallbacks: {
zoomIn: (range) => { console.log('range', range) }
},
renderLegend: false,
// discrete type config
type: {
discrete: {
enable: true,
step: 100,
groupSize: {
width: { value: 60, type: 'percent', }
}
}
}
}
);
console.time('render');
pod.render();
console.timeEnd('render');
</script>
</body>
</html>
<style>
.overlay {
fill: none;
}
</style>

57
examples/demo_formatters.html

@ -0,0 +1,57 @@
<!DOCTYPE html>
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<script src="../dist/index.dev.js" type="text/javascript"></script>
</head>
<body>
<div id="chart" style="width: 50%; height: 500px;"></div>
<script type="text/javascript">
// use formatters for color and opacity
const colorFormatter = (event) => (event.value > 50 ? 'red' : 'green');
const opacityFormatter = (event) => (event.key >= 200 ? 0.5 : 1);
var pod = new ChartwerkBarPod(
document.getElementById('chart'),
[
{ target: 'serie1', datapoints: [[0, 50], [100, 70], [200, 40], [300, 90]], color: colorFormatter, opacity: opacityFormatter },
],
{
usePanning: false,
axis: {
x: { format: 'custom', invert: false, valueFormatter: (value) => { return 'L' + value; }, ticksCount: 6 },
y: { format: 'custom', invert: false, valueFormatter: (value) => { return value + '%'; }, ticksCount: 8 }
},
zoomEvents: {
scroll: { zoom: { isActive: false }, pan: { isActive: false } },
},
eventsCallbacks: {
zoomIn: (range) => { console.log('range', range) }
},
renderLegend: false,
type: {
discrete: {
enable: true,
step: 100,
groupSize: {
width: { value: 60, type: 'percent', }
}
}
}
}
);
console.time('render');
pod.render();
console.timeEnd('render');
</script>
</body>
</html>
<style>
.overlay {
fill: none;
}
</style>

56
examples/demo_non_discrete.html

@ -0,0 +1,56 @@
<!DOCTYPE html>
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<script src="../dist/index.dev.js" type="text/javascript"></script>
</head>
<body>
<div id="chart" style="width: 50%; height: 500px;"></div>
<script type="text/javascript">
var pod = new ChartwerkBarPod(
document.getElementById('chart'),
[
{ target: 'serie1', datapoints: [[100, 10, 20, 5], [180, 15, 30, 5], [300, 20, 35, 15]], color: ['red', 'pink', 'blue'] },
{ target: 'serie2', datapoints: [[150, 10, 10], [220, 20, 15], [330, 30, 5]], color: ['green', 'yellow'] },
],
{
usePanning: false,
axis: {
x: { format: 'custom', invert: false, valueFormatter: (value) => { return 'L' + value; }, ticksCount: 6, range: [50, 380] },
y: { format: 'custom', invert: false, valueFormatter: (value) => { return value + '%'; }, ticksCount: 8 }
},
zoomEvents: {
scroll: { zoom: { isActive: false }, pan: { isActive: false } },
},
eventsCallbacks: {
zoomIn: (range) => { console.log('range', range) }
},
renderLegend: false,
// non_discrete type config
type: {
['non-discrete']: {
enable: true,
barWidth: {
estimated: { value: 35, type: 'unit' },
max: 30,
min: 10,
}
}
}
}
);
console.time('render');
pod.render();
console.timeEnd('render');
</script>
</body>
</html>
<style>
.overlay {
fill: none;
}
</style>

4
package.json

@ -1,6 +1,6 @@
{
"name": "@chartwerk/bar-pod",
"version": "0.8.1",
"version": "0.7.2",
"description": "Chartwerk bar pod",
"main": "dist/index.js",
"files": [
@ -19,7 +19,7 @@
"author": "CorpGlory",
"license": "Apache-2.0",
"dependencies": {
"@chartwerk/core": "latest"
"@chartwerk/core": "0.6.24"
},
"devDependencies": {
"css-loader": "^6.8.1",

380
src/index.ts

@ -2,17 +2,26 @@ import { ChartwerkPod, VueChartwerkPodMixin, TimeFormat, AxisFormat } from '@cha
import { BarConfig } from './models/bar_options';
import { BarSeries } from './models/bar_series';
import { BarAnnotation } from './models/bar_annotation';
import { DataProcessor, DataRow, DataItem } from './models/data_processor';
import { BarGroup } from './models/bar_group';
import { setBarScaleY, setBarScaleX } from './models/bar_state';
import {
BarSerie, BarOptions, DiscreteConfig, NonDiscreteConfig,
BarPodType, SizeType, CallbackEvent, Color, Opacity,
BarData, ColorFormatter, OpacityFormatter,
Datapoint, ValueX, ValueY,
} from './types';
import { BarSerie, BarOptions, RowValues } from './types';
import { findClosest } from './utils';
import * as d3 from 'd3';
import * as _ from 'lodash';
export class ChartwerkBarPod extends ChartwerkPod<BarSerie, BarOptions> {
barYScale: null | d3.ScaleLinear<number, number> = null;
_seriesDataForRendring = [];
dataProcessor: DataProcessor;
series: BarSeries;
options: BarConfig;
@ -20,6 +29,10 @@ export class ChartwerkBarPod extends ChartwerkPod<BarSerie, BarOptions> {
super(el, _series, _options);
this.series = new BarSeries(_series);
this.options = new BarConfig(_options);
this.dataProcessor = new DataProcessor(this.series.visibleSeries, this.options);
setBarScaleY(this.state, this.dataProcessor.dataRows, this.options);
setBarScaleX(this.state, this.dataProcessor.dataRows, this.options);
}
protected renderMetrics(): void {
@ -27,188 +40,33 @@ export class ChartwerkBarPod extends ChartwerkPod<BarSerie, BarOptions> {
this.renderNoDataPointsMessage();
return;
}
this.setBarPodScales();
this.setSeriesDataForRendering();
this.renderSerie(this._seriesDataForRendring);
}
get isMatchingDisabled(): boolean {
return this.options.barOptions.matching === false || this.seriesUniqKeys.length === 0;
}
setSeriesDataForRendering(): void {
if(this.isMatchingDisabled) {
this._seriesDataForRendring = this.getZippedDataForRender(this.series.visibleSeries);
} else {
const matchedSeries = this.seriesForMatching.map(
(series: BarSerie[], idx: number) => this.getZippedDataForRender(series)
this.dataProcessor.dataRows.forEach((dataRow: DataRow) => {
const barGroup = new BarGroup(
this.overlay, this.metricContainer,
dataRow, this.options, this.state,
{ width: this.width, height: this.height, zeroHorizon: this.state.yScale(0) },
this.dataProcessor.dataRows.length
);
this._seriesDataForRendring = this.mergeMacthedSeriesAndSort(matchedSeries);
}
}
setBarPodScales(): void {
// TODO: its a hack to avoid infinite scale function recalling
// It should be fixed by implenting BarState
this.barYScale = this.getYScale();
}
renderSerie(data: any): void {
this.metricContainer.selectAll(`.rects-container`)
.data(data)
.enter().append('g')
.attr('class', 'rects-container')
.each((d: RowValues, rowIndex: number, nodes: any) => {
const container = d3.select(nodes[rowIndex]);
container.selectAll('rect')
.data(d.values)
.enter().append('rect')
.style('fill', (val, idx) => this.getBarColor(d, val, idx, rowIndex))
.attr('opacity', () => this.getBarOpacity(d))
.attr('x', (val: number, idx: number) => {
return this.getBarPositionX(d.key, idx);
})
.attr('y', (val: number, idx: number) => {
return this.getBarPositionY(val, idx, d.values);
})
.attr('width', this.barWidth)
.attr('height', (val: number) => this.getBarHeight(val))
.on('contextmenu', this.contextMenu.bind(this))
.on('mouseover', this.redirectEventToOverlay.bind(this))
.on('mousemove', this.redirectEventToOverlay.bind(this))
.on('mouseout', this.redirectEventToOverlay.bind(this))
.on('mousedown', () => { d3.event.stopPropagation(); });
// render bar annotations, its all hardcoded
if(_.isEmpty(this.options.barOptions.annotations)) {
return;
}
// find all series for single matchedKey
const series = _.filter(this.series.visibleSeries, serie => _.includes(d.serieTarget, serie.target));
const matchedKeys = _.map(series, serie => serie.matchedKey); // here matchedKeys should be equal
const key = matchedKeys[0];
const lastRect = _.last(container.selectAll('rect')?.nodes());
const annotation = _.find(this.options.barOptions.annotations, a => a.key === key);
if(!lastRect || !key || !annotation) {
return;
}
const rectSelection = d3.select(lastRect);
// render triangle
container.append('path')
.attr('d', () => {
const x = Math.ceil(_.toNumber(rectSelection.attr('x')));
const y = Math.ceil(_.toNumber(rectSelection.attr('y')));
const options = { max: this.options.barOptions.maxAnnotationSize, min: this.options.barOptions.minAnnotationSize };
return this.getTrianglePath(x, y, this.barWidth, options);
})
.attr('fill', annotation.color)
.on('mouseover', this.redirectEventToOverlay.bind(this))
.on('mousemove', this.redirectEventToOverlay.bind(this))
.on('mouseout', this.redirectEventToOverlay.bind(this))
.on('mousedown', () => { d3.event.stopPropagation(); });
});
}
redirectEventToOverlay(): void {
this.overlay?.node().dispatchEvent(new MouseEvent(d3.event.type, d3.event));
}
getTrianglePath(x: number, y: number, length: number, options?: { max: number, min: number }): string {
// (x, y) - top left corner of bar
const minTriangleSize = options?.min || 6;
const maxTriagleSize = options?.max || 10;
const yOffset = 4; // offset between triangle and bar
const centerX = x + length / 2;
const correctedLength = _.clamp(length, minTriangleSize, maxTriagleSize);
const topY = Math.max(y - correctedLength - yOffset, 4);
const topLeftCorner = {
x: centerX - correctedLength / 2,
y: topY,
};
const topRightCorner = {
x: centerX + correctedLength / 2,
y: topY,
};
const bottomMiddleCorner = {
x: centerX,
y: topY + correctedLength,
};
return `M ${topLeftCorner.x} ${topLeftCorner.y}
L ${topRightCorner.x} ${topRightCorner.y}
L ${bottomMiddleCorner.x} ${bottomMiddleCorner.y} z`;
}
getBarOpacity(rowValues: RowValues): number {
if(this.options.barOptions.opacityFormatter === undefined) {
return 1;
}
return this.options.barOptions.opacityFormatter(rowValues);
}
getBarColor(rowValues: RowValues, val: number, i: number, rowIndex: number): string {
if(_.isFunction(rowValues.colors[i])) {
return (rowValues.colors[i] as Function)({ rowData: rowValues, val, stackedIndex: i, rowIndex });
}
return (rowValues.colors[i] as string);
}
mergeMacthedSeriesAndSort(matchedSeries: any[]) {
// TODO: refactor
if(matchedSeries.length === 0) {
throw new Error('Cant mergeMacthedSeriesAndSort');
}
if(matchedSeries.length === 1) {
return matchedSeries[0];
}
let unionSeries = _.clone(matchedSeries[0]);
for(let i = 1; i < matchedSeries.length; i++){
unionSeries = [...unionSeries, ...matchedSeries[i]];
}
const sortedSeries = _.sortBy(unionSeries, ['key']);
return sortedSeries;
}
get seriesUniqKeys(): string[] {
if(!this.series.isSeriesAvailable) {
return [];
}
const keys = this.series.visibleSeries.map(serie => serie.matchedKey);
const uniqKeys = _.uniq(keys);
const filteredKeys = _.filter(uniqKeys, key => key !== undefined);
return filteredKeys;
}
get seriesForMatching(): BarSerie[][] {
if(this.seriesUniqKeys.length === 0) {
return [this.series.visibleSeries];
}
const seriesList = this.seriesUniqKeys.map(key => {
const seriesWithKey = _.filter(this.series.visibleSeries, serie => serie.matchedKey === key);
return seriesWithKey;
this.renderAnnotationForGroup(barGroup, dataRow);
});
return seriesList;
}
getZippedDataForRender(series: BarSerie[]): RowValues[] {
if(series.length === 0) {
throw new Error('There is no visible series');
renderAnnotationForGroup(barGroup: BarGroup, dataRow: DataRow): void {
if(this.options.barType === BarPodType.DISCRETE) {
return;
}
const keysColumn = _.map(series[0].datapoints, row => row[0]);
const valuesColumns = _.map(series, serie => _.map(serie.datapoints, row => row[1]));
// @ts-ignore
const additionalValuesColumns = _.map(series, serie => _.map(serie.datapoints, row => row[2] !== undefined ? row[2] : null));
const zippedAdditionalValuesColumn = _.zip(...additionalValuesColumns);
const zippedValuesColumn = _.zip(...valuesColumns);
const colors = _.map(series, serie => serie.colorFormatter || serie.color);
const tagrets = _.map(series, serie => serie.target);
const zippedData = _.zip(keysColumn, zippedValuesColumn, zippedAdditionalValuesColumn, tagrets);
const data = _.map(zippedData, row => { return { key: row[0], values: row[1], additionalValues: row[2], colors, serieTarget: tagrets } });
return data.filter(v => v.key !== undefined);
const target = _.first(dataRow.items).target;
const serie = this.series.getSerieByTarget(target);
if(!serie.annotation?.enable) {
return;
}
const annotationOptions = {
size: barGroup.getGroupWidth(),
max: serie.annotation.size.max,
min: serie.annotation.size.min,
color: serie.annotation.color,
};
new BarAnnotation(this.overlay, barGroup.getGroupContainer(), annotationOptions);
}
public renderSharedCrosshair(values: { x?: number, y?: number }): void {
@ -231,28 +89,39 @@ export class ChartwerkBarPod extends ChartwerkPod<BarSerie, BarOptions> {
this.crosshair.select('#crosshair-line-x')
.attr('x1', eventX)
.attr('x2', eventX);
const series = this.getSeriesPointFromMousePosition(eventX);
const dataRow = this.getDataRowFromMousePosition(eventX);
this.options.callbackMouseMove({
x: d3.event.pageX,
y: d3.event.pageY,
time: this.state.xScale.invert(eventX),
series,
chartX: eventX,
chartWidth: this.width
position: {
eventX: event[0],
eventY: event[1],
pageX: d3.event.pageX,
pageY: d3.event.pageY,
valueX: this.state.xScale.invert(event[0]),
valueY: this.state.yScale.invert(event[1]),
},
data: dataRow,
});
}
getSeriesPointFromMousePosition(eventX: number): any[] | undefined {
getDataRowFromMousePosition(eventX: number): DataRow | undefined {
if(!this.series.isSeriesAvailable) {
return undefined;
}
const mousePoisitionKey = Math.ceil(this.state.xScale.invert(eventX));
const keys = _.map(this._seriesDataForRendring, el => el.key);
const idx = findClosest(keys, mousePoisitionKey);
return this._seriesDataForRendring[idx];
const mousePositionKey = this.state.xScale.invert(eventX);
const keys = _.map(this.dataProcessor.dataRows, (dataRow: DataRow) => dataRow.key);
let idx: number;
switch(this.options.barType) {
case BarPodType.DISCRETE:
idx = Math.floor(mousePositionKey);
break;
case BarPodType.NON_DISCRETE:
idx = findClosest(keys, mousePositionKey);
break;
default:
break;
}
return this.dataProcessor.dataRows[idx];
}
onMouseOver(): void {
@ -264,121 +133,6 @@ export class ChartwerkBarPod extends ChartwerkPod<BarSerie, BarOptions> {
this.options.callbackMouseOut();
this.crosshair.style('display', 'none');
}
contextMenu(): void {
// maybe it is not the best name, but i took it from d3.
d3.event.preventDefault(); // do not open browser's context menu.
const event = d3.mouse(this.chartContainer.node());
const eventX = event[0];
const series = this.getSeriesPointFromMousePosition(eventX);
this.options.callbackContextMenu({
pageX: d3.event.pageX,
pageY: d3.event.pageY,
xVal: this.state.xScale.invert(eventX),
series,
chartX: eventX
});
}
get barWidth(): number {
const xAxisStartValue = _.first(this.series.visibleSeries[0].datapoints)[0];
const xAxisEndValue = _.last(this.series.visibleSeries[0].datapoints)[0];
const timeInterval = (xAxisEndValue - xAxisStartValue) / this.series.visibleSeries[0].datapoints.length;
let width = this.state.xScale(timeInterval) / 2;
if(this.options.barOptions.barWidth !== undefined) {
// barWidth now has axis-x dimension
width = this.state.xScale(this.state.getMinValueX() + this.options.barOptions.barWidth);
}
let rectColumns = this.series.visibleSeries.length;
if(this.options.barOptions.stacked === true) {
rectColumns = 1;
}
return this.updateBarWidthWithBorders(width / rectColumns);
}
updateBarWidthWithBorders(width: number): number {
let barWidth = width;
if(this.options.barOptions.minBarWidth !== undefined) {
barWidth = Math.max(barWidth, this.options.barOptions.minBarWidth);
}
if(this.options.barOptions.maxBarWidth !== undefined) {
barWidth = Math.min(barWidth, this.options.barOptions.maxBarWidth);
}
return barWidth;
}
getBarHeight(value: number): number {
// TODO: Property 'sign' does not exist on type 'Math'
// @ts-ignore
const height = Math.sign(value) * (this.barYScale(0) - this.barYScale(value));
return height;
}
getBarPositionX(key: number, idx: number): number {
let xPosition: number = this.state.xScale(key);
if(this.options.barOptions.stacked === false) {
xPosition += idx * this.barWidth;
}
return xPosition;
}
getBarPositionY(val: number, idx: number, values: number[]): number {
let yPosition: number = this.barYScale(Math.max(val, 0));
if(this.options.barOptions.stacked === true) {
const previousBarsHeight = _.sum(
_.map(_.range(idx), i => this.getBarHeight(values[i]))
);
yPosition -= previousBarsHeight;
}
return yPosition;
}
getYScale(): d3.ScaleLinear<number, number> {
if(
this.state.getMinValueY() === undefined ||
this.state.getMaxValueY() === undefined
) {
return d3.scaleLinear()
.domain([1, 0])
.range([0, this.height]);
}
const yMaxValue = this.getYMaxValue();
return d3.scaleLinear()
.domain([yMaxValue, Math.min(this.state.getMinValueY(), 0)])
.range([0, this.height]);
}
getYMaxValue(): number | undefined {
if(!this.series.isSeriesAvailable) {
return undefined;
}
if(this.options.axis.y.range) {
return _.max(this.options.axis.y.range);
}
let maxValue: number;
if(this.options.barOptions.stacked === true) {
if(this.options.barOptions.matching === true && this.seriesUniqKeys.length > 0) {
const maxValues = this.seriesForMatching.map(series => {
const valuesColumns = _.map(series, serie => _.map(serie.datapoints, row => row[1]));
const zippedValuesColumn = _.zip(...valuesColumns);
return maxValue = _.max(_.map(zippedValuesColumn, row => _.sum(row)));
});
return _.max(maxValues);
} else {
const valuesColumns = _.map(this.series.visibleSeries, serie => _.map(serie.datapoints, row => row[1]));
const zippedValuesColumn = _.zip(...valuesColumns);
maxValue = _.max(_.map(zippedValuesColumn, row => _.sum(row)));
}
} else {
maxValue = _.max(
this.series.visibleSeries.map(
serie => _.maxBy<number[]>(serie.datapoints, dp => dp[1])[0]
)
);
}
return Math.max(maxValue, 0);
}
}
// it is used with Vue.component, e.g.: Vue.component('chartwerk-bar-chart', VueChartwerkBarChartObject)
@ -404,4 +158,10 @@ export const VueChartwerkBarChartObject = {
}
};
export { BarSerie, BarOptions, TimeFormat, AxisFormat };
export {
BarSerie, BarOptions, TimeFormat, AxisFormat,
DiscreteConfig, NonDiscreteConfig,
BarPodType, SizeType, CallbackEvent, Color, Opacity,
BarData, ColorFormatter, OpacityFormatter,
Datapoint, ValueX, ValueY, DataItem, DataRow,
};

69
src/models/bar_annotation.ts

@ -0,0 +1,69 @@
import * as d3 from 'd3';
import * as _ from 'lodash';
const DEFAULT_ANNOTATION_OFFSET_Y = 4; //offset between triangle and bar in px
const DEFAULT_ANNOTATION_COLOR = 'red';
export class BarAnnotation {
position: { x: number, y: number };
constructor(
protected overlay: d3.Selection<SVGRectElement, unknown, null, undefined>, // overlay from core. It should be global
protected groupContainer: d3.Selection<SVGGElement, unknown, null, undefined>, // group - bars as one item
protected annotationOptions: { size: number, max?: number, min?: number, offset?: number, color?: string },
) {
this.position = this.getGroupLastRectPosition();
this.renderAnnotation();
}
protected renderAnnotation(): void {
this.groupContainer.append('path')
.attr('d', () => this.getTrianglePath())
.attr('fill', this.annotationOptions.color || DEFAULT_ANNOTATION_COLOR)
.on('mouseover', this.redirectEventToOverlay.bind(this))
.on('mousemove', this.redirectEventToOverlay.bind(this))
.on('mouseout', this.redirectEventToOverlay.bind(this))
.on('mousedown', () => { d3.event.stopPropagation(); });
}
getGroupLastRectPosition(): { x: number, y: number } {
const lastRect = _.last(this.groupContainer.selectAll('rect')?.nodes());
const barSelection = d3.select(lastRect);
return {
x: Math.ceil(_.toNumber(barSelection.attr('x'))),
y: Math.ceil(_.toNumber(barSelection.attr('y'))),
}
}
protected getTrianglePath(): string {
// (x, y) - top left corner of bar
const minTriangleSize = this.annotationOptions?.min;
const maxTriagleSize = this.annotationOptions?.max;
const yOffset = this.annotationOptions?.offset || DEFAULT_ANNOTATION_OFFSET_Y;
const centerX = this.position.x + this.annotationOptions.size / 2;
const correctedLength = _.clamp(this.annotationOptions.size, minTriangleSize, maxTriagleSize);
const topY = Math.max(this.position.y - correctedLength - yOffset, 4);
const topLeftCorner = {
x: centerX - correctedLength / 2,
y: topY,
};
const topRightCorner = {
x: centerX + correctedLength / 2,
y: topY,
};
const bottomMiddleCorner = {
x: centerX,
y: topY + correctedLength,
};
return `M ${topLeftCorner.x} ${topLeftCorner.y}
L ${topRightCorner.x} ${topRightCorner.y}
L ${bottomMiddleCorner.x} ${bottomMiddleCorner.y} z`;
}
redirectEventToOverlay(): void {
this.overlay?.node().dispatchEvent(new MouseEvent(d3.event.type, d3.event));
}
}

183
src/models/bar_group.ts

@ -0,0 +1,183 @@
import { DataRow, DataItem } from './data_processor';
import { BarConfig } from './bar_options';
import { PodState } from '@chartwerk/core';
import { BarOptions, BarPodType, BarSerie, SizeType } from '../types';
import * as d3 from 'd3';
import * as _ from 'lodash';
export class BarGroup {
constructor(
protected overlay: d3.Selection<SVGRectElement, unknown, null, undefined>, // overlay from core. It should be global
protected container: d3.Selection<SVGGElement, unknown, null, undefined>,
protected dataRow: DataRow,
protected options: BarConfig,
protected state: PodState<BarSerie, BarOptions>,
protected boxParams: { width: number, height: number, zeroHorizon: number },
protected allDataLength: number,
) {
this.setGroupWidth();
this.setBarWidth();
this.renderBarGroup();
}
protected _groupContainer: d3.Selection<SVGGElement, unknown, null, undefined>;
protected _groupWidth: number;
protected _barWidth: number;
public getGroupContainer(): d3.Selection<SVGGElement, unknown, null, undefined> {
return this._groupContainer;
}
public getGroupWidth(): number {
return this._groupWidth;
}
public getBarWidth(): number {
return this._barWidth;
}
protected renderBarGroup(): void {
this._groupContainer = this.container.append('g').attr('class', `bar-group group-${this.dataRow.key}`);
_.forEach(this.dataRow.items, (data: DataItem, serieIdx: number) => {
this.renderStackedBars(data, serieIdx);
});
}
protected renderStackedBars(data: DataItem, serieIdx: number): void {
const barsHeightPositiveList = [];
const barsHeightNegativeList = [];
data.values.forEach((value: number, valueIdx: number) => {
const barHeight = this.getBarHeight(value);
const config = {
position: {
x: this.getBarPositionX(serieIdx),
y: this.getBarPositionY(value, barsHeightPositiveList, barsHeightNegativeList, barHeight),
},
width: this._barWidth,
height: barHeight,
color: data.colors[valueIdx],
opacity: data.opacity[valueIdx],
value,
};
if(value >= 0) {
barsHeightPositiveList.push(barHeight);
} else {
barsHeightNegativeList.push(barHeight);
}
this.renderBar(config);
});
}
protected getBarPositionX(idx: number): number {
return this.state.xScale(this.dataRow.key) + this._barWidth * idx;
}
protected getBarPositionY(
value: number, barsHeightPositiveList: number[], barsHeightNegativeList: number[], barHeight: number
): number {
if(value >= 0) {
const previousBarsHeight = _.sum(barsHeightPositiveList);
return this.boxParams.zeroHorizon - previousBarsHeight - barHeight;
}
const previousBarsHeight = _.sum(barsHeightNegativeList);
return this.boxParams.zeroHorizon + previousBarsHeight;
}
protected getBarHeight(value): number {
return Math.abs(this.boxParams.zeroHorizon - this.state.yScale(value));
}
protected setGroupWidth(): void {
switch(this.options.barType) {
case BarPodType.DISCRETE:
this.setDiscreteGroupWidth();
return;
case BarPodType.NON_DISCRETE:
this.setNonDiscreteGroupWidth();
return;
}
}
protected setDiscreteGroupWidth(): void {
const groupSizeConfig = this.options.dicreteConfig.groupSize.width;
let width;
if(groupSizeConfig.type === SizeType.PX) {
width = groupSizeConfig.value;
}
if(groupSizeConfig.type === SizeType.PERCENT) {
const factor = groupSizeConfig.value / 100;
width = (this.boxParams.width / this.allDataLength) * factor;
}
this._groupWidth = _.clamp(width, this.options.dicreteConfig.groupSize.min || width, this.options.dicreteConfig.groupSize.max || width);
}
protected setNonDiscreteGroupWidth(): void {
const widthConfig = this.options.nonDicreteConfig.barWidth;
if(widthConfig.estimated.value === undefined) {
const groupWidth = this.boxParams.width / (this.allDataLength * this.dataRow.items.length);
this._groupWidth = groupWidth * 0.5;
return;
}
let width;
if(widthConfig.estimated.type === SizeType.PX) {
width = widthConfig.estimated.value;
}
if(widthConfig.estimated.type === SizeType.UNIT) {
width = this.state.absXScale(widthConfig.estimated.value);
}
this._groupWidth = _.clamp(width, widthConfig.min || width, widthConfig.max || width);
}
protected setBarWidth(): void {
switch(this.options.barType) {
case BarPodType.DISCRETE:
this._barWidth = this._groupWidth / this.dataRow.items.length;
return;
case BarPodType.NON_DISCRETE:
this._barWidth = this._groupWidth;
return;
}
}
protected renderBar(config: any): void {
this._groupContainer.append('rect')
.attr('x', config.position.x)
.attr('y', config.position.y)
.attr('width', config.width)
.attr('height', config.height)
.style('fill', config.color)
.attr('opacity', config.opacity)
.on('contextmenu', this.contextMenu.bind(this))
.on('mouseover', this.redirectEventToOverlay.bind(this))
.on('mousemove', this.redirectEventToOverlay.bind(this))
.on('mouseout', this.redirectEventToOverlay.bind(this))
.on('mousedown', () => { d3.event.stopPropagation(); });
}
contextMenu(): void {
d3.event.preventDefault(); // do not open browser's context menu.
const event = d3.mouse(this.container.node());
this.options.callbackContextMenu({
position: {
eventX: event[0],
eventY: event[1],
pageX: d3.event.pageX,
pageY: d3.event.pageY,
valueX: this.state.xScale.invert(event[0]),
valueY: this.state.yScale.invert(event[1]),
},
data: this.dataRow,
});
}
redirectEventToOverlay(): void {
this.overlay?.node().dispatchEvent(new MouseEvent(d3.event.type, d3.event));
}
}

99
src/models/bar_options.ts

@ -1,40 +1,66 @@
import { CoreOptions } from '@chartwerk/core';
import { BarOptions, BarAdditionalOptions } from '../types';
import { BarOptions, BarPodType, DiscreteConfig, NonDiscreteConfig, SizeType } from '../types';
import * as _ from 'lodash';
const DEFAULT_MIN_BAR_WIDTH = 4; //px
const BAR_SERIE_DEFAULTS = {
renderBarLabels: false,
stacked: false,
barWidth: undefined,
maxBarWidth: undefined,
minBarWidth: undefined,
maxAnnotationSize: undefined,
minAnnotationSize: undefined,
matching: false,
opacityFormatter: undefined,
annotations: [],
type: {
[BarPodType.DISCRETE]: {
enable: false,
step: undefined,
innerSize: undefined,
groupSize: {
width: { value: 50, type: (SizeType.PERCENT as SizeType.PERCENT) },
max: undefined,
min: DEFAULT_MIN_BAR_WIDTH,
}
},
[BarPodType.NON_DISCRETE]: {
enable: false,
barWidth: {
estimated: { value: undefined, type: (SizeType.UNIT as SizeType.UNIT) },
max: undefined,
min: DEFAULT_MIN_BAR_WIDTH,
}
},
},
};
export class BarConfig extends CoreOptions<BarOptions> {
constructor(options: BarOptions) {
super(options, BAR_SERIE_DEFAULTS);
this.validateOptions();
}
get barOptions(): any {
return {};
}
get barOptions(): BarAdditionalOptions {
return {
renderBarLabels: this._options.renderBarLabels,
stacked: this._options.stacked,
barWidth: this._options.barWidth,
maxBarWidth: this._options.maxBarWidth,
minBarWidth: this._options.minBarWidth,
maxAnnotationSize: this._options.maxAnnotationSize,
minAnnotationSize: this._options.minAnnotationSize,
matching: this._options.matching,
opacityFormatter: this._options.opacityFormatter,
annotations: this._options.annotations,
get dicreteConfig(): DiscreteConfig {
if(!this._options.type[BarPodType.DISCRETE]?.enable) {
throw new Error(`Can't get discrete config for non_dicreste type`);
}
return this._options.type[BarPodType.DISCRETE];
}
get nonDicreteConfig(): NonDiscreteConfig {
if(!this._options.type[BarPodType.NON_DISCRETE]?.enable) {
throw new Error(`Can't get non_discrete config for dicreste type`);
}
return this._options.type[BarPodType.NON_DISCRETE];
}
get barType(): BarPodType {
if(this._options.type[BarPodType.DISCRETE]?.enable === true) {
return BarPodType.DISCRETE;
}
if(this._options.type[BarPodType.NON_DISCRETE]?.enable === true) {
return BarPodType.NON_DISCRETE;
}
throw new Error(`Unknown Ber Pod Type: ${this._options.type}`);
}
// event callbacks
@ -47,4 +73,31 @@ export class BarConfig extends CoreOptions<BarOptions> {
get contextMenu(): (evt: any) => void {
return this._options.eventsCallbacks.contextMenu;
}
validateOptions(): void {
if(
this._options.type[BarPodType.DISCRETE]?.enable === true &&
this._options.type[BarPodType.NON_DISCRETE]?.enable === true
) {
throw new Error(`Bar Options is not valid: only one BarPodType should be enabled`);
}
if(
this._options.type[BarPodType.DISCRETE]?.enable === false &&
this._options.type[BarPodType.NON_DISCRETE]?.enable === false
) {
// @ts-ignore
this._options.type[BarPodType.DISCRETE]?.enable = true;
console.warn(`Bar Options: no type has been provided -> BarPodType.DISCRETE type will be used af default`);
}
}
validateDiscreteOptions(): void {
const groupType = this._options.type[BarPodType.DISCRETE].groupSize?.width?.type;
if(
groupType !== undefined &&
groupType !== SizeType.PERCENT && groupType !== SizeType.PX
) {
throw new Error(`Bar Options is not valid: groupSize.width.type should be "px" on "percent": ${groupType}`);
}
}
}

24
src/models/bar_series.ts

@ -1,10 +1,23 @@
import { CoreSeries } from '@chartwerk/core';
import { BarSerie } from '../types';
import { BarSerie, SizeType } from '../types';
import * as _ from 'lodash';
const DEFAULT_MIN_ANNOTATION_SIZE = 6; //px
const DEFAULT_MAX_ANNOTATION_SIZE = 10; //px
const BAR_SERIE_DEFAULTS = {
matchedKey: undefined,
colorFormatter: undefined
annotation: {
enable: false,
color: undefined,
size: {
esimated: { value: undefined, type: (SizeType.PERCENT as SizeType.PERCENT) },
max: DEFAULT_MAX_ANNOTATION_SIZE,
min: DEFAULT_MIN_ANNOTATION_SIZE,
}
},
color: undefined,
opacity: 1,
};
export class BarSeries extends CoreSeries<BarSerie> {
@ -12,4 +25,9 @@ export class BarSeries extends CoreSeries<BarSerie> {
constructor(series: BarSerie[]) {
super(series, BAR_SERIE_DEFAULTS);
}
// move to parent
public getSerieByTarget(target: string): BarSerie | undefined {
return _.find(this.visibleSeries, serie => serie.target === target);
}
}

46
src/models/bar_state.ts

@ -0,0 +1,46 @@
import { PodState } from '@chartwerk/core';
import { DataRow } from './data_processor';
import { BarConfig } from './bar_options';
import { BarOptions, BarSerie, BarPodType, DiscreteConfig } from '../types';
import * as _ from 'lodash';
// It is not a real bar state. Just rewrite some core params. like xScale/yScale
// TODO: import core scale and extend it, same to bar_series and bar_options
export function setBarScaleX(state: PodState<BarSerie, BarOptions>, dataRows: DataRow[], options: BarConfig): void {
switch(options.barType) {
case BarPodType.DISCRETE:
const config: DiscreteConfig = options.dicreteConfig;
let discreteStep = 0;
if(_.isNumber(config.step)) {
discreteStep = config.step;
} else {
if(!_.isEmpty(dataRows)) {
discreteStep = (_.last(dataRows).key - _.first(dataRows).key) / dataRows.length;
}
}
state.xValueRange = [state.xValueRange[0], state.xValueRange[1] + discreteStep];
return;
case BarPodType.NON_DISCRETE:
if(!_.isEmpty(options.axis.x.range)) {
return;
}
let nonDiscreteStep = 0;
if(!_.isEmpty(dataRows)) {
nonDiscreteStep = (_.last(dataRows).key - _.first(dataRows).key) / dataRows.length;
}
state.xValueRange = [state.xValueRange[0], state.xValueRange[1] + nonDiscreteStep];
return;
}
}
export function setBarScaleY(state: PodState<BarSerie, BarOptions>, dataRows: DataRow[], options: BarOptions): void {
if(!_.isEmpty(options.axis.y.range)) {
return;
}
const maxValue = _.max(_.map(dataRows, (dataRow: DataRow) => dataRow.maxSumm));
const minValue = _.min(_.map(dataRows, (dataRow: DataRow) => dataRow.minSubtraction));
state.yValueRange = [minValue, maxValue];
}

143
src/models/data_processor.ts

@ -0,0 +1,143 @@
import {
Datapoint, Color, ValueX, Opacity,
BarPodType, BarSerie
} from '../types';
import { BarConfig } from './bar_options';
import * as _ from 'lodash';
export type DataRow = {
key: number; // x
items: DataItem[];
maxSumm: number;
minSubtraction: number;
};
export type DataItem = {
target: string; // serie target
values: number[]; // y list
colors: string[];
opacity: number[];
};
const DEFAULT_BAR_COLOR = 'green';
const DEFAULT_OPACITY = 1;
export class DataProcessor {
_formattedDataRows: DataRow[] = [];
constructor(protected visibleSeries: BarSerie[], protected options: BarConfig) {
this.validateData();
switch(this.options.barType) {
case BarPodType.DISCRETE:
this.setDataRowsForDiscreteType();
break;
case BarPodType.NON_DISCRETE:
this.setDataRowsForNonDiscreteType();
break;
default:
throw new Error(`Bar DataProcessor: Unknown BarPodType ${this.options.barType}`);
}
}
public get dataRows(): DataRow[] {
return this._formattedDataRows;
}
protected setDataRowsForDiscreteType(): void {
const zippedData = _.zip(..._.map(this.visibleSeries, serie => serie.datapoints));
this._formattedDataRows = _.map(zippedData, (dataRow: Datapoint[], rowIdx: number) => {
return {
key: _.first(_.first(dataRow)), // x
items: _.map(dataRow, (datapoint: Datapoint, pointIdx: number) => {
const serie = this.visibleSeries[pointIdx];
const values = _.tail(datapoint);
return {
target: serie.target,
values, // y list
colors: this.getColorsForEachValue(values, serie.color, datapoint[0], serie.target),
opacity: this.getOpacityForEachValue(values, serie.opacity, datapoint[0], serie.target),
}
}),
maxSumm: _.max(_.map(dataRow, (datapoint: Datapoint) => this.getMaxSumm(_.tail(datapoint)))), // max y axis scale
minSubtraction: _.min(_.map(dataRow, (datapoint: Datapoint) => this.getMinSubtraction(_.tail(datapoint)))), // min y axis scale
}
});
}
protected setDataRowsForNonDiscreteType(): void {
for(let serie of this.visibleSeries) {
const rows = _.map(serie.datapoints, (datapoint: Datapoint) => {
const values = _.tail(datapoint);
return {
key: datapoint[0], // x
items: [
{
target: serie.target,
values, // y list
colors: this.getColorsForEachValue(values, serie.color, datapoint[0], serie.target),
opacity: this.getOpacityForEachValue(values, serie.opacity, datapoint[0], serie.target),
}
],
maxSumm: this.getMaxSumm(values), // max y axis scale
minSubtraction: this.getMinSubtraction(values), // min y axis scale
}
});
this._formattedDataRows = _.concat(this._formattedDataRows, rows);
}
this._formattedDataRows = _.sortBy(this._formattedDataRows, 'key');
}
getColorsForEachValue(values: number[], color: Color, key: ValueX, target: string): string[] {
if(_.isString(color)) {
return _.map(values, value => color);
}
if(_.isArray(color)) {
return _.map(values, (value, i) => color[i] || DEFAULT_BAR_COLOR);
}
if(_.isFunction(color)) {
return _.map(values, (value, i) => (color as Function)({ value, barIndex: i, key, target }));
}
throw new Error(`Unknown type of serie color: ${target} ${color}`);
}
getOpacityForEachValue(values: number[], opacity: Opacity | undefined, key: ValueX, target: string): number[] {
if(opacity === undefined) {
return _.map(values, value => DEFAULT_OPACITY);
}
if(_.isNumber(opacity)) {
return _.map(values, value => opacity);
}
if(_.isArray(opacity)) {
return _.map(values, (value, i) => !_.isNil(opacity[i]) ? opacity[i] : DEFAULT_OPACITY);
}
if(_.isFunction(opacity)) {
return _.map(values, (value, i) => (opacity as Function)({ value, barIndex: i, key, target }));
}
throw new Error(`Unknown type of serie opacity: ${target} ${opacity}`);
}
getMaxSumm(values: number[]): number {
return values.reduce((prev, curr) => curr > 0 ? prev + curr : prev, 0);
}
getMinSubtraction(values: number[]): number {
return values.reduce((prev, curr) => curr < 0 ? prev + curr : prev, 0);
}
validateData(): void {
if(this.options.barType === BarPodType.NON_DISCRETE) {
return;
}
// TODO: move non-empty datapoints validation to core
if(_.isEmpty(this.visibleSeries)) {
return;
}
const xValuesList = _.map(_.first(this.visibleSeries).datapoints, dp => dp[0]);
_.forEach(this.visibleSeries, serie => {
const serieXList = _.map(serie.datapoints, dp => dp[0]);
if(!_.isEqual(xValuesList, serieXList)) {
throw new Error(`Bar DataProcessor: All series should have equal X values lists`);
}
});
}
}

102
src/types.ts

@ -1,34 +1,84 @@
import { Serie, Options } from '@chartwerk/core';
import { DataRow } from 'models/data_processor';
export type BarSerieParams = {
matchedKey: string;
colorFormatter: (serie: BarSerie) => string;
export type ValueX = (number | string);
export type ValueY = number;
export type Datapoint = [ValueX, ...ValueY[]]; // [x, y, y, y, ..., y], multiple y values as stacked bars
export type BarData = { value: ValueY, key: ValueX, barIndex: number, target: string };
export type ColorFormatter = (data: BarData) => string;
export type OpacityFormatter = (data: BarData) => number;
export type Color = string | string[] | ColorFormatter;
export type Opacity = number | number[] | OpacityFormatter;
export type BarSerieAdditionalParams = {
datapoints: Datapoint[];
// TODO add absolute/stacked type for y values. datapoint can be [x: 0, y1: 10, y2: 20] (absolute) === [x: 0, y1: 10, y2: 10] (stacked)
annotation?: {
// only for non_discrete type for now
enable: boolean;
color?: string;
size?: {
esimated: { value: number, type?: SizeType.PERCENT | SizeType.PX };
max?: number; // type always SizeType.PX
min?: number; // type always SizeType.PX
}
};
color?: Color;
opacity?: Opacity;
}
export type BarSerie = Serie & BarSerieAdditionalParams;
export type CallbackEvent = {
position: {
eventX: number,
eventY: number,
pageX: number,
pageY: number,
valueX: number,
valueY: number,
},
data: DataRow,
}
export type BarSerie = Serie & Partial<BarSerieParams>;
export type BarAdditionalOptions = {
renderBarLabels?: boolean;
stacked?: boolean;
barWidth?: number; // width in x axis unit
maxBarWidth?: number; // in px
minBarWidth?: number; // in px
maxAnnotationSize?: number; // in px TODO: move to annotaions
minAnnotationSize?: number; // in px
matching?: boolean;
opacityFormatter?: (data: RowValues) => number;
annotations?: {
key: string, // matchedKey from series
// TODO: add enum with "triangle" option
color: string,
}[];
eventsCallbacks?: {
contextMenu?: (data: any) => void;
type: { // BarPodType.DISCRETE or BarPodType.NON_DISCRETE. Cant be both
[BarPodType.DISCRETE]: DiscreteConfig;
[BarPodType.NON_DISCRETE]: NonDiscreteConfig;
}
eventsCallbacks?: {
contextMenu?: (data: CallbackEvent) => void;
};
}
export type BarOptions = Options & Partial<BarAdditionalOptions>;
export type RowValues = {
key: number,
values: number[],
additionalValues: (null | number)[], // values in datapoints third column
colors: (string | ((data: any) => string))[],
serieTarget: string[],
export enum SizeType {
UNIT = 'unit', // in units of X or Y values
PX = 'px',
PERCENT = 'percent', // from 0 to 100
}
export enum BarPodType {
DISCRETE = 'discrete', // render bars as groups
NON_DISCRETE = 'non-discrete', // render bars as time chart
}
export type DiscreteConfig = {
// union bars as one group, see examples/demo-group-by.html
enable: boolean;
step?: number; // X axis interval between two bars, type always SizeType.UNIT
groupSize?: {
width: { value: number, type?: SizeType.PERCENT | SizeType.PX, },
max?: number, // type always SizeType.PX
min?: number, // type always SizeType.PX
// TODO: margin between bars
};
};
export type NonDiscreteConfig = {
enable: boolean;
barWidth?: {
estimated?: { value: number, type?: SizeType.UNIT | SizeType.PX };
max?: number; // type always SizeType.PX
min?: number; // type always SizeType.PX
}
};

356
yarn.lock

@ -9,7 +9,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@chartwerk/bar-pod@workspace:."
dependencies:
"@chartwerk/core": latest
"@chartwerk/core": 0.6.24
css-loader: ^6.8.1
style-loader: ^3.3.3
ts-loader: ^9.4.3
@ -19,13 +19,13 @@ __metadata:
languageName: unknown
linkType: soft
"@chartwerk/core@npm:latest":
version: 0.6.26
resolution: "@chartwerk/core@npm:0.6.26"
"@chartwerk/core@npm:0.6.24":
version: 0.6.24
resolution: "@chartwerk/core@npm:0.6.24"
dependencies:
d3: ^5.16.0
lodash: ^4.17.21
checksum: d77ef83701dc13cf2b7fb36dc96448060b6301928bcc0730a7150930f83c51f295e176bcda4e1b8cb8f56d15fef5696edfe6f4e1033adbb5ef5d3487a02c3390
checksum: 023b980169c0cf586d05ba8ac8668dc4674b19d3257552d6ad4b499fc55da79bba537d55e7a3ad1e0acbf6819c86f16619177e356bf771f3aaa56b30a1cc446c
languageName: node
linkType: hard
@ -47,10 +47,10 @@ __metadata:
languageName: node
linkType: hard
"@jridgewell/resolve-uri@npm:^3.1.0":
version: 3.1.1
resolution: "@jridgewell/resolve-uri@npm:3.1.1"
checksum: f5b441fe7900eab4f9155b3b93f9800a916257f4e8563afbcd3b5a5337b55e52bd8ae6735453b1b745457d9f6cdb16d74cd6220bbdd98cf153239e13f6cbb653
"@jridgewell/resolve-uri@npm:3.1.0":
version: 3.1.0
resolution: "@jridgewell/resolve-uri@npm:3.1.0"
checksum: b5ceaaf9a110fcb2780d1d8f8d4a0bfd216702f31c988d8042e5f8fbe353c55d9b0f55a1733afdc64806f8e79c485d2464680ac48a0d9fcadb9548ee6b81d267
languageName: node
linkType: hard
@ -62,72 +62,77 @@ __metadata:
linkType: hard
"@jridgewell/source-map@npm:^0.3.3":
version: 0.3.5
resolution: "@jridgewell/source-map@npm:0.3.5"
version: 0.3.3
resolution: "@jridgewell/source-map@npm:0.3.3"
dependencies:
"@jridgewell/gen-mapping": ^0.3.0
"@jridgewell/trace-mapping": ^0.3.9
checksum: 1ad4dec0bdafbade57920a50acec6634f88a0eb735851e0dda906fa9894e7f0549c492678aad1a10f8e144bfe87f238307bf2a914a1bc85b7781d345417e9f6f
checksum: ae1302146339667da5cd6541260ecbef46ae06819a60f88da8f58b3e64682f787c09359933d050dea5d2173ea7fa40f40dd4d4e7a8d325c5892cccd99aaf8959
languageName: node
linkType: hard
"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14":
"@jridgewell/sourcemap-codec@npm:1.4.14":
version: 1.4.14
resolution: "@jridgewell/sourcemap-codec@npm:1.4.14"
checksum: 61100637b6d173d3ba786a5dff019e1a74b1f394f323c1fee337ff390239f053b87266c7a948777f4b1ee68c01a8ad0ab61e5ff4abb5a012a0b091bec391ab97
languageName: node
linkType: hard
"@jridgewell/sourcemap-codec@npm:^1.4.10":
version: 1.4.15
resolution: "@jridgewell/sourcemap-codec@npm:1.4.15"
checksum: b881c7e503db3fc7f3c1f35a1dd2655a188cc51a3612d76efc8a6eb74728bef5606e6758ee77423e564092b4a518aba569bbb21c9bac5ab7a35b0c6ae7e344c8
languageName: node
linkType: hard
"@jridgewell/trace-mapping@npm:^0.3.20, @jridgewell/trace-mapping@npm:^0.3.9":
version: 0.3.22
resolution: "@jridgewell/trace-mapping@npm:0.3.22"
"@jridgewell/trace-mapping@npm:^0.3.17, @jridgewell/trace-mapping@npm:^0.3.9":
version: 0.3.18
resolution: "@jridgewell/trace-mapping@npm:0.3.18"
dependencies:
"@jridgewell/resolve-uri": ^3.1.0
"@jridgewell/sourcemap-codec": ^1.4.14
checksum: ac7dd2cfe0b479aa1b81776d40d789243131cc792dc8b6b6a028c70fcd6171958ae1a71bf67b618ffe3c0c3feead9870c095ee46a5e30319410d92976b28f498
"@jridgewell/resolve-uri": 3.1.0
"@jridgewell/sourcemap-codec": 1.4.14
checksum: 0572669f855260808c16fe8f78f5f1b4356463b11d3f2c7c0b5580c8ba1cbf4ae53efe9f627595830856e57dbac2325ac17eb0c3dd0ec42102e6f227cc289c02
languageName: node
linkType: hard
"@types/eslint-scope@npm:^3.7.3":
version: 3.7.7
resolution: "@types/eslint-scope@npm:3.7.7"
version: 3.7.4
resolution: "@types/eslint-scope@npm:3.7.4"
dependencies:
"@types/eslint": "*"
"@types/estree": "*"
checksum: e2889a124aaab0b89af1bab5959847c5bec09809209255de0e63b9f54c629a94781daa04adb66bffcdd742f5e25a17614fb933965093c0eea64aacda4309380e
checksum: ea6a9363e92f301cd3888194469f9ec9d0021fe0a397a97a6dd689e7545c75de0bd2153dfb13d3ab532853a278b6572c6f678ce846980669e41029d205653460
languageName: node
linkType: hard
"@types/eslint@npm:*":
version: 8.56.2
resolution: "@types/eslint@npm:8.56.2"
version: 8.40.2
resolution: "@types/eslint@npm:8.40.2"
dependencies:
"@types/estree": "*"
"@types/json-schema": "*"
checksum: 38e054971596f5c0413f66a62dc26b10e0a21ac46ceacb06fbf8cfb838d20820787209b17218b3916e4c23d990ff77cfdb482d655cac0e0d2b837d430fcc5db8
checksum: a4780e45e677e3af21c44a900846996cb6d9ae8f71d51940942a047163ae93a05444392c005f491ed46aa169f3b25f8be125ab42c5d8bdb571154bf62a7c828a
languageName: node
linkType: hard
"@types/estree@npm:*, @types/estree@npm:^1.0.5":
version: 1.0.5
resolution: "@types/estree@npm:1.0.5"
checksum: dd8b5bed28e6213b7acd0fb665a84e693554d850b0df423ac8076cc3ad5823a6bc26b0251d080bdc545af83179ede51dd3f6fa78cad2c46ed1f29624ddf3e41a
"@types/estree@npm:*, @types/estree@npm:^1.0.0":
version: 1.0.1
resolution: "@types/estree@npm:1.0.1"
checksum: e9aa175eacb797216fafce4d41e8202c7a75555bc55232dee0f9903d7171f8f19f0ae7d5191bb1a88cb90e65468be508c0df850a9fb81b4433b293a5a749899d
languageName: node
linkType: hard
"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.8":
version: 7.0.15
resolution: "@types/json-schema@npm:7.0.15"
checksum: 97ed0cb44d4070aecea772b7b2e2ed971e10c81ec87dd4ecc160322ffa55ff330dace1793489540e3e318d90942064bb697cc0f8989391797792d919737b3b98
version: 7.0.12
resolution: "@types/json-schema@npm:7.0.12"
checksum: 00239e97234eeb5ceefb0c1875d98ade6e922bfec39dd365ec6bd360b5c2f825e612ac4f6e5f1d13601b8b30f378f15e6faa805a3a732f4a1bbe61915163d293
languageName: node
linkType: hard
"@types/node@npm:*":
version: 20.11.17
resolution: "@types/node@npm:20.11.17"
dependencies:
undici-types: ~5.26.4
checksum: 59c0dde187120adc97da30063c86511664b24b50fe777abfe1f557c217d0a0b84a68aaab5ef8ac44f5c2986b3f9cd605a15fa6e4f31195e594da96bbe9617c20
version: 20.3.1
resolution: "@types/node@npm:20.3.1"
checksum: 63a393ab6d947be17320817b35d7277ef03728e231558166ed07ee30b09fd7c08861be4d746f10fdc63ca7912e8cd023939d4eab887ff6580ff704ff24ed810c
languageName: node
linkType: hard
@ -339,11 +344,11 @@ __metadata:
linkType: hard
"acorn@npm:^8.7.1, acorn@npm:^8.8.2":
version: 8.11.3
resolution: "acorn@npm:8.11.3"
version: 8.8.2
resolution: "acorn@npm:8.8.2"
bin:
acorn: bin/acorn
checksum: 76d8e7d559512566b43ab4aadc374f11f563f0a9e21626dd59cb2888444e9445923ae9f3699972767f18af61df89cd89f5eaaf772d1327b055b45cb829b4a88c
checksum: f790b99a1bf63ef160c967e23c46feea7787e531292bb827126334612c234ed489a0dc2c7ba33156416f0ffa8d25bf2b0fdb7f35c2ba60eb3e960572bece4001
languageName: node
linkType: hard
@ -386,17 +391,17 @@ __metadata:
languageName: node
linkType: hard
"browserslist@npm:^4.21.10":
version: 4.22.3
resolution: "browserslist@npm:4.22.3"
"browserslist@npm:^4.14.5":
version: 4.21.9
resolution: "browserslist@npm:4.21.9"
dependencies:
caniuse-lite: ^1.0.30001580
electron-to-chromium: ^1.4.648
node-releases: ^2.0.14
update-browserslist-db: ^1.0.13
caniuse-lite: ^1.0.30001503
electron-to-chromium: ^1.4.431
node-releases: ^2.0.12
update-browserslist-db: ^1.0.11
bin:
browserslist: cli.js
checksum: e62b17348e92143fe58181b02a6a97c4a98bd812d1dc9274673a54f73eec53dbed1c855ebf73e318ee00ee039f23c9a6d0e7629d24f3baef08c7a5b469742d57
checksum: 80d3820584e211484ad1b1a5cfdeca1dd00442f47be87e117e1dda34b628c87e18b81ae7986fa5977b3e6a03154f6d13cd763baa6b8bf5dd9dd19f4926603698
languageName: node
linkType: hard
@ -407,10 +412,10 @@ __metadata:
languageName: node
linkType: hard
"caniuse-lite@npm:^1.0.30001580":
version: 1.0.30001585
resolution: "caniuse-lite@npm:1.0.30001585"
checksum: c5994f0b5de857349ae0c157a3c61883e800ed154bbeab339aecf01a0a0fd24f67d23ebb48bc995c4c9cde2a281a51b682d1b14bbf2f832f6b2261119f450af4
"caniuse-lite@npm:^1.0.30001503":
version: 1.0.30001503
resolution: "caniuse-lite@npm:1.0.30001503"
checksum: cd5f0af37655ff71ec4ab3c49124d75e0b8b68de625d07ea80e9a82329e616b5203d5dad6865192653be9da50081c06878f081ab069dac0be35adf29aa1599cd
languageName: node
linkType: hard
@ -491,26 +496,20 @@ __metadata:
linkType: hard
"css-loader@npm:^6.8.1":
version: 6.10.0
resolution: "css-loader@npm:6.10.0"
version: 6.8.1
resolution: "css-loader@npm:6.8.1"
dependencies:
icss-utils: ^5.1.0
postcss: ^8.4.33
postcss: ^8.4.21
postcss-modules-extract-imports: ^3.0.0
postcss-modules-local-by-default: ^4.0.4
postcss-modules-scope: ^3.1.1
postcss-modules-local-by-default: ^4.0.3
postcss-modules-scope: ^3.0.0
postcss-modules-values: ^4.0.0
postcss-value-parser: ^4.2.0
semver: ^7.5.4
semver: ^7.3.8
peerDependencies:
"@rspack/core": 0.x || 1.x
webpack: ^5.0.0
peerDependenciesMeta:
"@rspack/core":
optional: true
webpack:
optional: true
checksum: ee3d62b5f7e4eb24281a22506431e920d07a45bd6ea627731ce583f3c6a846ab8b8b703bace599b9b35256b9e762f9f326d969abb72b69c7e6055eacf39074fd
checksum: 7c1784247bdbe76dc5c55fb1ac84f1d4177a74c47259942c9cfdb7a8e6baef11967a0bc85ac285f26bd26d5059decb848af8154a03fdb4f4894f41212f45eef3
languageName: node
linkType: hard
@ -845,10 +844,10 @@ __metadata:
languageName: node
linkType: hard
"electron-to-chromium@npm:^1.4.648":
version: 1.4.664
resolution: "electron-to-chromium@npm:1.4.664"
checksum: ffb3f0f797f0fe47dcf55f9e4a7dd409df40a0c9e11ced38d952f171ab79188a632fcccce101d876d171bbeb34c92754e4507d83b636c039e89b7acdb7646af7
"electron-to-chromium@npm:^1.4.431":
version: 1.4.431
resolution: "electron-to-chromium@npm:1.4.431"
checksum: 51b76599b1e8141ced50339e873fe961aa56369cd622fb8a26964c084722204866fadbde94219a432398dab1317a5afd79843ba97cdcd5819dfc98be0e47c0a1
languageName: node
linkType: hard
@ -863,25 +862,25 @@ __metadata:
linkType: hard
"envinfo@npm:^7.7.3":
version: 7.11.1
resolution: "envinfo@npm:7.11.1"
version: 7.8.1
resolution: "envinfo@npm:7.8.1"
bin:
envinfo: dist/cli.js
checksum: f3d38ab6bc62388466e86e2f5665f90f238ca349c81bb36b311d908cb5ca96650569b43b308c9dcb6725a222693f6c43a704794e74a68fb445ec5575a90ca05e
checksum: de736c98d6311c78523628ff127af138451b162e57af5293c1b984ca821d0aeb9c849537d2fde0434011bed33f6bca5310ca2aab8a51a3f28fc719e89045d648
languageName: node
linkType: hard
"es-module-lexer@npm:^1.2.1":
version: 1.4.1
resolution: "es-module-lexer@npm:1.4.1"
checksum: a11b5a256d4e8e9c7d94c2fd87415ccd1591617b6edd847e064503f8eaece2d25e2e9078a02c5ce3ed5e83bb748f5b4820efbe78072c8beb07ac619c2edec35d
version: 1.3.0
resolution: "es-module-lexer@npm:1.3.0"
checksum: 48fd9f504a9d2a894126f75c8b7ccc6273a289983e9b67255f165bfd9ae765d50100218251e94e702ca567826905ea2f7b3b4a0c4d74d3ce99cce3a2a606a238
languageName: node
linkType: hard
"escalade@npm:^3.1.1":
version: 3.1.2
resolution: "escalade@npm:3.1.2"
checksum: 1ec0977aa2772075493002bdbd549d595ff6e9393b1cb0d7d6fcaf78c750da0c158f180938365486f75cb69fba20294351caddfce1b46552a7b6c3cde52eaa02
version: 3.1.1
resolution: "escalade@npm:3.1.1"
checksum: a3e2a99f07acb74b3ad4989c48ca0c3140f69f923e56d0cba0526240ee470b91010f9d39001f2a4a313841d237ede70a729e92125191ba5d21e74b106800b133
languageName: node
linkType: hard
@ -965,19 +964,10 @@ __metadata:
languageName: node
linkType: hard
"flat@npm:^5.0.2":
version: 5.0.2
resolution: "flat@npm:5.0.2"
bin:
flat: cli.js
checksum: 12a1536ac746db74881316a181499a78ef953632ddd28050b7a3a43c62ef5462e3357c8c29d76072bb635f147f7a9a1f0c02efef6b4be28f8db62ceb3d5c7f5d
languageName: node
linkType: hard
"function-bind@npm:^1.1.2":
version: 1.1.2
resolution: "function-bind@npm:1.1.2"
checksum: 2b0ff4ce708d99715ad14a6d1f894e2a83242e4a52ccfcefaee5e40050562e5f6dafc1adbb4ce2d4ab47279a45dc736ab91ea5042d843c3c092820dfe032efb1
"function-bind@npm:^1.1.1":
version: 1.1.1
resolution: "function-bind@npm:1.1.1"
checksum: b32fbaebb3f8ec4969f033073b43f5c8befbb58f1a79e12f1d7490358150359ebd92f49e72ff0144f65f2c48ea2a605bff2d07965f548f6474fd8efd95bf361a
languageName: node
linkType: hard
@ -1009,12 +999,12 @@ __metadata:
languageName: node
linkType: hard
"hasown@npm:^2.0.0":
version: 2.0.0
resolution: "hasown@npm:2.0.0"
"has@npm:^1.0.3":
version: 1.0.3
resolution: "has@npm:1.0.3"
dependencies:
function-bind: ^1.1.2
checksum: 6151c75ca12554565098641c98a40f4cc86b85b0fd5b6fe92360967e4605a4f9610f7757260b4e8098dd1c2ce7f4b095f2006fe72a570e3b6d2d28de0298c176
function-bind: ^1.1.1
checksum: b9ad53d53be4af90ce5d1c38331e712522417d017d5ef1ebd0507e07c2fbad8686fffb8e12ddecd4c39ca9b9b47431afbb975b8abf7f3c3b82c98e9aad052792
languageName: node
linkType: hard
@ -1055,12 +1045,12 @@ __metadata:
languageName: node
linkType: hard
"is-core-module@npm:^2.13.0":
version: 2.13.1
resolution: "is-core-module@npm:2.13.1"
"is-core-module@npm:^2.12.0":
version: 2.12.1
resolution: "is-core-module@npm:2.12.1"
dependencies:
hasown: ^2.0.0
checksum: 256559ee8a9488af90e4bad16f5583c6d59e92f0742e9e8bb4331e758521ee86b810b93bae44f390766ffbc518a0488b18d9dab7da9a5ff997d499efc9403f7c
has: ^1.0.3
checksum: f04ea30533b5e62764e7b2e049d3157dc0abd95ef44275b32489ea2081176ac9746ffb1cdb107445cf1ff0e0dfcad522726ca27c27ece64dadf3795428b8e468
languageName: node
linkType: hard
@ -1191,12 +1181,12 @@ __metadata:
languageName: node
linkType: hard
"nanoid@npm:^3.3.7":
version: 3.3.7
resolution: "nanoid@npm:3.3.7"
"nanoid@npm:^3.3.6":
version: 3.3.6
resolution: "nanoid@npm:3.3.6"
bin:
nanoid: bin/nanoid.cjs
checksum: d36c427e530713e4ac6567d488b489a36582ef89da1d6d4e3b87eded11eb10d7042a877958c6f104929809b2ab0bafa17652b076cdf84324aa75b30b722204f2
checksum: 7d0eda657002738aa5206107bd0580aead6c95c460ef1bdd0b1a87a9c7ae6277ac2e9b945306aaa5b32c6dcb7feaf462d0f552e7f8b5718abfc6ead5c94a71b3
languageName: node
linkType: hard
@ -1207,10 +1197,10 @@ __metadata:
languageName: node
linkType: hard
"node-releases@npm:^2.0.14":
version: 2.0.14
resolution: "node-releases@npm:2.0.14"
checksum: 59443a2f77acac854c42d321bf1b43dea0aef55cd544c6a686e9816a697300458d4e82239e2d794ea05f7bbbc8a94500332e2d3ac3f11f52e4b16cbe638b3c41
"node-releases@npm:^2.0.12":
version: 2.0.12
resolution: "node-releases@npm:2.0.12"
checksum: b8c56db82c4642a0f443332b331a4396dae452a2ac5a65c8dbd93ef89ecb2fbb0da9d42ac5366d4764973febadca816cf7587dad492dce18d2a6b2af59cda260
languageName: node
linkType: hard
@ -1292,27 +1282,27 @@ __metadata:
languageName: node
linkType: hard
"postcss-modules-local-by-default@npm:^4.0.4":
version: 4.0.4
resolution: "postcss-modules-local-by-default@npm:4.0.4"
"postcss-modules-local-by-default@npm:^4.0.3":
version: 4.0.3
resolution: "postcss-modules-local-by-default@npm:4.0.3"
dependencies:
icss-utils: ^5.0.0
postcss-selector-parser: ^6.0.2
postcss-value-parser: ^4.1.0
peerDependencies:
postcss: ^8.1.0
checksum: 578b955b0773147890caa88c30b10dfc849c5b1412a47ad51751890dba16fca9528c3ab00a19b186a8c2c150c2d08e2ce64d3d907800afee1f37c6d38252e365
checksum: 2f8083687f3d6067885f8863dd32dbbb4f779cfcc7e52c17abede9311d84faf6d3ed8760e7c54c6380281732ae1f78e5e56a28baf3c271b33f450a11c9e30485
languageName: node
linkType: hard
"postcss-modules-scope@npm:^3.1.1":
version: 3.1.1
resolution: "postcss-modules-scope@npm:3.1.1"
"postcss-modules-scope@npm:^3.0.0":
version: 3.0.0
resolution: "postcss-modules-scope@npm:3.0.0"
dependencies:
postcss-selector-parser: ^6.0.4
peerDependencies:
postcss: ^8.1.0
checksum: 9e9d23abb0babc7fa243be65704d72a5a9ceb2bded4dbaef96a88210d468b03c8c3158c197f4e22300c851f08c6fdddd6ebe65f44e4c34448b45b8a2e063a16d
checksum: 330b9398dbd44c992c92b0dc612c0626135e2cc840fee41841eb61247a6cfed95af2bd6f67ead9dd9d0bb41f5b0367129d93c6e434fa3e9c58ade391d9a5a138
languageName: node
linkType: hard
@ -1338,12 +1328,12 @@ __metadata:
linkType: hard
"postcss-selector-parser@npm:^6.0.4":
version: 6.0.15
resolution: "postcss-selector-parser@npm:6.0.15"
version: 6.0.13
resolution: "postcss-selector-parser@npm:6.0.13"
dependencies:
cssesc: ^3.0.0
util-deprecate: ^1.0.2
checksum: 57decb94152111004f15e27b9c61131eb50ee10a3288e7fcf424cebbb4aba82c2817517ae718f8b5d704ee9e02a638d4a2acff8f47685c295a33ecee4fd31055
checksum: f89163338a1ce3b8ece8e9055cd5a3165e79a15e1c408e18de5ad8f87796b61ec2d48a2902d179ae0c4b5de10fccd3a325a4e660596549b040bc5ad1b465f096
languageName: node
linkType: hard
@ -1354,14 +1344,14 @@ __metadata:
languageName: node
linkType: hard
"postcss@npm:^8.4.33":
version: 8.4.35
resolution: "postcss@npm:8.4.35"
"postcss@npm:^8.4.21":
version: 8.4.24
resolution: "postcss@npm:8.4.24"
dependencies:
nanoid: ^3.3.7
nanoid: ^3.3.6
picocolors: ^1.0.0
source-map-js: ^1.0.2
checksum: cf3c3124d3912a507603f6d9a49b3783f741075e9aa73eb592a6dd9194f9edab9d20a8875d16d137d4f779fe7b6fbd1f5727e39bfd1c3003724980ee4995e1da
checksum: 814e2126dacfea313588eda09cc99a9b4c26ec55c059188aa7a916d20d26d483483106dc5ff9e560731b59f45c5bb91b945dfadc670aed875cc90ddbbf4e787d
languageName: node
linkType: hard
@ -1407,28 +1397,28 @@ __metadata:
linkType: hard
"resolve@npm:^1.20.0":
version: 1.22.8
resolution: "resolve@npm:1.22.8"
version: 1.22.3
resolution: "resolve@npm:1.22.3"
dependencies:
is-core-module: ^2.13.0
is-core-module: ^2.12.0
path-parse: ^1.0.7
supports-preserve-symlinks-flag: ^1.0.0
bin:
resolve: bin/resolve
checksum: f8a26958aa572c9b064562750b52131a37c29d072478ea32e129063e2da7f83e31f7f11e7087a18225a8561cfe8d2f0df9dbea7c9d331a897571c0a2527dbb4c
checksum: fb834b81348428cb545ff1b828a72ea28feb5a97c026a1cf40aa1008352c72811ff4d4e71f2035273dc536dcfcae20c13604ba6283c612d70fa0b6e44519c374
languageName: node
linkType: hard
"resolve@patch:resolve@^1.20.0#~builtin<compat/resolve>":
version: 1.22.8
resolution: "resolve@patch:resolve@npm%3A1.22.8#~builtin<compat/resolve>::version=1.22.8&hash=07638b"
version: 1.22.3
resolution: "resolve@patch:resolve@npm%3A1.22.3#~builtin<compat/resolve>::version=1.22.3&hash=07638b"
dependencies:
is-core-module: ^2.13.0
is-core-module: ^2.12.0
path-parse: ^1.0.7
supports-preserve-symlinks-flag: ^1.0.0
bin:
resolve: bin/resolve
checksum: 5479b7d431cacd5185f8db64bfcb7286ae5e31eb299f4c4f404ad8aa6098b77599563ac4257cb2c37a42f59dfc06a1bec2bcf283bb448f319e37f0feb9a09847
checksum: ad59734723b596d0891321c951592ed9015a77ce84907f89c9d9307dd0c06e11a67906a3e628c4cae143d3e44898603478af0ddeb2bba3f229a9373efe342665
languageName: node
linkType: hard
@ -1464,23 +1454,23 @@ __metadata:
languageName: node
linkType: hard
"semver@npm:^7.3.4, semver@npm:^7.5.4":
version: 7.6.0
resolution: "semver@npm:7.6.0"
"semver@npm:^7.3.4, semver@npm:^7.3.8":
version: 7.5.1
resolution: "semver@npm:7.5.1"
dependencies:
lru-cache: ^6.0.0
bin:
semver: bin/semver.js
checksum: 7427f05b70786c696640edc29fdd4bc33b2acf3bbe1740b955029044f80575fc664e1a512e4113c3af21e767154a94b4aa214bf6cd6e42a1f6dba5914e0b208c
checksum: d16dbedad53c65b086f79524b9ef766bf38670b2395bdad5c957f824dcc566b624988013564f4812bcace3f9d405355c3635e2007396a39d1bffc71cfec4a2fc
languageName: node
linkType: hard
"serialize-javascript@npm:^6.0.1":
version: 6.0.2
resolution: "serialize-javascript@npm:6.0.2"
version: 6.0.1
resolution: "serialize-javascript@npm:6.0.1"
dependencies:
randombytes: ^2.1.0
checksum: c4839c6206c1d143c0f80763997a361310305751171dd95e4b57efee69b8f6edd8960a0b7fbfc45042aadff98b206d55428aee0dc276efe54f100899c7fa8ab7
checksum: 3c4f4cb61d0893b988415bdb67243637333f3f574e9e9cc9a006a2ced0b390b0b3b44aef8d51c951272a9002ec50885eefdc0298891bc27eb2fe7510ea87dc4f
languageName: node
linkType: hard
@ -1533,19 +1523,12 @@ __metadata:
languageName: node
linkType: hard
"source-map@npm:^0.7.4":
version: 0.7.4
resolution: "source-map@npm:0.7.4"
checksum: 01cc5a74b1f0e1d626a58d36ad6898ea820567e87f18dfc9d24a9843a351aaa2ec09b87422589906d6ff1deed29693e176194dc88bcae7c9a852dc74b311dbf5
languageName: node
linkType: hard
"style-loader@npm:^3.3.3":
version: 3.3.4
resolution: "style-loader@npm:3.3.4"
version: 3.3.3
resolution: "style-loader@npm:3.3.3"
peerDependencies:
webpack: ^5.0.0
checksum: caac3f2fe2c3c89e49b7a2a9329e1cfa515ecf5f36b9c4885f9b218019fda207a9029939b2c35821dec177a264a007e7c391ccdd3ff7401881ce6287b9c8f38b
checksum: f59c953f56f6a935bd6a1dfa409f1128fed2b66b48ce4a7a75b85862a7156e5e90ab163878962762f528ec4d510903d828da645e143fbffd26f055dc1c094078
languageName: node
linkType: hard
@ -1581,15 +1564,15 @@ __metadata:
languageName: node
linkType: hard
"terser-webpack-plugin@npm:^5.3.10":
version: 5.3.10
resolution: "terser-webpack-plugin@npm:5.3.10"
"terser-webpack-plugin@npm:^5.3.7":
version: 5.3.9
resolution: "terser-webpack-plugin@npm:5.3.9"
dependencies:
"@jridgewell/trace-mapping": ^0.3.20
"@jridgewell/trace-mapping": ^0.3.17
jest-worker: ^27.4.5
schema-utils: ^3.1.1
serialize-javascript: ^6.0.1
terser: ^5.26.0
terser: ^5.16.8
peerDependencies:
webpack: ^5.1.0
peerDependenciesMeta:
@ -1599,13 +1582,13 @@ __metadata:
optional: true
uglify-js:
optional: true
checksum: bd6e7596cf815f3353e2a53e79cbdec959a1b0276f5e5d4e63e9d7c3c5bb5306df567729da287d1c7b39d79093e56863c569c42c6c24cc34c76aa313bd2cbcea
checksum: 41705713d6f9cb83287936b21e27c658891c78c4392159f5148b5623f0e8c48559869779619b058382a4c9758e7820ea034695e57dc7c474b4962b79f553bc5f
languageName: node
linkType: hard
"terser@npm:^5.26.0":
version: 5.27.0
resolution: "terser@npm:5.27.0"
"terser@npm:^5.16.8":
version: 5.18.0
resolution: "terser@npm:5.18.0"
dependencies:
"@jridgewell/source-map": ^0.3.3
acorn: ^8.8.2
@ -1613,7 +1596,7 @@ __metadata:
source-map-support: ~0.5.20
bin:
terser: bin/terser
checksum: c165052cfea061e8512e9b9ba42a098c2ff6382886ae122b040fd5b6153443070cc2dcb4862269f1669c09c716763e856125a355ff984aa72be525d6fffd8729
checksum: d01eb9805a978b3338b68fd2d9e35c1cd4cad78ea093dc92c7b3c38965232f0af0f95e0c6d90920ecf600a74135c608aebae26302c036c01393a590e1918bb90
languageName: node
linkType: hard
@ -1627,51 +1610,43 @@ __metadata:
linkType: hard
"ts-loader@npm:^9.4.3":
version: 9.5.1
resolution: "ts-loader@npm:9.5.1"
version: 9.4.3
resolution: "ts-loader@npm:9.4.3"
dependencies:
chalk: ^4.1.0
enhanced-resolve: ^5.0.0
micromatch: ^4.0.0
semver: ^7.3.4
source-map: ^0.7.4
peerDependencies:
typescript: "*"
webpack: ^5.0.0
checksum: 7cf396e656d905388ea2a9b5e82f16d3c955fda8d3df2fbf219f4bee16ff50a3c995c44ae3e584634e9443f056cec70bb3151add3917ffb4588ecd7394bac0ec
checksum: 139ed53bc60717d0ca231cdffbdef7566b9feda11c72fecc697983113f1266ccca2e1cdf191f841a43afa6b87d6afe57a0caf4feecf02f30845aa7ac6f2411a4
languageName: node
linkType: hard
"typescript@npm:^5.1.3":
version: 5.3.3
resolution: "typescript@npm:5.3.3"
version: 5.1.3
resolution: "typescript@npm:5.1.3"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
checksum: 2007ccb6e51bbbf6fde0a78099efe04dc1c3dfbdff04ca3b6a8bc717991862b39fd6126c0c3ebf2d2d98ac5e960bcaa873826bb2bb241f14277034148f41f6a2
checksum: d9d51862d98efa46534f2800a1071a613751b1585dc78884807d0c179bcd93d6e9d4012a508e276742f5f33c480adefc52ffcafaf9e0e00ab641a14cde9a31c7
languageName: node
linkType: hard
"typescript@patch:typescript@^5.1.3#~builtin<compat/typescript>":
version: 5.3.3
resolution: "typescript@patch:typescript@npm%3A5.3.3#~builtin<compat/typescript>::version=5.3.3&hash=7ad353"
version: 5.1.3
resolution: "typescript@patch:typescript@npm%3A5.1.3#~builtin<compat/typescript>::version=5.1.3&hash=7ad353"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
checksum: f61375590b3162599f0f0d5b8737877ac0a7bc52761dbb585d67e7b8753a3a4c42d9a554c4cc929f591ffcf3a2b0602f65ae3ce74714fd5652623a816862b610
languageName: node
linkType: hard
"undici-types@npm:~5.26.4":
version: 5.26.5
resolution: "undici-types@npm:5.26.5"
checksum: 3192ef6f3fd5df652f2dc1cd782b49d6ff14dc98e5dced492aa8a8c65425227da5da6aafe22523c67f035a272c599bb89cfe803c1db6311e44bed3042fc25487
checksum: 32a25b2e128a4616f999d4ee502aabb1525d5647bc8955e6edf05d7fbc53af8aa98252e2f6ba80bcedfc0260c982b885f3c09cfac8bb65d2924f3133ad1e1e62
languageName: node
linkType: hard
"update-browserslist-db@npm:^1.0.13":
version: 1.0.13
resolution: "update-browserslist-db@npm:1.0.13"
"update-browserslist-db@npm:^1.0.11":
version: 1.0.11
resolution: "update-browserslist-db@npm:1.0.11"
dependencies:
escalade: ^3.1.1
picocolors: ^1.0.0
@ -1679,7 +1654,7 @@ __metadata:
browserslist: ">= 4.21.0"
bin:
update-browserslist-db: cli.js
checksum: 1e47d80182ab6e4ad35396ad8b61008ae2a1330221175d0abd37689658bdb61af9b705bfc41057fd16682474d79944fb2d86767c5ed5ae34b6276b9bed353322
checksum: b98327518f9a345c7cad5437afae4d2ae7d865f9779554baf2a200fdf4bac4969076b679b1115434bd6557376bdd37ca7583d0f9b8f8e302d7d4cc1e91b5f231
languageName: node
linkType: hard
@ -1742,13 +1717,12 @@ __metadata:
linkType: hard
"webpack-merge@npm:^5.7.3":
version: 5.10.0
resolution: "webpack-merge@npm:5.10.0"
version: 5.9.0
resolution: "webpack-merge@npm:5.9.0"
dependencies:
clone-deep: ^4.0.1
flat: ^5.0.2
wildcard: ^2.0.0
checksum: 1fe8bf5309add7298e1ac72fb3f2090e1dfa80c48c7e79fa48aa60b5961332c7d0d61efa8851acb805e6b91a4584537a347bc106e05e9aec87fa4f7088c62f2f
checksum: 64fe2c23aacc5f19684452a0e84ec02c46b990423aee6fcc5c18d7d471155bd14e9a6adb02bd3656eb3e0ac2532c8e97d69412ad14c97eeafe32fa6d10050872
languageName: node
linkType: hard
@ -1760,17 +1734,17 @@ __metadata:
linkType: hard
"webpack@npm:^5.87.0":
version: 5.90.1
resolution: "webpack@npm:5.90.1"
version: 5.87.0
resolution: "webpack@npm:5.87.0"
dependencies:
"@types/eslint-scope": ^3.7.3
"@types/estree": ^1.0.5
"@types/estree": ^1.0.0
"@webassemblyjs/ast": ^1.11.5
"@webassemblyjs/wasm-edit": ^1.11.5
"@webassemblyjs/wasm-parser": ^1.11.5
acorn: ^8.7.1
acorn-import-assertions: ^1.9.0
browserslist: ^4.21.10
browserslist: ^4.14.5
chrome-trace-event: ^1.0.2
enhanced-resolve: ^5.15.0
es-module-lexer: ^1.2.1
@ -1784,7 +1758,7 @@ __metadata:
neo-async: ^2.6.2
schema-utils: ^3.2.0
tapable: ^2.1.1
terser-webpack-plugin: ^5.3.10
terser-webpack-plugin: ^5.3.7
watchpack: ^2.4.0
webpack-sources: ^3.2.3
peerDependenciesMeta:
@ -1792,7 +1766,7 @@ __metadata:
optional: true
bin:
webpack: bin/webpack.js
checksum: a7be844d5720a0c6282fec012e6fa34b1137dff953c5d48bf2ef066a6c27c1dbc92a9b9effc05ee61c9fe269499266db9782073f2d82a589d3c5c966ffc56584
checksum: b7d0e390f9d30627e303d54b17cb87b62f49ecffe2d35481f830679904993bae208e23748ffe0e6091b6dd4810562b2f2e88bb0f23b96515d74fb1e3c2898210
languageName: node
linkType: hard

Loading…
Cancel
Save