@progress/kendo-charts
Version:
Kendo UI platform-independent Charts library
267 lines (208 loc) • 6.7 kB
JavaScript
import { geometry as geo, drawing } from '@progress/kendo-drawing';
import { elementSize, setDefaultOptions, deepExtend, isArray, isNumber } from '../common';
import { DEFAULT_WIDTH, DEFAULT_HEIGHT } from './constants';
import { ChartService } from '../services';
import { unpad } from './utils';
const DEFAULT_MARGIN = 5;
const { Path, Surface } = drawing;
class Gauge {
constructor(element, userOptions, theme, context = {}) {
this.element = element;
this.theme = theme;
this.contextService = new ChartService(this, context);
this._originalOptions = deepExtend({}, this.options, userOptions);
this.options = deepExtend({}, this._originalOptions);
this._initTheme(theme);
this.redraw();
}
destroy() {
if (this.surface) {
this.surface.destroy();
this.surface = null;
}
delete this.element;
delete this.surfaceElement;
}
value(pointerValue) {
const pointer = this.pointers[0];
if (arguments.length === 0) {
return pointer.value();
}
pointer.value(pointerValue);
this._setValueOptions(pointerValue);
}
_draw() {
const surface = this.surface;
surface.clear();
surface.draw(this._visuals);
}
exportVisual() {
return this._visuals;
}
allValues(values) {
const pointers = this.pointers;
const allValues = [];
if (arguments.length === 0) {
for (let i = 0; i < pointers.length; i++) {
allValues.push(pointers[i].value());
}
return allValues;
}
if (isArray(values)) {
for (let i = 0; i < values.length; i++) {
if (isNumber(values[i])) {
pointers[i].value(values[i]);
}
}
}
this._setValueOptions(values);
}
_setValueOptions(values) {
const pointers = [].concat(this.options.pointer);
const arrayValues = [].concat(values);
for (let i = 0; i < arrayValues.length; i++) {
pointers[i].value = arrayValues[i];
}
}
resize() {
this.noTransitionsRedraw();
}
noTransitionsRedraw() {
const transitions = this.options.transitions;
this._toggleTransitions(false);
this.redraw();
this._toggleTransitions(transitions);
}
redraw() {
const size = this._surfaceSize();
const wrapper = new geo.Rect([ 0, 0 ], [ size.width, size.height ]);
this._initSurface();
this.gaugeArea = this._createGaugeArea();
this._createModel();
const bbox = unpad(wrapper.bbox(), this._gaugeAreaMargin);
this.reflow(bbox);
}
setOptions(options, theme) {
this._originalOptions = deepExtend(this._originalOptions, options);
this.options = deepExtend({}, this._originalOptions);
this._initTheme(theme);
this.redraw();
}
setDirection(rtl) {
this.contextService.rtl = Boolean(rtl);
if (this.surface && this.surface.type === 'svg') {
this.surface.destroy();
this.surface = null;
}
}
setIntlService(intl) {
this.contextService.intl = intl;
}
_initTheme(theme) {
let currentTheme = theme || this.theme || {};
this.theme = currentTheme;
this.options = deepExtend({}, currentTheme, this.options);
const options = this.options;
const pointer = options.pointer;
if (isArray(pointer)) {
const pointers = [];
for (let i = 0; i < pointer.length; i++) {
pointers.push(deepExtend({}, currentTheme.pointer, pointer[i]));
}
options.pointer = pointers;
}
}
_createGaugeArea() {
const options = this.options.gaugeArea;
const size = this.surface.size();
const border = options.border || {};
let areaGeometry = new geo.Rect([ 0, 0 ], [ size.width, size.height ]);
this._gaugeAreaMargin = options.margin || DEFAULT_MARGIN;
if (border.width > 0) {
areaGeometry = unpad(areaGeometry, border.width);
}
const gaugeArea = Path.fromRect(areaGeometry, {
stroke: {
color: border.width ? border.color : "",
width: border.width,
opacity: border.opacity,
dashType: border.dashType,
lineJoin: "round",
lineCap: "round"
},
fill: {
color: options.background
}
});
return gaugeArea;
}
_initSurface() {
const { options, surface } = this;
const element = this._surfaceElement();
const size = this._surfaceSize();
elementSize(element, size);
if (!surface || surface.options.type !== options.renderAs) {
if (surface) {
surface.destroy();
}
this.surface = Surface.create(element, {
type: options.renderAs
});
} else {
this.surface.clear();
this.surface.resize();
}
}
_surfaceSize() {
const options = this.options;
const size = this._getSize();
if (options.gaugeArea) {
deepExtend(size, options.gaugeArea);
}
return size;
}
_surfaceElement() {
if (!this.surfaceElement) {
this.surfaceElement = document.createElement('div');
this.element.appendChild(this.surfaceElement);
}
return this.surfaceElement;
}
getSize() {
return this._getSize();
}
_getSize() {
const element = this.element;
const defaultSize = this._defaultSize();
let width = element.offsetWidth;
let height = element.offsetHeight;
if (!width) {
width = defaultSize.width;
}
if (!height) {
height = defaultSize.height;
}
return { width: width, height: height };
}
_defaultSize() {
return {
width: DEFAULT_WIDTH,
height: DEFAULT_HEIGHT
};
}
_toggleTransitions(value) {
this.options.transitions = value;
for (let i = 0; i < this.pointers.length; i++) {
this.pointers[i].options.animation.transitions = value;
}
}
}
setDefaultOptions(Gauge, {
plotArea: {},
theme: "default",
renderAs: "",
pointer: {},
scale: {},
gaugeArea: {}
});
export default Gauge;