@progress/kendo-charts
Version:
Kendo UI platform-independent Charts library
351 lines (284 loc) • 11.6 kB
JavaScript
import { ChartElement, Box } from '../../core';
import ClipAnimationMixin from '../mixins/clip-animation-mixin';
import ErrorRangeCalculator from '../error-bars/error-range-calculator';
import ScatterErrorBar from '../error-bars/scatter-error-bar';
import LinePoint from '../line-chart/line-point';
import { hasValue, evalOptions } from '../utils';
import { deepExtend, isNumber, isString, defined, isFunction, setDefaultOptions } from '../../common';
import { X, Y, MIN_VALUE, MAX_VALUE } from '../../common/constants';
import { parseDate } from '../../date-utils';
var ScatterChart = (function (ChartElement) {
function ScatterChart(plotArea, options) {
ChartElement.call(this, options);
this.plotArea = plotArea;
this.chartService = plotArea.chartService;
this._initFields();
this.render();
}
if ( ChartElement ) ScatterChart.__proto__ = ChartElement;
ScatterChart.prototype = Object.create( ChartElement && ChartElement.prototype );
ScatterChart.prototype.constructor = ScatterChart;
ScatterChart.prototype._initFields = function _initFields () {
// X and Y axis ranges grouped by name, e.g.:
// primary: { min: 0, max: 1 }
this.xAxisRanges = {};
this.yAxisRanges = {};
this.points = [];
this.seriesPoints = [];
this.seriesOptions = [];
this._evalSeries = [];
};
ScatterChart.prototype.render = function render () {
this.traverseDataPoints(this.addValue.bind(this));
};
ScatterChart.prototype.addErrorBar = function addErrorBar (point, field, fields) {
var value = point.value[field];
var valueErrorField = field + "Value";
var lowField = field + "ErrorLow";
var highField = field + "ErrorHigh";
var seriesIx = fields.seriesIx;
var series = fields.series;
var errorBars = point.options.errorBars;
var lowValue = fields[lowField];
var highValue = fields[highField];
if (isNumber(value)) {
var errorRange;
if (isNumber(lowValue) && isNumber(highValue)) {
errorRange = { low: lowValue, high: highValue };
}
if (errorBars && defined(errorBars[valueErrorField])) {
this.seriesErrorRanges = this.seriesErrorRanges || { x: [], y: [] };
this.seriesErrorRanges[field][seriesIx] = this.seriesErrorRanges[field][seriesIx] ||
new ErrorRangeCalculator(errorBars[valueErrorField], series, field);
errorRange = this.seriesErrorRanges[field][seriesIx].getErrorRange(value, errorBars[valueErrorField]);
}
if (errorRange) {
this.addPointErrorBar(errorRange, point, field);
}
}
};
ScatterChart.prototype.addPointErrorBar = function addPointErrorBar (errorRange, point, field) {
var low = errorRange.low;
var high = errorRange.high;
var series = point.series;
var options = point.options.errorBars;
var isVertical = field === Y;
var item = {};
point[field + "Low"] = low;
point[field + "High"] = high;
point.errorBars = point.errorBars || [];
var errorBar = new ScatterErrorBar(low, high, isVertical, this, series, options);
point.errorBars.push(errorBar);
point.append(errorBar);
item[field] = low;
this.updateRange(item, series);
item[field] = high;
this.updateRange(item, series);
};
ScatterChart.prototype.addValue = function addValue (value, fields) {
var x = value.x;
var y = value.y;
var seriesIx = fields.seriesIx;
var series = this.options.series[seriesIx];
var missingValues = this.seriesMissingValues(series);
var seriesPoints = this.seriesPoints[seriesIx];
var pointValue = value;
if (!(hasValue(x) && hasValue(y))) {
pointValue = this.createMissingValue(pointValue, missingValues);
}
var point;
if (pointValue) {
point = this.createPoint(pointValue, fields);
if (point) {
Object.assign(point, fields);
this.addErrorBar(point, X, fields);
this.addErrorBar(point, Y, fields);
}
this.updateRange(pointValue, fields.series);
}
this.points.push(point);
seriesPoints.push(point);
};
ScatterChart.prototype.seriesMissingValues = function seriesMissingValues (series) {
return series.missingValues;
};
ScatterChart.prototype.createMissingValue = function createMissingValue () {};
ScatterChart.prototype.updateRange = function updateRange (value, series) {
var intlService = this.chartService.intl;
var xAxisName = series.xAxis;
var yAxisName = series.yAxis;
var x = value.x;
var y = value.y;
var xAxisRange = this.xAxisRanges[xAxisName];
var yAxisRange = this.yAxisRanges[yAxisName];
if (hasValue(x)) {
xAxisRange = this.xAxisRanges[xAxisName] =
xAxisRange || { min: MAX_VALUE, max: MIN_VALUE };
if (isString(x)) {
x = parseDate(intlService, x);
}
xAxisRange.min = Math.min(xAxisRange.min, x);
xAxisRange.max = Math.max(xAxisRange.max, x);
}
if (hasValue(y)) {
yAxisRange = this.yAxisRanges[yAxisName] =
yAxisRange || { min: MAX_VALUE, max: MIN_VALUE };
if (isString(y)) {
y = parseDate(intlService, y);
}
yAxisRange.min = Math.min(yAxisRange.min, y);
yAxisRange.max = Math.max(yAxisRange.max, y);
}
};
ScatterChart.prototype.evalPointOptions = function evalPointOptions (options, value, fields) {
var series = fields.series;
var seriesIx = fields.seriesIx;
var state = {
defaults: series._defaults,
excluded: [
"data", "tooltip", "content", "template", "visual", "toggle",
"_outOfRangeMinPoint", "_outOfRangeMaxPoint",
"drilldownSeriesFactory", "ariaTemplate", "ariaContent"
]
};
var doEval = this._evalSeries[seriesIx];
if (!defined(doEval)) {
this._evalSeries[seriesIx] = doEval = evalOptions(options, {}, state, true);
}
var pointOptions = options;
if (doEval) {
pointOptions = deepExtend({}, options);
evalOptions(pointOptions, {
value: value,
series: series,
dataItem: fields.dataItem
}, state);
}
return pointOptions;
};
ScatterChart.prototype.pointType = function pointType () {
return LinePoint;
};
ScatterChart.prototype.pointOptions = function pointOptions (series, seriesIx) {
var options = this.seriesOptions[seriesIx];
if (!options) {
var defaults = this.pointType().prototype.defaults;
this.seriesOptions[seriesIx] = options = deepExtend({}, defaults, {
markers: {
opacity: series.opacity
},
tooltip: {
format: this.options.tooltip.format
},
labels: {
format: this.options.labels.format
}
}, series);
}
return options;
};
ScatterChart.prototype.createPoint = function createPoint (value, fields) {
var series = fields.series;
var pointOptions = this.pointOptions(series, fields.seriesIx);
var color = fields.color || series.color;
pointOptions = this.evalPointOptions(pointOptions, value, fields);
if (isFunction(series.color)) {
color = pointOptions.color;
}
var point = new LinePoint(value, pointOptions);
point.color = color;
this.append(point);
return point;
};
ScatterChart.prototype.seriesAxes = function seriesAxes (series) {
var xAxisName = series.xAxis;
var yAxisName = series.yAxis;
var plotArea = this.plotArea;
var xAxis = xAxisName ? plotArea.namedXAxes[xAxisName] : plotArea.axisX;
var yAxis = yAxisName ? plotArea.namedYAxes[yAxisName] : plotArea.axisY;
if (!xAxis) {
throw new Error("Unable to locate X axis with name " + xAxisName);
}
if (!yAxis) {
throw new Error("Unable to locate Y axis with name " + yAxisName);
}
return {
x: xAxis,
y: yAxis
};
};
ScatterChart.prototype.reflow = function reflow (targetBox) {
var this$1 = this;
var chartPoints = this.points;
var limit = !this.options.clip;
var pointIx = 0;
this.traverseDataPoints(function (value, fields) {
var point = chartPoints[pointIx++];
var seriesAxes = this$1.seriesAxes(fields.series);
var slotX = seriesAxes.x.getSlot(value.x, value.x, limit);
var slotY = seriesAxes.y.getSlot(value.y, value.y, limit);
if (point) {
if (slotX && slotY) {
var pointSlot = this$1.pointSlot(slotX, slotY);
point.reflow(pointSlot);
} else {
point.visible = false;
}
}
});
this.box = targetBox;
};
ScatterChart.prototype.pointSlot = function pointSlot (slotX, slotY) {
return new Box(slotX.x1, slotY.y1, slotX.x2, slotY.y2);
};
ScatterChart.prototype.traverseDataPoints = function traverseDataPoints (callback) {
var this$1 = this;
var ref = this;
var series = ref.options.series;
var seriesPoints = ref.seriesPoints;
for (var seriesIx = 0; seriesIx < series.length; seriesIx++) {
var currentSeries = series[seriesIx];
var currentSeriesPoints = seriesPoints[seriesIx];
if (!currentSeriesPoints) {
seriesPoints[seriesIx] = [];
}
for (var pointIx = 0; pointIx < currentSeries.data.length; pointIx++) {
var ref$1 = this$1.plotArea.bindPoint(currentSeries, pointIx);
var value = ref$1.valueFields;
var fields = ref$1.fields;
callback(value, deepExtend({
pointIx: pointIx,
series: currentSeries,
seriesIx: seriesIx,
dataItem: currentSeries.data[pointIx],
owner: this$1
}, fields));
}
}
};
ScatterChart.prototype.formatPointValue = function formatPointValue (point, format) {
var value = point.value;
return this.chartService.format.auto(format, value.x, value.y);
};
ScatterChart.prototype.animationPoints = function animationPoints () {
var points = this.points;
var result = [];
for (var idx = 0; idx < points.length; idx++) {
result.push((points[idx] || {}).marker);
}
return result;
};
return ScatterChart;
}(ChartElement));
setDefaultOptions(ScatterChart, {
series: [],
tooltip: {
format: "{0}, {1}"
},
labels: {
format: "{0}, {1}"
},
clip: true
});
deepExtend(ScatterChart.prototype, ClipAnimationMixin);
export default ScatterChart;