@progress/kendo-ui
Version:
This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.
1,543 lines (1,275 loc) • 54.7 kB
JavaScript
import './kendo.breadcrumb.js';
import './kendo.data.js';
import './kendo.dataviz.core.js';
import './kendo.dataviz.themes.js';
import './html-DIrOxn6k.js';
import './kendo.userevents.js';
import './kendo.icons.js';
import * as chartExport from '@progress/kendo-charts/dist/es/chart-export.js';
import { DomEventsBuilder, InstanceObserver, SeriesBinder, defined, getField, Chart, chartBaseTheme, chartTheme, grep, inArray } from '@progress/kendo-charts';
import './kendo.core.js';
import './kendo.licensing.js';
import '@progress/kendo-licensing';
import './kendo.html.icon.js';
import './kendo.html.base.js';
import '@progress/kendo-svg-icons';
import './kendo.data.odata.js';
import './kendo.data.xml.js';
import '@progress/kendo-charts/dist/es/core-export.js';
import './kendo.popup.js';
import '@progress/kendo-drawing';
import './kendo.color.js';
(function($, undefined$1) {
const kendo = window.kendo;
const dataviz = kendo.dataviz;
const Widget = kendo.ui.Widget;
const ChartBreadcrumb = Widget.extend({
init: function(element, options) {
Widget.fn.init.call(this, element, options);
if (!options.chart) {
throw new Error('ChartBreadcrumb: No Chart instance supplied as `options.chart`');
}
this._attachChartEvents();
this._renderBreadcrumb();
kendo.notify(this, dataviz.ui);
},
events: [],
options: {
name: "ChartBreadcrumb",
rootItem: {
type: 'rootitem',
icon: 'home',
text: 'Home',
showIcon: true
}
},
destroy: function() {
if (this.breadcrumb) {
this.breadcrumb.destroy();
this.breadcrumb = null;
}
if (this.chart) {
this.chart.unbind('drilldown', this._onChartDrilldown);
this.chart.unbind('drilldownLevelChange', this._onChartDrilldownLevelChange);
this.chart = null;
}
Widget.fn.destroy.call(this);
},
_attachChartEvents(deferred) {
const options = this.options;
if (typeof options.chart.resetDrilldownLevel === 'function') {
this.chart = options.chart;
} else if (typeof options.chart === 'string') {
this.chart = $(options.chart).getKendoChart() || $('#' + options.chart).getKendoChart();
if (!this.chart && !deferred) {
setTimeout(() => this._attachChartEvents(true));
return;
}
} else {
throw new Error('ChartBreadcrumb: `options.chart` must be a Chart instance, element ID or a selector');
}
this._onChartDrilldown = this._onChartDrilldown.bind(this);
this.chart.bind('drilldown', this._onChartDrilldown);
this._onChartDrilldownLevelChange = this._onChartDrilldownLevelChange.bind(this);
this.chart.bind('drilldownLevelChange', this._onChartDrilldownLevelChange);
},
_renderBreadcrumb: function() {
const breadcrumbElement = $('<nav />');
this.element.append(breadcrumbElement);
this.breadcrumb = new kendo.ui.Breadcrumb(breadcrumbElement, {
items: [this.options.rootItem]
});
this.breadcrumb.bind('click', e => this._onBreadcrumbClick(e));
},
_onBreadcrumbClick: function(e) {
if (!this.breadcrumb || !this.chart) {
return;
}
let items = this.breadcrumb.items();
const level = items.findIndex((item) => item === e.item);
const chart = this.chart;
chart.resetDrilldownLevel(level);
},
_onChartDrilldown: function(e) {
if (!this.breadcrumb || e.isDefaultPrevented()) {
return;
}
this.breadcrumb.items([
...this.breadcrumb.items(),
{ type: 'item', text: e.point.category }
]);
},
_onChartDrilldownLevelChange: function(e) {
if (!this.breadcrumb) {
return;
}
let items = this.breadcrumb.items();
items = items.slice(0, e.level + 1);
this.breadcrumb.items(items);
}
});
dataviz.ui.plugin(ChartBreadcrumb);
})(window.kendo.jQuery);
const __meta__ = {
id: "dataviz.chart",
name: "Chart",
category: "dataviz",
description: "The Chart widget uses modern browser technologies to render high-quality data visualizations in the browser.",
depends: [ "data", "userevents", "drawing", "dataviz.core", "dataviz.themes", "breadcrumb" ],
features: [{
id: "dataviz.chart-pdf-export",
name: "PDF export",
description: "Export Chart as PDF",
depends: [ "pdf" ]
}]
};
(function($, undefined$1) {
var kendo = window.kendo;
kendo.dataviz = kendo.dataviz || {};
kendo.deepExtend(kendo.dataviz, kendo.deepExtend({}, chartExport));
var NS = ".kendoChart";
var Class = kendo.Class;
var outerWidth = kendo._outerWidth;
var outerHeight = kendo._outerHeight;
var dataviz = kendo.dataviz;
var Widget = kendo.ui.Widget;
var DataSource = kendo.data.DataSource;
var deepExtend = kendo.deepExtend;
var isArray = Array.isArray;
var extend = $.extend;
var template = kendo.template;
var encode = kendo.htmlEncode;
var MOUSELEAVE_NS = "mouseleave" + NS;
var constants = chartExport.constants;
var AXIS_LABEL_CLICK = "axisLabelClick";
var LEGEND_ITEM_CLICK = constants.LEGEND_ITEM_CLICK;
var LEGEND_ITEM_HOVER = constants.LEGEND_ITEM_HOVER;
var LEGEND_ITEM_LEAVE = constants.LEGEND_ITEM_LEAVE;
var SERIES_CLICK = constants.SERIES_CLICK;
var SERIES_HOVER = constants.SERIES_HOVER;
var SERIES_OVER = constants.SERIES_OVER;
var SERIES_LEAVE = constants.SERIES_LEAVE;
var PANE_RENDER = constants.PANE_RENDER;
var PLOT_AREA_CLICK = constants.PLOT_AREA_CLICK;
var PLOT_AREA_HOVER = constants.PLOT_AREA_HOVER;
var PLOT_AREA_LEAVE = constants.PLOT_AREA_LEAVE;
var DRAG = constants.DRAG;
var DRAG_END = constants.DRAG_END;
var DRAG_START = constants.DRAG_START;
var DRILLDOWN = constants.DRILLDOWN;
var DRILLDOWN_LEVEL_CHANGE = "drilldownLevelChange";
var ZOOM_START = constants.ZOOM_START;
var ZOOM = constants.ZOOM;
var ZOOM_END = constants.ZOOM_END;
var SELECT_START = constants.SELECT_START;
var SELECT = constants.SELECT;
var SELECT_END = constants.SELECT_END;
var RENDER = constants.RENDER;
var NOTE_CLICK = "noteClick";
var NOTE_HOVER = "noteHover";
var NOTE_LEAVE = "noteLeave";
var DOCUMENT_ELEMENT = $(document.documentElement);
var CHANGE = "change";
var DATABOUND = "dataBound";
var LEAVE = "leave";
var MOUSEDOWN = "down";
var VALUE = "value";
var PIE = constants.PIE;
var DONUT = constants.DONUT;
var FUNNEL = constants.FUNNEL;
var Observable = kendo.Observable;
var TOOLTIP_ANIMATION_DURATION = 150;
var TOOLTIP_SHOW_DELAY = 100;
var TOOLTIP_INVERSE = "k-chart-tooltip-inverse";
var SHARED_TOOLTIP_CLASS = "k-chart-shared-tooltip";
var RTL = "rtl";
DomEventsBuilder.register({
create: function(element, events) {
return new kendo.UserEvents(element, deepExtend({
global: true,
multiTouch: true,
fastTap: true
}, events));
}
});
let ConvertedObserver = kendo.ConvertClass(InstanceObserver);
var ChartInstanceObserver = ConvertedObserver.extend({
handlerMap: {
showTooltip: '_showTooltip',
hideTooltip: '_hideTooltip',
legendItemClick: '_onLegendItemClick',
render: '_onRender',
init: '_onInit',
drilldown: '_onDrilldown'
}
});
var Chart$1 = Widget.extend({
init: function(element, userOptions) {
var dataSource;
kendo.destroy(element);
Widget.fn.init.call(this, element);
if (userOptions) {
dataSource = userOptions.dataSource;
delete userOptions.dataSource;
}
this.options = deepExtend({}, this.options, userOptions);
this.wrapper = this.element;
this._attachEvents();
if (userOptions) {
userOptions.dataSource = dataSource;
}
this._seriesVisibility = new SeriesVisibilityState();
this.bind(this.events, this.options);
this._initDataSource(userOptions);
this._drilldownState = [];
kendo.notify(this, dataviz.ui);
if (this._showWatermarkOverlay) {
this._showWatermarkOverlay(this.wrapper[0]);
}
},
events: [
DATABOUND,
DRILLDOWN,
DRILLDOWN_LEVEL_CHANGE,
SERIES_CLICK,
SERIES_HOVER,
SERIES_OVER,
SERIES_LEAVE,
AXIS_LABEL_CLICK,
LEGEND_ITEM_CLICK,
LEGEND_ITEM_HOVER,
LEGEND_ITEM_LEAVE,
PANE_RENDER,
PLOT_AREA_CLICK,
PLOT_AREA_HOVER,
PLOT_AREA_LEAVE,
DRAG_START,
DRAG,
DRAG_END,
ZOOM_START,
ZOOM,
ZOOM_END,
SELECT_START,
SELECT,
SELECT_END,
NOTE_CLICK,
NOTE_HOVER,
NOTE_LEAVE,
RENDER
],
options: {
name: "Chart",
renderAs: "",
theme: "sass",
axisDefaults: {},
chartArea: {},
legend: {},
categoryAxis: {},
autoBind: true,
seriesDefaults: {},
series: [],
seriesColors: null,
tooltip: {},
transitions: true,
valueAxis: {},
plotArea: {},
title: {},
xAxis: {},
yAxis: {},
panes: [{}],
pannable: false,
zoomable: false,
noData: true,
messages: {
noData: "No data available"
}
},
items: function() {
return $();
},
refresh: function() {
var chart = this;
var instance = chart._instance;
instance.applyDefaults(chart.options);
instance.applySeriesColors();
chart._bindSeries();
chart._bindCategories();
chart.trigger(DATABOUND);
chart._redraw();
},
getSize: function() {
return kendo.dimensions(this.element);
},
redraw: function(paneName) {
this._size = null;
this._instance.redraw(paneName);
},
setOptions: function(options) {
var chart = this,
dataSource = options.dataSource;
delete options.dataSource;
Widget.fn._setEvents.call(chart, options);
this._instance.applyOptions(options, this._getThemeOptions(options));
this.options = this._instance.options;
this._tooltip.setOptions(this.options.tooltip);
this._seriesVisibility.setOptions(this.options);
this._sourceSeries = null;
if (dataSource) {
chart.setDataSource(dataSource);
}
if (chart._hasDataSource) {
chart._onDataChanged();
} else {
chart._bindCategories();
chart.redraw();
}
chart._destroyNoData();
chart._initNoData();
chart._instance.updateMouseMoveHandler();
chart._instance._restoreOverlayElement();
},
setDataSource: function(dataSource) {
var chart = this;
chart.dataSource.unbind(CHANGE, chart._dataChangeHandler);
chart.dataSource = dataSource = DataSource.create(dataSource);
chart._hasDataSource = true;
chart._hasData = false;
dataSource.bind(CHANGE, chart._dataChangeHandler);
if (chart.options.autoBind) {
dataSource.fetch();
}
},
destroy: function() {
var chart = this,
dataSource = chart.dataSource;
chart.element.off(NS);
if (dataSource) {
dataSource.unbind(CHANGE, chart._dataChangeHandler);
}
if (chart._instance) {
chart._instance.destroy();
delete this._instance;
}
if (this._tooltip) {
this._tooltip.destroy();
delete this._tooltip;
}
this._destroyNoData();
this._destroyCrosshairTooltips();
Widget.fn.destroy.call(chart);
},
findPaneByName: function(name) {
var panes = this._plotArea.panes;
for (var idx = 0; idx < panes.length; idx++) {
if (panes[idx].options.name === name) {
return new ChartPane(this, panes[idx]);
}
}
},
findPaneByIndex: function(idx) {
var panes = this._plotArea.panes;
if (panes[idx]) {
return new ChartPane(this, panes[idx]);
}
},
findSeries: function(callback) {
var plotArea = this._plotArea;
var series = plotArea.srcSeries || plotArea.series;
for (var idx = 0; idx < series.length; idx++) {
if (callback(series[idx])) {
return new ChartSeries(this, series[idx]);
}
}
},
findSeriesByName: function(name) {
return this._createSeries({ name: name });
},
findSeriesByIndex: function(index) {
return this._createSeries({ index: index });
},
exportVisual: function(options) {
var instance = this._instance;
if (!instance) {
return;
}
var visual;
//TO DO: support for setting any options. already available in kendo-charts
if (options && (options.width || options.height)) {
var chartArea = instance.options.chartArea;
var originalChartArea = instance._originalOptions.chartArea;
deepExtend(chartArea, options);
var model = instance._getModel();
chartArea.width = originalChartArea.width;
chartArea.height = originalChartArea.height;
model.renderVisual();
triggerPaneRender(model._plotArea.panes);
visual = model.visual;
} else {
visual = instance.exportVisual();
}
return visual;
},
resetDrilldownLevel(level) {
level = level || 0;
const state = this._drilldownState;
if (!state || level < 0 || level > state.length - 1) {
return;
}
const args = {
level,
sender: this
};
this.trigger(DRILLDOWN_LEVEL_CHANGE, args);
this.options.series = this._drilldownState[level];
this._drilldownState = this._drilldownState.slice(0, level);
this._bindCategories();
this._redraw();
},
_createSeries: function(options) {
var seriesOptions = this._seriesOptions(options);
if (seriesOptions) {
return new ChartSeries(this, seriesOptions);
}
},
_seriesOptions: function(options) {
var plotArea = this._plotArea;
var series = plotArea.srcSeries || plotArea.series;
var seriesOptions;
if (defined(options.index)) {
seriesOptions = series[options.index];
} else if (defined(options.name)) {
for (var idx = 0; idx < series.length; idx++) {
if (series[idx].name === options.name) {
seriesOptions = series[idx];
break;
}
}
}
return seriesOptions;
},
_attachEvents: function() {
this.element.on(MOUSELEAVE_NS, this._mouseleave.bind(this));
},
_mouseleave: function(e) {
var instance = this._instance;
var tooltip = this._tooltip;
var target = e.relatedTarget;
if (!(target && $(target).closest(tooltip.element).length) && instance && !instance.handlingTap) {
instance.hideElements({
keepTooltipOpen: !tooltip.options.autoHide
});
}
},
_getThemeOptions: function(userOptions) {
var themeName = (userOptions || {}).theme;
if (themeName && dataviz.SASS_THEMES.indexOf(themeName.toLowerCase()) !== -1) {
this.element.addClass("k-chart");
const theme = deepExtend(chartBaseTheme(), chartTheme(this.element[0]));
this.element.removeClass("k-chart");
return theme;
}
if (defined(themeName)) {
var themes = dataviz.ui.themes || {};
var theme = themes[themeName] || themes[themeName.toLowerCase()] || {};
return theme.chart || {};
}
},
_initChart: function() {
this._createChart(this.options, this._getThemeOptions(this.options));
this.options = this._instance.options;
this._seriesVisibility.setOptions(this.options);
},
_createChart: function(options, themeOptions) {
this._instance = new Chart(this.element[0], options, themeOptions, {
observer: new InstanceObserver(this, {
showTooltip: '_showTooltip',
hideTooltip: '_hideTooltip',
legendItemClick: '_onLegendItemClick',
render: '_onRender',
init: '_onInit',
drilldown: '_onDrilldown'
}),
sender: this,
rtl: this._isRtl(),
createSurface: kendo.drawing.Surface.create
});
},
_onInit: function(e) {
this._instance = e.sender;
},
_initDataSource: function(userOptions) {
var chart = this,
dataSource = (userOptions || {}).dataSource;
chart._dataChangeHandler = chart._onDataChanged.bind(chart);
chart.dataSource = DataSource
.create(dataSource)
.bind("change", chart._dataChangeHandler);
chart._bindCategories();
if (dataSource) {
chart._hasDataSource = true;
}
this._initNoData();
this._initChart();
this._initTooltip();
if (dataSource) {
if (chart.options.autoBind) {
chart.dataSource.fetch();
}
}
},
_destroyCrosshairTooltips: function() {
var tooltips = this._crosshairTooltips;
if (tooltips) {
for (var key in tooltips) {
tooltips[key].destroy();
}
}
this._crosshairTooltips = {};
},
_getCrosshairTooltip: function(name, index) {
var tooltips = this._crosshairTooltips = this._crosshairTooltips || {};
var key = name + index;
var tooltip = tooltips[key];
if (!tooltip) {
tooltip = tooltips[key] = new CrosshairTooltip(this.element);
}
return tooltip;
},
_showTooltip: function(e) {
if (e.crosshair) {
var tooltip = this._getCrosshairTooltip(e.axisName, e.axisIndex);
tooltip.show(e);
} else if (this._tooltip) {
this._tooltip.show(e);
}
},
_hideTooltip: function(e) {
if (e.crosshair) {
var tooltip = this._getCrosshairTooltip(e.axisName, e.axisIndex);
tooltip.hide();
} else if (this._tooltip) {
this._tooltip.hide();
}
},
_onRender: function(e) {
this._destroyCrosshairTooltips();
this._copyMembers(e.sender);
if (!this._hasDataSource || this._hasData || !this.options.autoBind) {
this.trigger(RENDER);
}
},
_copyMembers: function(instance) {
this.options = instance.options;
this._originalOptions = instance._originalOptions;
this.surface = instance.surface;
this._plotArea = instance._plotArea;
this._model = instance._model;
this._highlight = instance._highlight;
this._selections = instance._selections;
this._pannable = instance._pannable;
this._zoomSelection = instance._zoomSelection;
this._mousewheelZoom = instance._mousewheelZoom;
},
requiresHandlers: function(names) {
var events = this._events;
for (var idx = 0; idx < names.length; idx++) {
if (defined(events[names[idx]])) {
return true;
}
}
},
_initTooltip: function() {
this._tooltip = this._createTooltip();
this._tooltip.bind(LEAVE, this._tooltipleave.bind(this));
},
_onLegendItemClick: function(e) {
if (!this.trigger(LEGEND_ITEM_CLICK, e)) {
this._legendItemClick(e.seriesIndex, e.pointIndex);
}
},
_legendItemClick: function(seriesIndex, pointIndex) {
var chart = this._instance,
plotArea = chart._plotArea,
currentSeries = (plotArea.srcSeries || plotArea.series)[seriesIndex];
if (chart._hasInactiveOpacity() && chart._activeChartInstance) {
chart._updateSeriesOpacity(null, true);
chart._applySeriesOpacity(chart._activeChartInstance.children, null, true);
chart._activeChartInstance = null;
}
if ($.inArray(currentSeries.type, [PIE, DONUT, FUNNEL]) >= 0) {
var point = currentSeries.data[pointIndex];
if (point && defined(point.visible)) {
point.visible = !point.visible;
} else {
var pointVisibility = currentSeries.pointVisibility = currentSeries.pointVisibility || {};
var visible = pointVisibility[pointIndex];
pointVisibility[pointIndex] = defined(visible) ? !visible : false;
}
} else {
currentSeries.visible = !currentSeries.visible;
this._seriesVisibility.save(currentSeries);
}
chart._noTransitionsRedraw();
},
_createTooltip: function() {
return new Tooltip(this.element, extend({}, this.options.tooltip, {
rtl: this._isRtl()
}));
},
_tooltipleave: function() {
if (this._instance) {
this._instance.hideElements();
}
},
_onDrilldown: function(e) {
const { series, value } = e;
if (series.drilldownSeriesFactory) {
const result = series.drilldownSeriesFactory(value);
if (!result) {
return;
} else if (result instanceof Promise) {
result.then((resolved) => this._onDrilldownData(e, resolved));
} else {
this._onDrilldownData(e, result);
}
} else if (typeof value === 'object') {
this._onDrilldownData(e, value);
}
},
_onDrilldownData: function(e, data) {
const drilldownSeries = Object.assign({}, e.series, data);
const args = {
point: e.point,
series: e.series,
drilldownSeries,
sender: this
};
const prevented = this.trigger(DRILLDOWN, args);
if (!prevented) {
this._drilldownState.push(this.options.series);
this.options.series = [drilldownSeries];
this._bindCategories();
this._redraw();
}
},
_bindData: function(e) {
var chart = this,
options = chart.options,
series = chart._sourceSeries || options.series,
seriesIx,
seriesLength = series.length,
data = chart.dataSource.view(),
grouped = (chart.dataSource.group() || []).length > 0,
processedSeries = [],
seriesVisibility = this._seriesVisibility,
currentSeries,
groupedSeries;
seriesVisibility.read();
for (seriesIx = 0; seriesIx < seriesLength; seriesIx++) {
currentSeries = series[seriesIx];
if (chart._isBindable(currentSeries) && grouped) {
groupedSeries = groupSeries(currentSeries, data);
processedSeries = processedSeries.concat(groupedSeries);
seriesVisibility.applyByGroup(groupedSeries, e);
} else {
currentSeries = extend({}, currentSeries);
processedSeries.push(currentSeries);
seriesVisibility.applyByIndex(currentSeries, e);
}
}
chart._sourceSeries = series;
options.series = processedSeries;
this._instance.applySeriesColors();
chart._bindSeries();
chart._bindCategories();
this._hasData = true;
},
_initNoData: function() {
if (this._noData || this.options.noData === false) {
return;
}
const noDataWrap = $("<div class='k-chart-overlay'></div>");
this._noData = noDataWrap.hide().appendTo(this.wrapper);
const noDataContent = $("<div class='k-no-data'></div>");
noDataContent.appendTo(this._noData);
const template = this.options.noData?.template || (() => encode(this.options.messages.noData));
if (template) {
const templateFn = typeof template !== "function" ? kendo.template(template) : template;
noDataContent.html(templateFn({}));
}
if (this._instance && !this._instance.overlayElement) {
this._instance.overlayElement = noDataWrap[0];
}
},
_destroyNoData: function() {
if (this._noData) {
kendo.destroy(this._noData);
this._noData.remove();
delete this._noData;
delete this._noDataContent;
}
if (this._instance) {
delete this._instance.overlayElement;
}
},
_onDataChanged: function(e) {
this._bindData(e);
// If there is data in the dataSource, remove the no data overlay.
if (this.dataSource.total() > 0) {
this._destroyNoData();
}
this.trigger(DATABOUND);
if (this._instance && this._instance.fontLoaded) {
this._redraw();
}
},
_bindSeries: function() {
var chart = this,
data = chart.dataSource.view(),
series = chart.options.series,
instanceOrigOptions = this._instance ? this._instance._originalOptions : {},
instanceOrigSeries = instanceOrigOptions.series || [],
seriesIx,
seriesLength = series.length,
currentSeries,
groupIx,
seriesData;
for (seriesIx = 0; seriesIx < seriesLength; seriesIx++) {
currentSeries = series[seriesIx];
if (chart._isBindable(currentSeries)) {
groupIx = currentSeries._groupIx;
seriesData = defined(groupIx) ? (data[groupIx] || {}).items : data;
if (currentSeries.autoBind !== false) {
currentSeries.data = seriesData;
if (instanceOrigSeries[seriesIx]) {
instanceOrigSeries[seriesIx].data = seriesData.slice();
}
}
}
}
},
_bindCategories: function() {
var chart = this,
data = chart.dataSource.view() || [],
grouped = (chart.dataSource.group() || []).length > 0,
categoriesData = data,
options = chart.options,
definitions = [].concat(options.categoryAxis),
axisIx,
axis;
if (grouped) {
if (data.length) {
categoriesData = data[0].items;
}
}
for (axisIx = 0; axisIx < definitions.length; axisIx++) {
axis = definitions[axisIx];
if (axis.autoBind !== false) {
chart._bindCategoryAxis(axis, categoriesData, axisIx);
}
}
},
_bindCategoryAxis: function(axis, data, axisIx) {
var count = (data || []).length,
categoryIx,
category,
row;
if (axis.field) {
axis.categories = [];
for (categoryIx = 0; categoryIx < count; categoryIx++) {
row = data[categoryIx];
category = getField(axis.field, row);
if (categoryIx === 0) {
axis.categories = [category];
axis.dataItems = [row];
} else {
axis.categories.push(category);
axis.dataItems.push(row);
}
}
} else if (this._instance) {
this._instance.bindCategoryAxisFromSeries(axis, axisIx);
}
},
_isBindable: function(series) {
var valueFields = SeriesBinder.current.valueFields(series),
result = true,
field, i;
for (i = 0; i < valueFields.length; i++) {
field = valueFields[i];
if (field === VALUE) {
field = "field";
} else {
field = field + "Field";
}
if (!defined(series[field])) {
result = false;
break;
}
}
return result;
},
_isRtl: function() {
return kendo.support.isRtl(this.element) && this.element.css("direction") === RTL;
}
});
var proxyMembers = ["getAxis", "findAxisByName", "plotArea", "toggleHighlight", "showTooltip",
"hideTooltip", "_resize", "_redraw", "_noTransitionsRedraw", "_legendItemHover", "_eventCoordinates"];
function createProxyMember(name) {
Chart$1.fn[name] = function() {
var instance = this._instance;
if (instance) {
return instance[name].apply(instance, arguments);
}
};
}
for (var idx = 0; idx < proxyMembers.length; idx++) {
createProxyMember(proxyMembers[idx]);
}
function groupSeries(series, data) {
var result = [],
nameTemplate,
legacyTemplate = series.groupNameTemplate,
groupIx,
dataLength = data.length,
seriesClone,
defaultNameTemplate = ({ group }) => `${defined(series.name) ? group.value + ": " + series.name : group.value}`;
if (dataLength === 0) {
seriesClone = deepExtend({}, series);
seriesClone.visibleInLegend = false;
return [seriesClone];
}
if (defined(legacyTemplate)) {
kendo.logToConsole(
"'groupNameTemplate' is obsolete and will be removed in future versions. " +
"Specify the group name template as 'series.name'"
);
if (legacyTemplate) {
nameTemplate = template(legacyTemplate);
}
} else {
nameTemplate = template(series.name || defaultNameTemplate);
}
for (groupIx = 0; groupIx < dataLength; groupIx++) {
seriesClone = deepExtend({}, series);
if (!kendo.isFunction(seriesClone.color)) {
seriesClone.color = undefined$1;
}
seriesClone._groupIx = groupIx;
seriesClone._groupValue = data[groupIx].value;
result.push(seriesClone);
if (nameTemplate) {
seriesClone.name = nameTemplate({
series: seriesClone, group: data[groupIx]
});
}
}
return result;
}
dataviz.ExportMixin.extend(Chart$1.fn);
if (kendo.PDFMixin) {
kendo.PDFMixin.extend(Chart$1.fn);
}
dataviz.ui.plugin(Chart$1);
var SeriesVisibilityState = Class.extend({
init: function() {
this.groups = {};
this.index = {};
this.options = {};
},
applyByGroup: function(series, e) {
if ((e && e.action) || this.options.persistSeriesVisibility) {
for (var idx = 0; idx < series.length; idx++) {
if (this.groups[series[idx]._groupValue] === false) {
series[idx].visible = false;
}
}
} else {
this.groups = {};
}
},
applyByIndex: function(series, e) {
if ((e && e.action) || this.options.persistSeriesVisibility) {
if (this.index[series.index] === false) {
series.visible = false;
}
} else {
this.index = {};
}
},
save: function(series) {
if (!series) {
return;
}
if (this.options.persistSeriesVisibility) {
this.options.series[series.index].visible = series.visible;
} else {
this.saveState(series);
}
},
setOptions: function(options) {
this.options = options;
this.groups = {};
this.index = {};
},
read: function() {
var options = this.options;
if (options.persistSeriesVisibility) {
var series = options.series;
for (var idx = 0; idx < series.length; idx++) {
this.saveState(series[idx]);
}
}
},
saveState: function(series) {
if (defined(series._groupValue)) {
this.groups[series._groupValue] = series.visible;
} else {
this.index[series.index] = series.visible;
}
}
});
var geom = kendo.geometry;
function normalizeStyle(style) {
for (var field in style) {
if (style[field] === undefined$1) {
style[field] = '';
}
}
return style;
}
var Tooltip = Observable.extend({
init: function(chartElement, options) {
var tooltip = this;
Observable.fn.init.call(tooltip);
this.setOptions(options);
tooltip.chartElement = chartElement;
tooltip.template = Tooltip.template;
if (!tooltip.template) {
tooltip.template = Tooltip.template = ({ autoHide, rtl, font, border, opacity }) =>
`<div class='k-tooltip ${autoHide ? "k-tooltip-closable" : ""} k-chart-tooltip ${rtl ? "k-rtl" : ""}' ` +
`${kendo.attr("style-display")}="none" ${kendo.attr("style-position")}="absolute" ` +
`${kendo.attr("style-font")}="${font}" ${kendo.attr("style-opacity")}="${opacity}" ` +
`${border ? `${kendo.attr("style-border")}="${border.width}px solid" ` : ""}` +
`>` +
'<div class="k-tooltip-content"></div>' +
`${autoHide ? '' : '<div class="k-tooltip-button">' + kendo.ui.icon($('<a href="#" title="Close"></a>'), { icon: "x" }) + '</div>'}` +
"</div>";
}
tooltip.element = $(tooltip.template(tooltip.options));
kendo.applyStylesFromKendoAttributes(tooltip.element, ["display", "position", "font", "border", "opacity"]);
tooltip.move = tooltip.move.bind(tooltip);
tooltip._mouseleave = tooltip._mouseleave.bind(tooltip);
var mobileScrollerSelector = kendo.format("[{0}='content'],[{0}='scroller']", kendo.attr("role"));
tooltip._mobileScroller = chartElement.closest(mobileScrollerSelector).data("kendoMobileScroller");
tooltip.downEvent = kendo.applyEventMap(MOUSEDOWN, kendo.guid());
tooltip._closeTooltipHandler = tooltip._closeTooltip.bind(tooltip);
},
destroy: function() {
var tooltip = this;
this._clearShowTimeout();
DOCUMENT_ELEMENT.off(tooltip.downEvent, tooltip._closeTooltipHandler);
if (this.element) {
this.element.off(MOUSELEAVE_NS).remove();
this.element = null;
}
},
setOptions: function(options) {
this.options = deepExtend({}, this.options, options);
},
options: {
opacity: 1,
animation: {
duration: TOOLTIP_ANIMATION_DURATION
},
sharedTemplate: ({ colspan, categoryText, points, content, colorMarker, nameColumn }) =>
"<table>" +
`<th colspan='${colspan}'>${categoryText}</th>` +
sharedTemplateIterator(points, colorMarker, nameColumn, content) +
"</table>",
categoryFormat: "{0:d}",
autoHide: true
},
move: function() {
var tooltip = this,
options = tooltip.options,
element = tooltip.element,
offset;
if (!tooltip.anchor || !tooltip.element) {
return;
}
offset = tooltip._offset();
if (!tooltip.visible) {
element.css({ top: offset.top, left: offset.left });
}
tooltip.visible = true;
tooltip._ensureElement(document.body);
element
.stop(true, true)
.show()
.animate({
left: offset.left,
top: offset.top
}, options.animation.duration);
},
_clearShowTimeout: function() {
if (this.showTimeout) {
clearTimeout(this.showTimeout);
this.showTimeout = null;
}
},
getAnchor: function(size) {
var anchor = this.anchor;
var point = anchor.point;
var align = anchor.align;
var x = point.left;
var y = point.top;
if (align.horizontal === "center") {
x -= size.width / 2;
} else if (align.horizontal === "right") {
x -= size.width;
}
if (align.vertical === "center") {
y -= size.height / 2;
} else if (align.vertical === "bottom") {
y -= size.height;
}
return {
x: x,
y: y
};
},
_offset: function() {
var tooltip = this,
size = tooltip._measure(),
anchor = tooltip.getAnchor(size),
top = anchor.y,
left = anchor.x,
zoomLevel = kendo.support.zoomLevel(),
viewport = $(window),
scrollTop = window.pageYOffset || document.documentElement.scrollTop || 0,
scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || 0,
movable = (this._mobileScroller || {}).movable;
if (!movable || movable.scale === 1) {
top += tooltip._fit(top - scrollTop, size.height, outerHeight(viewport) / zoomLevel);
left += tooltip._fit(left - scrollLeft, size.width, outerWidth(viewport) / zoomLevel);
} else {
var transform = geom.transform().scale(movable.scale, movable.scale, [movable.x, movable.y]);
var point = new geom.Point(left, top).transform(transform);
left = point.x;
top = point.y;
}
return {
top: top,
left: left
};
},
show: function(e) {
var tooltip = this;
var fakeContainer = $("<div></div>");
this.anchor = e.anchor;
this.element.css(normalizeStyle(e.style));
this.element.toggleClass(TOOLTIP_INVERSE, !!e.className);
this.element.toggleClass(SHARED_TOOLTIP_CLASS, !!e.shared);
var content = e.shared ? this._sharedContent(e) : this._pointContent(e.point);
fakeContainer.html(content);
kendo.applyStylesFromKendoAttributes(fakeContainer, ["background-color"]);
this.element.find('.k-tooltip-content').empty().append(fakeContainer);
if (!tooltip.options.autoHide) {
tooltip.element.off("click" + NS).on("click" + NS, ".k-tooltip-button", tooltip._closeTooltipHandler);
DOCUMENT_ELEMENT.off(tooltip.downEvent, tooltip._closeTooltipHandler)
.on(tooltip.downEvent, tooltip._closeTooltipHandler);
}
this._clearShowTimeout();
this.showTimeout = setTimeout(this.move, TOOLTIP_SHOW_DELAY);
},
hide: function(forceHide) {
var tooltip = this;
if (!tooltip.options.autoHide && !forceHide) {
return;
}
clearTimeout(tooltip.showTimeout);
tooltip._hideElement();
if (tooltip.visible) {
tooltip.point = null;
tooltip.visible = false;
tooltip.index = null;
DOCUMENT_ELEMENT.off(tooltip.downEvent, tooltip._closeTooltipHandler);
}
},
_closeTooltip: function(e) {
var target = $(e.target);
if (!target.is(".k-chart-tooltip, .k-tooltip-content")) {
e.preventDefault();
this.chartElement.data("kendoChart")._instance.hideElements();
this.hide(true);
}
},
_sharedContent: function(e) {
var points = e.points;
var that = this;
var nameColumn = grep(points, function(point) {
return defined(point.series.name);
}).length;
var colorMarker = e.series.length > 1;
var colspan = 1;
if (nameColumn) {
colspan++;
}
if (colorMarker) {
colspan++;
}
var template = kendo.template(this.options.sharedTemplate);
var content = template({
points: points,
category: e.category,
categoryText: e.categoryText,
content: this._pointContent.bind(that),
colorMarker: colorMarker,
nameColumn: nameColumn,
colspan: colspan
});
return content;
},
_measure: function() {
this._ensureElement();
var size = {
width: outerWidth(this.element),
height: outerHeight(this.element)
};
return size;
},
_ensureElement: function() {
if (this.element) {
this.element
.appendTo(document.body)
.on(MOUSELEAVE_NS, this._mouseleave);
}
},
_mouseleave: function(e) {
var target = e.relatedTarget;
var chart = this.chartElement[0];
if (target && target !== chart && !$.contains(chart, target)) {
this.trigger(LEAVE);
}
},
_hideElement: function() {
var tooltip = this;
var element = this.element;
if (element) {
element.fadeOut({
always: function() {
if (!tooltip.visible) {
element.off(MOUSELEAVE_NS).remove();
}
}
});
}
},
_pointContent: function(point) {
var tooltip = this,
options = deepExtend({}, tooltip.options, point.options.tooltip),
content, tooltipTemplate;
if (defined(point.value)) {
content = point.value.toString();
}
if (options.template) {
tooltipTemplate = template(options.template);
content = tooltipTemplate({
value: point.value,
category: point.category,
series: point.series,
dataItem: point.dataItem,
percentage: point.percentage,
runningTotal: point.runningTotal,
total: point.total,
low: point.low,
high: point.high,
xLow: point.xLow,
xHigh: point.xHigh,
yLow: point.yLow,
yHigh: point.yHigh
});
} else if (options.format) {
content = point.formatValue(options.format);
}
return content;
},
_fit: function(offset, size, viewPortSize) {
var output = 0;
if (offset + size > viewPortSize) {
output = viewPortSize - (offset + size);
}
if (offset < 0) {
output = -offset;
}
return output;
}
});
var CrosshairTooltip = Tooltip.extend({
init: function(chartElement, options) {
Tooltip.fn.init.call(this, chartElement, options);
this.element.addClass("k-chart-crosshair-tooltip");
},
show: function(e) {
var element = this.element;
if (element) {
this.anchor = e.anchor;
this.element.css(e.style);
this.element.html(this.content(e));
this.move();
}
},
move: function() {
var tooltip = this,
element = tooltip.element,
offset = tooltip._offset();
tooltip._ensureElement();
element.css({ top: offset.top, left: offset.left }).show();
},
content: function(e) {
var content = e.value,
options = e.crosshair.options.tooltip;
if (options.template) {
content = template(options.template)({
value: content
});
}
return content;
},
hide: function() {
this.element.hide();
}
});
var ChartPane = Class.extend({
init: function(chart, pane) {
this._chart = chart;
this._pane = pane;
this.visual = pane.visual;
this.chartsVisual = pane.chartContainer.visual;
this.name = pane.options.name;
},
series: function() {
var chart = this._chart;
var seriesByPane = chart._plotArea.groupSeriesByPane();
var series = seriesByPane[this.name || "default"];
var result = [];
if (series) {
for (var idx = 0; idx < series.length; idx++) {
result.push(new ChartSeries(chart, series[idx]));
}
}
return result;
}
});
var ChartSeries = Class.extend({
init: function(chart, options) {
this._chart = chart;
this._options = options;
},
points: function(filter) {
var points = this._points;
if (!points) {
var series = this._seriesOptions();
var plotArea = this._chart._plotArea;
this._points = points = plotArea.p