@syncfusion/ej2-lineargauge
Version:
Essential JS 2 LinearGauge Components
1,300 lines (1,293 loc) • 122 kB
JavaScript
import { Animation, Browser, ChildProperty, Collection, Complex, Component, Event, EventHandler, Internationalization, NotifyPropertyChanges, Property, compile, createElement, isNullOrUndefined, merge, remove, resetBlazorTemplate, updateBlazorTemplate } from '@syncfusion/ej2-base';
import { SvgRenderer, Tooltip } from '@syncfusion/ej2-svg-base';
var __decorate$1 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
/**
* Options for customizing the fonts.
*/
class Font extends ChildProperty {
}
__decorate$1([
Property('16px')
], Font.prototype, "size", void 0);
__decorate$1([
Property('')
], Font.prototype, "color", void 0);
__decorate$1([
Property('Segoe UI')
], Font.prototype, "fontFamily", void 0);
__decorate$1([
Property('Regular')
], Font.prototype, "fontWeight", void 0);
__decorate$1([
Property('Normal')
], Font.prototype, "fontStyle", void 0);
__decorate$1([
Property(1)
], Font.prototype, "opacity", void 0);
/**
* Configures the margin of linear gauge.
*/
class Margin extends ChildProperty {
}
__decorate$1([
Property(10)
], Margin.prototype, "left", void 0);
__decorate$1([
Property(10)
], Margin.prototype, "right", void 0);
__decorate$1([
Property(10)
], Margin.prototype, "top", void 0);
__decorate$1([
Property(10)
], Margin.prototype, "bottom", void 0);
/**
* Configures the border in linear gauge.
*/
class Border extends ChildProperty {
}
__decorate$1([
Property(null)
], Border.prototype, "color", void 0);
__decorate$1([
Property(0)
], Border.prototype, "width", void 0);
/**
* Options for customizing the annotation.
*/
class Annotation extends ChildProperty {
}
__decorate$1([
Property('')
], Annotation.prototype, "content", void 0);
__decorate$1([
Property(0)
], Annotation.prototype, "x", void 0);
__decorate$1([
Property(0)
], Annotation.prototype, "y", void 0);
__decorate$1([
Property('None')
], Annotation.prototype, "verticalAlignment", void 0);
__decorate$1([
Property('None')
], Annotation.prototype, "horizontalAlignment", void 0);
__decorate$1([
Property('-1')
], Annotation.prototype, "zIndex", void 0);
__decorate$1([
Complex({ size: '12px', color: null }, Font)
], Annotation.prototype, "font", void 0);
__decorate$1([
Property(null)
], Annotation.prototype, "axisIndex", void 0);
__decorate$1([
Property(null)
], Annotation.prototype, "axisValue", void 0);
/**
* Options for customizing the container of linear gauge.
*/
class Container extends ChildProperty {
}
__decorate$1([
Property('Normal')
], Container.prototype, "type", void 0);
__decorate$1([
Property(0)
], Container.prototype, "height", void 0);
__decorate$1([
Property(0)
], Container.prototype, "width", void 0);
__decorate$1([
Property(10)
], Container.prototype, "roundedCornerRadius", void 0);
__decorate$1([
Property('transparent')
], Container.prototype, "backgroundColor", void 0);
__decorate$1([
Complex({ width: 1, color: '#bfbfbf' }, Border)
], Container.prototype, "border", void 0);
__decorate$1([
Property(0)
], Container.prototype, "offset", void 0);
/**
* Options for customizing the tooltip in linear gauge.
*/
class TooltipSettings extends ChildProperty {
}
__decorate$1([
Property(false)
], TooltipSettings.prototype, "enable", void 0);
__decorate$1([
Property('')
], TooltipSettings.prototype, "fill", void 0);
__decorate$1([
Complex({ color: '', size: '13px' }, Font)
], TooltipSettings.prototype, "textStyle", void 0);
__decorate$1([
Property(null)
], TooltipSettings.prototype, "format", void 0);
__decorate$1([
Property(null)
], TooltipSettings.prototype, "template", void 0);
__decorate$1([
Property(true)
], TooltipSettings.prototype, "enableAnimation", void 0);
__decorate$1([
Complex({}, Border)
], TooltipSettings.prototype, "border", void 0);
var __decorate$2 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
/** Options for customizing the axis line. */
class Line extends ChildProperty {
}
__decorate$2([
Property('')
], Line.prototype, "dashArray", void 0);
__decorate$2([
Property(null)
], Line.prototype, "height", void 0);
__decorate$2([
Property(2)
], Line.prototype, "width", void 0);
__decorate$2([
Property(null)
], Line.prototype, "color", void 0);
__decorate$2([
Property(0)
], Line.prototype, "offset", void 0);
/**
* Options for customizing the axis labels appearance.
*/
class Label extends ChildProperty {
}
__decorate$2([
Complex({ size: '12px', color: null }, Font)
], Label.prototype, "font", void 0);
__decorate$2([
Property(false)
], Label.prototype, "useRangeColor", void 0);
__decorate$2([
Property('')
], Label.prototype, "format", void 0);
__decorate$2([
Property(0)
], Label.prototype, "offset", void 0);
/**
* Options for customizing the ranges of an axis.
*/
class Range extends ChildProperty {
}
__decorate$2([
Property(0)
], Range.prototype, "start", void 0);
__decorate$2([
Property(0)
], Range.prototype, "end", void 0);
__decorate$2([
Property('Outside')
], Range.prototype, "position", void 0);
__decorate$2([
Property('')
], Range.prototype, "color", void 0);
__decorate$2([
Property(10)
], Range.prototype, "startWidth", void 0);
__decorate$2([
Property(10)
], Range.prototype, "endWidth", void 0);
__decorate$2([
Property(0)
], Range.prototype, "offset", void 0);
__decorate$2([
Complex({ color: '#000000', width: 0 }, Border)
], Range.prototype, "border", void 0);
/**
* Options for customizing the minor tick lines.
*/
class Tick extends ChildProperty {
}
__decorate$2([
Property(20)
], Tick.prototype, "height", void 0);
__decorate$2([
Property(2)
], Tick.prototype, "width", void 0);
__decorate$2([
Property(null)
], Tick.prototype, "interval", void 0);
__decorate$2([
Property(null)
], Tick.prototype, "color", void 0);
__decorate$2([
Property(null)
], Tick.prototype, "offset", void 0);
/**
* Options for customizing the pointers of an axis.
*/
class Pointer extends ChildProperty {
constructor() {
super(...arguments);
/** @private */
this.animationComplete = true;
/** @private */
this.currentValue = null;
}
}
__decorate$2([
Property('Marker')
], Pointer.prototype, "type", void 0);
__decorate$2([
Property(null)
], Pointer.prototype, "value", void 0);
__decorate$2([
Property('InvertedTriangle')
], Pointer.prototype, "markerType", void 0);
__decorate$2([
Property(null)
], Pointer.prototype, "imageUrl", void 0);
__decorate$2([
Complex({ color: '#808080' }, Border)
], Pointer.prototype, "border", void 0);
__decorate$2([
Property(10)
], Pointer.prototype, "roundedCornerRadius", void 0);
__decorate$2([
Property('Far')
], Pointer.prototype, "placement", void 0);
__decorate$2([
Property(20)
], Pointer.prototype, "height", void 0);
__decorate$2([
Property(20)
], Pointer.prototype, "width", void 0);
__decorate$2([
Property(null)
], Pointer.prototype, "color", void 0);
__decorate$2([
Property(1)
], Pointer.prototype, "opacity", void 0);
__decorate$2([
Property(0)
], Pointer.prototype, "animationDuration", void 0);
__decorate$2([
Property(false)
], Pointer.prototype, "enableDrag", void 0);
__decorate$2([
Property(0)
], Pointer.prototype, "offset", void 0);
__decorate$2([
Property(null)
], Pointer.prototype, "description", void 0);
/**
* Options for customizing the axis of a gauge.
*/
class Axis extends ChildProperty {
constructor() {
/**
* Specifies the minimum value of an axis.
*/
super(...arguments);
/** @private */
this.visibleLabels = [];
}
}
__decorate$2([
Property(0)
], Axis.prototype, "minimum", void 0);
__decorate$2([
Property(100)
], Axis.prototype, "maximum", void 0);
__decorate$2([
Property(false)
], Axis.prototype, "isInversed", void 0);
__decorate$2([
Property(false)
], Axis.prototype, "opposedPosition", void 0);
__decorate$2([
Complex({}, Line)
], Axis.prototype, "line", void 0);
__decorate$2([
Collection([{}], Range)
], Axis.prototype, "ranges", void 0);
__decorate$2([
Collection([{}], Pointer)
], Axis.prototype, "pointers", void 0);
__decorate$2([
Complex({ width: 2, height: 20 }, Tick)
], Axis.prototype, "majorTicks", void 0);
__decorate$2([
Complex({ width: 1, height: 10 }, Tick)
], Axis.prototype, "minorTicks", void 0);
__decorate$2([
Complex({}, Label)
], Axis.prototype, "labelStyle", void 0);
/**
* Specifies the linear gauge constant value
*/
/** @private */
const loaded = 'loaded';
/** @private */
const load = 'load';
/** @private */
const animationComplete = 'animationComplete';
/** @private */
const axisLabelRender = 'axisLabelRender';
/** @private */
const tooltipRender = 'tooltipRender';
/** @private */
const annotationRender = 'annotationRender';
/** @private */
const gaugeMouseMove = 'gaugeMouseMove';
/** @private */
const gaugeMouseLeave = 'gaugeMouseLeave';
/** @private */
const gaugeMouseDown = 'gaugeMouseDown';
/** @private */
const gaugeMouseUp = 'gaugeMouseUp';
/** @private */
const valueChange = 'valueChange';
/** @private */
const resized = 'resized';
/**
* Specifies Linear-Gauge Helper methods
*/
/** @private */
function stringToNumber(value, containerSize) {
if (value !== null && value !== undefined) {
return value.indexOf('%') !== -1 ? (containerSize / 100) * parseInt(value, 10) : parseInt(value, 10);
}
return null;
}
/**
* Function to measure the height and width of the text.
* @param {string} text
* @param {FontModel} font
* @param {string} id
* @returns no
* @private
*/
function measureText(text, font) {
let htmlObject = document.getElementById('gauge-measuretext');
let size;
if (htmlObject === null) {
htmlObject = createElement('text', { id: 'gauge-measuretext' });
document.body.appendChild(htmlObject);
}
htmlObject.innerHTML = text;
htmlObject.style.position = 'absolute';
htmlObject.style.fontSize = font.size;
htmlObject.style.fontWeight = font.fontWeight;
htmlObject.style.fontStyle = font.fontStyle;
htmlObject.style.fontFamily = font.fontFamily;
htmlObject.style.visibility = 'hidden';
htmlObject.style.top = '-100';
htmlObject.style.left = '0';
htmlObject.style.whiteSpace = 'nowrap';
size = new Size(htmlObject.clientWidth, htmlObject.clientHeight);
//remove(htmlObject);
return size;
}
/** @private */
function withInRange(value, start, end, max, min, type) {
let withIn;
if (type === 'pointer') {
withIn = (((value <= max) && (value >= min)));
}
else {
withIn = (start != null && (start <= max) && (start >= min)) && (end != null && (end <= max) && (end >= min));
}
return withIn;
}
function convertPixelToValue(parentElement, pointerElement, orientation, axis, type, location) {
let elementRect = parentElement.getBoundingClientRect();
let pointerRect = pointerElement.getBoundingClientRect();
let height = (pointerElement.id.indexOf('MarkerPointer') > -1) ? (pointerRect.height / 2) :
(!axis.isInversed) ? 0 : pointerRect.height;
let width = (pointerElement.id.indexOf('MarkerPointer') > -1) ? (pointerRect.width / 2) :
(!axis.isInversed) ? pointerRect.width : 0;
let size = new Size(axis.lineBounds.width, axis.lineBounds.height);
let y = (type === 'drag') ? (location.y - axis.lineBounds.y) :
((pointerRect.top + height) - elementRect.top - axis.lineBounds.y);
let x = (type === 'drag') ? (location.x - axis.lineBounds.x) :
((pointerRect.left + width) - elementRect.left - axis.lineBounds.x);
let newSize = (orientation === 'Vertical') ? size.height : size.width;
let divideVal = (orientation === 'Vertical') ? y : x;
let value = (orientation === 'Vertical') ? (axis.isInversed) ? (divideVal / newSize) :
(1 - (divideVal / newSize)) : (axis.isInversed) ? (1 - (divideVal / newSize)) : (divideVal / newSize);
value = value * (axis.visibleRange.delta) + axis.visibleRange.min;
return value;
}
function getPathToRect(path, size, parentElement) {
let tempDiv = document.getElementById('gauge_path');
if (tempDiv === null) {
tempDiv = createElement('text', { id: 'gauge_path' });
tempDiv.style.position = 'absolute';
tempDiv.style.top = '0px';
tempDiv.style.left = '0px';
parentElement.appendChild(tempDiv);
}
let render = new SvgRenderer('id');
let svg = render.createSvg({ id: 'box_path', width: size.width, height: size.height });
svg.appendChild(path);
tempDiv.appendChild(svg);
let svgRect = path.getBBox();
remove(tempDiv);
return svgRect;
}
/** @private */
function getElement(id) {
return document.getElementById(id);
}
/** @private */
function removeElement(id) {
let element = getElement(id);
if (element) {
remove(element);
}
}
/** @private */
function isPointerDrag(axes) {
let pointerEnable = false;
axes.map((axis, index) => {
axis.pointers.map((pointer, index) => {
if (pointer.enableDrag) {
pointerEnable = true;
}
});
});
return pointerEnable;
}
/** @private */
function valueToCoefficient(value, axis, orientation, range) {
let result = (value - range.min) / range.delta;
result = (orientation === 'Vertical') ? (!axis.isInversed) ? (1 - result) : result : (!axis.isInversed) ? result : (1 - result);
return result;
}
function getFontStyle(font) {
let style = '';
style = 'font-size:' + font.size +
'; font-style:' + font.fontStyle + '; font-weight:' + font.fontWeight +
'; font-family:' + font.fontFamily + ';opacity:' + font.opacity +
'; color:' + font.color + ';';
return style;
}
function textFormatter(format, data, gauge) {
if (isNullOrUndefined(format)) {
return null;
}
let keys = Object.keys(data);
for (let key of keys) {
format = format.split('{' + key + '}').join(formatValue(data[key], gauge).toString());
}
return format;
}
function formatValue(value, gauge) {
let formatValue;
let formatFunction;
if (gauge.format && !isNaN(Number(value))) {
formatFunction = gauge.intl.getNumberFormat({ format: gauge.format, useGrouping: gauge.useGroupingSeparator });
formatValue = formatFunction(Number(value));
}
else {
formatValue = value;
}
return formatValue !== null ? formatValue : '';
}
/** @private */
function getLabelFormat(format) {
let customLabelFormat = format && format.match('{value}') !== null;
let skeleton = customLabelFormat ? '' : format;
return skeleton;
}
/** @private */
function getTemplateFunction(template) {
let templateFn = null;
try {
if (document.querySelectorAll(template).length) {
templateFn = compile(document.querySelector(template).innerHTML.trim());
}
}
catch (e) {
templateFn = compile(template);
}
return templateFn;
}
/** @private */
function getElementOffset(childElement, parentElement) {
let width;
let height;
parentElement.appendChild(childElement);
width = childElement.offsetWidth;
height = childElement.offsetHeight;
parentElement.removeChild(childElement);
return new Size(width, height);
}
/** @private */
class VisibleRange {
constructor(min, max, interval, delta) {
this.min = min;
this.max = max;
this.interval = interval;
this.delta = delta;
}
}
/**
* Internal use of gauge location
*/
class GaugeLocation {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
/**
* Internal class size for height and width
*/
class Size {
constructor(width, height) {
this.width = width;
this.height = height;
}
}
/** @private */
class Rect {
constructor(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
}
/** @private */
class CustomizeOption {
constructor(id) {
this.id = id;
}
}
/** @private */
class PathOption extends CustomizeOption {
constructor(id, fill, width, color, opacity, dashArray, d, transform = '') {
super(id);
this.opacity = opacity;
this.fill = fill;
this.stroke = color;
this['stroke-width'] = width;
this['stroke-dasharray'] = dashArray;
this.d = d;
this.transform = transform;
}
}
/** @private */
class RectOption {
constructor(id, fill, border, opacity, rect, transform, dashArray) {
this.opacity = opacity;
this.id = id;
this.y = rect.y;
this.x = rect.x;
this.fill = fill;
this.stroke = border.color;
this['stroke-width'] = border.width;
this.height = rect.height;
this.width = rect.width;
}
}
/** @private */
class TextOption extends CustomizeOption {
constructor(id, x, y, anchor, text, transform = '', baseLine) {
super(id);
this.transform = '';
this.baseLine = 'auto';
this.x = x;
this.y = y;
this.anchor = anchor;
this.text = text;
this.transform = transform;
this.baseLine = baseLine;
}
}
/** @private */
class VisibleLabels {
constructor(text, value, size) {
this.text = text;
this.value = value;
this.size = size;
}
}
/** @private */
class Align {
constructor(axisIndex, align) {
this.align = align;
this.axisIndex = axisIndex;
}
}
/** @private */
function textElement(options, font, color, parent) {
let renderOptions = {};
let htmlObject;
let renderer = new SvgRenderer('');
let style = 'fill:' + color + '; font-size:' + font.size +
'; font-style:' + font.fontStyle + ' ; font-weight:' + font.fontWeight + '; font-family:' +
font.fontFamily + '; text-anchor:' + options.anchor + '; transform:' + options.transform +
'; opacity:' + font.opacity + '; dominant-baseline:' + options.baseLine + ';';
renderOptions = {
'id': options.id,
'x': options.x,
'y': options.y,
'style': style
};
htmlObject = renderer.createText(renderOptions, options.text);
parent.appendChild(htmlObject);
return htmlObject;
}
function calculateNiceInterval(min, max, size, orientation) {
let delta = max - min;
let currentInterval;
let intervalDivs = [10, 5, 2, 1];
let desiredIntervalsCount = getActualDesiredIntervalsCount(size, orientation);
let niceInterval = delta / desiredIntervalsCount;
let minInterval = Math.pow(10, Math.floor(Math.log(niceInterval) / Math.log(10)));
for (let interval of intervalDivs) {
currentInterval = minInterval * interval;
if (desiredIntervalsCount < (delta / currentInterval)) {
break;
}
niceInterval = currentInterval;
}
return niceInterval;
}
function getActualDesiredIntervalsCount(size, orientation) {
let maximumLabels = 5;
let desiredIntervalsCount = (orientation === 'Horizontal' ? 0.533 : 1) * maximumLabels;
desiredIntervalsCount = Math.max((size * (desiredIntervalsCount / 100)), 1);
return desiredIntervalsCount;
}
/** @private */
function getPointer(target, gauge) {
let split = [];
let axisIndex;
let radix = 10;
let pointIndex;
let axis;
let pointer;
split = target.id.replace(gauge.element.id, '').split('_');
axisIndex = parseInt(split[2], radix);
pointIndex = parseInt(split[4], radix);
axis = gauge.axes[axisIndex];
pointer = gauge.axes[axisIndex].pointers[pointIndex];
return { axis: axis, axisIndex: axisIndex, pointer: pointer, pointerIndex: pointIndex };
}
/** @private */
function getRangeColor(value, ranges) {
let rangeColor = null;
ranges.forEach((range, index) => {
if (value >= range.start && range.end >= value) {
rangeColor = range.interior;
}
});
return rangeColor;
}
/** @private */
function getRangePalette() {
let palette = ['#ff5985', '#ffb133', '#fcde0b', '#27d5ff', '#50c917'];
return palette;
}
/** @private */
function calculateShapes(location, shape, size, url, options, orientation, axis, pointer) {
let path;
let width = size.width;
let height = size.height;
let locX = location.x;
let locY = location.y;
let radius;
switch (shape) {
case 'Circle':
radius = ((width + height) / 4);
locX = (orientation === 'Vertical') ? (!axis.opposedPosition) ? (pointer.placement !== 'Far') ? locX - radius : locX + radius :
pointer.placement === 'Near' ? locX - radius : locX + radius : locX;
locY = (orientation === 'Vertical') ? locY : (!axis.opposedPosition) ? (pointer.placement === 'Far') ?
locY + radius : locY - radius : (pointer.placement === 'Near') ? locY - radius : locY + radius;
merge(options, { 'r': radius, 'cx': locX, 'cy': locY });
break;
case 'Diamond':
case 'Rectangle':
locX = (orientation === 'Horizontal') ? ((locX - (width / 2))) : ((!axis.opposedPosition && pointer.placement !== 'Far') ||
(axis.opposedPosition && pointer.placement === 'Near')) ? locX - width : locX;
locY = (orientation === 'Vertical') ? locY : (!axis.opposedPosition) ?
(pointer.placement === 'Far') ? locY + (height / 2) : locY - (height / 2) :
(pointer.placement === 'Near') ? locY - (height / 2) : locY + (height / 2);
if (shape === 'Diamond') {
path = 'M' + ' ' + locX + ' ' + locY + ' ' +
'L' + ' ' + (locX + (width / 2)) + ' ' + (locY - (height / 2)) + ' ' +
'L' + ' ' + (locX + width) + ' ' + locY + ' ' +
'L' + ' ' + (locX + (width / 2)) + ' ' + (locY + (height / 2)) + ' ' +
'L' + ' ' + locX + ' ' + locY + ' z';
}
else {
path = 'M' + ' ' + locX + ' ' + (locY - (height / 2)) + ' ' +
'L' + ' ' + (locX + width) + ' ' + (locY - (height / 2)) + ' ' +
'L' + ' ' + (locX + width) + ' ' + (locY + (height / 2)) + ' ' +
'L' + ' ' + locX + ' ' + (locY + (height / 2)) + ' ' +
'L' + ' ' + locX + ' ' + (locY - (height / 2)) + ' z';
}
merge(options, { 'd': path });
break;
case 'Triangle':
if (orientation === 'Vertical') {
path = 'M' + ' ' + locX + ' ' + locY + ' ' +
'L' + (locX - width) + ' ' + (locY - (height / 2)) +
'L' + (locX - width) + ' ' + (locY + (height / 2)) + ' Z';
}
else {
path = 'M' + ' ' + locX + ' ' + locY + ' ' +
'L' + (locX + (width / 2)) + ' ' + (locY - height) +
'L' + (locX - (width / 2)) + ' ' + (locY - height) + ' Z';
}
merge(options, { 'd': path });
break;
case 'InvertedTriangle':
if (orientation === 'Vertical') {
path = 'M' + ' ' + locX + ' ' + locY + ' ' +
'L' + (locX + width) + ' ' + (locY - (height / 2)) +
'L' + (locX + width) + ' ' + (locY + (height / 2)) + ' Z';
}
else {
path = 'M' + ' ' + locX + ' ' + locY + ' ' +
'L' + (locX + (width / 2)) + ' ' + (locY + height) +
'L' + (locX - (width / 2)) + ' ' + (locY + height) + ' Z';
}
merge(options, { 'd': path });
break;
case 'Arrow':
if (orientation === 'Vertical') {
path = 'M' + ' ' + locX + ' ' + locY + ' ' + 'L' + (locX - (width / 2)) + ' ' + (locY - (height / 2)) + ' ' +
'L' + (locX - (width / 2)) + ' ' + ((locY - (height / 2)) + (height / 4)) + ' ' + 'L' + (locX - width) + ' '
+ ((locY - (height / 2)) + (height / 4)) + ' ' + 'L' + (locX - width) + ' ' + ((locY + (height / 2)) -
(height / 4)) + ' ' + 'L' + (locX - (width / 2)) + ' ' + ((locY + (height / 2)) - (height / 4)) + ' ' +
'L' + (locX - (width / 2)) + ' ' + (locY + height / 2) + 'z';
}
else {
path = 'M' + ' ' + locX + ' ' + locY + ' ' + 'L' + (locX + (width / 2)) + ' ' + (locY - (height / 2)) + ' ' +
'L' + ((locX + (width / 2)) - (width / 4)) + ' ' + (locY - (height / 2)) + ' ' + 'L' + ((locX + (width / 2)) -
(width / 4)) + ' ' + (locY - height) + ' ' + 'L' + ((locX - (width / 2)) + (width / 4)) + ' ' + (locY - height) +
' ' + 'L' + ((locX - (width / 2)) + (width / 4)) + ' ' + (locY - (height / 2)) + ' ' + 'L' + (locX - (width / 2))
+ ' ' + (locY - (height / 2)) + 'z';
}
merge(options, { 'd': path });
break;
case 'InvertedArrow':
if (orientation === 'Vertical') {
path = 'M' + ' ' + locX + ' ' + locY + 'L' + (locX + (width / 2)) + ' ' + (locY - (height / 2)) + ' ' +
'L' + (locX + (width / 2)) + ' ' + ((locY - (height / 2)) + (height / 4)) + ' ' + 'L' + (locX + width) + ' '
+ ((locY - (height / 2)) + (height / 4)) + ' ' + 'L' + (locX + width) + ' ' + ((locY + (height / 2)) - (height / 4))
+ ' ' + 'L' + (locX + (width / 2)) + ' ' + ((locY + (height / 2)) - (height / 4)) + ' ' +
'L' + (locX + (width / 2)) + ' ' + (locY + height / 2) + 'z';
}
else {
path = 'M' + ' ' + locX + ' ' + locY + ' ' + 'L' + (locX + (width / 2)) + ' ' + (locY + (height / 2)) + ' ' +
'L' + ((locX + (width / 2)) - (width / 4)) + ' ' + (locY + (height / 2)) + ' ' + 'L' + ((locX + (width / 2)) -
(width / 4)) + ' ' + (locY + height) + ' ' + 'L' + ((locX - (width / 2)) + (width / 4)) + ' ' + (locY + height)
+ ' ' + 'L' + ((locX - (width / 2)) + (width / 4)) + ' ' + (locY + (height / 2)) + ' ' +
'L' + (locX - (width / 2)) + ' ' + (locY + (height / 2)) + 'z';
}
merge(options, { 'd': path });
break;
case 'Image':
merge(options, { 'href': url, 'height': height, 'width': width, x: locX - (width / 2), y: locY - (height / 2) });
break;
}
return options;
}
/** @private */
function getBox(location, boxName, orientation, size, type, containerWidth, axis, cornerRadius) {
let path = ' ';
let radius = cornerRadius;
let x1;
let y1;
let rectWidth;
let rectHeight;
let bottomRadius;
let topRadius;
switch (boxName) {
case 'RoundedRectangle':
x1 = location.x;
y1 = location.y;
rectWidth = location.width;
rectHeight = location.height;
path = 'M' + ' ' + x1 + ' ' + (radius + y1) + ' Q ' + x1 + ' ' + y1 + ' ' + (x1 + radius) + ' ' + y1 + ' ';
path += 'L' + ' ' + (x1 + rectWidth - radius) + ' ' + y1 + ' Q ' + (x1 + rectWidth) + ' ' + y1 + ' '
+ (x1 + rectWidth) + ' ' + (y1 + radius) + ' ';
path += 'L ' + (x1 + rectWidth) + ' ' + (y1 + rectHeight - radius) + ' Q ' + (x1 + rectWidth) + ' ' + (y1 + rectHeight)
+ ' ' + (x1 + rectWidth - radius) + ' ' + (y1 + rectHeight) + ' ';
path += ' L ' + (x1 + radius) + ' ' + (y1 + rectHeight) + ' Q ' + x1 + ' ' + (y1 + rectHeight)
+ ' ' + x1 + ' ' + (y1 + rectHeight - radius) + ' ';
path += 'L' + ' ' + x1 + ' ' + (radius + y1) + ' ' + 'z';
break;
case 'Thermometer':
let width = (orientation === 'Vertical') ? location.width : location.height;
bottomRadius = width + ((width / 2) / Math.PI);
topRadius = width / 2;
if (orientation === 'Vertical') {
let addValue = ((containerWidth + ((containerWidth / 2) / Math.PI)) - bottomRadius);
let y1 = (type === 'bar') ? location.y + addValue : location.y;
let locY = (type === 'bar') ? location.y + (topRadius - (topRadius / Math.PI)) : location.y;
let locHeight = location.height;
path = 'M' + location.x + ' ' + (y1 + locHeight) +
' A ' + bottomRadius + ' ' + bottomRadius + ', 0, 1, 0, ' + (location.x + location.width) + ' ' + (y1 + locHeight) +
' L ' + (location.x + location.width) + ' ' + locY +
' A ' + topRadius + ' ' + topRadius + ', 0, 1, 0, ' + location.x + ' ' + locY + ' z ';
}
else {
let x1 = (type === 'bar' && !axis.isInversed) ?
location.x - ((containerWidth + ((containerWidth / 2) / Math.PI)) - bottomRadius) : location.x;
let locWidth = (type === 'bar') ? (location.width - (topRadius - ((topRadius / Math.PI)))) : location.width;
path = 'M' + x1 + ' ' + (location.y) +
' A ' + bottomRadius + ' ' + bottomRadius + ', 0, 1, 0, ' + x1 + ' ' + (location.y + location.height) +
' L ' + ((type === 'bar' ? location.x : x1) + locWidth) + ' ' + (location.y + location.height) +
' A ' + topRadius + ' ' + topRadius + ', 0, 1, 0, ' +
((type === 'bar' ? location.x : x1) + locWidth) + ' ' + (location.y) + ' z ';
}
break;
}
return path;
}
/**
* @private
* To calculate the overall axis bounds for gauge.
*/
class AxisLayoutPanel {
constructor(gauge) {
this.gauge = gauge;
}
/**
* To calculate the axis bounds
*/
calculateAxesBounds() {
let axis;
let bounds;
this.gauge.nearSizes = [];
this.gauge.farSizes = [];
let x;
let y;
let width;
let height;
let axisPadding = 8;
let containerRect = this.gauge.containerBounds;
this.checkThermometer();
for (let i = 0; i < this.gauge.axes.length; i++) {
axis = this.gauge.axes[i];
axis.checkAlign = new Align(i, ((!axis.opposedPosition) ? 'Near' : 'Far'));
(!axis.opposedPosition) ? this.gauge.nearSizes.push(1) : this.gauge.farSizes.push(1);
this.calculateLineBounds(axis, i);
this.calculateTickBounds(axis, i);
this.calculateLabelBounds(axis, i);
if (axis.pointers.length > 0) {
this.calculatePointerBounds(axis, i);
}
if (axis.ranges.length > 0) {
this.calculateRangesBounds(axis, i);
}
bounds = axis.labelBounds;
if (this.gauge.orientation === 'Vertical') {
x = (!axis.opposedPosition) ? bounds.x - axisPadding : axis.lineBounds.x;
y = axis.lineBounds.y;
height = axis.lineBounds.height;
width = Math.abs((!axis.opposedPosition) ? (axis.lineBounds.x - x) : ((bounds.x + bounds.width + axisPadding) - x));
}
else {
y = (!axis.opposedPosition) ? bounds.y - bounds.height - axisPadding : axis.lineBounds.y;
x = axis.lineBounds.x;
width = axis.lineBounds.width;
height = Math.abs((!axis.opposedPosition) ? Math.abs(axis.lineBounds.y - y) : (bounds.y + axisPadding) - y);
}
axis.bounds = new Rect(x, y, width, height);
}
}
/**
* Calculate axis line bounds
* @param axis
* @param axisIndex
*/
calculateLineBounds(axis, axisIndex) {
let x;
let y;
let width;
let height;
let index;
let prevAxis;
let lineHeight = axis.line.height;
let orientation = this.gauge.orientation;
let containerRect = this.gauge.containerBounds;
lineHeight = (axis.line.width > 0) ? lineHeight : null;
if (orientation === 'Vertical') {
y = (isNullOrUndefined(lineHeight)) ? containerRect.y :
containerRect.y + ((containerRect.height / 2) - (lineHeight / 2));
width = axis.line.width;
height = (isNullOrUndefined(lineHeight)) ? containerRect.height : lineHeight;
}
else {
x = (isNullOrUndefined(lineHeight)) ? containerRect.x :
containerRect.x + ((containerRect.width / 2) - (lineHeight / 2));
height = axis.line.width;
width = (isNullOrUndefined(lineHeight)) ? containerRect.width : lineHeight;
}
index = this.checkPreviousAxes(axis, axisIndex);
if (isNullOrUndefined(index)) {
if (orientation === 'Vertical') {
x = (!axis.opposedPosition ? containerRect.x : containerRect.x + containerRect.width) + axis.line.offset;
}
else {
y = (!axis.opposedPosition ? containerRect.y : containerRect.y + containerRect.height) + axis.line.offset;
}
}
else {
prevAxis = this.gauge.axes[index];
if (orientation === 'Vertical') {
x = ((!axis.opposedPosition) ? prevAxis.bounds.x : (prevAxis.bounds.x + prevAxis.bounds.width)) + axis.line.offset;
}
else {
y = ((!axis.opposedPosition) ? prevAxis.bounds.y : (prevAxis.bounds.y + prevAxis.bounds.height)) + axis.line.offset;
}
}
axis.lineBounds = new Rect(x, y, width, height);
}
/**
* Calculate axis tick bounds
* @param axis
* @param axisIndex
*/
calculateTickBounds(axis, axisIndex) {
let x;
let y;
let major;
let minor;
let min = Math.min(axis.minimum, axis.maximum);
let max = Math.max(axis.minimum, axis.maximum);
min = (min === max) ? max - 1 : min;
let interval = axis.majorTicks.interval;
let bounds = axis.lineBounds;
major = axis.majorTicks;
minor = axis.minorTicks;
axis.majorInterval = major.interval;
axis.minorInterval = minor.interval;
let size = (this.gauge.orientation === 'Vertical' ? bounds.height : bounds.width);
let lineSize = (this.gauge.orientation === 'Vertical' ? bounds.width : bounds.height) / 2;
axis.majorInterval = isNullOrUndefined(axis.majorInterval) ? calculateNiceInterval(min, max, size, this.gauge.orientation)
: major.interval;
axis.visibleRange = new VisibleRange(min, max, axis.majorInterval, (max - min));
axis.minorInterval = (isNullOrUndefined(axis.minorInterval)) ? axis.majorInterval / 2 : axis.minorInterval;
if (this.gauge.orientation === 'Vertical') {
x = (!axis.opposedPosition ? (bounds.x - lineSize - major.height) : bounds.x + lineSize) + major.offset;
axis.majorTickBounds = new Rect(x, bounds.y, major.height, bounds.height);
x = (!axis.opposedPosition ? (bounds.x - lineSize - minor.height) : bounds.x + lineSize) + minor.offset;
axis.minorTickBounds = new Rect(x, bounds.y, minor.height, bounds.height);
}
else {
y = (!axis.opposedPosition ? (bounds.y - lineSize - major.height) : bounds.y + lineSize) + major.offset;
axis.majorTickBounds = new Rect(bounds.x, y, bounds.width, major.height);
y = (!axis.opposedPosition ? (bounds.y - lineSize - minor.height) : bounds.y + lineSize) + minor.offset;
axis.minorTickBounds = new Rect(bounds.x, y, bounds.width, minor.height);
}
}
/**
* To Calculate axis label bounds
* @param axis
* @param axisIndex
*/
calculateLabelBounds(axis, axisIndex) {
let x;
let y;
let width;
let height;
let padding = 5;
let bounds = axis.majorTickBounds;
let offset = axis.labelStyle.offset;
this.calculateVisibleLabels(axis);
width = axis.maxLabelSize.width;
height = axis.maxLabelSize.height / 2;
if (this.gauge.orientation === 'Vertical') {
x = (!axis.opposedPosition ? (bounds.x - width - padding) : (bounds.x + bounds.width + padding)) + offset;
y = axis.lineBounds.y;
}
else {
y = (!axis.opposedPosition ? (bounds.y - padding) : ((bounds.y + bounds.height + padding) + height)) + offset;
x = axis.lineBounds.x;
}
axis.labelBounds = new Rect(x, y, width, height);
}
/**
* Calculate pointer bounds
* @param axis
* @param axisIndex
*/
calculatePointerBounds(axis, axisIndex) {
let pointer;
let range = axis.visibleRange;
let orientation = this.gauge.orientation;
let line = axis.lineBounds;
let label = axis.labelBounds;
let minimumValue = Math.min(range.min, range.max);
let maximumValue = Math.max(range.min, range.max);
for (let i = 0; i < axis.pointers.length; i++) {
pointer = axis.pointers[i];
pointer.currentValue = pointer.value !== null ?
pointer.value < minimumValue ? minimumValue : pointer.value > maximumValue ? maximumValue : pointer.value
: minimumValue;
if (pointer.width > 0 && withInRange(pointer.currentValue, null, null, range.max, range.min, 'pointer')) {
this['calculate' + pointer.type + 'Bounds'](axisIndex, axis, i, pointer);
}
}
}
/**
* Calculate marker pointer bounds
* @param axisIndex
* @param axis
* @param pointerIndex
* @param pointer
*/
calculateMarkerBounds(axisIndex, axis, pointerIndex, pointer) {
let x;
let y;
let line = axis.lineBounds;
let offset = pointer.offset;
let range = axis.visibleRange;
let placement = pointer.placement;
let tick = axis.majorTickBounds;
let label = axis.labelBounds;
let border = pointer.border.width;
if (this.gauge.orientation === 'Vertical') {
x = (!axis.opposedPosition) ? (placement === 'Near') ? label.x : (placement === 'Center') ? tick.x : line.x :
placement === 'Far' ? label.x + label.width : (placement === 'Center' ? tick.x + tick.width : line.x);
x = !axis.opposedPosition ? ((pointer.placement === 'Far' ? x + border : x - border) + (offset)) :
((pointer.placement === 'Near' ? x - border : x + border) + (offset));
y = ((valueToCoefficient(pointer.currentValue, axis, this.gauge.orientation, range) * line.height) + line.y);
}
else {
y = (!axis.opposedPosition) ? (placement === 'Near') ? label.y - label.height : (placement === 'Center') ? tick.y :
line.y : (placement === 'Far') ? label.y : (placement === 'Center') ? tick.y + tick.height : line.y;
y = !axis.opposedPosition ? ((pointer.placement === 'Far' ? y + border : y - border) + (offset)) :
((pointer.placement === 'Near' ? y - border : y + border) + (offset));
x = ((valueToCoefficient(pointer.currentValue, axis, this.gauge.orientation, range) * line.width) + line.x);
}
pointer.bounds = new Rect(x, y, pointer.width, pointer.height);
}
/**
* Calculate bar pointer bounds
* @param axisIndex
* @param axis
* @param pointerIndex
* @param pointer
*/
calculateBarBounds(axisIndex, axis, pointerIndex, pointer) {
let x1;
let x2;
let y1;
let y2;
let height;
let width;
let line = axis.lineBounds;
let padding = 10;
let range = axis.visibleRange;
let orientation = this.gauge.orientation;
let offset = pointer.offset;
let container = this.gauge.containerBounds;
if (orientation === 'Vertical') {
x1 = (container.width > 0) ? container.x + ((container.width / 2) - (pointer.width / 2)) :
(!axis.opposedPosition) ? (line.x + padding) : (line.x - pointer.width - padding);
x1 += (offset);
y1 = ((valueToCoefficient(pointer.currentValue, axis, orientation, range) * line.height) + line.y);
y2 = ((valueToCoefficient(range.min, axis, orientation, range) * line.height) + line.y);
height = Math.abs(y2 - y1);
y1 = (!axis.isInversed) ? y1 : y2;
width = pointer.width;
}
else {
x1 = ((valueToCoefficient(range.min, axis, orientation, range) * line.width) + line.x);
y1 = (container.height > 0) ? (container.y + (container.height / 2) - (pointer.height) / 2) :
(!axis.opposedPosition) ? (line.y + padding) : (line.y - pointer.height - padding);
y1 += (offset);
height = pointer.height;
x2 = ((valueToCoefficient(pointer.currentValue, axis, orientation, range) * line.width) + line.x);
width = Math.abs(x2 - x1);
x1 = (!axis.isInversed) ? x1 : x2;
}
pointer.bounds = new Rect(x1, y1, width, height);
}
/**
* Calculate ranges bounds
* @param axis
* @param axisIndex
*/
calculateRangesBounds(axis, axisIndex) {
let range;
let start;
let end;
let line = axis.lineBounds;
let visibleRange = axis.visibleRange;
let orientation = this.gauge.orientation;
let startVal;
let endVal;
let pointX;
let pointY;
let width;
let height;
let position;
let startWidth;
let endWidth;
let colors;
for (let i = 0; i < axis.ranges.length; i++) {
range = axis.ranges[i];
if (withInRange(null, range.start, range.end, visibleRange.max, visibleRange.min, 'range')) {
start = Math.min(range.start, range.end);
end = Math.max(range.start, range.end);
position = range.position;
startWidth = range.startWidth;
endWidth = range.endWidth;
colors = this.gauge.rangePalettes.length ? this.gauge.rangePalettes : getRangePalette();
range.interior = range.color ? range.color : colors[i % colors.length];
if (this.gauge.orientation === 'Vertical') {
pointX = line.x + (range.offset);
pointY = (valueToCoefficient(end, axis, orientation, visibleRange) * line.height) + line.y;
height = (valueToCoefficient(start, axis, orientation, visibleRange) * line.height) + line.y;
height -= pointY;
startVal = !axis.opposedPosition ? position === 'Inside' ? (pointX + startWidth) : (pointX - startWidth)
: position === 'Inside' ? (pointX - startWidth) : (pointX + startWidth);
endVal = !axis.opposedPosition ? position === 'Inside' ? (pointX + endWidth) : (pointX - endWidth) :
position === 'Inside' ? (pointX - endWidth) : (pointX + endWidth);
range.path = 'M' + pointX + ' ' + pointY + ' L ' + pointX + ' ' + (pointY + height) +
' L ' + startVal + ' ' + (pointY + height) + ' L ' + endVal + ' ' + pointY +
' L ' + pointX + ' ' + pointY + ' z ';
}
else {
pointX = (valueToCoefficient(end, axis, orientation, visibleRange) * line.width) + line.x;
pointY = axis.lineBounds.y + (range.offset);
width = (valueToCoefficient(start, axis, orientation, visibleRange) * line.width) + line.x;
width = pointX - width;
startVal = !axis.opposedPosition ? position === 'Inside' ? (pointY + startWidth) :
(pointY - startWidth) : (position === 'Inside') ? (pointY - startWidth) :
(pointY + startWidth);
endVal = !axis.opposedPosition ? position === 'Inside' ? (pointY + endWidth) : (pointY - endWidth) :
(position === 'Inside') ? (pointY - endWidth) : (pointY + endWidth);
range.path = 'M' + pointX + ' ' + pointY + ' L ' + (pointX - width) + ' ' + pointY +
' L ' + (pointX - width) + ' ' + startVal + ' L ' + pointX + ' ' + endVal +
' L ' + pointX + ' ' + pointY + ' z ';
}
}
}
}
checkPreviousAxes(currentAxis, axisIndex) {
let index = axisIndex - 1;
let prevAxis;
let isPositive = (index >= 0) ? true : false;
if (isPositive) {
prevAxis = this.gauge.axes[index];
index = (prevAxis.checkAlign.align === currentAxis.checkAlign.align) ? index : this.checkPreviousAxes(currentAxis, index);
}
else {
index = null;
}
return index;
}
/**
*
* @param axis To calculate the visible labels
*/
calculateVisibleLabels(axis) {
axis.visibleLabels = [];
let min = axis.visibleRange.min;
let max = axis.visibleRange.max;
let interval = axis.visibleRange.interval;
let format;
let argsData;
let style = axis.labelStyle;
let labelSize;
let customLabelFormat = style.format && style.format.match('{value}') !== null;
format = this.gauge.intl.getNumberFormat({
format: getLabelFormat(style.format), useGrouping: this.gauge.useGroupingSeparator
});
for (let i = min; (i <= max && interval > 0); i += interval) {
argsData = {
cancel: false, name: axisLabelRender, axis: axis,
text: customLabelFormat ? textFormatter(style.format, { value: i }, this.gauge) :
formatValue(i, this.gauge).toString(),
value: i
};
this.gauge.trigger('axisLabelRender', argsData, (argsData) => {
labelSize = measureText(argsData.text, axis.labelStyle.font);
if (!argsData.cancel) {
axis.visibleLabels.push(new VisibleLabels(argsData.text, i, labelSize));
}
});
}
this.getMaxLabelWidth(this.gauge, axis);
}
/**
* Calculate maximum label width for the axis.
* @return {void}
* @private
*/
getMaxLabelWidth(gauge, axis) {
axis.maxLabelSize = new Size(0, 0);
let label;
for (let i = 0; i < axis.visibleLabels.length; i++) {
label = axis.visibleLabels[i];
label.size = measureText(label.text, axis.labelStyle.font);
if (label.size.width > axis.maxLabelSize.width) {
axis.maxLabelSize.width = label.size.width;
}
if (label.size.height > axis.maxLabelSize.height) {
axis.maxLabelSize.height = label.size.height;
}
}
}
checkThermometer() {
if (this.gauge.container.type === 'Thermometer') {
this.gauge.axes.map((axis, index) => {
if (axis.isInversed) {
axis.pointers.map((pointer, index) => {
if (pointer.type === 'Bar') {
axis.isInversed = false;
}
});
}
});
}
}
}
/**
* @private
* To handle the animation for gauge
*/
class Animations {
constructor(gauge) {
this.gauge = gauge;
}
/**
* To do the marker pointer animation.
* @return {void}
* @private
*/
performMarkerAnimation(element, axis, pointer) {
let markerElement = element;
let options;
let timeStamp;
let range = axis.visibleRange;
let rectHeight = (this.gauge.orientation === 'Vertical') ? axis.lineBounds.height : axis.lineBounds.width;
let rectY = (this.gauge.orientation === 'Vertical') ? axis.lineBounds.y : axis.lineBounds.x;
if (this.gauge.orientation === 'Vertical') {
pointer.bounds.y = (valueToCoefficient(pointer.currentValue, axis, this.gauge.orientation, range) * rectHeight) + rectY;
}
else {
pointer.bounds.x = (valueToCoefficient(pointer.currentValue, axis, this.gauge.orientation, range) * rectHeight) + rectY;
}
options = new PathOption(markerElement.id, null, null, null);
options = calculateShapes(pointer.bounds, pointer.markerType, new Size(pointer.width, pointer.height), pointer.imageUrl, options, this.gauge.orientation, axis,