@progress/kendo-ui
Version:
This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.
2,105 lines • 69.7 kB
JavaScript
Object.defineProperties(exports, {
__esModule: { value: true },
[Symbol.toStringTag]: { value: "Module" }
});
require("./kendo.core-kmRaf_Lg.js");
require("./kendo.html.icon.js");
require("./kendo.icons.js");
require("./kendo.form.js");
require("./kendo.window.js");
require("./kendo.dropdownbutton.js");
require("./kendo.colorpicker.js");
require("./kendo.tabstrip.js");
require("./kendo.expansionpanel.js");
require("./kendo.grid-Ctlb0cYE.js");
require("./kendo.splitter.js");
require("./kendo.dataviz.chart.js");
let _progress_kendo_charts = require("@progress/kendo-charts");
//#region ../src/kendo.chartwizard.js
const __meta__ = {
id: "chartwizard",
name: "ChartWizard",
category: "web",
description: "The ChartWizard allows configuration and visual representation of various charts",
depends: [
"core",
"icons",
"html.icon",
"grid",
"expansionpanel",
"window",
"form",
"tabstrip",
"dataviz.chart",
"splitter",
"dropdownbutton",
"colorpicker"
]
};
(function($) {
const kendo = window.kendo, Widget = kendo.ui.Widget, DataSource = kendo.data.DataSource, keys = kendo.keys, fontSizes = _progress_kendo_charts.ChartWizardCommon.fontSizes, fontNames = _progress_kendo_charts.ChartWizardCommon.fontNames, isCategorical = _progress_kendo_charts.ChartWizardCommon.isCategorical, updateState = _progress_kendo_charts.ChartWizardCommon.updateState, mergeStates = _progress_kendo_charts.ChartWizardCommon.mergeStates, actionTypes = _progress_kendo_charts.ChartWizardCommon.ActionTypes, getWizardDataFromDataRows = _progress_kendo_charts.ChartWizardCommon.getWizardDataFromDataRows, NS = ".kendoChartWizard", ui = kendo.ui, extend = $.extend, deepExtend = kendo.deepExtend, RESIZING = "resizing", RESIZE = "resize", MAXIMIZE = "maximize", RESTORE = "restore", CLICK = "click", KEYDOWN = "keydown", OPEN = "open", CLOSE = "close", ACTIVATE = "activate", CHANGE = "change", DATA_BINGING = "dataBinding", DATA_BOUND = "dataBound", EXPORT_PDF = "exportPDF", EXPORT_SVG = "exportSVG", EXPORT_IMAGE = "exportImage", KENDO_KEYDOWN = "kendoKeydown", ICON_SIZE = "xlarge", CHART = "chart", DATA = "data", FORMAT = "format", DOT = ".", REF = "ref", REF_SELECTOR = "ref*=", DATA_ACTION = "data-action", DATA_ACTION_SELECTOR = "[data-action]", DATA_ROLE = "data-role", DATA_ROLE_SELECTOR = "data-role=", DATA_CHART_TYPE_ATTR = "data-chart-type", SELECTED_STATE = "k-selected", FILL_MODE_OUTLINE = "outline", FILL_MODE_FLAT = "flat", STACKED = "stacked", INITIAL_TYPE = "bar", HUNDRED_STACKED = "hundredstacked", REG_EXP_CAPITAL = /(?=[A-Z])/;
const cssClasses = {
chartWizard: "k-chart-wizard",
previewPane: "k-chart-wizard-preview-pane",
previewPaneHeader: "k-preview-pane-header",
previewPaneContent: "k-preview-pane-content",
propertyPane: "k-chart-wizard-property-pane",
splitter: "k-chart-wizard-splitter",
expansionPanelWrapper: "k-expander",
cols2gap4: "k-grid-cols-2 k-gap-x-4",
colSpan2: "k-col-span-2"
};
const inputRoles = {
numericTextBox: "numerictextbox",
colorPicker: "colorpicker",
textBox: "textbox",
comboBox: "combobox",
checkBox: "checkbox",
dropDownList: "dropdownlist",
switch: "switch"
};
const exportButtonOptions = {
icon: "export",
fillMode: FILL_MODE_FLAT,
items: [
{
id: "export-pdf",
icon: "file-pdf"
},
{
id: "export-svg",
icon: "file"
},
{
id: "export-png",
icon: "file-image"
}
]
};
const expansionPanelForChart = {
bar: { content: {
bar: "chart-bar-clustered",
stackedBar: "chart-bar-stacked",
hundredStackedBar: "chart-bar-stacked100"
} },
pie: { content: { pie: "chart-pie" } },
column: { content: {
column: "chart-column-clustered",
stackedColumn: "chart-column-stacked",
hundredStackedColumn: "chart-column-stacked100"
} },
line: { content: {
line: "chart-line",
stackedLine: "chart-line-stacked",
hundredStackedLine: "chart-line-stacked100"
} },
scatter: { content: { scatter: "chart-scatter" } }
};
const dataTabPanel = (messages) => [
{
legend: messages.configuration.categoryAxis,
editors: {
id: "category-axis",
role: inputRoles.dropDownList,
action: "categoryAxisX"
}
},
{
legend: messages.configuration.valueAxis,
editors: {
id: "value-axis",
role: inputRoles.dropDownList,
action: "valueAxisY"
}
},
{
legend: messages.configuration.series.title,
editors: { custom: `<div class="k-grid" ${DATA_ACTION}="seriesChange"></div>` }
}
];
const chartAreaPanel = (messages) => [{
legend: messages.chartArea.margins.default,
layoutClass: cssClasses.cols2gap4,
editors: [
{
label: {
text: messages.chartArea.margins.left,
for: "left"
},
field: {
id: "left",
role: inputRoles.numericTextBox,
placeholder: messages.chartArea.margins.auto,
action: "areaMarginLeft"
}
},
{
label: {
text: messages.chartArea.margins.right,
for: "right"
},
field: {
id: "right",
role: inputRoles.numericTextBox,
placeholder: messages.chartArea.margins.auto,
action: "areaMarginRight"
}
},
{
label: {
text: messages.chartArea.margins.top,
for: "top"
},
field: {
id: "top",
role: inputRoles.numericTextBox,
placeholder: messages.chartArea.margins.auto,
action: "areaMarginTop"
}
},
{
label: {
text: messages.chartArea.margins.bottom,
for: "bottom"
},
field: {
id: "bottom",
role: inputRoles.numericTextBox,
placeholder: messages.chartArea.margins.auto,
action: "areaMarginBottom"
}
}
]
}, {
legend: messages.chartArea.background.default,
editors: [{
label: {
text: messages.chartArea.background.color,
for: "background"
},
field: {
id: "background",
role: inputRoles.colorPicker,
action: "areaBackground"
}
}]
}];
const titlePanel = (messages) => [{
layoutClass: cssClasses.cols2gap4,
editors: [
{
label: {
text: messages.title.applyTo,
for: "apply-to-title"
},
field: {
id: "apply-to-title",
role: inputRoles.dropDownList,
action: "activateTitle"
},
className: cssClasses.colSpan2
},
{
label: {
text: messages.title.label,
for: "title-text"
},
field: {
id: "title-text",
role: inputRoles.textBox,
action: "titleText"
},
className: cssClasses.colSpan2
},
{
label: {
text: messages.title.font,
for: "title-font"
},
field: {
id: "title-font",
role: inputRoles.comboBox,
placeholder: messages.title.fontPlaceholder,
action: "titleFontName"
},
className: cssClasses.colSpan2
},
{
label: {
text: messages.title.size,
for: "title-size"
},
field: {
id: "title-size",
role: inputRoles.comboBox,
placeholder: messages.title.sizePlaceholder,
action: "titleFontSize"
}
},
{
label: {
text: messages.title.color,
for: "title-color"
},
field: {
id: "title-color",
role: inputRoles.colorPicker,
action: "titleColor"
}
}
]
}];
const seriesPanel = (messages) => [{ editors: [
{
label: {
text: messages.series.applyTo,
for: "apply-to-series"
},
field: {
id: "apply-to-series",
role: inputRoles.dropDownList,
action: "activateSeries"
}
},
{
label: {
text: messages.series.color,
for: "series-color"
},
field: {
id: "series-color",
role: inputRoles.colorPicker,
action: "seriesColor"
}
},
{ field: {
id: "show-labels",
type: "checkbox",
role: inputRoles.checkBox,
action: "seriesLabel"
} }
] }];
const legendPanel = (messages) => [{
layoutClass: cssClasses.cols2gap4,
editors: [
{
nowrap: true,
label: {
text: messages.legend.showLegend,
for: "show-legend"
}
},
{
nowrap: true,
field: {
id: "show-legend",
role: inputRoles.switch,
action: "legendVisible"
}
},
{
label: {
text: messages.legend.font,
for: "legend-font"
},
field: {
id: "legend-font",
placeholder: messages.legend.fontPlaceholder,
role: inputRoles.comboBox,
action: "legendFontName"
},
className: cssClasses.colSpan2
},
{
label: {
text: messages.legend.size,
for: "legend-size"
},
field: {
id: "legend-size",
role: inputRoles.comboBox,
placeholder: messages.legend.sizePlaceholder,
action: "legendFontSize"
}
},
{
label: {
text: messages.title.color,
for: "legend-color"
},
field: {
id: "legend-color",
role: inputRoles.colorPicker,
action: "legendColor"
}
},
{
label: {
text: messages.legend.position.default,
for: "legend-position"
},
field: {
id: "legend-position",
role: inputRoles.dropDownList,
action: "legendPosition"
},
className: cssClasses.colSpan2
}
]
}];
const categoryAxisPanel = (messages) => [{
legend: messages.categoryAxis.title.text,
layoutClass: cssClasses.cols2gap4,
editors: [
{
field: {
id: "category-axis-title",
role: inputRoles.textBox,
placeholder: messages.categoryAxis.title.placeholder,
action: "categoryAxisTitleText"
},
className: cssClasses.colSpan2
},
{
label: {
text: messages.categoryAxis.title.font,
for: "category-axis-title-font"
},
field: {
id: "category-axis-title-font",
role: inputRoles.comboBox,
placeholder: messages.categoryAxis.title.fontPlaceholder,
action: "categoryAxisTitleFontName"
},
className: cssClasses.colSpan2
},
{
label: {
text: messages.categoryAxis.title.size,
for: "category-axis-title-size"
},
field: {
id: "category-axis-title-size",
role: inputRoles.comboBox,
placeholder: messages.categoryAxis.title.sizePlaceholder,
action: "categoryAxisTitleFontSize"
}
},
{
label: {
text: messages.categoryAxis.title.color,
for: "category-axis-title-color"
},
field: {
id: "category-axis-title-color",
role: inputRoles.colorPicker,
action: "categoryAxisTitleColor"
}
}
]
}, {
layoutClass: cssClasses.cols2gap4,
legend: messages.categoryAxis.labels.text,
editors: [
{
label: {
text: messages.categoryAxis.labels.font,
for: "category-axis-labels-font"
},
field: {
id: "category-axis-labels-font",
role: inputRoles.comboBox,
placeholder: messages.categoryAxis.labels.fontPlaceholder,
action: "categoryAxisLabelsFontName"
},
className: cssClasses.colSpan2
},
{
label: {
text: messages.categoryAxis.labels.size,
for: "category-axis-labels-size"
},
field: {
id: "category-axis-labels-size",
role: inputRoles.comboBox,
placeholder: messages.categoryAxis.labels.sizePlaceholder,
action: "categoryAxisLabelsFontSize"
}
},
{
label: {
text: messages.categoryAxis.labels.color,
for: "category-axis-labels-color"
},
field: {
id: "category-axis-labels-color",
role: inputRoles.colorPicker,
action: "categoryAxisLabelsColor"
}
},
{
label: {
text: messages.categoryAxis.labels.rotation.text,
for: "category-axis-labels-rotation"
},
field: {
id: "category-axis-labels-rotation",
role: inputRoles.numericTextBox,
placeholder: messages.categoryAxis.labels.rotation.auto,
action: "categoryAxisLabelsRotation"
}
},
{
field: {
id: "category-axis-labels-reverse-order",
role: inputRoles.checkBox,
action: "categoryAxisReverseOrder"
},
className: cssClasses.colSpan2
}
]
}];
const valueAxisPanel = (messages) => [{
legend: messages.valueAxis.title.text,
layoutClass: cssClasses.cols2gap4,
editors: [
{
field: {
id: "value-axis-title",
role: inputRoles.textBox,
placeholder: messages.valueAxis.title.placeholder,
action: "valueAxisTitleText"
},
className: cssClasses.colSpan2
},
{
label: {
text: messages.categoryAxis.title.font,
for: "value-axis-title-font"
},
field: {
id: "value-axis-title-font",
role: inputRoles.comboBox,
placeholder: messages.valueAxis.title.fontPlaceholder,
action: "valueAxisTitleFontName"
},
className: cssClasses.colSpan2
},
{
label: {
text: messages.valueAxis.title.size,
for: "value-axis-title-size"
},
field: {
id: "value-axis-title-size",
role: inputRoles.comboBox,
placeholder: messages.valueAxis.title.sizePlaceholder,
action: "valueAxisTitleFontSize"
}
},
{
label: {
text: messages.valueAxis.title.color,
for: "value-axis-title-color"
},
field: {
id: "value-axis-title-color",
role: inputRoles.colorPicker,
action: "valueAxisTitleColor"
}
}
]
}, {
layoutClass: cssClasses.cols2gap4,
legend: messages.valueAxis.labels.text,
editors: [
{
label: {
text: messages.valueAxis.labels.labelFormat.default,
for: "value-axis-label-format"
},
field: {
id: "value-axis-label-format",
role: inputRoles.dropDownList,
action: "valueAxisLabelsFormat"
},
className: cssClasses.colSpan2
},
{
label: {
text: messages.valueAxis.labels.font,
for: "value-axis-label-font"
},
field: {
id: "value-axis-label-font",
role: inputRoles.comboBox,
placeholder: messages.valueAxis.labels.fontPlaceholder,
action: "valueAxisLabelsFontName"
},
className: cssClasses.colSpan2
},
{
label: {
text: messages.valueAxis.labels.size,
for: "value-axis-label-size"
},
field: {
id: "value-axis-label-size",
role: inputRoles.comboBox,
placeholder: messages.valueAxis.labels.sizePlaceholder,
action: "valueAxisLabelsFontSize"
}
},
{
label: {
text: messages.valueAxis.labels.color,
for: "value-axis-labels-color"
},
field: {
id: "value-axis-labels-color",
role: inputRoles.colorPicker,
action: "valueAxisLabelsColor"
}
},
{
label: {
text: messages.valueAxis.labels.rotation.text,
for: "value-axis-labels-rotation"
},
field: {
id: "value-axis-labels-rotation",
role: inputRoles.numericTextBox,
placeholder: messages.valueAxis.labels.rotation.auto,
action: "valueAxisLabelsRotation"
}
}
]
}];
function createState(data, seriesType) {
return _progress_kendo_charts.ChartWizardCommon.createState(data, seriesType);
}
function createInitialStateInstance(data, seriesType, defaultState, stateObject) {
var state = createState(data, defaultState && defaultState.seriesType || seriesType);
if (stateObject) state = deepExtend({}, state, stateObject);
return typeof (defaultState && defaultState.stack) !== "undefined" ? updateState(state, actionTypes.stacked, defaultState.stack) : state;
}
function getFormatPanels() {
return [
{
ref: "chartarea",
getData: chartAreaPanel
},
{
ref: "title",
getData: titlePanel
},
{
ref: "series",
getData: seriesPanel
},
{
ref: "legend",
getData: legendPanel
},
{
ref: "categoryaxis",
getData: categoryAxisPanel
},
{
ref: "valueaxis",
getData: valueAxisPanel
}
];
}
function getNewState({ state, data, type, action, change }) {
let newState = state;
if (data && type) newState = mergeStates(state, createState(data, type));
if (action && change !== null && change !== void 0) newState = updateState(newState, action, change);
newState.transitions = false;
return newState;
}
function prepareReorderedDataForGrid(grid, prevIndex, currentIndex) {
const data = grid.options.dataSource;
const item = data.splice(prevIndex, 1);
data.splice(currentIndex, 0, item[0]);
return data;
}
const templates = {
chartTypesWrapper: () => `<div class="k-chart-types-wrapper"></div>`,
iconTextItem: (iconWrapper, text, attribute) => `<div class="k-icon-text-wrapper" ${attribute ?? ""}>${iconWrapper}${kendo.htmlEncode(text)}</div>`,
iconWrapper: (icon, size) => `<div class="k-icon-background-area" tabindex="0">${kendo.ui.icon({
icon,
size
})}</div>`,
formElement: () => `<form class="k-form"></form>`,
formFieldSet: (legend, editorsBase) => `<fieldset class="k-form-fieldset">
${legend ? `<legend class="k-form-legend">${legend}</legend>` : ""}
${editorsBase}
</fieldset>`,
divContentWrapper: (ref) => `<div ref=${ref}></div>`,
formFieldWrap: (field) => `<div class="k-form-field-wrap">${field}</div>`,
formField: (content, className) => `<div class="k-form-field${className ? " " + className : ""}">
${content}
</div>`,
fieldContent: (label, field) => `
${label}
${field}`,
label: (text, editorId, className) => `<label for="${editorId}" class="k-label${className ? " " + className : ""}">${text}</label>`,
formGridLayout: (classes) => `<div class="k-form-layout k-d-grid${" " + classes}"></div>`,
inputBaseElement: (field) => `<input ${field.id ? `id="${field.id}"` : ""} ${DATA_ROLE}=${field.role} ${DATA_ACTION}=${field.action} ${field.type ? `type="${field.type}"` : ""} ${field.placeholder ? `placeholder="${kendo.htmlEncode(field.placeholder)}"` : ""}/>`
};
const legendPositions = (messages) => [
{
value: "bottom",
text: messages.position.bottom
},
{
value: "top",
text: messages.position.top
},
{
value: "left",
text: messages.position.left
},
{
value: "right",
text: messages.position.right
}
];
const labelFormats = (messages) => [
{
value: "",
text: messages.labels.labelFormat.text
},
{
value: "n0",
text: messages.labels.labelFormat.number
},
{
value: "c0",
text: messages.labels.labelFormat.currency
},
{
value: "p0",
text: messages.labels.labelFormat.percent
}
];
const titles = (messages) => [{
value: "title",
text: messages.format.title.chartTitle
}, {
value: "subtitle",
text: messages.format.title.chartSubtitle
}];
const commonOptions = {
colorPicker: {
fillMode: FILL_MODE_OUTLINE,
view: "gradient",
buttons: false,
format: "rgb",
opacity: true
},
comboBox: {
filter: "contains",
suggest: true,
dataTextField: "text",
dataValueField: "value"
},
numericTextBox: {
step: 1,
fillMode: FILL_MODE_OUTLINE
},
dropDownList: {
fillMode: FILL_MODE_OUTLINE,
animation: false,
dataTextField: "text",
dataValueField: "value",
index: 0
},
tabStrip: {
dataTextField: "name",
dataContentField: "content"
},
grid: {
columns: [
{
id: 1,
field: "reoreder",
draggable: true,
editable: () => false,
width: "40px"
},
{
id: 2,
field: "name"
},
{
id: 3,
field: "remove",
editable: () => false,
width: "40px",
template: () => `<button ${DATA_ACTION}="remove" tabindex="0"></button>`
}
],
pageable: false,
scrollable: false,
navigatable: false,
editable: {
confirmation: false,
mode: "incell"
},
reorderable: { rows: true }
}
};
const generateDataRows = (data, columns) => {
let rows = [];
data.forEach((item) => {
const row = rows.find((rowInstance) => rowInstance.uid === item.uid);
if (!row) rows.push(item);
else extend(row, item);
});
const dataRows = rows.map((row) => ({
dataItem: row,
dataColumns: columns
}));
return getWizardDataFromDataRows(dataRows);
};
const ChartWizard = Widget.extend({
init: function(element, options) {
let that = this;
options = options || {};
that.options = deepExtend({}, that.options, options);
Widget.fn.init.call(that, element, options);
that._initial = true;
that._dataSource();
kendo.notify(that);
Widget.fn.endInit.call(that);
},
options: {
name: "ChartWizard",
dataSource: [],
dataColumns: [],
defaultState: {},
state: {},
window: {
actions: ["Maximize", "Close"],
resizable: true,
visible: true,
modal: true,
scrollable: false,
animation: false,
width: 700,
height: 550
},
exportOptions: {
fileName: "chart",
pdf: { margin: "1cm" },
image: {
width: 800,
height: 600
}
},
messages: {
window: { title: "Chart Preview" },
export: "Export",
exportPDF: "PDF File",
exportSVG: "SVG File",
exportPNG: "PNG File",
tab: {
chart: "Chart",
data: "Data",
format: "Format"
},
chart: {
bar: {
expandText: "Bar Chart",
bar: "Bar",
stackedBar: "Stacked Bar",
hundredStackedBar: "100% Stacked Bar"
},
pie: {
expandText: "Pie Chart",
pie: "Pie"
},
column: {
expandText: "Column Chart",
column: "Column",
stackedColumn: "Stacked Column",
hundredStackedColumn: "100% Stacked Column"
},
line: {
expandText: "Line Chart",
line: "Line",
stackedLine: "Stacked Line",
hundredStackedLine: "100% Stacked Line"
},
scatter: {
expandText: "Scatter Chart",
scatter: "Scatter"
}
},
data: { configuration: {
expandText: "Configuration",
series: {
title: "Series",
add: "Add"
},
valueAxis: "Value Axis",
categoryAxis: "Category Axis",
xAxis: "X Axis"
} },
format: {
chartArea: {
expandText: "Chart Area",
margins: {
default: "Margins",
auto: "Auto",
left: "Left",
right: "Right",
top: "Top",
bottom: "Bottom"
},
background: {
default: "Background",
color: "Color"
}
},
title: {
expandText: "Title",
applyTo: "Apply to",
chartTitle: "Chart Title",
chartSubtitle: "Chart Subtitle",
label: "Title",
font: "Font",
fontPlaceholder: "(inherited font)",
size: "Size",
sizePlaceholder: "px",
color: "Color"
},
series: {
expandText: "Series",
applyTo: "Apply to",
allSeries: "All Series",
color: "Color",
showLabels: "Show Labels"
},
legend: {
expandText: "Legend",
showLegend: "Show Legend",
font: "Font",
fontPlaceholder: "(inherited font)",
size: "Size",
sizePlaceholder: "px",
color: "Color",
position: {
default: "Position",
top: "Top",
bottom: "Bottom",
left: "Left",
right: "Right"
}
},
categoryAxis: {
expandText: "Category Axis",
title: {
text: "Title",
placeholder: "Axis Title",
font: "Font",
fontPlaceholder: "(inherited font)",
size: "Size",
sizePlaceholder: "px",
color: "Color"
},
labels: {
text: "Labels",
font: "Font",
fontPlaceholder: "(inherited font)",
size: "Size",
sizePlaceholder: "px",
color: "Color",
rotation: {
text: "Rotation",
auto: "Auto"
},
reverseOrder: "Reverse Order"
}
},
valueAxis: {
expandText: "Value Axis",
title: {
text: "Title",
placeholder: "Axis Title",
font: "Font",
fontPlaceholder: "(inherited font)",
size: "Size",
sizePlaceholder: "px",
color: "Color"
},
labels: {
text: "Labels",
labelFormat: {
default: "Label Format",
text: "Text",
number: "Number",
currency: "Currency",
percent: "Percent"
},
font: "Font",
fontPlaceholder: "(inherited font)",
size: "Size",
sizePlaceholder: "px",
color: "Color",
rotation: {
text: "Rotation",
auto: "Auto"
}
}
},
xAxis: { expandText: "X Axis" },
yAxis: { expandText: "Y Axis" }
}
}
},
events: [
RESIZING,
DATA_BINGING,
DATA_BOUND,
RESIZE,
CLICK,
KEYDOWN,
OPEN,
CLOSE,
CHANGE,
EXPORT_PDF,
EXPORT_SVG,
EXPORT_IMAGE,
KENDO_KEYDOWN
],
open: function() {
this.window.open();
},
close: function() {
this.window.close();
},
_attachEvents: function() {
const that = this;
that.splitter.bind(RESIZING, ({ pane }) => {
kendo.resize(pane);
});
that.splitter.bind(RESIZE, (event) => {
event.sender.element.find(".k-pane").each((_, pane) => {
kendo.resize(pane);
});
});
that.window.bind(ACTIVATE, that._windowActivateHandler.bind(that));
that.window.bind(RESIZE, that._windowResizeHandler.bind(that));
that.window.bind(MAXIMIZE, that._windowActivateHandler.bind(that));
that.window.bind(RESTORE, that._windowActivateHandler.bind(that));
that.window.bind(CLOSE, function() {
that.trigger(CLOSE);
});
that.window.bind(OPEN, function() {
that.trigger(OPEN);
});
that.tabStrip.contentElements.on("click.kendoChartWizard", ".k-icon-text-wrapper", that._handleChartTypeClick.bind(that));
that.tabStrip.contentElements.on("keydown.kendoChartWizard", ".k-icon-text-wrapper", that, that._handleChartTypeKeydown.bind(that));
},
_dataSource: function() {
const that = this;
let dataSource = that.options.dataSource;
if (that.dataSource && that._refreshHandler) that.dataSource.unbind(CHANGE, that._refreshHandler);
else that._refreshHandler = that._refresh.bind(that);
if (dataSource && dataSource instanceof DataSource) that.dataSource = dataSource.bind(CHANGE, that._refreshHandler);
else {
dataSource = Array.isArray(dataSource) ? { data: dataSource } : dataSource;
that.dataSource = DataSource.create(dataSource).bind(CHANGE, that._refreshHandler);
}
if (that.dataSource.data().length) that._refresh();
else if (!that.dataSource._requestInProgress) that.dataSource.fetch();
},
_refreshContent: function() {
const that = this;
const options = that.options;
const chartState = that._getChartStateInstance(options);
const previewHeader = that.previewPane.find(DOT + cssClasses.previewPaneHeader);
that.window.setOptions({
title: kendo.htmlEncode(options.messages.window.title),
...options.window
});
that._oldType = null;
that._setChartContainerHeight();
that.chartState = extend(that.chartState, chartState);
that.chart.setOptions(that.chartState);
that._detachEvents();
kendo.destroy(previewHeader);
previewHeader.empty();
that._createExportButton(previewHeader);
kendo.destroy(that.propertyPane);
that.propertyPane.empty();
that._seriesGrid = null;
that._seriesValueAxisDDL = null;
that._initPropertyPane();
that._attachEvents();
if (!that.window.wrapper.is(":visible") && options.window.visible) that.window.open();
if (!options.position) that.window.center();
},
_refresh: function(e) {
const that = this;
let data = Array.from(that.dataSource.data());
that.trigger(DATA_BINGING, { data });
data = that._data = that._getWizardData(data);
if (that._initial) {
that._initWindow();
that._initSplitter();
that._initPreviewPane();
that._initPropertyPane();
that._attachEvents();
that._initial = false;
} else that._refreshContent();
that.trigger(DATA_BOUND, { data });
},
_getWizardData: function(data) {
const that = this;
let wizardData = data;
const dataColumns = that.options.dataColumns ? that.options.dataColumns.map((column) => {
if (typeof column === "string") return { field: column };
return column;
}) : [];
if (data.length && data[0].dataItem && data[0].dataColumns) wizardData = getWizardDataFromDataRows(data);
else if (data.length && !Array.isArray(data[0]) && dataColumns.length) wizardData = generateDataRows(data, dataColumns);
return wizardData;
},
setDataSource: function(dataSource) {
const that = this;
const options = that.options;
if (dataSource) {
options.dataSource = dataSource;
that._dataSource();
}
},
setDataColumns: function(dataColumns) {
const options = this.options;
if (dataColumns.length) options.dataColumns = dataColumns;
},
_detachEvents: function() {
const that = this;
that.splitter.unbind(RESIZING);
that.splitter.unbind(RESIZE);
that.window.unbind(ACTIVATE);
that.window.unbind(RESIZE);
that.window.unbind(CLOSE);
that.window.unbind(OPEN);
that.window.unbind(MAXIMIZE);
that.window.unbind(RESTORE);
that.tabStrip.contentElements.off("click.kendoChartWizard");
that.tabStrip.contentElements.off("keydown.kendoChartWizard");
},
_setChartContainerHeight: function() {
const that = this;
that.previewPane.find(DOT + cssClasses.previewPaneContent).css({ height: that.previewPane.height() - 50 });
},
_windowActivateHandler: function() {
const that = this;
that._setChartContainerHeight();
that.chart.resize();
},
_windowResizeHandler: function() {
this._setChartContainerHeight();
},
_handleChartTypeKeydown: function(e) {
if (!kendo.keyDownHandler(e, this)) return;
if (e.keyCode === keys.ENTER) this._handleChartTypeClick(e);
},
_handleChartTypeClick: function(e) {
const that = this;
const item = $(e.currentTarget);
const newType = that._getRefAttributeValue(item.closest(".k-expander-content")[0])[0];
const chartType = item.attr(DATA_CHART_TYPE_ATTR);
const chartState = that.chartState;
let change = null;
let action = null;
if (chartType.includes(HUNDRED_STACKED)) {
action = actionTypes.stacked;
change = { type: "100%" };
} else if (chartType.includes(STACKED)) {
action = actionTypes.stacked;
change = { type: "normal" };
}
that._executeAction(change, { element: item }, chartState.data, newType, action);
item.closest(".k-tabstrip-content").find(".k-selected").removeClass(SELECTED_STATE);
item.addClass(SELECTED_STATE);
that._toggleFieldsForSeriesPanel(newType);
that._toggleFormatPanels();
that._refreshEditors();
},
_refreshEditors: function() {
const that = this;
that.propertyPane.find("[data-action]:not('.k-button')").each((_, editor) => {
const element = $(editor);
const kendoElement = element.data("handler");
const id = element.attr("id");
const panel = $(editor).closest(`[${REF}]`);
const elementRole = element.attr(DATA_ROLE);
const panelRef = that._getRefAttributeValue(panel[0])[0];
if (kendoElement && kendoElement.setOptions) {
const changed = that._getOptionsForPanel(id)[panelRef][elementRole];
if (changed && changed.options) if (elementRole === inputRoles.checkBox) kendoElement.check(changed.options.checked);
else if (panelRef === "series") {
kendoElement.setOptions(changed.options);
if (changed.options && changed.options.enable) kendoElement.enable(changed.options.enable);
} else {
let val = changed.options.value;
if (val && typeof val !== "string" && val.value) val = val.value;
kendoElement.value(val);
}
if (elementRole === inputRoles.comboBox) {
const state = that._getFontState(element);
if (state && state.value) kendoElement.value(state.value);
}
}
});
if (that._seriesGrid) that._seriesGrid.setDataSource(that.chartState.series);
},
_initWindow: function() {
const that = this;
const messages = that.options.messages;
const options = that.options.window;
const centered = !options.position;
that.window = that.element.kendoWindow({
title: kendo.htmlEncode(messages.window.title),
...options
}).data("kendoWindow");
if (centered) that.window.center();
that.window.element.attr("tabindex", "-1");
that.wrapper = that.window.wrapper.addClass(cssClasses.chartWizard);
},
_initSplitter: function() {
const that = this;
that.splitter = $("<div>").kendoSplitter({ orientation: "horizontal" }).data("kendoSplitter");
that.previewPane = that.splitter.append({ scrollable: false });
that.propertyPane = that.splitter.append({
size: "300px",
collapsible: true
});
that.splitter.wrapper.addClass(cssClasses.splitter);
that.window.content(that.splitter.wrapper);
},
_initPreviewPane: function() {
const that = this;
const options = that.options;
that.previewPane.addClass(cssClasses.previewPane);
const previewHeader = $("<div></div>").addClass(cssClasses.previewPaneHeader);
const previewContent = $("<div></div>").addClass(cssClasses.previewPaneContent);
if (that.options.window.visible) previewContent.css({ height: that.previewPane.height() - 50 });
const chart = $("<div id='chart'>");
that._createExportButton(previewHeader);
previewContent.append(chart);
that.previewPane.append(previewHeader.add(previewContent));
that._initChart(chart, options);
},
_getChartStateInstance: function(options, skipDefault) {
const that = this;
const defaultState = skipDefault ? {} : options.defaultState;
const hasState = Object.keys(options.state).length;
const data = hasState ? options.state.data : that._data;
const seriesType = hasState ? !skipDefault && options.state.seriesType || INITIAL_TYPE : INITIAL_TYPE;
return createInitialStateInstance(data || [], seriesType, defaultState, options.state);
},
_initChart: function(element, options) {
const that = this;
const isPie = options.defaultState && options.defaultState.seriesType === "pie" || options.state && options.state.seriesType === "pie";
let initialState = that._getChartStateInstance(options, isPie);
initialState.chartArea = initialState.area;
initialState.transitions = false;
that.chartState = initialState;
that.chart = element.kendoChart(initialState).data("kendoChart");
that.chart.wrapper.css({
width: "100%",
height: "100%"
});
if (isPie) {
const pieState = that._getChartStateInstance(options);
that.chartState = extend(that.chartState, pieState);
that.chart.setOptions(that.chartState);
}
if (!that._initialState) that._initialState = that.chart.options;
},
_createExportButton: function(previewHeader) {
const that = this;
that._configureExportButton(exportButtonOptions);
const dropDownButton = $(`<button>${kendo.htmlEncode(that.options.messages.export)}</button>`).kendoDropDownButton(exportButtonOptions);
previewHeader.append(dropDownButton);
},
_configureExportButton: function(options) {
const that = this;
const messages = that.options.messages;
const idSeparator = "-";
const exportHandlers = {
"export-pdf": function() {
if (!that.trigger(EXPORT_PDF, {
chart: that.chart,
exportOptions: that.options.exportOptions
})) that.chart.exportPDF(that.options.exportOptions.pdf).done(function(data) {
kendo.saveAs({
dataURI: data,
fileName: that.options.exportOptions.fileName
});
});
},
"export-svg": function() {
if (!that.trigger(EXPORT_SVG, {
chart: that.chart,
exportOptions: that.options.exportOptions
})) that.chart.exportSVG(that.options.exportOptions.fileName).done(function(data) {
kendo.saveAs({
dataURI: data,
fileName: that.options.exportOptions.fileName
});
});
},
"export-png": function() {
if (!that.trigger(EXPORT_IMAGE, {
chart: that.chart,
exportOptions: that.options.exportOptions
})) that.chart.exportImage(that.options.exportOptions.image).done(function(data) {
kendo.saveAs({
dataURI: data,
fileName: that.options.exportOptions.fileName
});
});
}
};
options.items.forEach((item) => {
const textParts = item.id.split(idSeparator);
const text = textParts[0] + textParts[1].toUpperCase();
item.text = kendo.htmlEncode(messages[text]);
item.click = exportHandlers[item.id];
});
},
_preventLabelPointerEvents: function() {
this.propertyPane.find(".k-label").addClass("k-pointer-events-none");
},
_initPropertyPane: function() {
const that = this;
const tabStripOptions = commonOptions.tabStrip;
tabStripOptions.dataSource = Object.values(that.options.messages.tab).map((tab) => ({ name: kendo.htmlEncode(tab) }));
that._createTabsContent(tabStripOptions.dataSource);
that.tabStrip = $("<div>").kendoTabStrip({
...tabStripOptions,
activate: function(e) {
if ($(e.contentElement).find(`[${REF_SELECTOR}'data']`).length) {
const content = $(e.contentElement).find("#category-axis").parent().siblings(".k-form-legend");
if (content.length && that.chart.options.seriesType === "scatter") content.text(kendo.htmlEncode(that.options.messages.data.configuration.xAxis));
else if (content.length) content.text(kendo.htmlEncode(that.options.messages.data.configuration.categoryAxis));
}
if (that._seriesGrid && that._seriesGrid.wrapper.is(":visible")) {
that._seriesGrid._draggableRows();
that._seriesGrid._reorderableRows();
}
}
}).data("kendoTabStrip");
that.propertyPane.addClass(cssClasses.propertyPane);
that.propertyPane.append(that.tabStrip.wrapper);
that._expansionPanels();
that._prepareDataTab();
that._prepareFormatTab();
that._initStaticEditors();
that.tabStrip.activateTab(that.tabStrip.tabGroup.children().first());
if (that.options.window.visible) that.chart.resize();
},
_createTabsContent: function(tabs) {
const that = this;
tabs.forEach((tab) => {
tab.content = that._createExpansionPanelContent(tab.name) ?? "";
});
},
_createExpansionPanelContent: function(tab) {
const that = this;
let content = "";
const tabs = that.options.messages.tab;
if (tab === tabs[CHART]) Object.keys(expansionPanelForChart).forEach((chartType) => {
content += that._createChartTypesPanel(expansionPanelForChart[chartType].content, `${chartType}-chart-panel`, chartType);
});
else if (tab === tabs[DATA]) {
const data = dataTabPanel(that.options.messages.data);
content += that._createFormPanel(data, "configuration-data-panel");
} else if (tab === tabs[FORMAT]) getFormatPanels().forEach((panel) => {
const panelData = panel.getData(that.options.messages.format);
content += that._createFormPanel(panelData, `${panel.ref}-format-panel`);
});
return content;
},
_createChartTypesPanel: function(data, ref, mainChartType) {
const messages = this.options.messages.chart;
const content = $(templates.divContentWrapper(ref));
const chartTypesWrapper = $(templates.chartTypesWrapper());
Object.keys(data).forEach((chartType) => {
const text = kendo.htmlEncode(messages[mainChartType][chartType]);
const attribute = `${DATA_CHART_TYPE_ATTR}=${chartType.toLowerCase()}`;
chartTypesWrapper.append(templates.iconTextItem(templates.iconWrapper(data[chartType], ICON_SIZE), text, attribute));
});
content.append(chartTypesWrapper);
return content[0].outerHTML;
},
_createFormPanel: function(data, ref) {
const content = $(templates.divContentWrapper(ref));
const form = $(templates.formElement());
data.forEach((fields) => {
const legend = fields.legend;
const layoutClass = fields.layoutClass;
const editors = fields.editors;
let target = "";
if (editors instanceof Array) {
let formFields = "";
editors.forEach((editor) => {
const nowrap = editor.nowrap;
const label = editor.label ? templates.label(kendo.htmlEncode(editor.label.text), editor.label.for, !nowrap && "k-form-label") : "";
const className = editor.className;
let field;
if (editor.field && editor.field.custom) field = editor.field.custom;
else if (editor.field) field = templates.inputBaseElement(editor.field);
else field = "";
if (nowrap) formFields += templates.fieldContent(label, field);
else formFields += templates.formField(templates.fieldContent(label, templates.formFieldWrap(field)), className);
});
if (layoutClass) {
const formGridLayout = $(templates.formGridLayout(layoutClass));
formGridLayout.append(formFields);
target = formGridLayout[0].outerHTML;
} else target = formFields;
} else if (editors && editors.custom) target = editors.custom;
else target = templates.inputBaseElement(editors);
if (legend) form.append(templates.formFieldSet(kendo.htmlEncode(legend), target));
else form.append(target);
});
content.append(form);
return content[0].outerHTML;
},
_ensureSizeValue: function(fontSize, callback) {
const numberRegExp = /^\d+$/;
const size = fontSize.toString();
let item = fontSizes.find((fs) => fs.text === size);
if (!item) {
if (!numberRegExp.test(size) || isNaN(parseInt(size, 10))) return false;
item = {
text: size,
value: size + "px"
};
fontSizes.push(item);
fontSizes.sort((a, b) => parseInt(a.text, 10) - parseInt(b.text, 10));
callback(fontSizes);
}
return true;
},
_executeAction: function(change, from, data, type, dataAction) {
const that = this;
const action = from.element.data("action");
const state = {
state: that.chartState,
action: dataAction ?? actionTypes[action],
change
};
if (data) {
state.data = data;
state.type = type ?? that.chartState.seriesType;
}
const newState = getNewState(state);
newState.chartArea = newState.area;
that.chart.setOptions(newState);
that.chartState = newState;
return newState;
},
_seriesDropDownChange: function(e) {
const that = this;
that._seriesChange = true;
e.preventChange = true;
const newState = that._handlePropertyChange(e);
delete that._seriesChange;
that._seriesGrid && that._seriesGrid.setDataSource(newState.series);
},
_prepareDataTab: function() {
const that = this;
const form = that.element.find(`[${REF_SELECTOR}'data'] > form`);
const gridField = form.find(".k-grid").closest(".k-form-fieldset");
const valueAxisField = form.find("#value-axis").closest(".k-form-fieldset");
that._dynamicConfigurationFields = {
grid: gridField.clone(),
valueAxis: valueAxisField.clone(),
container: form
};
gridField.remove();
valueAxisField.remove();
},
_resetFontValue: function(isInitial, field) {
if (isInitial && field) {
field.font = "";
return true;
}
return false;
},
_getFontField: function(activeField, activeFieldInitial, isInitial) {
const that = this;
let newValue;
if (isInitial) newValue = activeFieldInitial && activeFieldInitial.font;
else newValue = activeField && activeField.font;
that._valueReset = that._resetFontValue(isInitial, activeField);
return newValue;
},
_getFontValue: function(fontState, field, type, fromSibling) {
const that = this;
let newValue;
const isInitial = type === "initial";
const activeFieldInitial = that._initialState[fontState.active];
const activeField = that.chartState[fontState.active];
if (Array.isArray(activeField)) newValue = that._getFontField(activeField[0], activeFieldInitial, isInitial, fromSibling);
else newValue = that._getFontField(activeField, activeFieldInitial, isInitial, fromSibling);
if (!newValue && fontState.subfield) {
const sub = fontState.subfield.toLowerCase();
if (Array.isArray(activeField)) newValue = that._getFontField(activeField[0][sub], activeFieldInitial[sub], isInitial, fromSibling);
else newValue = that._getFontField(activeField[sub], activeFieldInitial[sub], isInitial, fromSibling);
}
if (newValue) newValue = that._parseFont(newValue)[field];
return newValue;
},
_createFontCombobox: function(element) {
const that = this;
const state = that._getFontState(element);
const comboBox = element.kendoComboBox({
dataSource: state.dataSource,
value: state.value,
change: function(e) {
const fontState = e.sender._fontState;
const fontNameChanged = fontState.type === "name";
const applySubfieldToSelector = fontState.subfield && state.active !== "legend";
const selector = `${fontState.active}${fontState.subfield && applySubfieldToSelector ? `${fontState.subfield}` : ""}Font`;
let field = fontNameChanged ? "Size" : "Name";
let value = e.sender.value();
const sibling = e.sender.wrapper.closest(".k-form").find(`[${DATA_ACTION}*=${selector + field}]`).data("kendoComboBox");
field = field.toLowerCase();
const initial = !value;
if (initial) {
that._getFontValue(fontState, fontState.type, "initial");
if (that._valueReset) {
e.sender.value("");
sibling.value("");
return that.chart.setOptions(that.chartState);
}
} else {
if (!fontNameChanged) value = value.replace("px", "");
if (value !== "" && !fontNameChanged && !that._ensureSizeValue(value, e.sender.setDataSource.bind(e.sender))) return;
that._handlePropertyChange(e);
}
if (!initial && !sibling.value()) {
let newValue = that._getFontValue(fontState, field);
let change;
if (!fontNameChanged) {
newValue = newValue.replace(/^['"]*([a-zA-Z0-9\s]+)['"]*$/g, "$1");
change = fontNames.find((item) => item.value.includes(newValue));
} else if (that._ensureSizeValue(newValue, sibling.setDataSource.bind(sibling))) change = fontSizes.find((item) => item.text === newValue.toString());
if (change && change.value) {
sibling.value(change.text);
that._handlePropertyChange({
sender: sibling,
preventChange: true
}, change.value);
}
}
},
...commonOptions.comboBox
}).data("kendoComboBox");
comboBox._fontState = state;
return comboBox;
},
_createDropDownList: function(element, options, handler) {
const that = this;
return $(element).kendoDropDownList({
...commonOptions.dropDownList,
...options,
change: handler || function(e) {
that._handlePropertyChange(e);
}
}).data("kendoDropDownList");
},
_createSwitch: function(element, options, handler) {
const that = this;
return element.kendoSwitch({
...options,
change: handler || function(e) {
that._handlePropertyChange(e);
}
}).data("kendoSwitch");
},
_createCheckBox: function(element, options, handler) {
const that = this;
return element.kendoCheckBox({
...options,
change: handler || function(e) {
that._handlePropertyChange(e);
}
}).data("kendoCheckBox");
},
_createColorPicker: function(element, options, handler) {
const that = this;
const config = options ?? {};
const enabled = config.enable !== void 0 ? config.enable : true;
delete config.enabled;
const colorPicker = element.kendoColorPicker({
...commonOptions.colorPicker,
...config,
change: handler || function(e) {
that._handlePropertyChange(e);
},
select: handler || function(e) {
that._handlePropertyChange(e, e.value);
}
}).data("kendoColorPicker");
colorPicker.enable(enabled);
return colorPicker;
},
_createNumericTextBox: function(element, options, handler) {
const that = this;
return element.kendoNumericTextBox({
...commonOptions.numericTextBox,
...options,
change: handler || function(e) {
that._handlePropertyChange(e);
},
spin: handler || function(e) {
that._handlePropertyChange(e);
}
}).data("kendoNumericTextBox");
},
_createTextBox: function(element, options) {
const that = this;
const textbox = element.kendoTextBox({ ...options });
textbox.on("input.kendoChartWizard", function(e) {
const sender = { element: $(e.target) };
that._handlePropertyChange({ sender }, $(e.target).val());
});
return textbox.data("kendoTextBox");
},
_getFieldValue: function(action) {
const parts = action.split(REG_EXP_CAPITAL);
const fontIndex = parts.indexOf("Font");
const path = parts.slice(0, fontIndex);
const type = parts[fontIndex + 1].toLowerCase();
let field;
let subfield;
if (path.length === 1) field = path[0];
else if (path.length > 1) {
subfield = path.pop();
field = path.join("");
}
return {
type,
field,
subfield: field === "legend" ? "Labels" : subfield
};
},
_getFontState: function(element) {
const that = this;
const state = that.chartState;
const action = element.data("action");
const parts = that._getFieldValue(action);
const field = parts.field;
const subfield = parts.subfield && parts.subfield.toLowerCase();
let font = state[field] && state[field].font;
if (!font && subfield) font = state[field] && state[field][subfield] && state[field][subfield].font;
let value = null;
let dataSource = [];
if (parts.type === "name") {
dataSource = fontNames;
value = font && dataSource.find((f) => f.value === that._parseFont(font).name) || null;
} else {
dataSource = fontSizes;
value = font && dataSource.find((f) => f.value === that._parseFont(font).size) || null;
}
return {
dataSource,
value,
type: parts.type,
active: field,
subfield: parts.subfield
};
},
_parseFont: function(font) {
const el = $("<span></span>");
el.css("font", font);
return {
fontWeight: el.css("fontWeight"),
size: parseInt(parseFloat(el.css("fontSize"))),
name: el.css("fontFamily")
};
},
_addSeries: function(e) {
const that = this;
const grid = that._seriesGrid;
const item = that._removedSeries.pop();
const data = grid.options.dataSource;
data.push(item);
grid.setDataSource(data);
},
_removeSeries: function(e) {
const that = this;
const target = e.target.closest("tr");
that._seriesGrid.removeRow(target);
},
_gridDataBoundHandler: function(grid) {
const that = this;
const clickHandlers = {
add: this._addSeries.bind(that),
remove: this._removeSeries.bind(that)
};
grid.wrapper.find(".k-grid-header").remove();
grid.wrapper.find(DATA_ACTION_SELECTOR).each((_, button) => {
const buttonElement = $(button);
if (buttonElement.data("kendoButton")) {
buttonElement.data("kendoButton").destroy();
buttonElement.removeAttr("disabled");
}
const action = buttonElement.data("action");
const enableRemove = !!(action === "remove" && grid._data.length > 1);
const enableAdd = !!(action === "add" && that._removedSeries && that._removedSeries.length > 0);
const enabled = enableRemove || enableAdd;
buttonElement.kendoButton({
icon: action === "add" ? "plus" : "trash",
enabled,
fillMode: FILL_MODE_FLAT,
click: clickHandlers[action]
});
});
},
_initGrid: function(element) {
const that = this;
const messages = that.options.messages.data.configuration.series;
that._seriesGrid = element.kendoGrid({
...commonOptions.grid,
toolbar: [{ template: () => `<button ${DATA_ACTION}='add' tabindex="0">${kendo.htmlEncode(messages.add)}</button>` }],
dataBound: function(e) {
const grid = e.sender;
that._preventChange = true;
if (that._seriesReordering) {
if (grid._data.length === that._reorderedData.length) {
that._seriesReordering = false;
that._executeAction(that._reorderedData, grid);
delete that._reorderedData;
that.trigger(CHANGE, { state: that.chartState });
}
} else {
that._executeAction(grid.options.dataSource, grid);
that.trigger(CHANGE, { state: that.chartState });
}
that._preventChange = false;
that._gridDataBoundHandler(grid);
},
cellClose: function(e) {
if (e.type === "save") that._handleSeriesEdit(e);
},
remove: function(e) {
that._handleSeriesRemove(e);
},
rowReorder: function(e) {
that._seriesReordering = true;
that._reorderedData = prepareReorderedDataForGrid(e.sender, e.oldIndex, e.newIndex - 1);
},
dataSource: that.chartState.series
}).data("kendoGrid");
},
_handleSeriesEdit: function(e) {
const that = this;
const grid = e.sender;
const data = grid.options.dataSource;
const itemIndex = grid.dataSource.indexOf(e.model);
const newField = {
...data[itemIndex],
name: e.model.name
};
data.splice(itemIndex, 1, newField);
that._executeAction(data, grid);
that.trigger(CHANGE, { state: that.chartState });
},
_handleSeriesRemove: function(e) {
const that = this;
const data = e.sender.options.dataSource;
let itemIndex;
const item = data.find((item, index) => {
itemIndex = index;
return item.name === e.model.name;
});
data.splice(itemIndex, 1);
if (that._removedSeries) that._removedSeries.unshift(item);
else that._removedSeries = [item];
},
_toggleFieldsForSeriesPanel: function(type) {
const that = this;
const gridField = $(that._dynamicConfigurationFields.grid[0].outerHTML);
const valueAxisField = $(that._dynamicConfigurationFields.valueAxis[0].outerHTML);
const container = that._dynamicConfigurationFields.container;
const typeIsCategorical = isCategorical(type);
if (!gridField || !valueAxisField) return;
if (that._oldType === type || isCategorical(that._oldType) && typeIsCategorical) return;
if (typeIsCategorical) {
that._seriesValueAxisDDL && that._seriesValueAxisDDL.wrapper && that._seriesValueAxisDDL.wrapper.data && that._seriesValueAxisDDL.destroy();
delete that._seriesValueAxisDDL;
container.find("[data-action=valueAxisY]").closest(".k-form-fieldset").remove();
container.append(gridField);
that._initGrid(gridField.find(".k-grid"));
} else {
that._seriesGrid && that._seriesGrid.wrapper && that._seriesGrid.wrapper.data && that._seriesGrid.destroy();
delete that._seriesGrid;
container.find(".k-grid").closest(".k-form-fieldset").remove();
container.append(valueAxisField);
const valueAxisDDL = valueAxisField.find(`[${DATA_ROLE_SELECTOR}${inputRoles.dropDownList}]`);
that._seriesValueAxisDDL = that._createDropDownList(valueAxisDDL, {
value: that.chartState.valueField || "",
dataSource: that.chartState.columns.map((column) => ({
text: column,
value: column
}))
}, that._seriesDropDownChange.bind(that));
}
that._oldType = type;
that._preventLabelPointerEvents();
},
_initStaticEditors: function() {
const that = this;
that.element.find(".k-form").each((_, form) => {
const panel = $(form).closest(`[${REF}]`);
const editors = $(panel).find(`[${DATA_ROLE}]`);
const panelRef = that._getRefAttributeValue(panel[0])[0];
that._initEditors(editors, panelRef);
});
that._toggleFieldsForSeriesPanel(that.chartState.seriesType);
that._toggleFormatPanels();
},
_initEditors: function(editors, panelRef) {
const that = this;
editors.each((_, editor) => {
const element = $(editor);
const id = element.attr("id");
const editorType = element.data("role");
const editorOptions = that._getOptionsForPanel(id)[panelRef][editorType];
const options = editorOptions ? editorOptions.options : editorOptions;
const handler = editorOptions ? editorOptions.handler : editorOptions;
if (editorType === "combobox") that._createFontCombobox(element, options, handler);
else if (editorType === "dropdownlist") that._createDropDownList(element, options, handler);
else if (editorType === "colorpicker") that._createColorPicker(element, options, handler);
else if (editorType === "numerictextbox") that._createNumericTextBox(element, options, handler);
else if (editorType === "switch") that._createSwitch(element, options, handler);
else if (editorType === "checkbox") that._createCheckBox(element, options, handler);
else if (editorType === "textbox") that._createTextBox(element, options, handler);
});
},
_prepareFormatTab: function() {
const that = this;
const categoryAxisField = that.element.find(`[${REF_SELECTOR}'categoryaxis'] > form`);
const valueAxisField = that.element.find(`[${REF_SELECTOR}'valueaxis'] > form`);
that._dynamicFormatPanels = {
categoryAxis: categoryAxisField,
valueAxis: valueAxisField,
container: categoryAxisField.closest(DOT + cssClasses.expansionPanelWrapper).parent()
};
that._initialAxesPanelsContent = {
categoryAxis: categoryAxisField.clone(),
valueAxis: valueAxisField.clone()
};
categoryAxisField.closest(DOT + cssClasses.expansionPanelWrapper).remove();
valueAxisField.closest(DOT + cssClasses.expansionPanelWrapper).remove();
},
_toggleFormatPanels: function() {
const that = this;
const messages = that.options.messages.format;
const chartType = that.chartState.seriesType;
const categoryAxisField = that._dynamicFormatPanels.categoryAxis;
const valueAxisField = that._dynamicFormatPanels.valueAxis;
const container = that._dynamicFormatPanels.container;
const initialContentCategory = that._initialAxesPanelsContent.categoryAxis.html();
const initialContentValue = that._initialAxesPanelsContent.valueAxis.html();
categoryAxisField.empty().append(initialContentCategory);
valueAxisField.empty().append(initialContentValue);
if (chartType !== "pie") {
let messagesCategory = kendo.htmlEncode(messages.categoryAxis.expandText);
let messagesValue = kendo.htmlEncode(messages.valueAxis.expandText);
if (chartType === "scatter") {
messagesCategory = kendo.htmlEncode(messages.xAxis.expandText);
messagesValue = kendo.htmlEncode(messages.yAxis.expandText);
}
if (container.find($(valueAxisField)).length === 0) {
const categoryWrapper = $(templates.divContentWrapper("categoryaxis-format-panel")).append(categoryAxisField);
const valueWrapper = $(templates.divContentWrapper("valueaxis-format-panel")).append(valueAxisField);
container.append(categoryWrapper);
container.append(valueWrapper);
$(categoryWrapper).kendoExpansionPanel({ title: messagesCategory });
$(valueWrapper).kendoExpansionPanel({ title: messagesValue });
} else {
categoryAxisField.closest(DOT + cssClasses.expansionPanelWrapper).find(".k-expander-title").text(messagesCategory);
valueAxisField.closest(DOT + cssClasses.expansionPanelWrapper).find(".k-expander-title").text(messagesValue);
}
if (categoryAxisField.closest(DOT + cssClasses.expansionPanelWrapper).length) categoryAxisField.closest(`[${REF}]`).add(valueAxisField.closest(`[${REF}]`)).each((_, expander) => {
const editors = $(expander).find(`[${DATA_ROLE}]`);
const panelRef = that._getRefAttributeValue(expander)[0];
that._initEditors(editors, panelRef);
});
} else if (container.find(valueAxisField).length) {
const categoryAxisExpander = categoryAxisField.closest(DOT + cssClasses.expansionPanelWrapper);
const valueAxisFieldExpander = valueAxisField.closest(DOT + cssClasses.expansionPanelWrapper);
kendo.destroy(categoryAxisExpander);
kendo.destroy(valueAxisFieldExpander);
categoryAxisExpander.remove();
valueAxisFieldExpander.remove();
}
that._preventLabelPointerEvents();
},
_handlePropertyChange: function(e, value) {
const that = this;
const change = value || value === "" ? value : e.sender.value();
const newState = that._executeAction(change, e.sender);
!e.preventChange && that.trigger(CHANGE, { state: that.chartState });
return newState;
},
_getOptionsForPanel: function(id) {
const that = this;
const chartState = that.chartState;
const messages = that.options.messages;
const positionsData = legendPositions(messages.format.legend).map((position) => ({
...position,
text: kendo.htmlEncode(position.text)
}));
const formats = labelFormats(messages.format.valueAxis).map((format) => ({
...format,
text: kendo.htmlEncode(format.text)
}));
const titleValues = titles(messages).map((title) => ({
...title,
text: kendo.htmlEncode(title.text)
}));
const fieldForAxes = id.includes("title") ? "title" : "labels";
return {
configuration: { dropdownlist: {
options: {
value: chartState[id.includes("category") ? "categoryField" : "valueField"],
dataSource: chartState.columns.map((column) => ({
text: column,
value: column
}))
},
handler: that._seriesDropDownChange.bind(that)
} },
chartarea: {
numerictextbox: { options: {
value: chartState.chartArea && chartState.chartArea.margin[id] ? chartState.chartArea.margin[id] : null,
min: 0,
max: 1e3
} },
colorpicker: { options: { value: chartState.chartArea.background && chartState.chartArea.background.color || "" } }
},
title: {
dropdownlist: {
options: {
dataSource: titleValues,
value: that._activeTitle && titleValues.find((t) => t.value === that._activeTitle.value)
},
handler: that._titleFieldChange.bind(that)
},
textbox: { options: { value: that._activeTitle && chartState[that._activeTitle].text } },
colorpicker: { options: { value: that._activeTitle && chartState[that._activeTitle].color } }
},
series: {
dropdownlist: {
options: {
dataSource: [{ name: kendo.htmlEncode(messages.format.series.allSeries) }, ...chartState.series],
dataTextField: "name",
dataValueField: "name",
enable: isCategorical(chartState.seriesType),
value: that._activeSeries && chartState.series.find((s) => s.name === that._activeSeries)
},
handler: that._activeSeriesChange.bind(that)
},
colorpicker: {
options: {
value: that._activeSeries ? chartState.series.find((s) => s.name === that._activeSeries).color : "",
enable: false
},
handler: that._changeSeriesColor.bind(that)
},
checkbox: {
options: {
label: messages.format.series.showLabels,
checked: that._activeSeries ? chartState.series.find((s) => s.name === that._activeSeries).labels.visible : chartState.series.every((s) => s.labels?.visible)
},
handler: that._showLabels.bind(that)
}
},
legend: {
dropdownlist: { options: {
dataSource: positionsData,
value: chartState.legend && chartState.legend.position && positionsData.find((p) => p.value === chartState.legend.position)
} },
colorPicker: { options: { value: chartState.legend && chartState.legend.labels && chartState.legend.labels.color || "" } },
switch: { options: { checked: chartState.legend && chartState.legend.visible } }
},
categoryaxis: {
textbox: { options: { value: chartState.categoryAxis[0][fieldForAxes] && chartState.categoryAxis[0][fieldForAxes].text || "" } },
numerictextbox: { options: {
value: chartState.categoryAxis[fieldForAxes] && chartState.categoryAxis[fieldForAxes].rotation,
min: -360,
max: 360
} },
checkbox: { options: {
label: messages.format.categoryAxis[fieldForAxes].reverseOrder,
checked: chartState.categoryAxis[0].reverse || false
} },
colorpicker: { options: { value: chartState.categoryAxis[0][fieldForAxes] && chartState.categoryAxis[0][fieldForAxes].color || "" } }
},
valueaxis: {
dropdownlist: { options: {
dataSource: formats,
value: chartState.valueAxis[fieldForAxes] && chartState.valueAxis[fieldForAxes].labelFormat && formats.find((f) => f.value === chartState.valueAxis[fieldForAxes].labelFormat)
} },
textbox: { options: { value: chartState.valueAxis[fieldForAxes] && chartState.valueAxis[fieldForAxes].text || "" } },
numerictextbox: { options: {
value: chartState.valueAxis[0][fieldForAxes] && typeof chartState.valueAxis[0][fieldForAxes].rotation === "number" ? chartState.valueAxis[0][fieldForAxes].rotation : null,
min: -360,
max: 360
} },
colorpicker: { options: { value: chartState.valueAxis[0][fieldForAxes] && chartState.valueAxis[0][fieldForAxes].color || "" } }
}
};
},
_titleFieldChange: function(e) {
const that = this;
const value = that._applyTo(e);
const form = e.sender.wrapper.closest(".k-form");
form.find(`[${DATA_ROLE_SELECTOR}${inputRoles.textBox}]`).data("kendoTextBox").value(that.chartState[value].text);
form.find(`[${DATA_ROLE_SELECTOR}${inputRoles.colorPicker}]`).data("kendoColorPicker").value(that.chartState[value].color ?? "");
form.find(`[${DATA_ROLE_SELECTOR}${inputRoles.comboBox}]`).each((_, editor) => {
const field = $(editor).data("action").includes("FontName") ? "name" : "size";
const newValue = that._parseFont(that.chartState[value].font)[field].toString();
const instance = $(editor).data("kendoComboBox");
let change;
if (newValue) {
const regex = new RegExp(`${newValue.replaceAll(`"`, "").split(",")[0]}`, "g");
if (field === "name") change = fontNames.find((item) => regex.test(item.text));
else change = fontSizes.find((item) => item.text === newValue.toString());
if (change && that._handlePropertyChange) that._handlePropertyChange({ sender: instance }, change.value);
}
that._activeTitle = value;
instance._fontState.active = value;
instance.value(change ? change.text : null);
});
},
_activeSeriesChange: function(e) {
const that = this;
const value = e.sender.value();
const colorPicker = e.sender.wrapper.closest(".k-form").find(`[${DATA_ROLE_SELECTOR}${inputRoles.colorPicker}]`).data("kendoColorPicker");
if (value !== that.options.messages.format.series.allSeries) {
const series = that.chart.options.series.find((s) => s.name === value);
colorPicker.enable(true);
if (series) colorPicker.value(series.color);
colorPicker._currentActiveSeries = value;
that._activeSeries = value;
} else {
colorPicker.value("");
colorPicker.enable(false);
colorPicker._currentActiveSeries = null;
that._activeSeries = null;
}
},
_applyTo: function(e) {
const value = e.sender.value();
e.sender.wrapper.closest(".k-form").find(DATA_ACTION_SELECTOR).each((_, el) => {
const element = $(el);
if (!element.is(e.sender.element)) {
const currentAction = element.data("action").split(REG_EXP_CAPITAL);
currentAction.shift();
const newAction = value + currentAction.join("");
element.attr(DATA_ACTION, newAction).data("action", newAction);
}
});
return value;
},
_showLabels: function(e) {
const that = this;
const value = e.sender.check();
const colorPicker = e.sender.wrapper.closest(".k-form").find(`[${DATA_ROLE_SELECTOR}${inputRoles.colorPicker}]`).data("kendoColorPicker");
that._handlePropertyChange(e, {
seriesName: colorPicker._currentActiveSeries,
all: !colorPicker._currentActiveSeries,
visible: value
});
},
_changeSeriesColor: function(e) {
const that = this;
const value = e.value;
that._handlePropertyChange(e, {
seriesName: e.sender._currentActiveSeries,
color: value
});
},
_getRefAttributeValue: function(element) {
return element.getAttribute(`${REF}`).split("-");
},
_expansionPanels: function() {
const that = this;
let prevRef = "";
let index = 0;
that.tabStrip.contentElements.children().each((_, element) => {
const tabRef = that._getRefAttributeValue(element)[1];
if (prevRef === tabRef) index++;
else index = 0;
const titles = Object.keys(that.options.messages[tabRef]);
const expansionPanel = $(element).kendoExpansionPanel({
title: kendo.htmlEncode(that.options.messages[tabRef][titles[index]].expandText),
complete: () => {
if (that._seriesGrid && that._seriesGrid.wrapper.is(":visible")) {
that._seriesGrid._draggableRows();
that._seriesGrid._reorderableRows();
}
}
}).data("kendoExpansionPanel");
expansionPanel.wrapper.removeClass();
expansionPanel.wrapper.addClass(cssClasses.expansionPanelWrapper);
prevRef = tabRef;
});
},
setOptions: function(options) {
if (!options) return;
const that = this;
const hasNewDataSource = options.dataSource !== null && options.dataSource !== void 0;
const hasNewDataColumns = options.dataColumns !== null && options.dataColumns !== void 0;
if (options.state !== null && options.state !== void 0) delete that.options.state;
if (hasNewDataSource) delete that.options.dataSource;
if (hasNewDataColumns) delete that.options.dataColumns;
deepExtend(that.options, options);
if (hasNewDataColumns) that.setDataColumns(options.dataColumns);
if (hasNewDataSource) that.setDataSource(that.options.dataSource);
else that._refreshContent();
},
destroy: function() {
const that = this;
kendo.destroy(that.previewPane);
kendo.destroy(that.propertyPane);
that.element.empty();
Widget.fn.destroy.call(that);
that.element.off(NS);
that.wrapper.off(NS);
that._detachEvents();
if (that.splitter) that.splitter.destroy();
if (that.chart) that.chart.destroy();
if (that.tabStrip) that.tabStrip.destroy();
if (that.window) that.window.destroy();
that.chart = that.tabStrip = that.window = that.splitter = that.propertyPane = that.chartState = that.previewPane = null;
that._dynamicConfigurationFields = that._dynamicFormatPanels = that._initialAxesPanelsContent = that._initialState = that._oldType = that._seriesGrid = null;
}
});
ui.plugin(ChartWizard);
extend(kendo.ui.ChartWizard, {
generateDataRows,
getWizardDataFromDataRows
});
})(window.kendo.jQuery);
var kendo_chartwizard_default = kendo;
//#endregion
exports.__meta__ = __meta__;
exports.default = kendo_chartwizard_default;