devextreme
Version:
HTML5 JavaScript Component Suite for Responsive Web Development
296 lines (282 loc) • 11.1 kB
JavaScript
/**
* DevExtreme (cjs/__internal/grids/pivot_grid/chart_integration/m_chart_integration.js)
* Version: 24.2.6
* Build date: Mon Mar 17 2025
*
* Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED
* Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
*/
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.ChartIntegrationMixin = void 0;
var _renderer = _interopRequireDefault(require("../../../../core/renderer"));
var _extend = require("../../../../core/utils/extend");
var _iterator = require("../../../../core/utils/iterator");
var _m_widget_utils = require("../m_widget_utils");
function _interopRequireDefault(e) {
return e && e.__esModule ? e : {
default: e
}
}
const FORMAT_DICTIONARY = {
number: "numeric",
date: "datetime"
};
const UNBIND_KEY = "dxPivotGridUnbinding";
function getFormattedValue(path, fields) {
const value = [];
const lastFieldIndex = fields.length - 1;
(0, _iterator.each)(path, ((i, item) => {
value.push(item.text || (0, _m_widget_utils.formatValue)(item.value, fields[lastFieldIndex - i]))
}));
return value.reverse()
}
function getExpandedLevel(node) {
let level = 0;
(0, _m_widget_utils.foreachTree)(node, (members => {
level = Math.max(level, members.length - 1)
}));
return level
}
function processDataCell(processCellArgs, processCell) {
let {
chartDataItem: chartDataItem
} = processCellArgs;
let processedCell = processCell && processCell(processCellArgs);
if (processedCell) {
chartDataItem = (0, _extend.extend)({}, chartDataItem, processedCell.chartDataItem);
processedCell = (0, _extend.extend)({}, processCellArgs, processedCell, {
chartDataItem: chartDataItem
});
return processedCell
}
return processCellArgs
}
function createChartDataSource(pivotGridDataSource, mapOptions, axisDictionary) {
const data = pivotGridDataSource.getData();
const dataSource = [];
const dataFields = pivotGridDataSource.getAreaFields("data");
const rowFields = pivotGridDataSource.getAreaFields("row");
const columnFields = pivotGridDataSource.getAreaFields("column");
const columnElements = [{
index: data.grandTotalColumnIndex,
children: data.columns
}];
const rowElements = [{
index: data.grandTotalRowIndex,
children: data.rows
}];
const rowLevel = getExpandedLevel(rowElements);
const columnLevel = getExpandedLevel(columnElements);
let measureIndex;
let dataField;
let rowMemberIndex;
let rowVisibility;
let rowPathFormatted;
let rowPath;
let columnMemberIndex;
let columnVisibility;
let columnPath;
let columnPathFormatted;
function createDataItem() {
const dataCell = (data.values[rowMemberIndex] || [])[columnMemberIndex] || [];
const value = dataCell[measureIndex];
let axis;
let processCellArgs = {
rowPath: rowPath,
maxRowLevel: rowLevel,
rowPathFormatted: rowPathFormatted,
rowFields: rowFields,
columnPathFormatted: columnPathFormatted,
maxColumnLevel: columnLevel,
columnPath: columnPath,
columnFields: columnFields,
dataFields: dataFields,
dataIndex: measureIndex,
dataValues: dataCell,
visible: columnVisibility && rowVisibility
};
let seriesName = (mapOptions.inverted ? columnPathFormatted : rowPathFormatted).join(" - ");
let argument = (mapOptions.inverted ? rowPathFormatted : columnPathFormatted).join("/");
if (dataFields.length > 1) {
if ("args" === mapOptions.putDataFieldsInto || "both" === mapOptions.putDataFieldsInto) {
argument += ` | ${dataField.caption}`
}
if ("args" !== mapOptions.putDataFieldsInto) {
seriesName += ` | ${dataField.caption}`;
if ("singleAxis" !== mapOptions.dataFieldsDisplayMode) {
axis = dataField.caption
}
}
}
processCellArgs.chartDataItem = {
val: void 0 === value ? null : value,
series: seriesName,
arg: argument
};
processCellArgs = processDataCell(processCellArgs, mapOptions.processCell);
if (processCellArgs.visible) {
axisDictionary[processCellArgs.chartDataItem.series] = axisDictionary[processCellArgs.chartDataItem.series] || axis;
dataSource.push(processCellArgs.chartDataItem)
}
}
function foreachRowColumn(callBack) {
(0, _m_widget_utils.foreachTree)(rowElements, (rowMembers => {
rowMemberIndex = rowMembers[0].index;
rowMembers = rowMembers.slice(0, rowMembers.length - 1);
rowVisibility = rowLevel === rowMembers.length;
rowPath = (0, _m_widget_utils.createPath)(rowMembers);
rowPathFormatted = getFormattedValue(rowMembers, rowFields);
if (0 === rowPath.length) {
rowPathFormatted = [mapOptions.grandTotalText]
}(0, _m_widget_utils.foreachTree)(columnElements, (columnMembers => {
columnMemberIndex = columnMembers[0].index;
columnMembers = columnMembers.slice(0, columnMembers.length - 1);
columnVisibility = columnLevel === columnMembers.length;
columnPath = (0, _m_widget_utils.createPath)(columnMembers);
columnPathFormatted = getFormattedValue(columnMembers, columnFields);
if (0 === columnPath.length) {
columnPathFormatted = [mapOptions.grandTotalText]
}
callBack()
}))
}))
}
function foreachDataField(callback) {
(0, _iterator.each)(dataFields, ((index, field) => {
dataField = field;
measureIndex = index;
callback()
}))
}
if (false === mapOptions.alternateDataFields) {
foreachDataField((() => {
foreachRowColumn(createDataItem)
}))
} else {
foreachRowColumn((() => {
foreachDataField(createDataItem)
}))
}
return dataSource
}
function createValueAxisOptions(dataSource, options) {
const dataFields = dataSource.getAreaFields("data");
if ("args" !== options.putDataFieldsInto && "singleAxis" !== options.dataFieldsDisplayMode || 1 === dataFields.length) {
const valueAxisSettings = [];
(0, _iterator.each)(dataFields, ((_, dataField) => {
const valueAxisOptions = {
name: dataField.caption,
title: dataField.caption,
valueType: FORMAT_DICTIONARY[dataField.dataType] || dataField.dataType,
label: {
format: dataField.format
}
};
if (dataField.customizeText) {
valueAxisOptions.label.customizeText = function(formatObject) {
return dataField.customizeText.call(dataField, formatObject)
}
}
if ("splitPanes" === options.dataFieldsDisplayMode) {
valueAxisOptions.pane = dataField.caption
}
valueAxisSettings.push(valueAxisOptions)
}));
return valueAxisSettings
}
return [{}]
}
function createPanesOptions(dataSource, options) {
const panes = [];
const dataFields = dataSource.getAreaFields("data");
if (dataFields.length > 1 && "splitPanes" === options.dataFieldsDisplayMode && "args" !== options.putDataFieldsInto) {
(0, _iterator.each)(dataFields, ((_, dataField) => {
panes.push({
name: dataField.caption
})
}))
}
if (!panes.length) {
panes.push({})
}
return panes
}
function createChartOptions(dataSource, options) {
const {
customizeSeries: customizeSeries
} = options;
const {
customizeChart: customizeChart
} = options;
let chartOptions = {
valueAxis: createValueAxisOptions(dataSource, options),
panes: createPanesOptions(dataSource, options)
};
const axisDictionary = {};
if (customizeChart) {
chartOptions = (0, _extend.extend)(true, {}, chartOptions, customizeChart(chartOptions))
}
chartOptions.dataSource = createChartDataSource(dataSource, options, axisDictionary);
chartOptions.seriesTemplate = {
nameField: "series",
customizeSeries(seriesName) {
let seriesOptions = {};
if ("splitPanes" === options.dataFieldsDisplayMode) {
seriesOptions.pane = axisDictionary[seriesName]
} else if ("singleAxis" !== options.dataFieldsDisplayMode) {
seriesOptions.axis = axisDictionary[seriesName]
}
if (customizeSeries) {
seriesOptions = (0, _extend.extend)(seriesOptions, customizeSeries(seriesName, seriesOptions))
}
return seriesOptions
}
};
return chartOptions
}
function getChartInstance(chartElement) {
if (!chartElement) {
return false
}
if (chartElement.NAME) {
return "dxChart" === chartElement.NAME && chartElement
}
const element = (0, _renderer.default)(chartElement);
return element.data("dxChart") && element.dxChart("instance")
}
function removeBinding(chart) {
const unbind = chart.$element().data(UNBIND_KEY);
unbind && unbind()
}
const ChartIntegrationMixin = exports.ChartIntegrationMixin = {
bindChart(chart, integrationOptions) {
integrationOptions = (0, _extend.extend)({}, integrationOptions);
const that = this;
const updateChart = function() {
integrationOptions.grandTotalText = that.option("texts.grandTotal");
const chartOptions = createChartOptions(that.getDataSource(), integrationOptions);
chart.option(chartOptions)
};
chart = getChartInstance(chart);
if (!chart) {
return null
}
removeBinding(chart);
that.on("changed", updateChart);
updateChart();
const disposeBinding = function() {
chart.$element().removeData(UNBIND_KEY);
that.off("changed", updateChart)
};
chart.on("disposing", disposeBinding);
this.on("disposing", disposeBinding);
chart.$element().data(UNBIND_KEY, disposeBinding);
return disposeBinding
}
};
var _default = exports.default = {
ChartIntegrationMixin: ChartIntegrationMixin
};