Browse Source

update core

merge-requests/2/head
rozetko 2 years ago
parent
commit
f8374b9ff5
  1. 3
      package.json
  2. 121
      src/index.ts
  3. 170
      src/models/gauge_options.ts
  4. 17
      src/models/gauge_series.ts
  5. 19
      src/types.ts
  6. 6
      yarn.lock

3
package.json

@ -6,7 +6,8 @@
"scripts": { "scripts": {
"build": "webpack --config build/prod.webpack.conf.js && webpack --config build/dev.webpack.conf.js", "build": "webpack --config build/prod.webpack.conf.js && webpack --config build/dev.webpack.conf.js",
"dev": "webpack --watch --config build/dev.webpack.conf.js", "dev": "webpack --watch --config build/dev.webpack.conf.js",
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1",
"update-core": "yarn up @chartwerk/core && yarn up @chartwerk/core@latest"
}, },
"author": "CorpGlory", "author": "CorpGlory",
"license": "Apache-2.0", "license": "Apache-2.0",

121
src/index.ts

@ -1,105 +1,40 @@
import { GaugeTimeSerie, GaugeOptions, Stat, Stop, IconConfig, IconPosition, PointCoordinate } from './types'; import { GaugeData, GaugeConfig, Stat, Stop, IconConfig, IconPosition, PointCoordinate } from './types';
import { GaugeSeries } from './models/gauge_series';
import { ChartwerkPod, VueChartwerkPodMixin, AxisFormat, CrosshairOrientation } from '@chartwerk/core'; import { CORE_OPTIONS_DEFAULTS, GaugeOptions } from './models/gauge_options';
import { findClosest } from './utils'; import { findClosest } from './utils';
import { ChartwerkPod, VueChartwerkPodMixin } from '@chartwerk/core';
import * as d3 from 'd3'; import * as d3 from 'd3';
import * as _ from 'lodash'; import * as _ from 'lodash';
const SPACE_BETWEEN_CIRCLES = 2; const SPACE_BETWEEN_CIRCLES = 2;
const CIRCLES_ROUNDING = 0.25; //radians const CIRCLES_ROUNDING = 0.25; //radians
const BACKGROUND_COLOR = 'rgba(38, 38, 38, 0.1)';
const DEFAULT_INNER_RADIUS = 52;
const DEFAULT_OUTER_RADIUS = 72;
const STOPS_CIRCLE_WIDTH = 8; const STOPS_CIRCLE_WIDTH = 8;
const DEFAULT_VALUE_TEXT_FONT_SIZE = 16; const DEFAULT_VALUE_TEXT_FONT_SIZE = 16;
const VALUE_TEXT_MARGIN = 10; const VALUE_TEXT_MARGIN = 10;
const DEFAULT_ICON_SIZE = 20; //px const DEFAULT_ICON_SIZE = 20; //px
const DEFAULT_GAUGE_OPTIONS: GaugeOptions = { export class ChartwerkGaugePod extends ChartwerkPod<GaugeData, GaugeConfig> {
renderLegend: false, series: GaugeSeries;
grid: { options: GaugeOptions;
x: {
enabled: false
},
y: {
enabled: false
}
},
zoomEvents: {
mouse: {
zoom: {
isActive: false,
},
pan: {
isActive: false
},
},
scroll: {
zoom: {
isActive: false
},
pan: {
isActive: false,
}
},
},
axis: {
x: { isActive: false, format: AxisFormat.NUMERIC },
y: { isActive: false, format: AxisFormat.NUMERIC },
y1: { isActive: false, format: AxisFormat.NUMERIC },
},
margin: {
top: 0, bottom: 0,
left: 0, right: 0
},
stops: [
{
color: 'green',
value: 10
},
{
color: 'yellow',
value: 20
}
],
crosshair: {
orientation: CrosshairOrientation.VERTICAL,
color: 'red'
},
defaultColor: 'red',
stat: Stat.CURRENT,
innerRadius: DEFAULT_INNER_RADIUS,
outerRadius: DEFAULT_OUTER_RADIUS,
icons: [],
valueFontSize: null,
valueArcBackgroundColor: BACKGROUND_COLOR,
reversed: false,
enableExtremumLabels: false,
enableThresholdLabels: false,
enableThresholdDrag: false,
};
export class ChartwerkGaugePod extends ChartwerkPod<GaugeTimeSerie, GaugeOptions> {
_draggableLines: any[] = []; _draggableLines: any[] = [];
_draggedThresholdValues: number[] = []; // threshold values after dragging _draggedThresholdValues: number[] = []; // threshold values after dragging
_thresholdArc: any | null = null; _thresholdArc: any | null = null;
_thresholdTextLabels: any[] = []; _thresholdTextLabels: any[] = [];
constructor(el: HTMLElement, _series: GaugeTimeSerie[] = [], _options: GaugeOptions = {}) { constructor(el: HTMLElement, _series: GaugeData[] = [], _options: GaugeConfig = {}) {
super( // TODO: update core options to disable grid
el, _series, super(el, _series, _.assign(_options, CORE_OPTIONS_DEFAULTS));
_.defaults(_options, DEFAULT_GAUGE_OPTIONS) this.series = new GaugeSeries(_series);
); this.options = new GaugeOptions(_options);
} }
renderMetrics(): void { renderMetrics(): void {
if(this.series.length === 0 || this.series[0].datapoints.length === 0) {
this.renderNoDataPointsMessage();
return;
}
this._renderOverlayBackground(); this._renderOverlayBackground();
this._renderValueArc(); this._renderValueArc();
this._renderThresholdArc(); this._renderThresholdArc();
@ -109,13 +44,11 @@ export class ChartwerkGaugePod extends ChartwerkPod<GaugeTimeSerie, GaugeOptions
this._renderLabels(); this._renderLabels();
} }
protected updateOptions(newOptions: GaugeOptions): void { protected updateOptions(newOptions: GaugeConfig): void {
if(newOptions === undefined) { if(newOptions === undefined) {
return; return;
} }
let options = _.cloneDeep(newOptions); this.options = new GaugeOptions(newOptions);
_.defaultsDeep(options, DEFAULT_GAUGE_OPTIONS);
this.options = options;
} }
get _gaugeTransform(): string { get _gaugeTransform(): string {
@ -140,7 +73,7 @@ export class ChartwerkGaugePod extends ChartwerkPod<GaugeTimeSerie, GaugeOptions
} }
private _renderIcons(): void { private _renderIcons(): void {
if(this.options.icons === undefined || this.options.icons.length === 0) { if(this.options.icons.length === 0) {
return; return;
} }
this.options.icons.map(icon => { this.options.icons.map(icon => {
@ -284,7 +217,7 @@ export class ChartwerkGaugePod extends ChartwerkPod<GaugeTimeSerie, GaugeOptions
get arcScale(): d3.ScaleLinear<number, number> { get arcScale(): d3.ScaleLinear<number, number> {
return d3.scaleLinear() return d3.scaleLinear()
.domain([this.options.minValue, this.options.maxValue]) .domain([this.options.minValue , this.options.maxValue])
.range([(-1 * Math.PI) / 2 - CIRCLES_ROUNDING, Math.PI / 2 + CIRCLES_ROUNDING]); .range([(-1 * Math.PI) / 2 - CIRCLES_ROUNDING, Math.PI / 2 + CIRCLES_ROUNDING]);
} }
@ -334,9 +267,7 @@ export class ChartwerkGaugePod extends ChartwerkPod<GaugeTimeSerie, GaugeOptions
this.updateThresholdArcByNewValues(this._draggedThresholdValues); this.updateThresholdArcByNewValues(this._draggedThresholdValues);
this.updateThresholdLabel(value, idx); this.updateThresholdLabel(value, idx);
this.onGaugeMouseMove(); this.onGaugeMouseMove();
if(this.options.dragCallback) { this.options.callbackDrag({ value, idx });
this.options.dragCallback({ value, idx });
}
} }
updateThresholdArcByNewValues(stops: number[]): void { updateThresholdArcByNewValues(stops: number[]): void {
@ -367,9 +298,7 @@ export class ChartwerkGaugePod extends ChartwerkPod<GaugeTimeSerie, GaugeOptions
onDragEnd(idx: number): void { onDragEnd(idx: number): void {
this.onGaugeMouseOut(); this.onGaugeMouseOut();
if(this.options.dragEndCallback) { this.options.callbackDragEnd({ idx });
this.options.dragEndCallback({ idx });
}
} }
getAngleFromCoordinates(x: number, y: number): number { getAngleFromCoordinates(x: number, y: number): number {
@ -533,10 +462,6 @@ export class ChartwerkGaugePod extends ChartwerkPod<GaugeTimeSerie, GaugeOptions
} }
private get _valueText(): string { private get _valueText(): string {
if(this.options.valueFormatter === undefined) {
console.log('valueFormatter function is not specified, rendering raw value');
return this.aggregatedValue.toString();
}
return this.options.valueFormatter(this.aggregatedValue); return this.options.valueFormatter(this.aggregatedValue);
} }
@ -604,7 +529,7 @@ export class ChartwerkGaugePod extends ChartwerkPod<GaugeTimeSerie, GaugeOptions
private get aggregatedValue(): number { private get aggregatedValue(): number {
switch(this._stat) { switch(this._stat) {
case Stat.CURRENT: case Stat.CURRENT:
return _.last(this.series[0].datapoints)[1]; return _.last(this.series.visibleSeries[0].datapoints)[1];
// TODO: support other stats // TODO: support other stats
default: default:
throw new Error(`Unsupported stat: ${this._stat}`); throw new Error(`Unsupported stat: ${this._stat}`);
@ -656,7 +581,7 @@ export const VueChartwerkGaugePodObject = {
mixins: [VueChartwerkPodMixin], mixins: [VueChartwerkPodMixin],
methods: { methods: {
render() { render() {
if(this.pod === undefined) { if(this.pod === undefined) {
this.pod = new ChartwerkGaugePod(document.getElementById(this.id), this.series, this.options); this.pod = new ChartwerkGaugePod(document.getElementById(this.id), this.series, this.options);
this.pod.render(); this.pod.render();
} else { } else {
@ -666,4 +591,4 @@ export const VueChartwerkGaugePodObject = {
} }
}; };
export { GaugeOptions, GaugeTimeSerie, Stat }; export { GaugeConfig, GaugeData, Stat };

170
src/models/gauge_options.ts

@ -0,0 +1,170 @@
import { GaugeConfig, IconConfig, Stat, Stop } from '../types';
import { AxisFormat, CoreOptions } from '@chartwerk/core';
import lodashIsNil from 'lodash/isNil';
const BACKGROUND_COLOR = 'rgba(38, 38, 38, 0.1)';
const DEFAULT_INNER_RADIUS = 52;
const DEFAULT_OUTER_RADIUS = 72;
export const CORE_OPTIONS_DEFAULTS = {
renderLegend: false,
// TODO: find a method in lodash (defaultsDeep?)
grid: {
x: {
enabled: false
},
y: {
enabled: false
}
},
zoomEvents: {
mouse: {
zoom: {
isActive: false,
},
pan: {
isActive: false
},
},
scroll: {
zoom: {
isActive: false
},
pan: {
isActive: false,
}
},
},
axis: {
x: { isActive: false, format: AxisFormat.NUMERIC },
y: { isActive: false, format: AxisFormat.NUMERIC },
y1: { isActive: false, format: AxisFormat.NUMERIC },
},
margin: {
top: 0, bottom: 0,
left: 0, right: 0
},
}
const GAUGE_OPTIONS_DEFAULTS: GaugeConfig = {
innerRadius: DEFAULT_INNER_RADIUS,
outerRadius: DEFAULT_OUTER_RADIUS,
stops: [
{
color: 'green',
value: 10
},
{
color: 'yellow',
value: 20
}
],
defaultColor: 'red',
stat: Stat.CURRENT,
icons: [],
valueArcBackgroundColor: BACKGROUND_COLOR,
reversed: false,
enableExtremumLabels: false,
enableThresholdLabels: false,
enableThresholdDrag: false,
minValue: undefined,
maxValue: undefined,
valueFontSize: undefined, // undefined === auto
valueFormatter: undefined,
dragCallback: undefined,
dragEndCallback: undefined,
};
export class GaugeOptions extends CoreOptions<GaugeConfig> {
constructor(options: GaugeConfig) {
super(options);
}
protected get defaults(): GaugeConfig {
console.log({ ...this._coreDefaults, ...GAUGE_OPTIONS_DEFAULTS })
return { ...this._coreDefaults, ...GAUGE_OPTIONS_DEFAULTS };
}
get icons(): IconConfig[] {
return this._options.icons;
}
get minValue(): number | undefined {
return this._options.minValue;
}
get maxValue(): number | undefined {
return this._options.maxValue;
}
get enableThresholdDrag(): boolean {
return this._options.enableThresholdDrag;
}
get enableThresholdLabels(): boolean {
return this._options.enableThresholdLabels;
}
get enableExtremumLabels(): boolean {
return this._options.enableExtremumLabels;
}
get reversed(): boolean {
return this._options.reversed;
}
get defaultColor(): string {
return this._options.defaultColor;
}
get stops(): Stop[] {
return this._options.stops;
}
get valueFontSize(): number | undefined {
return this._options.valueFontSize;
}
get stat(): Stat {
return this._options.stat;
}
get valueArcBackgroundColor(): string {
return this._options.valueArcBackgroundColor;
}
get innerRadius(): number {
return this._options.innerRadius;
}
get outerRadius(): number {
return this._options.outerRadius;
}
valueFormatter(value: number): string {
if(this._options.valueFormatter) {
return this._options.valueFormatter(value);
}
if(lodashIsNil(value)) {
return 'not defined';
}
return value.toString();
}
callbackDrag(event: any): void {
if(this._options.dragCallback) {
this._options.dragCallback(event);
}
}
callbackDragEnd(event: any): void {
if(this._options.dragEndCallback) {
this._options.dragEndCallback(event);
}
}
}

17
src/models/gauge_series.ts

@ -0,0 +1,17 @@
import { GaugeData } from '../types';
import { CoreSeries } from '@chartwerk/core';
const GAUGE_DATA_DEFAULTS = { };
export class GaugeSeries extends CoreSeries<GaugeData> {
constructor(series: GaugeData[]) {
super(series);
}
protected get defaults(): GaugeData {
return { ...this._coreDefaults, ...GAUGE_DATA_DEFAULTS };
}
}

19
src/types.ts

@ -1,4 +1,5 @@
import { TimeSerie, Options } from '@chartwerk/core'; import { Serie, Options } from '@chartwerk/core';
export enum Stat { export enum Stat {
CURRENT = 'current', CURRENT = 'current',
@ -16,9 +17,7 @@ export type PointCoordinate = {
x: number, y: number x: number, y: number
} }
export type ValueFormatter = (value: number) => string; export type ValueFormatter = (value?: number | null) => string;
export type GaugeTimeSerie = TimeSerie;
export type IconConfig = { export type IconConfig = {
src: string, src: string,
@ -34,7 +33,6 @@ export enum IconPosition {
export type GaugeOptionsParams = { export type GaugeOptionsParams = {
innerRadius: number; innerRadius: number;
outerRadius: number; outerRadius: number;
// TODO: minValue
maxValue: number; maxValue: number;
minValue: number; minValue: number;
stops: { color: string , value: number }[]; stops: { color: string , value: number }[];
@ -48,7 +46,12 @@ export type GaugeOptionsParams = {
enableThresholdLabels: boolean; // render threshold values as a text under the gauge enableThresholdLabels: boolean; // render threshold values as a text under the gauge
enableExtremumLabels: boolean; // render min/max values as a text above the gauge enableExtremumLabels: boolean; // render min/max values as a text above the gauge
enableThresholdDrag: boolean; // drag threshold arcs to change stops values enableThresholdDrag: boolean; // drag threshold arcs to change stops values
dragCallback: (event: any) => void; dragCallback: DragCallback;
dragEndCallback: (event: any) => void; dragEndCallback: DragEndCallback;
} }
export type GaugeOptions = Options & Partial<GaugeOptionsParams>;
export type GaugeData = Serie;
export type GaugeConfig = Options & Partial<GaugeOptionsParams>;
export type DragCallback = (event: any) => void;
export type DragEndCallback = (event: any) => void;

6
yarn.lock

@ -6,12 +6,12 @@ __metadata:
cacheKey: 8 cacheKey: 8
"@chartwerk/core@npm:latest": "@chartwerk/core@npm:latest":
version: 0.5.4 version: 0.6.3
resolution: "@chartwerk/core@npm:0.5.4" resolution: "@chartwerk/core@npm:0.6.3"
dependencies: dependencies:
d3: ^5.7.2 d3: ^5.7.2
lodash: ^4.14.149 lodash: ^4.14.149
checksum: 0d686409377d6880f0012db3d9c1e1910cf3660885ac13196dabe93f57eca53984cf52dcf781b2876373fe9efc7b9d0209117cbcd811c50892b1de4f38a4a37f checksum: bb804b1a2339fc19857e5caa07d16ed78fb1b0739878d3f7488e9f8661667ed78ada3a63afd15206bd4210746b50916b253e98f077451cc8d899728ecf08ba50
languageName: node languageName: node
linkType: hard linkType: hard

Loading…
Cancel
Save