Browse Source

init data processor with non discrete type

pull/1/head
vargburz 2 years ago
parent
commit
cdd03b410c
  1. 60
      src/models/data_processor.ts
  2. 50
      src/types.ts

60
src/models/data_processor.ts

@ -0,0 +1,60 @@
import { BarSerie, BarOptions, Datapoint, Color, ValueX, OpacityFormatter } from '../types';
import * as _ from 'lodash';
export type DataRow = {
key: number, // x
values: number[], // y list
colors: string[],
opacity: number[],
serieTarget: string,
}
export class DataProcessor {
_formattedDataRows: DataRow[];
constructor(protected series: BarSerie[], protected options: BarOptions) {
}
public get dataRows(): DataRow[] {
return this._formattedDataRows;
}
protected setDataRowsForNonDiscreteType(): void {
for(let serie of this.series) {
const rows = _.map(serie.datapoints, (datapoint: Datapoint) => {
const values = _.tail(datapoint);
return {
key: datapoint[0], // x
values, // y list
colors: this.getColorsForEachValue(values, serie.color, datapoint[0], serie.target),
opacity: this.getOpacityForEachValue(values, serie.opacityFormatter, datapoint[0], serie.target),
target: serie.target,
}
});
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] || 'red');
}
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: OpacityFormatter | undefined, key: ValueX, target: string): number[] {
if(opacity === undefined) {
return _.map(values, value => 1);
}
return _.map(values, (value, i) => opacity({ value, barIndex: i, key, target }));
}
}

50
src/types.ts

@ -1,51 +1,55 @@
import { Serie, Options } from '@chartwerk/core';
type ValueX = (number | string);
export type ValueX = (number | string);
type ValueY = number;
export type Datapoint = [ValueX, ...ValueY[]]; // [x, y, y, y, ..., y], multiple y values as stacked bars
export type ColorFormatter = (data: { value: ValueY, key: ValueX, barIndex: number, target: string }) => string;
export type OpacityFormatter = (data: { value: ValueY, key: ValueX, barIndex: number, target: string }) => number;
export type Color = string | string[] | ColorFormatter;
export type BarSerieAdditionalParams = {
datapoints: [ValueX, ...ValueY[]]; // [x, y, y, y, ..., y], multiple y values as stacked bars
datapoints: Datapoint[];
annotation?: {
color: string;
size: {
max?: number; // type always SizeType.PX
min?: number; // type always SizeType.PX
}
}
opacityFormatter?: (data: RowValues) => number;
colorFormatter?: (data: any) => string;
};
color: Color;
opacityFormatter?: OpacityFormatter;
}
export type BarSerie = Serie & BarSerieAdditionalParams;
export type BarAdditionalOptions = {
group: { // for more than 1 serie and discrete.enable == true
by: { x: ValueX[] }; // union bars as one group, see examples/demo-group-by.html
size: number; // type always SizeType.PERCENT
};
discrete: {
enable: boolean; // if false -> render bars as time chart | group will not work, see examples/demo-non-discrete.html
barWidth: {
estimated?: { value: number, type?: SizeType };
max?: number; // type always SizeType.PX
min?: number; // type always SizeType.PX
type: { // BarPodType.DISCRETE or BarPodType.NON_DISCRETE. Cant be both
[BarPodType.DISCRETE]: {
groupBy: { x: ValueX[] }; // union bars as one group, see examples/demo-group-by.html
innerSize: { value: number, type?: SizeType.PERCENT | SizeType.PX }; // size of bars inside one group
groupSize: { value: number, type?: SizeType.PERCENT | SizeType.PX };
};
[BarPodType.NON_DISCRETE]: {
barWidth: {
estimated?: { value: number, type?: SizeType.UNIT | SizeType.PX };
max?: number; // type always SizeType.PX
min?: number; // type always SizeType.PX
}
}
};
}
eventsCallbacks?: {
contextMenu?: (data: any) => 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
}

Loading…
Cancel
Save