581 lines
19 KiB
JavaScript
581 lines
19 KiB
JavaScript
|
|
/*
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance
|
|
* with the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing,
|
|
* software distributed under the License is distributed on an
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
* KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations
|
|
* under the License.
|
|
*/
|
|
|
|
var zrUtil = require("zrender/lib/core/util");
|
|
|
|
var _number = require("../util/number");
|
|
|
|
var parsePercent = _number.parsePercent;
|
|
|
|
var _dataStackHelper = require("../data/helper/dataStackHelper");
|
|
|
|
var isDimensionStacked = _dataStackHelper.isDimensionStacked;
|
|
|
|
var createRenderPlanner = require("../chart/helper/createRenderPlanner");
|
|
|
|
/*
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance
|
|
* with the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing,
|
|
* software distributed under the License is distributed on an
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
* KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations
|
|
* under the License.
|
|
*/
|
|
|
|
/* global Float32Array */
|
|
var STACK_PREFIX = '__ec_stack_';
|
|
var LARGE_BAR_MIN_WIDTH = 0.5;
|
|
var LargeArr = typeof Float32Array !== 'undefined' ? Float32Array : Array;
|
|
|
|
function getSeriesStackId(seriesModel) {
|
|
return seriesModel.get('stack') || STACK_PREFIX + seriesModel.seriesIndex;
|
|
}
|
|
|
|
function getAxisKey(axis) {
|
|
return axis.dim + axis.index;
|
|
}
|
|
/**
|
|
* @param {Object} opt
|
|
* @param {module:echarts/coord/Axis} opt.axis Only support category axis currently.
|
|
* @param {number} opt.count Positive interger.
|
|
* @param {number} [opt.barWidth]
|
|
* @param {number} [opt.barMaxWidth]
|
|
* @param {number} [opt.barMinWidth]
|
|
* @param {number} [opt.barGap]
|
|
* @param {number} [opt.barCategoryGap]
|
|
* @return {Object} {width, offset, offsetCenter} If axis.type is not 'category', return undefined.
|
|
*/
|
|
|
|
|
|
function getLayoutOnAxis(opt) {
|
|
var params = [];
|
|
var baseAxis = opt.axis;
|
|
var axisKey = 'axis0';
|
|
|
|
if (baseAxis.type !== 'category') {
|
|
return;
|
|
}
|
|
|
|
var bandWidth = baseAxis.getBandWidth();
|
|
|
|
for (var i = 0; i < opt.count || 0; i++) {
|
|
params.push(zrUtil.defaults({
|
|
bandWidth: bandWidth,
|
|
axisKey: axisKey,
|
|
stackId: STACK_PREFIX + i
|
|
}, opt));
|
|
}
|
|
|
|
var widthAndOffsets = doCalBarWidthAndOffset(params);
|
|
var result = [];
|
|
|
|
for (var i = 0; i < opt.count; i++) {
|
|
var item = widthAndOffsets[axisKey][STACK_PREFIX + i];
|
|
item.offsetCenter = item.offset + item.width / 2;
|
|
result.push(item);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
function prepareLayoutBarSeries(seriesType, ecModel) {
|
|
var seriesModels = [];
|
|
ecModel.eachSeriesByType(seriesType, function (seriesModel) {
|
|
// Check series coordinate, do layout for cartesian2d only
|
|
if (isOnCartesian(seriesModel) && !isInLargeMode(seriesModel)) {
|
|
seriesModels.push(seriesModel);
|
|
}
|
|
});
|
|
return seriesModels;
|
|
}
|
|
/**
|
|
* Map from (baseAxis.dim + '_' + baseAxis.index) to min gap of two adjacent
|
|
* values.
|
|
* This works for time axes, value axes, and log axes.
|
|
* For a single time axis, return value is in the form like
|
|
* {'x_0': [1000000]}.
|
|
* The value of 1000000 is in milliseconds.
|
|
*/
|
|
|
|
|
|
function getValueAxesMinGaps(barSeries) {
|
|
/**
|
|
* Map from axis.index to values.
|
|
* For a single time axis, axisValues is in the form like
|
|
* {'x_0': [1495555200000, 1495641600000, 1495728000000]}.
|
|
* Items in axisValues[x], e.g. 1495555200000, are time values of all
|
|
* series.
|
|
*/
|
|
var axisValues = {};
|
|
zrUtil.each(barSeries, function (seriesModel) {
|
|
var cartesian = seriesModel.coordinateSystem;
|
|
var baseAxis = cartesian.getBaseAxis();
|
|
|
|
if (baseAxis.type !== 'time' && baseAxis.type !== 'value') {
|
|
return;
|
|
}
|
|
|
|
var data = seriesModel.getData();
|
|
var key = baseAxis.dim + '_' + baseAxis.index;
|
|
var dim = data.mapDimension(baseAxis.dim);
|
|
|
|
for (var i = 0, cnt = data.count(); i < cnt; ++i) {
|
|
var value = data.get(dim, i);
|
|
|
|
if (!axisValues[key]) {
|
|
// No previous data for the axis
|
|
axisValues[key] = [value];
|
|
} else {
|
|
// No value in previous series
|
|
axisValues[key].push(value);
|
|
} // Ignore duplicated time values in the same axis
|
|
|
|
}
|
|
});
|
|
var axisMinGaps = [];
|
|
|
|
for (var key in axisValues) {
|
|
if (axisValues.hasOwnProperty(key)) {
|
|
var valuesInAxis = axisValues[key];
|
|
|
|
if (valuesInAxis) {
|
|
// Sort axis values into ascending order to calculate gaps
|
|
valuesInAxis.sort(function (a, b) {
|
|
return a - b;
|
|
});
|
|
var min = null;
|
|
|
|
for (var j = 1; j < valuesInAxis.length; ++j) {
|
|
var delta = valuesInAxis[j] - valuesInAxis[j - 1];
|
|
|
|
if (delta > 0) {
|
|
// Ignore 0 delta because they are of the same axis value
|
|
min = min === null ? delta : Math.min(min, delta);
|
|
}
|
|
} // Set to null if only have one data
|
|
|
|
|
|
axisMinGaps[key] = min;
|
|
}
|
|
}
|
|
}
|
|
|
|
return axisMinGaps;
|
|
}
|
|
|
|
function makeColumnLayout(barSeries) {
|
|
var axisMinGaps = getValueAxesMinGaps(barSeries);
|
|
var seriesInfoList = [];
|
|
zrUtil.each(barSeries, function (seriesModel) {
|
|
var cartesian = seriesModel.coordinateSystem;
|
|
var baseAxis = cartesian.getBaseAxis();
|
|
var axisExtent = baseAxis.getExtent();
|
|
var bandWidth;
|
|
|
|
if (baseAxis.type === 'category') {
|
|
bandWidth = baseAxis.getBandWidth();
|
|
} else if (baseAxis.type === 'value' || baseAxis.type === 'time') {
|
|
var key = baseAxis.dim + '_' + baseAxis.index;
|
|
var minGap = axisMinGaps[key];
|
|
var extentSpan = Math.abs(axisExtent[1] - axisExtent[0]);
|
|
var scale = baseAxis.scale.getExtent();
|
|
var scaleSpan = Math.abs(scale[1] - scale[0]);
|
|
bandWidth = minGap ? extentSpan / scaleSpan * minGap : extentSpan; // When there is only one data value
|
|
} else {
|
|
var data = seriesModel.getData();
|
|
bandWidth = Math.abs(axisExtent[1] - axisExtent[0]) / data.count();
|
|
}
|
|
|
|
var barWidth = parsePercent(seriesModel.get('barWidth'), bandWidth);
|
|
var barMaxWidth = parsePercent(seriesModel.get('barMaxWidth'), bandWidth);
|
|
var barMinWidth = parsePercent( // barMinWidth by default is 1 in cartesian. Because in value axis,
|
|
// the auto-calculated bar width might be less than 1.
|
|
seriesModel.get('barMinWidth') || 1, bandWidth);
|
|
var barGap = seriesModel.get('barGap');
|
|
var barCategoryGap = seriesModel.get('barCategoryGap');
|
|
seriesInfoList.push({
|
|
bandWidth: bandWidth,
|
|
barWidth: barWidth,
|
|
barMaxWidth: barMaxWidth,
|
|
barMinWidth: barMinWidth,
|
|
barGap: barGap,
|
|
barCategoryGap: barCategoryGap,
|
|
axisKey: getAxisKey(baseAxis),
|
|
stackId: getSeriesStackId(seriesModel)
|
|
});
|
|
});
|
|
return doCalBarWidthAndOffset(seriesInfoList);
|
|
}
|
|
|
|
function doCalBarWidthAndOffset(seriesInfoList) {
|
|
// Columns info on each category axis. Key is cartesian name
|
|
var columnsMap = {};
|
|
zrUtil.each(seriesInfoList, function (seriesInfo, idx) {
|
|
var axisKey = seriesInfo.axisKey;
|
|
var bandWidth = seriesInfo.bandWidth;
|
|
var columnsOnAxis = columnsMap[axisKey] || {
|
|
bandWidth: bandWidth,
|
|
remainedWidth: bandWidth,
|
|
autoWidthCount: 0,
|
|
categoryGap: '20%',
|
|
gap: '30%',
|
|
stacks: {}
|
|
};
|
|
var stacks = columnsOnAxis.stacks;
|
|
columnsMap[axisKey] = columnsOnAxis;
|
|
var stackId = seriesInfo.stackId;
|
|
|
|
if (!stacks[stackId]) {
|
|
columnsOnAxis.autoWidthCount++;
|
|
}
|
|
|
|
stacks[stackId] = stacks[stackId] || {
|
|
width: 0,
|
|
maxWidth: 0
|
|
}; // Caution: In a single coordinate system, these barGrid attributes
|
|
// will be shared by series. Consider that they have default values,
|
|
// only the attributes set on the last series will work.
|
|
// Do not change this fact unless there will be a break change.
|
|
|
|
var barWidth = seriesInfo.barWidth;
|
|
|
|
if (barWidth && !stacks[stackId].width) {
|
|
// See #6312, do not restrict width.
|
|
stacks[stackId].width = barWidth;
|
|
barWidth = Math.min(columnsOnAxis.remainedWidth, barWidth);
|
|
columnsOnAxis.remainedWidth -= barWidth;
|
|
}
|
|
|
|
var barMaxWidth = seriesInfo.barMaxWidth;
|
|
barMaxWidth && (stacks[stackId].maxWidth = barMaxWidth);
|
|
var barMinWidth = seriesInfo.barMinWidth;
|
|
barMinWidth && (stacks[stackId].minWidth = barMinWidth);
|
|
var barGap = seriesInfo.barGap;
|
|
barGap != null && (columnsOnAxis.gap = barGap);
|
|
var barCategoryGap = seriesInfo.barCategoryGap;
|
|
barCategoryGap != null && (columnsOnAxis.categoryGap = barCategoryGap);
|
|
});
|
|
var result = {};
|
|
zrUtil.each(columnsMap, function (columnsOnAxis, coordSysName) {
|
|
result[coordSysName] = {};
|
|
var stacks = columnsOnAxis.stacks;
|
|
var bandWidth = columnsOnAxis.bandWidth;
|
|
var categoryGap = parsePercent(columnsOnAxis.categoryGap, bandWidth);
|
|
var barGapPercent = parsePercent(columnsOnAxis.gap, 1);
|
|
var remainedWidth = columnsOnAxis.remainedWidth;
|
|
var autoWidthCount = columnsOnAxis.autoWidthCount;
|
|
var autoWidth = (remainedWidth - categoryGap) / (autoWidthCount + (autoWidthCount - 1) * barGapPercent);
|
|
autoWidth = Math.max(autoWidth, 0); // Find if any auto calculated bar exceeded maxBarWidth
|
|
|
|
zrUtil.each(stacks, function (column) {
|
|
var maxWidth = column.maxWidth;
|
|
var minWidth = column.minWidth;
|
|
|
|
if (!column.width) {
|
|
var finalWidth = autoWidth;
|
|
|
|
if (maxWidth && maxWidth < finalWidth) {
|
|
finalWidth = Math.min(maxWidth, remainedWidth);
|
|
} // `minWidth` has higher priority. `minWidth` decide that wheter the
|
|
// bar is able to be visible. So `minWidth` should not be restricted
|
|
// by `maxWidth` or `remainedWidth` (which is from `bandWidth`). In
|
|
// the extreme cases for `value` axis, bars are allowed to overlap
|
|
// with each other if `minWidth` specified.
|
|
|
|
|
|
if (minWidth && minWidth > finalWidth) {
|
|
finalWidth = minWidth;
|
|
}
|
|
|
|
if (finalWidth !== autoWidth) {
|
|
column.width = finalWidth;
|
|
remainedWidth -= finalWidth + barGapPercent * finalWidth;
|
|
autoWidthCount--;
|
|
}
|
|
} else {
|
|
// `barMinWidth/barMaxWidth` has higher priority than `barWidth`, as
|
|
// CSS does. Becuase barWidth can be a percent value, where
|
|
// `barMaxWidth` can be used to restrict the final width.
|
|
var finalWidth = column.width;
|
|
|
|
if (maxWidth) {
|
|
finalWidth = Math.min(finalWidth, maxWidth);
|
|
} // `minWidth` has higher priority, as described above
|
|
|
|
|
|
if (minWidth) {
|
|
finalWidth = Math.max(finalWidth, minWidth);
|
|
}
|
|
|
|
column.width = finalWidth;
|
|
remainedWidth -= finalWidth + barGapPercent * finalWidth;
|
|
autoWidthCount--;
|
|
}
|
|
}); // Recalculate width again
|
|
|
|
autoWidth = (remainedWidth - categoryGap) / (autoWidthCount + (autoWidthCount - 1) * barGapPercent);
|
|
autoWidth = Math.max(autoWidth, 0);
|
|
var widthSum = 0;
|
|
var lastColumn;
|
|
zrUtil.each(stacks, function (column, idx) {
|
|
if (!column.width) {
|
|
column.width = autoWidth;
|
|
}
|
|
|
|
lastColumn = column;
|
|
widthSum += column.width * (1 + barGapPercent);
|
|
});
|
|
|
|
if (lastColumn) {
|
|
widthSum -= lastColumn.width * barGapPercent;
|
|
}
|
|
|
|
var offset = -widthSum / 2;
|
|
zrUtil.each(stacks, function (column, stackId) {
|
|
result[coordSysName][stackId] = result[coordSysName][stackId] || {
|
|
bandWidth: bandWidth,
|
|
offset: offset,
|
|
width: column.width
|
|
};
|
|
offset += column.width * (1 + barGapPercent);
|
|
});
|
|
});
|
|
return result;
|
|
}
|
|
/**
|
|
* @param {Object} barWidthAndOffset The result of makeColumnLayout
|
|
* @param {module:echarts/coord/Axis} axis
|
|
* @param {module:echarts/model/Series} [seriesModel] If not provided, return all.
|
|
* @return {Object} {stackId: {offset, width}} or {offset, width} if seriesModel provided.
|
|
*/
|
|
|
|
|
|
function retrieveColumnLayout(barWidthAndOffset, axis, seriesModel) {
|
|
if (barWidthAndOffset && axis) {
|
|
var result = barWidthAndOffset[getAxisKey(axis)];
|
|
|
|
if (result != null && seriesModel != null) {
|
|
result = result[getSeriesStackId(seriesModel)];
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|
|
/**
|
|
* @param {string} seriesType
|
|
* @param {module:echarts/model/Global} ecModel
|
|
*/
|
|
|
|
|
|
function layout(seriesType, ecModel) {
|
|
var seriesModels = prepareLayoutBarSeries(seriesType, ecModel);
|
|
var barWidthAndOffset = makeColumnLayout(seriesModels);
|
|
var lastStackCoords = {};
|
|
var lastStackCoordsOrigin = {};
|
|
zrUtil.each(seriesModels, function (seriesModel) {
|
|
var data = seriesModel.getData();
|
|
var cartesian = seriesModel.coordinateSystem;
|
|
var baseAxis = cartesian.getBaseAxis();
|
|
var stackId = getSeriesStackId(seriesModel);
|
|
var columnLayoutInfo = barWidthAndOffset[getAxisKey(baseAxis)][stackId];
|
|
var columnOffset = columnLayoutInfo.offset;
|
|
var columnWidth = columnLayoutInfo.width;
|
|
var valueAxis = cartesian.getOtherAxis(baseAxis);
|
|
var barMinHeight = seriesModel.get('barMinHeight') || 0;
|
|
lastStackCoords[stackId] = lastStackCoords[stackId] || [];
|
|
lastStackCoordsOrigin[stackId] = lastStackCoordsOrigin[stackId] || []; // Fix #4243
|
|
|
|
data.setLayout({
|
|
bandWidth: columnLayoutInfo.bandWidth,
|
|
offset: columnOffset,
|
|
size: columnWidth
|
|
});
|
|
var valueDim = data.mapDimension(valueAxis.dim);
|
|
var baseDim = data.mapDimension(baseAxis.dim);
|
|
var stacked = isDimensionStacked(data, valueDim
|
|
/*, baseDim*/
|
|
);
|
|
var isValueAxisH = valueAxis.isHorizontal();
|
|
var valueAxisStart = getValueAxisStart(baseAxis, valueAxis, stacked);
|
|
|
|
for (var idx = 0, len = data.count(); idx < len; idx++) {
|
|
var value = data.get(valueDim, idx);
|
|
var baseValue = data.get(baseDim, idx);
|
|
var sign = value >= 0 ? 'p' : 'n';
|
|
var baseCoord = valueAxisStart; // Because of the barMinHeight, we can not use the value in
|
|
// stackResultDimension directly.
|
|
|
|
if (stacked) {
|
|
// Only ordinal axis can be stacked.
|
|
if (!lastStackCoords[stackId][baseValue]) {
|
|
lastStackCoords[stackId][baseValue] = {
|
|
p: valueAxisStart,
|
|
// Positive stack
|
|
n: valueAxisStart // Negative stack
|
|
|
|
};
|
|
} // Should also consider #4243
|
|
|
|
|
|
baseCoord = lastStackCoords[stackId][baseValue][sign];
|
|
}
|
|
|
|
var x;
|
|
var y;
|
|
var width;
|
|
var height;
|
|
|
|
if (isValueAxisH) {
|
|
var coord = cartesian.dataToPoint([value, baseValue]);
|
|
x = baseCoord;
|
|
y = coord[1] + columnOffset;
|
|
width = coord[0] - valueAxisStart;
|
|
height = columnWidth;
|
|
|
|
if (Math.abs(width) < barMinHeight) {
|
|
width = (width < 0 ? -1 : 1) * barMinHeight;
|
|
} // Ignore stack from NaN value
|
|
|
|
|
|
if (!isNaN(width)) {
|
|
stacked && (lastStackCoords[stackId][baseValue][sign] += width);
|
|
}
|
|
} else {
|
|
var coord = cartesian.dataToPoint([baseValue, value]);
|
|
x = coord[0] + columnOffset;
|
|
y = baseCoord;
|
|
width = columnWidth;
|
|
height = coord[1] - valueAxisStart;
|
|
|
|
if (Math.abs(height) < barMinHeight) {
|
|
// Include zero to has a positive bar
|
|
height = (height <= 0 ? -1 : 1) * barMinHeight;
|
|
} // Ignore stack from NaN value
|
|
|
|
|
|
if (!isNaN(height)) {
|
|
stacked && (lastStackCoords[stackId][baseValue][sign] += height);
|
|
}
|
|
}
|
|
|
|
data.setItemLayout(idx, {
|
|
x: x,
|
|
y: y,
|
|
width: width,
|
|
height: height
|
|
});
|
|
}
|
|
}, this);
|
|
} // TODO: Do not support stack in large mode yet.
|
|
|
|
|
|
var largeLayout = {
|
|
seriesType: 'bar',
|
|
plan: createRenderPlanner(),
|
|
reset: function (seriesModel) {
|
|
if (!isOnCartesian(seriesModel) || !isInLargeMode(seriesModel)) {
|
|
return;
|
|
}
|
|
|
|
var data = seriesModel.getData();
|
|
var cartesian = seriesModel.coordinateSystem;
|
|
var coordLayout = cartesian.grid.getRect();
|
|
var baseAxis = cartesian.getBaseAxis();
|
|
var valueAxis = cartesian.getOtherAxis(baseAxis);
|
|
var valueDim = data.mapDimension(valueAxis.dim);
|
|
var baseDim = data.mapDimension(baseAxis.dim);
|
|
var valueAxisHorizontal = valueAxis.isHorizontal();
|
|
var valueDimIdx = valueAxisHorizontal ? 0 : 1;
|
|
var barWidth = retrieveColumnLayout(makeColumnLayout([seriesModel]), baseAxis, seriesModel).width;
|
|
|
|
if (!(barWidth > LARGE_BAR_MIN_WIDTH)) {
|
|
// jshint ignore:line
|
|
barWidth = LARGE_BAR_MIN_WIDTH;
|
|
}
|
|
|
|
return {
|
|
progress: progress
|
|
};
|
|
|
|
function progress(params, data) {
|
|
var count = params.count;
|
|
var largePoints = new LargeArr(count * 2);
|
|
var largeBackgroundPoints = new LargeArr(count * 2);
|
|
var largeDataIndices = new LargeArr(count);
|
|
var dataIndex;
|
|
var coord = [];
|
|
var valuePair = [];
|
|
var pointsOffset = 0;
|
|
var idxOffset = 0;
|
|
|
|
while ((dataIndex = params.next()) != null) {
|
|
valuePair[valueDimIdx] = data.get(valueDim, dataIndex);
|
|
valuePair[1 - valueDimIdx] = data.get(baseDim, dataIndex);
|
|
coord = cartesian.dataToPoint(valuePair, null, coord); // Data index might not be in order, depends on `progressiveChunkMode`.
|
|
|
|
largeBackgroundPoints[pointsOffset] = valueAxisHorizontal ? coordLayout.x + coordLayout.width : coord[0];
|
|
largePoints[pointsOffset++] = coord[0];
|
|
largeBackgroundPoints[pointsOffset] = valueAxisHorizontal ? coord[1] : coordLayout.y + coordLayout.height;
|
|
largePoints[pointsOffset++] = coord[1];
|
|
largeDataIndices[idxOffset++] = dataIndex;
|
|
}
|
|
|
|
data.setLayout({
|
|
largePoints: largePoints,
|
|
largeDataIndices: largeDataIndices,
|
|
largeBackgroundPoints: largeBackgroundPoints,
|
|
barWidth: barWidth,
|
|
valueAxisStart: getValueAxisStart(baseAxis, valueAxis, false),
|
|
backgroundStart: valueAxisHorizontal ? coordLayout.x : coordLayout.y,
|
|
valueAxisHorizontal: valueAxisHorizontal
|
|
});
|
|
}
|
|
}
|
|
};
|
|
|
|
function isOnCartesian(seriesModel) {
|
|
return seriesModel.coordinateSystem && seriesModel.coordinateSystem.type === 'cartesian2d';
|
|
}
|
|
|
|
function isInLargeMode(seriesModel) {
|
|
return seriesModel.pipelineContext && seriesModel.pipelineContext.large;
|
|
} // See cases in `test/bar-start.html` and `#7412`, `#8747`.
|
|
|
|
|
|
function getValueAxisStart(baseAxis, valueAxis, stacked) {
|
|
return valueAxis.toGlobalCoord(valueAxis.dataToCoord(valueAxis.type === 'log' ? 1 : 0));
|
|
}
|
|
|
|
exports.getLayoutOnAxis = getLayoutOnAxis;
|
|
exports.prepareLayoutBarSeries = prepareLayoutBarSeries;
|
|
exports.makeColumnLayout = makeColumnLayout;
|
|
exports.retrieveColumnLayout = retrieveColumnLayout;
|
|
exports.layout = layout;
|
|
exports.largeLayout = largeLayout; |