devextreme
Version:
HTML5 JavaScript Component Suite for Responsive Web Development
527 lines (442 loc) • 18.9 kB
JavaScript
var extend = require("../../core/utils/extend").extend,
inArray = require("../../core/utils/array").inArray,
each = require("../../core/utils/iterator").each,
rangeModule = require("../translators/range"),
DEFAULT_AXIS_NAME = "defaultAxisName",
axisModule = require("../axes/base_axis"),
seriesFamilyModule = require("../core/series_family"),
BaseChart = require("./base_chart").BaseChart,
crosshairModule = require("./crosshair"),
_isArray = Array.isArray,
_isDefined = require("../../core/utils/type").isDefined,
_each = each,
_noop = require("../../core/utils/common").noop,
_extend = extend,
vizUtils = require("../core/utils"),
_map = vizUtils.map,
mergeMarginOptions = vizUtils.mergeMarginOptions;
function prepareAxis(axisOptions) {
return _isArray(axisOptions) ? axisOptions.length === 0 ? [{}] : axisOptions : [axisOptions];
}
function processBubbleMargin(opt, bubbleSize) {
if (opt.processBubbleSize) {
opt.size = bubbleSize;
}
return opt;
}
function estimateBubbleSize(size, panesCount, maxSize, rotated) {
var width = rotated ? size.width / panesCount : size.width,
height = rotated ? size.height : size.height / panesCount;
return Math.min(width, height) * maxSize;
}
var AdvancedChart = BaseChart.inherit({
_setDeprecatedOptions: function _setDeprecatedOptions() {
this.callBase.apply(this, arguments);
_extend(this._deprecatedOptions, {
"barWidth": { since: "18.1", message: "Use the 'commonSeriesSettings.barPadding' or 'series.barPadding' option instead" },
"equalBarWidth": { since: "18.1", message: "Use the 'commonSeriesSettings.ignoreEmptyPoints' or 'series.ignoreEmptyPoints' option instead" }
});
},
_dispose: function _dispose() {
var that = this,
disposeObjectsInArray = this._disposeObjectsInArray;
that.callBase();
that.panes = null;
if (that._legend) {
that._legend.dispose();
that._legend = null;
}
disposeObjectsInArray.call(that, "panesBackground");
disposeObjectsInArray.call(that, "seriesFamilies");
that._disposeAxes();
},
_reinitAxes: function _reinitAxes() {
this.panes = this._createPanes();
this._populateAxes();
},
_getCrosshairMargins: function _getCrosshairMargins() {
var crosshairOptions = this._getCrosshairOptions() || {},
crosshairEnabled = crosshairOptions.enabled,
margins = crosshairModule.getMargins();
return {
x: crosshairEnabled && crosshairOptions.horizontalLine.visible ? margins.x : 0,
y: crosshairEnabled && crosshairOptions.verticalLine.visible ? margins.y : 0
};
},
_populateAxes: function _populateAxes() {
var that = this,
valueAxes = [],
argumentAxes,
panes = that.panes,
rotated = that._isRotated(),
valueAxisOptions = that.option("valueAxis") || {},
argumentOption = that.option("argumentAxis") || {},
argumentAxesOptions = prepareAxis(argumentOption)[0],
valueAxesOptions = prepareAxis(valueAxisOptions),
axisNames = [],
valueAxesCounter = 0,
paneWithNonVirtualAxis,
crosshairMargins = that._getCrosshairMargins();
function getNextAxisName() {
return DEFAULT_AXIS_NAME + valueAxesCounter++;
}
that._disposeAxes();
if (rotated) {
paneWithNonVirtualAxis = argumentAxesOptions.position === "right" ? panes[panes.length - 1].name : panes[0].name;
} else {
paneWithNonVirtualAxis = argumentAxesOptions.position === "top" ? panes[0].name : panes[panes.length - 1].name;
}
argumentAxes = _map(panes, function (pane, index) {
return that._createAxis("argumentAxis", argumentAxesOptions, {
pane: pane.name,
name: null,
crosshairMargin: rotated ? crosshairMargins.x : crosshairMargins.y
}, rotated, pane.name !== paneWithNonVirtualAxis, index);
});
_each(valueAxesOptions, function (priority, axisOptions) {
var axisPanes = [],
name = axisOptions.name;
if (name && inArray(name, axisNames) !== -1) {
that._incidentOccurred("E2102");
return;
}
name && axisNames.push(name);
if (axisOptions.pane) {
axisPanes.push(axisOptions.pane);
}
if (axisOptions.panes && axisOptions.panes.length) {
axisPanes = axisPanes.concat(axisOptions.panes.slice(0));
}
axisPanes = vizUtils.unique(axisPanes);
if (!axisPanes.length) {
axisPanes.push(undefined);
}
_each(axisPanes, function (_, pane) {
valueAxes.push(that._createAxis("valueAxis", axisOptions, {
name: name || getNextAxisName(),
pane: pane,
priority: priority,
crosshairMargin: rotated ? crosshairMargins.y : crosshairMargins.x
}, rotated));
});
});
// that's it. For now
that._valueAxes = valueAxes;
that._argumentAxes = argumentAxes;
},
_prepareStackPoints: function _prepareStackPoints(singleSeries, stackPoints) {
var points = singleSeries.getPoints(),
stackName = singleSeries.getStackName();
_each(points, function (_, point) {
var argument = point.argument;
if (!stackPoints[argument]) {
stackPoints[argument] = {};
stackPoints[argument][null] = [];
}
if (stackName && !_isArray(stackPoints[argument][stackName])) {
stackPoints[argument][stackName] = [];
_each(stackPoints[argument][null], function (_, point) {
if (!point.stackName) {
stackPoints[argument][stackName].push(point);
}
});
}
if (stackName) {
stackPoints[argument][stackName].push(point);
stackPoints[argument][null].push(point);
} else {
_each(stackPoints[argument], function (_, stack) {
stack.push(point);
});
}
point.stackPoints = stackPoints[argument][stackName];
point.stackName = stackName;
});
},
_resetStackPoints: function _resetStackPoints(singleSeries) {
_each(singleSeries.getPoints(), function (_, point) {
point.stackPoints = null;
point.stackName = null;
});
},
_disposeAxes: function _disposeAxes() {
var that = this,
disposeObjectsInArray = that._disposeObjectsInArray;
disposeObjectsInArray.call(that, "_argumentAxes");
disposeObjectsInArray.call(that, "_valueAxes");
},
_appendAdditionalSeriesGroups: function _appendAdditionalSeriesGroups() {
this._crosshairCursorGroup.linkAppend();
// this._legendGroup.linkAppend();
this._scrollBar && this._scrollBarGroup.linkAppend(); // TODO: Must be appended in the same place where removed (chart)
},
_getLegendTargets: function _getLegendTargets() {
var that = this;
return _map(that.series, function (item) {
if (item.getOptions().showInLegend) {
return that._getLegendOptions(item);
}
return null;
});
},
_legendItemTextField: "name",
_seriesPopulatedHandlerCore: function _seriesPopulatedHandlerCore() {
this._processSeriesFamilies();
this._processValueAxisFormat();
},
_renderTrackers: function _renderTrackers() {
var that = this,
i;
for (i = 0; i < that.series.length; ++i) {
that.series[i].drawTrackers();
}
// TODO we don't need it
// if (that._legend) {
// legendHasInsidePosition && that._legendGroup.append(that._renderer.root);
// }
},
_specialProcessSeries: function _specialProcessSeries() {
this._processSeriesFamilies();
},
_processSeriesFamilies: function _processSeriesFamilies() {
var that = this,
types = [],
families = [],
paneSeries,
themeManager = that._themeManager,
negativesAsZeroes = themeManager.getOptions("negativesAsZeroes"),
negativesAsZeros = themeManager.getOptions("negativesAsZeros"),
// misspelling case
familyOptions = {
equalBarWidth: themeManager.getOptions("equalBarWidth"),
minBubbleSize: themeManager.getOptions("minBubbleSize"),
maxBubbleSize: themeManager.getOptions("maxBubbleSize"),
barWidth: themeManager.getOptions("barWidth"),
barGroupPadding: themeManager.getOptions("barGroupPadding"),
barGroupWidth: themeManager.getOptions("barGroupWidth"),
negativesAsZeroes: _isDefined(negativesAsZeroes) ? negativesAsZeroes : negativesAsZeros
};
if (that.seriesFamilies && that.seriesFamilies.length) {
_each(that.seriesFamilies, function (_, family) {
family.updateOptions(familyOptions);
family.adjustSeriesValues();
});
return;
}
_each(that.series, function (_, item) {
if (inArray(item.type, types) === -1) {
types.push(item.type);
}
});
_each(that._getLayoutTargets(), function (_, pane) {
paneSeries = that._getSeriesForPane(pane.name);
_each(types, function (_, type) {
var family = new seriesFamilyModule.SeriesFamily({
type: type,
pane: pane.name,
equalBarWidth: familyOptions.equalBarWidth,
minBubbleSize: familyOptions.minBubbleSize,
maxBubbleSize: familyOptions.maxBubbleSize,
barWidth: familyOptions.barWidth,
barGroupPadding: familyOptions.barGroupPadding,
barGroupWidth: familyOptions.barGroupWidth,
negativesAsZeroes: familyOptions.negativesAsZeroes,
rotated: that._isRotated()
});
family.add(paneSeries);
family.adjustSeriesValues();
families.push(family);
});
});
that.seriesFamilies = families;
},
_updateSeriesDimensions: function _updateSeriesDimensions() {
var that = this,
i,
seriesFamilies = that.seriesFamilies || [];
for (i = 0; i < seriesFamilies.length; i++) {
var family = seriesFamilies[i];
family.updateSeriesValues();
family.adjustSeriesDimensions();
}
},
_getLegendCallBack: function _getLegendCallBack(series) {
return this._legend && this._legend.getActionCallback(series);
},
_appendAxesGroups: function _appendAxesGroups() {
var that = this;
that._stripsGroup.linkAppend();
that._gridGroup.linkAppend();
that._axesGroup.linkAppend();
that._constantLinesGroup.linkAppend();
that._labelAxesGroup.linkAppend();
that._scaleBreaksGroup.linkAppend();
},
_populateMarginOptions: function _populateMarginOptions() {
var that = this;
var bubbleSize = estimateBubbleSize(that.getSize(), that.panes.length, that._themeManager.getOptions("maxBubbleSize"), that._isRotated());
var argumentMarginOptions = {};
that._valueAxes.forEach(function (valueAxis) {
var groupSeries = that.series.filter(function (series) {
return series.getValueAxis() === valueAxis;
});
var marginOptions = {};
groupSeries.forEach(function (series) {
if (series.isVisible()) {
var seriesMarginOptions = processBubbleMargin(series.getMarginOptions(), bubbleSize);
marginOptions = mergeMarginOptions(marginOptions, seriesMarginOptions);
argumentMarginOptions = mergeMarginOptions(argumentMarginOptions, seriesMarginOptions);
}
});
valueAxis.setMarginOptions(marginOptions);
});
that._argumentAxes.forEach(function (a) {
return a.setMarginOptions(argumentMarginOptions);
});
},
_populateBusinessRange: function _populateBusinessRange(useZoom) {
var that = this;
var businessRanges = [];
var rotated = that._isRotated();
var argAxes = that._argumentAxes;
var argRange = new rangeModule.Range({ rotated: !!rotated });
var groupsData = that._groupsData;
argAxes.forEach(function (axis) {
return argRange.addRange(axis.getRangeData(useZoom));
});
that._valueAxes.forEach(function (valueAxis) {
var groupRange = new rangeModule.Range({
rotated: !!rotated,
pane: valueAxis.pane,
axis: valueAxis.name
}),
groupSeries = that.series.filter(function (series) {
return series.getValueAxis() === valueAxis;
});
groupRange.addRange(valueAxis.getRangeData(useZoom));
groupSeries.forEach(function (series) {
var seriesRange = series.getRangeData();
groupRange.addRange(seriesRange.val);
argRange.addRange(seriesRange.arg);
});
if (!groupRange.isDefined()) {
groupRange.setStubData(valueAxis.getOptions().valueType);
}
if (valueAxis.getOptions().showZero) {
groupRange.correctValueZeroLevel();
}
valueAxis.setGroupSeries(groupSeries);
valueAxis.setBusinessRange(groupRange);
businessRanges.push({ val: groupRange, arg: argRange });
});
argRange.sortCategories(groupsData.categories);
if (!argRange.isDefined()) {
argRange.setStubData(argAxes[0].getOptions().argumentType);
}
that._argumentAxes.forEach(function (a) {
return a.setBusinessRange(argRange);
});
that._populateMarginOptions();
that.businessRanges = businessRanges;
},
_getArgumentAxis: function _getArgumentAxis() {
return this._argumentAxes[0];
},
_getArgumentAxes: function _getArgumentAxes() {
return this._argumentAxes;
},
_getValueAxes: function _getValueAxes() {
return this._valueAxes;
},
_getGroupsData: function _getGroupsData() {
var that = this,
groups = [];
that._valueAxes.forEach(function (axis) {
groups.push({
series: that.series.filter(function (series) {
return series.getValueAxis() === axis;
}),
valueAxis: axis,
valueOptions: axis.getOptions()
});
});
return {
groups: groups,
argumentAxes: that._argumentAxes,
argumentOptions: that._argumentAxes[0].getOptions()
};
},
_groupSeries: function _groupSeries() {
var that = this;
that._correctValueAxes(false);
that._groupsData = that._getGroupsData();
},
_processValueAxisFormat: function _processValueAxisFormat() {
var axesWithFullStackedFormat = [];
this.series.forEach(function (series) {
var axis = series.getValueAxis();
if (series.isFullStackedSeries()) {
axis.setPercentLabelFormat();
axesWithFullStackedFormat.push(axis);
}
});
this._valueAxes.forEach(function (axis) {
if (axesWithFullStackedFormat.indexOf(axis) === -1) {
axis.resetAutoLabelFormat(); // B239299
}
});
},
_createAxis: function _createAxis(typeSelector, userOptions, axisOptions, rotated, virtual, index) {
var that = this,
renderingSettings = _extend({
renderer: that._renderer,
incidentOccurred: that._incidentOccurred,
axisClass: typeSelector === "argumentAxis" ? "arg" : "val",
widgetClass: "dxc",
stripsGroup: that._stripsGroup,
labelAxesGroup: that._labelAxesGroup,
constantLinesGroup: that._constantLinesGroup,
scaleBreaksGroup: that._scaleBreaksGroup,
axesContainerGroup: that._axesGroup,
gridGroup: that._gridGroup,
isArgumentAxis: typeSelector === "argumentAxis"
}, that._getAxisRenderingOptions(typeSelector)),
axis,
preparedUserOptions = that._prepareStripsAndConstantLines(typeSelector, userOptions, rotated),
options = _extend(true, {}, preparedUserOptions, axisOptions, that._prepareAxisOptions(typeSelector, preparedUserOptions, rotated));
if (virtual) {
options.visible = options.tick.visible = options.minorTick.visible = options.label.visible = false;
options.title = {};
}
axis = new axisModule.Axis(renderingSettings);
axis.updateOptions(options);
if (!virtual && _isDefined(index)) {
that._displayedArgumentAxisIndex = index;
}
return axis;
},
_getTrackerSettings: function _getTrackerSettings() {
return _extend(this.callBase(), {
argumentAxis: this._argumentAxes[this._displayedArgumentAxisIndex]
});
},
_prepareStripsAndConstantLines: function _prepareStripsAndConstantLines(typeSelector, userOptions, rotated) {
userOptions = this._themeManager.getOptions(typeSelector, userOptions, rotated);
if (userOptions.strips) {
_each(userOptions.strips, function (i) {
userOptions.strips[i] = _extend(true, {}, userOptions.stripStyle, userOptions.strips[i]);
});
}
if (userOptions.constantLines) {
_each(userOptions.constantLines, function (i, line) {
userOptions.constantLines[i] = _extend(true, {}, userOptions.constantLineStyle, line);
});
}
return userOptions;
},
_legendDataField: "series",
_adjustSeriesLabels: _noop,
_correctValueAxes: _noop
});
exports.AdvancedChart = AdvancedChart;
;