Core code of ChartWerk project
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

181 lines
4.6 KiB

import { Serie, yAxisOrientation } from '../types';
import { palette } from '../colors';
import lodashDefaultsDeep from 'lodash/defaultsDeep';
import lodashMap from 'lodash/map';
import lodashCloneDeep from 'lodash/cloneDeep';
import lodashUniq from 'lodash/uniq';
import lodashMin from 'lodash/min';
import lodashMinBy from 'lodash/minBy';
import lodashMax from 'lodash/max';
import lodashMaxBy from 'lodash/maxBy';
import lodashIsNil from 'lodash/isNil';
import lodashIncludes from 'lodash/includes';
export const CORE_SERIE_DEFAULTS = {
alias: '',
target: '',
visible: true,
yOrientation: yAxisOrientation.LEFT,
datapoints: [],
class: '',
// fields below will be set in "fillDefaults" method
idx: undefined,
color: undefined,
};
export enum Extremum {
MIN = 'min',
MAX = 'max',
}
export class CoreSeries<T extends Serie> {
_series: Array<T> = [];
constructor(series: T[], private _podDefaults?: Partial<T>) {
this.setSeries(series);
}
public updateSeries(series: T[]): void {
this.setSeries(series);
}
protected setSeries(series: T[]): void {
this._series = lodashMap(series, (serie, serieIdx) => this.fillDefaults(lodashCloneDeep(serie), serieIdx));
this.ensureSeriesValid(this._series);
}
ensureSeriesValid(series: T[]): void {
const targets = lodashMap(series, serie => serie.target);
const uniqTargets = lodashUniq(targets);
if(uniqTargets.length !== series.length) {
throw new Error(`All serie.target should be uniq`);
}
}
protected fillDefaults(serie: T, idx: number): T {
let defaults = lodashCloneDeep(this.getDefaults());
defaults.color = palette[idx % palette.length];
defaults.idx = idx;
lodashDefaultsDeep(serie, defaults);
return serie;
}
// this getter can be overrited in Pod
protected getDefaults(): Partial<T> {
return lodashDefaultsDeep(this._podDefaults, CORE_SERIE_DEFAULTS);
}
private _isSerieEmpty(serie: T): boolean {
if(serie.datapoints.length > 0) {
for(const datapoint of serie.datapoints) {
// TODO: axis-related
if(!lodashIsNil(datapoint[1])) {
return false;
}
}
}
return true;
}
get isSeriesAvailable(): boolean {
if(this.visibleSeries.length > 0) {
const seriesEmptiness = lodashMap(this.visibleSeries, this._isSerieEmpty.bind(this));
return lodashIncludes(seriesEmptiness, false);
}
return false;
}
get visibleSeries(): Array<T> {
return this._series.filter(serie => serie.visible);
}
get allSeries(): Array<T> {
return this._series;
}
get leftYRelatedSeries(): Array<T> {
return this.visibleSeries.filter(serie => serie.yOrientation === yAxisOrientation.LEFT);
}
get rightYRelatedSeries(): Array<T> {
return this.visibleSeries.filter(serie => serie.yOrientation === yAxisOrientation.RIGHT);
}
get areSeriesForY1Exist(): boolean {
return this.rightYRelatedSeries.length > 0;
}
get areSeriesForYExist(): boolean {
return this.leftYRelatedSeries.length > 0;
}
get minValueY(): number | undefined {
return lodashMin(
this.leftYRelatedSeries.map(
serie => {
const mins = lodashMinBy<number[]>(serie.datapoints, dp => dp[1]);
return !lodashIsNil(mins) ? mins[1] : undefined;
}
)
);
}
get maxValueY(): number | undefined {
return lodashMax(
this.leftYRelatedSeries.map(
serie => {
const maxs = lodashMaxBy<number[]>(serie.datapoints, dp => dp[1]);
return !lodashIsNil(maxs) ? maxs[1] : undefined;
}
)
);
}
get minValueX(): number | undefined {
return lodashMin(
this.visibleSeries.map(
serie => {
const mins = lodashMinBy<number[]>(serie.datapoints, dp => dp[0]);
return !lodashIsNil(mins) ? mins[0] : undefined;
}
)
);
}
get maxValueX(): number | undefined {
return lodashMax(
this.visibleSeries.map(
serie => {
const maxs = lodashMaxBy<number[]>(serie.datapoints, dp => dp[0]);
return !lodashIsNil(maxs) ? maxs[0] : undefined;
}
)
);
}
get minValueY1(): number | undefined {
return lodashMin(
this.rightYRelatedSeries.map(
serie => {
const mins = lodashMinBy<number[]>(serie.datapoints, dp => dp[1]);
return !lodashIsNil(mins) ? mins[1] : undefined;
}
)
);
}
get maxValueY1(): number | undefined {
return lodashMax(
this.rightYRelatedSeries.map(
serie => {
const maxs = lodashMaxBy<number[]>(serie.datapoints, dp => dp[1]);
return !lodashIsNil(maxs) ? maxs[1] : undefined;
}
)
);
}
}