提交 748f33eb 编写于 作者: S sushuang

(1) Some refactor about axisTick, axisLabel, splitLine, splitArea interval...

(1) Some refactor about axisTick, axisLabel, splitLine, splitArea interval logic: arrange and uniform the API, about 'ifIgnoreOnTick', 'isLabelIgnored', 'getTicksCoords',  'getLabelsCoords', etc. Fixed the inconsistent calling of user specified "axis interval" function.
(2) Make the choice of axisTick, axisLabel, splitLine, splitArea be stable when category axis auto interval exists and moving by dataZoom.
(3) Make the animation appropriate for label, ticks, splitLine, splitArea when view window moving (by dataZoom) in category axis.
上级 a8ef1835
...@@ -605,15 +605,26 @@ export default ChartView.extend({ ...@@ -605,15 +605,26 @@ export default ChartView.extend({
this._polygon = polygon; this._polygon = polygon;
return polygon; return polygon;
}, },
/** /**
* @private * @private
*/ */
_getSymbolIgnoreFunc: function (data, coordSys) { _getSymbolIgnoreFunc: function (data, coordSys) {
var categoryAxis = coordSys.getAxesByScale('ordinal')[0]; var categoryAxis = coordSys.getAxesByScale('ordinal')[0];
// `getLabelInterval` is provided by echarts/component/axis if (!categoryAxis) {
if (categoryAxis && categoryAxis.isLabelIgnored) { return;
return zrUtil.bind(categoryAxis.isLabelIgnored, categoryAxis);
} }
var categoryDataDim = data.mapDimension(categoryAxis.dim);
var labelMap = {};
zrUtil.each(categoryAxis.getViewLabels(), function (labelItem) {
labelMap[labelItem.tickValue] = 1;
});
return function (dataIndex) {
return !labelMap.hasOwnProperty(data.get(categoryDataDim, dataIndex));
};
}, },
/** /**
......
...@@ -23,6 +23,18 @@ function getRadiusIdx(polar) { ...@@ -23,6 +23,18 @@ function getRadiusIdx(polar) {
return radiusAxis.inverse ? 0 : 1; return radiusAxis.inverse ? 0 : 1;
} }
// Remove the last tick which will overlap the first tick
function fixAngleOverlap(list) {
var firstItem = list[0];
var lastItem = list[list.length - 1];
if (firstItem
&& lastItem
&& Math.abs(Math.abs(firstItem.coord - lastItem.coord) - 360) < 1e-4
) {
list.pop();
}
}
export default AxisView.extend({ export default AxisView.extend({
type: 'angleAxis', type: 'angleAxis',
...@@ -38,18 +50,22 @@ export default AxisView.extend({ ...@@ -38,18 +50,22 @@ export default AxisView.extend({
var angleAxis = angleAxisModel.axis; var angleAxis = angleAxisModel.axis;
var polar = angleAxis.polar; var polar = angleAxis.polar;
var radiusExtent = polar.getRadiusAxis().getExtent(); var radiusExtent = polar.getRadiusAxis().getExtent();
var ticksAngles = angleAxis.getTicksCoords(); var ticksAngles = angleAxis.getTicksCoords();
var labels = angleAxis.getViewLabels();
if (angleAxis.type !== 'category') { zrUtil.each(labels, function (labelItem) {
// Remove the last tick which will overlap the first tick labelItem.coord = angleAxis.dataToCoord(labelItem.tickValue);
ticksAngles.pop(); });
}
fixAngleOverlap(labels);
fixAngleOverlap(ticksAngles);
zrUtil.each(elementList, function (name) { zrUtil.each(elementList, function (name) {
if (angleAxisModel.get(name +'.show') if (angleAxisModel.get(name +'.show')
&& (!angleAxis.scale.isBlank() || name === 'axisLine') && (!angleAxis.scale.isBlank() || name === 'axisLine')
) { ) {
this['_' + name](angleAxisModel, polar, ticksAngles, radiusExtent); this['_' + name](angleAxisModel, polar, ticksAngles, radiusExtent, labels);
} }
}, this); }, this);
}, },
...@@ -84,9 +100,9 @@ export default AxisView.extend({ ...@@ -84,9 +100,9 @@ export default AxisView.extend({
var tickLen = (tickModel.get('inside') ? -1 : 1) * tickModel.get('length'); var tickLen = (tickModel.get('inside') ? -1 : 1) * tickModel.get('length');
var radius = radiusExtent[getRadiusIdx(polar)]; var radius = radiusExtent[getRadiusIdx(polar)];
var lines = zrUtil.map(ticksAngles, function (tickAngle) { var lines = zrUtil.map(ticksAngles, function (tickAngleItem) {
return new graphic.Line({ return new graphic.Line({
shape: getAxisLineShape(polar, [radius, radius + tickLen], tickAngle) shape: getAxisLineShape(polar, [radius, radius + tickLen], tickAngleItem.coord)
}); });
}); });
this.group.add(graphic.mergePath( this.group.add(graphic.mergePath(
...@@ -104,24 +120,20 @@ export default AxisView.extend({ ...@@ -104,24 +120,20 @@ export default AxisView.extend({
/** /**
* @private * @private
*/ */
_axisLabel: function (angleAxisModel, polar, ticksAngles, radiusExtent) { _axisLabel: function (angleAxisModel, polar, ticksAngles, radiusExtent, labels) {
var axis = angleAxisModel.axis;
var rawCategoryData = angleAxisModel.getCategories(true); var rawCategoryData = angleAxisModel.getCategories(true);
var commonLabelModel = angleAxisModel.getModel('axisLabel'); var commonLabelModel = angleAxisModel.getModel('axisLabel');
var labels = angleAxisModel.getFormattedLabels();
var labelMargin = commonLabelModel.get('margin'); var labelMargin = commonLabelModel.get('margin');
var labelsAngles = axis.getLabelsCoords();
var ticks = axis.scale.getTicks();
// Use length of ticksAngles because it may remove the last tick to avoid overlapping // Use length of ticksAngles because it may remove the last tick to avoid overlapping
for (var i = 0; i < ticks.length; i++) { zrUtil.each(labels, function (labelItem, idx) {
var labelModel = commonLabelModel; var labelModel = commonLabelModel;
var tickVal = ticks[i]; var tickValue = labelItem.tickValue;
var r = radiusExtent[getRadiusIdx(polar)]; var r = radiusExtent[getRadiusIdx(polar)];
var p = polar.coordToPoint([r + labelMargin, labelsAngles[i]]); var p = polar.coordToPoint([r + labelMargin, labelItem.coord]);
var cx = polar.cx; var cx = polar.cx;
var cy = polar.cy; var cy = polar.cy;
...@@ -130,8 +142,8 @@ export default AxisView.extend({ ...@@ -130,8 +142,8 @@ export default AxisView.extend({
var labelTextVerticalAlign = Math.abs(p[1] - cy) / r < 0.3 var labelTextVerticalAlign = Math.abs(p[1] - cy) / r < 0.3
? 'middle' : (p[1] > cy ? 'top' : 'bottom'); ? 'middle' : (p[1] > cy ? 'top' : 'bottom');
if (rawCategoryData && rawCategoryData[tickVal] && rawCategoryData[tickVal].textStyle) { if (rawCategoryData && rawCategoryData[tickValue] && rawCategoryData[tickValue].textStyle) {
labelModel = new Model(rawCategoryData[tickVal].textStyle, commonLabelModel, commonLabelModel.ecModel); labelModel = new Model(rawCategoryData[tickValue].textStyle, commonLabelModel, commonLabelModel.ecModel);
} }
var textEl = new graphic.Text({silent: true}); var textEl = new graphic.Text({silent: true});
...@@ -140,11 +152,11 @@ export default AxisView.extend({ ...@@ -140,11 +152,11 @@ export default AxisView.extend({
x: p[0], x: p[0],
y: p[1], y: p[1],
textFill: labelModel.getTextColor() || angleAxisModel.get('axisLine.lineStyle.color'), textFill: labelModel.getTextColor() || angleAxisModel.get('axisLine.lineStyle.color'),
text: labels[i], text: labelItem.formattedLabel,
textAlign: labelTextAlign, textAlign: labelTextAlign,
textVerticalAlign: labelTextVerticalAlign textVerticalAlign: labelTextVerticalAlign
}); });
} }, this);
}, },
/** /**
...@@ -164,7 +176,7 @@ export default AxisView.extend({ ...@@ -164,7 +176,7 @@ export default AxisView.extend({
var colorIndex = (lineCount++) % lineColors.length; var colorIndex = (lineCount++) % lineColors.length;
splitLines[colorIndex] = splitLines[colorIndex] || []; splitLines[colorIndex] = splitLines[colorIndex] || [];
splitLines[colorIndex].push(new graphic.Line({ splitLines[colorIndex].push(new graphic.Line({
shape: getAxisLineShape(polar, radiusExtent, ticksAngles[i]) shape: getAxisLineShape(polar, radiusExtent, ticksAngles[i].coord)
})); }));
} }
...@@ -185,6 +197,9 @@ export default AxisView.extend({ ...@@ -185,6 +197,9 @@ export default AxisView.extend({
* @private * @private
*/ */
_splitArea: function (angleAxisModel, polar, ticksAngles, radiusExtent) { _splitArea: function (angleAxisModel, polar, ticksAngles, radiusExtent) {
if (!ticksAngles.length) {
return;
}
var splitAreaModel = angleAxisModel.getModel('splitArea'); var splitAreaModel = angleAxisModel.getModel('splitArea');
var areaStyleModel = splitAreaModel.getModel('areaStyle'); var areaStyleModel = splitAreaModel.getModel('areaStyle');
...@@ -196,7 +211,7 @@ export default AxisView.extend({ ...@@ -196,7 +211,7 @@ export default AxisView.extend({
var splitAreas = []; var splitAreas = [];
var RADIAN = Math.PI / 180; var RADIAN = Math.PI / 180;
var prevAngle = -ticksAngles[0] * RADIAN; var prevAngle = -ticksAngles[0].coord * RADIAN;
var r0 = Math.min(radiusExtent[0], radiusExtent[1]); var r0 = Math.min(radiusExtent[0], radiusExtent[1]);
var r1 = Math.max(radiusExtent[0], radiusExtent[1]); var r1 = Math.max(radiusExtent[0], radiusExtent[1]);
...@@ -212,12 +227,12 @@ export default AxisView.extend({ ...@@ -212,12 +227,12 @@ export default AxisView.extend({
r0: r0, r0: r0,
r: r1, r: r1,
startAngle: prevAngle, startAngle: prevAngle,
endAngle: -ticksAngles[i] * RADIAN, endAngle: -ticksAngles[i].coord * RADIAN,
clockwise: clockwise clockwise: clockwise
}, },
silent: true silent: true
})); }));
prevAngle = -ticksAngles[i] * RADIAN; prevAngle = -ticksAngles[i].coord * RADIAN;
} }
// Simple optimization // Simple optimization
......
...@@ -53,8 +53,6 @@ function makeAxisEventDataBase(axisModel) { ...@@ -53,8 +53,6 @@ function makeAxisEventDataBase(axisModel) {
* @param {string} [opt.axisName] default get from axisModel. * @param {string} [opt.axisName] default get from axisModel.
* @param {number} [opt.axisNameAvailableWidth] * @param {number} [opt.axisNameAvailableWidth]
* @param {number} [opt.labelRotate] by degree, default get from axisModel. * @param {number} [opt.labelRotate] by degree, default get from axisModel.
* @param {number} [opt.labelInterval] Default label interval when label
* interval from model is null or 'auto'.
* @param {number} [opt.strokeContainThreshold] Default label interval when label * @param {number} [opt.strokeContainThreshold] Default label interval when label
* @param {number} [opt.nameTruncateMaxWidth] * @param {number} [opt.nameTruncateMaxWidth]
*/ */
...@@ -542,48 +540,6 @@ function isNameLocationCenter(nameLocation) { ...@@ -542,48 +540,6 @@ function isNameLocationCenter(nameLocation) {
return nameLocation === 'middle' || nameLocation === 'center'; return nameLocation === 'middle' || nameLocation === 'center';
} }
/**
* @static
*/
var ifIgnoreOnTick = AxisBuilder.ifIgnoreOnTick = function (
axis,
i,
interval,
ticksCnt,
showMinLabel,
showMaxLabel
) {
if (i === 0 && showMinLabel || i === ticksCnt - 1 && showMaxLabel) {
return false;
}
// FIXME
// Have not consider label overlap (if label is too long) yet.
var rawTick;
var scale = axis.scale;
return scale.type === 'ordinal'
&& (
typeof interval === 'function'
? (
rawTick = scale.getTicks()[i],
!interval(rawTick, scale.getLabel(rawTick))
)
: i % (interval + 1)
);
};
/**
* @static
*/
var getInterval = AxisBuilder.getInterval = function (model, labelInterval) {
var interval = model.get('interval');
if (interval == null || interval == 'auto') {
interval = labelInterval;
}
return interval;
};
function buildAxisTick(axisBuilder, axisModel, opt) { function buildAxisTick(axisBuilder, axisModel, opt) {
var axis = axisModel.axis; var axis = axisModel.axis;
...@@ -596,14 +552,7 @@ function buildAxisTick(axisBuilder, axisModel, opt) { ...@@ -596,14 +552,7 @@ function buildAxisTick(axisBuilder, axisModel, opt) {
var lineStyleModel = tickModel.getModel('lineStyle'); var lineStyleModel = tickModel.getModel('lineStyle');
var tickLen = tickModel.get('length'); var tickLen = tickModel.get('length');
var tickInterval = getInterval(tickModel, opt.labelInterval); var ticksCoords = axis.getTicksCoords();
var ticksCoords = axis.getTicksCoords(tickModel.get('alignWithLabel'));
// FIXME
// Corresponds to ticksCoords ?
var ticks = axis.scale.getTicks();
var showMinLabel = axisModel.get('axisLabel.showMinLabel');
var showMaxLabel = axisModel.get('axisLabel.showMaxLabel');
var pt1 = []; var pt1 = [];
var pt2 = []; var pt2 = [];
...@@ -611,17 +560,8 @@ function buildAxisTick(axisBuilder, axisModel, opt) { ...@@ -611,17 +560,8 @@ function buildAxisTick(axisBuilder, axisModel, opt) {
var tickEls = []; var tickEls = [];
var ticksCnt = ticksCoords.length; for (var i = 0; i < ticksCoords.length; i++) {
for (var i = 0; i < ticksCnt; i++) { var tickCoord = ticksCoords[i].coord;
// Only ordinal scale support tick interval
if (ifIgnoreOnTick(
axis, i, tickInterval, ticksCnt,
showMinLabel, showMaxLabel
)) {
continue;
}
var tickCoord = ticksCoords[i];
pt1[0] = tickCoord; pt1[0] = tickCoord;
pt1[1] = 0; pt1[1] = 0;
...@@ -635,7 +575,7 @@ function buildAxisTick(axisBuilder, axisModel, opt) { ...@@ -635,7 +575,7 @@ function buildAxisTick(axisBuilder, axisModel, opt) {
// Tick line, Not use group transform to have better line draw // Tick line, Not use group transform to have better line draw
var tickEl = new graphic.Line(graphic.subPixelOptimizeLine({ var tickEl = new graphic.Line(graphic.subPixelOptimizeLine({
// Id for animation // Id for animation
anid: 'tick_' + ticks[i], anid: 'tick_' + ticksCoords[i].tickValue,
shape: { shape: {
x1: pt1[0], x1: pt1[0],
...@@ -669,8 +609,7 @@ function buildAxisLabel(axisBuilder, axisModel, opt) { ...@@ -669,8 +609,7 @@ function buildAxisLabel(axisBuilder, axisModel, opt) {
var labelModel = axisModel.getModel('axisLabel'); var labelModel = axisModel.getModel('axisLabel');
var labelMargin = labelModel.get('margin'); var labelMargin = labelModel.get('margin');
var ticks = axis.scale.getTicks(); var labels = axis.getViewLabels();
var labels = axisModel.getFormattedLabels();
// Special label rotate. // Special label rotate.
var labelRotation = ( var labelRotation = (
...@@ -684,37 +623,30 @@ function buildAxisLabel(axisBuilder, axisModel, opt) { ...@@ -684,37 +623,30 @@ function buildAxisLabel(axisBuilder, axisModel, opt) {
var silent = isSilent(axisModel); var silent = isSilent(axisModel);
var triggerEvent = axisModel.get('triggerEvent'); var triggerEvent = axisModel.get('triggerEvent');
var showMinLabel = axisModel.get('axisLabel.showMinLabel'); each(labels, function (labelItem, index) {
var showMaxLabel = axisModel.get('axisLabel.showMaxLabel'); var tickValue = labelItem.tickValue;
var formattedLabel = labelItem.formattedLabel;
each(ticks, function (tickVal, index) { var rawLabel = labelItem.rawLabel;
if (ifIgnoreOnTick(
axis, index, opt.labelInterval, ticks.length,
showMinLabel, showMaxLabel
)) {
return;
}
var itemLabelModel = labelModel; var itemLabelModel = labelModel;
if (rawCategoryData && rawCategoryData[tickVal] && rawCategoryData[tickVal].textStyle) { if (rawCategoryData && rawCategoryData[tickValue] && rawCategoryData[tickValue].textStyle) {
itemLabelModel = new Model( itemLabelModel = new Model(
rawCategoryData[tickVal].textStyle, labelModel, axisModel.ecModel rawCategoryData[tickValue].textStyle, labelModel, axisModel.ecModel
); );
} }
var textColor = itemLabelModel.getTextColor() var textColor = itemLabelModel.getTextColor()
|| axisModel.get('axisLine.lineStyle.color'); || axisModel.get('axisLine.lineStyle.color');
var tickCoord = axis.dataToCoord(tickVal); var tickCoord = axis.dataToCoord(tickValue);
var pos = [ var pos = [
tickCoord, tickCoord,
opt.labelOffset + opt.labelDirection * labelMargin opt.labelOffset + opt.labelDirection * labelMargin
]; ];
var labelStr = axis.scale.getLabel(tickVal);
var textEl = new graphic.Text({ var textEl = new graphic.Text({
// Id for animation // Id for animation
anid: 'label_' + tickVal, anid: 'label_' + tickValue,
position: pos, position: pos,
rotation: labelLayout.rotation, rotation: labelLayout.rotation,
silent: silent, silent: silent,
...@@ -722,7 +654,7 @@ function buildAxisLabel(axisBuilder, axisModel, opt) { ...@@ -722,7 +654,7 @@ function buildAxisLabel(axisBuilder, axisModel, opt) {
}); });
graphic.setTextStyle(textEl.style, itemLabelModel, { graphic.setTextStyle(textEl.style, itemLabelModel, {
text: labels[index], text: formattedLabel,
textAlign: itemLabelModel.getShallow('align', true) textAlign: itemLabelModel.getShallow('align', true)
|| labelLayout.textAlign, || labelLayout.textAlign,
textVerticalAlign: itemLabelModel.getShallow('verticalAlign', true) textVerticalAlign: itemLabelModel.getShallow('verticalAlign', true)
...@@ -733,11 +665,15 @@ function buildAxisLabel(axisBuilder, axisModel, opt) { ...@@ -733,11 +665,15 @@ function buildAxisLabel(axisBuilder, axisModel, opt) {
// (1) In category axis with data zoom, tick is not the original // (1) In category axis with data zoom, tick is not the original
// index of axis.data. So tick should not be exposed to user // index of axis.data. So tick should not be exposed to user
// in category axis. // in category axis.
// (2) Compatible with previous version, which always returns labelStr. // (2) Compatible with previous version, which always use formatted label as
// But in interval scale labelStr is like '223,445', which maked // input. But in interval scale the formatted label is like '223,445', which
// user repalce ','. So we modify it to return original val but remain // maked user repalce ','. So we modify it to return original val but remain
// it as 'string' to avoid error in replacing. // it as 'string' to avoid error in replacing.
axis.type === 'category' ? labelStr : axis.type === 'value' ? tickVal + '' : tickVal, axis.type === 'category'
? rawLabel
: axis.type === 'value'
? tickValue + ''
: tickValue,
index index
) )
: textColor : textColor
...@@ -747,7 +683,7 @@ function buildAxisLabel(axisBuilder, axisModel, opt) { ...@@ -747,7 +683,7 @@ function buildAxisLabel(axisBuilder, axisModel, opt) {
if (triggerEvent) { if (triggerEvent) {
textEl.eventData = makeAxisEventDataBase(axisModel); textEl.eventData = makeAxisEventDataBase(axisModel);
textEl.eventData.targetType = 'axisLabel'; textEl.eventData.targetType = 'axisLabel';
textEl.eventData.value = labelStr; textEl.eventData.value = rawLabel;
} }
// FIXME // FIXME
......
...@@ -2,10 +2,7 @@ import * as zrUtil from 'zrender/src/core/util'; ...@@ -2,10 +2,7 @@ import * as zrUtil from 'zrender/src/core/util';
import * as graphic from '../../util/graphic'; import * as graphic from '../../util/graphic';
import AxisBuilder from './AxisBuilder'; import AxisBuilder from './AxisBuilder';
import AxisView from './AxisView'; import AxisView from './AxisView';
import * as cartesianAxisHelper from './cartesianAxisHelper'; import * as cartesianAxisHelper from '../../coord/cartesian/cartesianAxisHelper';
var ifIgnoreOnTick = AxisBuilder.ifIgnoreOnTick;
var getInterval = AxisBuilder.getInterval;
var axisBuilderAttrs = [ var axisBuilderAttrs = [
'axisLine', 'axisTickLabel', 'axisName' 'axisLine', 'axisTickLabel', 'axisName'
...@@ -56,7 +53,7 @@ var CartesianAxisView = AxisView.extend({ ...@@ -56,7 +53,7 @@ var CartesianAxisView = AxisView.extend({
zrUtil.each(selfBuilderAttrs, function (name) { zrUtil.each(selfBuilderAttrs, function (name) {
if (axisModel.get(name + '.show')) { if (axisModel.get(name + '.show')) {
this['_' + name](axisModel, gridModel, layout.labelInterval); this['_' + name](axisModel, gridModel);
} }
}, this); }, this);
...@@ -65,13 +62,16 @@ var CartesianAxisView = AxisView.extend({ ...@@ -65,13 +62,16 @@ var CartesianAxisView = AxisView.extend({
CartesianAxisView.superCall(this, 'render', axisModel, ecModel, api, payload); CartesianAxisView.superCall(this, 'render', axisModel, ecModel, api, payload);
}, },
remove: function () {
this._splitAreaColors = null;
},
/** /**
* @param {module:echarts/coord/cartesian/AxisModel} axisModel * @param {module:echarts/coord/cartesian/AxisModel} axisModel
* @param {module:echarts/coord/cartesian/GridModel} gridModel * @param {module:echarts/coord/cartesian/GridModel} gridModel
* @param {number|Function} labelInterval
* @private * @private
*/ */
_splitLine: function (axisModel, gridModel, labelInterval) { _splitLine: function (axisModel, gridModel) {
var axis = axisModel.axis; var axis = axisModel.axis;
if (axis.scale.isBlank()) { if (axis.scale.isBlank()) {
...@@ -82,8 +82,6 @@ var CartesianAxisView = AxisView.extend({ ...@@ -82,8 +82,6 @@ var CartesianAxisView = AxisView.extend({
var lineStyleModel = splitLineModel.getModel('lineStyle'); var lineStyleModel = splitLineModel.getModel('lineStyle');
var lineColors = lineStyleModel.get('color'); var lineColors = lineStyleModel.get('color');
var lineInterval = getInterval(splitLineModel, labelInterval);
lineColors = zrUtil.isArray(lineColors) ? lineColors : [lineColors]; lineColors = zrUtil.isArray(lineColors) ? lineColors : [lineColors];
var gridRect = gridModel.coordinateSystem.getRect(); var gridRect = gridModel.coordinateSystem.getRect();
...@@ -91,28 +89,18 @@ var CartesianAxisView = AxisView.extend({ ...@@ -91,28 +89,18 @@ var CartesianAxisView = AxisView.extend({
var lineCount = 0; var lineCount = 0;
var ticksCoords = axis.getTicksCoords( var ticksCoords = axis.getTicksCoords({
// splitLineModel.get('alignWithLabel') tickModel: splitLineModel
); });
var ticks = axis.scale.getTicks();
var showMinLabel = axisModel.get('axisLabel.showMinLabel');
var showMaxLabel = axisModel.get('axisLabel.showMaxLabel');
var p1 = []; var p1 = [];
var p2 = []; var p2 = [];
// Simple optimization // Simple optimization
// Batching the lines if color are the same // Batching the lines if color are the same
var lineStyle = lineStyleModel.getLineStyle(); var lineStyle = lineStyleModel.getLineStyle();
for (var i = 0; i < ticksCoords.length; i++) { for (var i = 0; i < ticksCoords.length; i++) {
if (ifIgnoreOnTick( var tickCoord = axis.toGlobalCoord(ticksCoords[i].coord);
axis, i, lineInterval, ticksCoords.length,
showMinLabel, showMaxLabel
)) {
continue;
}
var tickCoord = axis.toGlobalCoord(ticksCoords[i]);
if (isHorizontal) { if (isHorizontal) {
p1[0] = tickCoord; p1[0] = tickCoord;
...@@ -129,8 +117,7 @@ var CartesianAxisView = AxisView.extend({ ...@@ -129,8 +117,7 @@ var CartesianAxisView = AxisView.extend({
var colorIndex = (lineCount++) % lineColors.length; var colorIndex = (lineCount++) % lineColors.length;
this._axisGroup.add(new graphic.Line(graphic.subPixelOptimizeLine({ this._axisGroup.add(new graphic.Line(graphic.subPixelOptimizeLine({
anid: 'line_' + ticks[i], anid: 'line_' + ticksCoords[i].tickValue,
shape: { shape: {
x1: p1[0], x1: p1[0],
y1: p1[1], y1: p1[1],
...@@ -148,10 +135,9 @@ var CartesianAxisView = AxisView.extend({ ...@@ -148,10 +135,9 @@ var CartesianAxisView = AxisView.extend({
/** /**
* @param {module:echarts/coord/cartesian/AxisModel} axisModel * @param {module:echarts/coord/cartesian/AxisModel} axisModel
* @param {module:echarts/coord/cartesian/GridModel} gridModel * @param {module:echarts/coord/cartesian/GridModel} gridModel
* @param {number|Function} labelInterval
* @private * @private
*/ */
_splitArea: function (axisModel, gridModel, labelInterval) { _splitArea: function (axisModel, gridModel) {
var axis = axisModel.axis; var axis = axisModel.axis;
if (axis.scale.isBlank()) { if (axis.scale.isBlank()) {
...@@ -164,55 +150,63 @@ var CartesianAxisView = AxisView.extend({ ...@@ -164,55 +150,63 @@ var CartesianAxisView = AxisView.extend({
var gridRect = gridModel.coordinateSystem.getRect(); var gridRect = gridModel.coordinateSystem.getRect();
var ticksCoords = axis.getTicksCoords( var ticksCoords = axis.getTicksCoords({
// splitAreaModel.get('alignWithLabel') tickModel: splitAreaModel,
); clamp: true
var ticks = axis.scale.getTicks(); });
var prevX = axis.toGlobalCoord(ticksCoords[0]); if (!ticksCoords.length) {
var prevY = axis.toGlobalCoord(ticksCoords[0]); return;
}
var count = 0; // For Making appropriate splitArea animation, the color and anid
// should be corresponding to previous one if possible.
var areaColorsLen = areaColors.length;
var lastSplitAreaColors = this._splitAreaColors;
var newSplitAreaColors = zrUtil.createHashMap();
var colorIndex = 0;
if (lastSplitAreaColors) {
for (var i = 0; i < ticksCoords.length; i++) {
var cIndex = lastSplitAreaColors.get(ticksCoords[i].tickValue);
if (cIndex != null) {
colorIndex = (cIndex + (areaColorsLen - 1) * i) % areaColorsLen;
break;
}
}
}
var areaInterval = getInterval(splitAreaModel, labelInterval); var prev = axis.toGlobalCoord(ticksCoords[0].coord);
var areaStyle = areaStyleModel.getAreaStyle(); var areaStyle = areaStyleModel.getAreaStyle();
areaColors = zrUtil.isArray(areaColors) ? areaColors : [areaColors]; areaColors = zrUtil.isArray(areaColors) ? areaColors : [areaColors];
var showMinLabel = axisModel.get('axisLabel.showMinLabel');
var showMaxLabel = axisModel.get('axisLabel.showMaxLabel');
for (var i = 1; i < ticksCoords.length; i++) { for (var i = 1; i < ticksCoords.length; i++) {
if (ifIgnoreOnTick( var tickCoord = axis.toGlobalCoord(ticksCoords[i].coord);
axis, i, areaInterval, ticksCoords.length,
showMinLabel, showMaxLabel
) && (i < ticksCoords.length - 1)) {
continue;
}
var tickCoord = axis.toGlobalCoord(ticksCoords[i]);
var x; var x;
var y; var y;
var width; var width;
var height; var height;
if (axis.isHorizontal()) { if (axis.isHorizontal()) {
x = prevX; x = prev;
y = gridRect.y; y = gridRect.y;
width = tickCoord - x; width = tickCoord - x;
height = gridRect.height; height = gridRect.height;
prev = x + width;
} }
else { else {
x = gridRect.x; x = gridRect.x;
y = prevY; y = prev;
width = gridRect.width; width = gridRect.width;
height = tickCoord - y; height = tickCoord - y;
prev = y + height;
} }
var colorIndex = (count++) % areaColors.length; var tickValue = ticksCoords[i - 1].tickValue;
this._axisGroup.add(new graphic.Rect({ newSplitAreaColors.set(tickValue, colorIndex);
anid: 'area_' + ticks[i],
this._axisGroup.add(new graphic.Rect({
anid: 'area_' + tickValue,
shape: { shape: {
x: x, x: x,
y: y, y: y,
...@@ -225,9 +219,10 @@ var CartesianAxisView = AxisView.extend({ ...@@ -225,9 +219,10 @@ var CartesianAxisView = AxisView.extend({
silent: true silent: true
})); }));
prevX = x + width; colorIndex = (colorIndex + 1) % areaColorsLen;
prevY = y + height;
} }
this._splitAreaColors = newSplitAreaColors;
} }
}); });
......
...@@ -60,7 +60,7 @@ export default AxisView.extend({ ...@@ -60,7 +60,7 @@ export default AxisView.extend({
shape: { shape: {
cx: polar.cx, cx: polar.cx,
cy: polar.cy, cy: polar.cy,
r: ticksCoords[i] r: ticksCoords[i].coord
}, },
silent: true silent: true
})); }));
...@@ -83,6 +83,9 @@ export default AxisView.extend({ ...@@ -83,6 +83,9 @@ export default AxisView.extend({
* @private * @private
*/ */
_splitArea: function (radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords) { _splitArea: function (radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords) {
if (!ticksCoords.length) {
return;
}
var splitAreaModel = radiusAxisModel.getModel('splitArea'); var splitAreaModel = radiusAxisModel.getModel('splitArea');
var areaStyleModel = splitAreaModel.getModel('areaStyle'); var areaStyleModel = splitAreaModel.getModel('areaStyle');
...@@ -93,7 +96,7 @@ export default AxisView.extend({ ...@@ -93,7 +96,7 @@ export default AxisView.extend({
var splitAreas = []; var splitAreas = [];
var prevRadius = ticksCoords[0]; var prevRadius = ticksCoords[0].coord;
for (var i = 1; i < ticksCoords.length; i++) { for (var i = 1; i < ticksCoords.length; i++) {
var colorIndex = (lineCount++) % areaColors.length; var colorIndex = (lineCount++) % areaColors.length;
splitAreas[colorIndex] = splitAreas[colorIndex] || []; splitAreas[colorIndex] = splitAreas[colorIndex] || [];
...@@ -102,13 +105,13 @@ export default AxisView.extend({ ...@@ -102,13 +105,13 @@ export default AxisView.extend({
cx: polar.cx, cx: polar.cx,
cy: polar.cy, cy: polar.cy,
r0: prevRadius, r0: prevRadius,
r: ticksCoords[i], r: ticksCoords[i].coord,
startAngle: 0, startAngle: 0,
endAngle: Math.PI * 2 endAngle: Math.PI * 2
}, },
silent: true silent: true
})); }));
prevRadius = ticksCoords[i]; prevRadius = ticksCoords[i].coord;
} }
// Simple optimization // Simple optimization
......
...@@ -2,12 +2,9 @@ ...@@ -2,12 +2,9 @@
import * as zrUtil from 'zrender/src/core/util'; import * as zrUtil from 'zrender/src/core/util';
import AxisBuilder from './AxisBuilder'; import AxisBuilder from './AxisBuilder';
import * as graphic from '../../util/graphic'; import * as graphic from '../../util/graphic';
import * as singleAxisHelper from './singleAxisHelper'; import * as singleAxisHelper from '../../coord/single/singleAxisHelper';
import AxisView from './AxisView'; import AxisView from './AxisView';
var getInterval = AxisBuilder.getInterval;
var ifIgnoreOnTick = AxisBuilder.ifIgnoreOnTick;
var axisBuilderAttrs = [ var axisBuilderAttrs = [
'axisLine', 'axisTickLabel', 'axisName' 'axisLine', 'axisTickLabel', 'axisName'
]; ];
...@@ -35,13 +32,13 @@ var SingleAxisView = AxisView.extend({ ...@@ -35,13 +32,13 @@ var SingleAxisView = AxisView.extend({
group.add(axisBuilder.getGroup()); group.add(axisBuilder.getGroup());
if (axisModel.get(selfBuilderAttr + '.show')) { if (axisModel.get(selfBuilderAttr + '.show')) {
this['_' + selfBuilderAttr](axisModel, layout.labelInterval); this['_' + selfBuilderAttr](axisModel);
} }
SingleAxisView.superCall(this, 'render', axisModel, ecModel, api, payload); SingleAxisView.superCall(this, 'render', axisModel, ecModel, api, payload);
}, },
_splitLine: function(axisModel, labelInterval) { _splitLine: function(axisModel) {
var axis = axisModel.axis; var axis = axisModel.axis;
if (axis.scale.isBlank()) { if (axis.scale.isBlank()) {
...@@ -52,7 +49,6 @@ var SingleAxisView = AxisView.extend({ ...@@ -52,7 +49,6 @@ var SingleAxisView = AxisView.extend({
var lineStyleModel = splitLineModel.getModel('lineStyle'); var lineStyleModel = splitLineModel.getModel('lineStyle');
var lineWidth = lineStyleModel.get('width'); var lineWidth = lineStyleModel.get('width');
var lineColors = lineStyleModel.get('color'); var lineColors = lineStyleModel.get('color');
var lineInterval = getInterval(splitLineModel, labelInterval);
lineColors = lineColors instanceof Array ? lineColors : [lineColors]; lineColors = lineColors instanceof Array ? lineColors : [lineColors];
...@@ -62,22 +58,15 @@ var SingleAxisView = AxisView.extend({ ...@@ -62,22 +58,15 @@ var SingleAxisView = AxisView.extend({
var splitLines = []; var splitLines = [];
var lineCount = 0; var lineCount = 0;
var ticksCoords = axis.getTicksCoords(); var ticksCoords = axis.getTicksCoords({
tickModel: splitLineModel
});
var p1 = []; var p1 = [];
var p2 = []; var p2 = [];
var showMinLabel = axisModel.get('axisLabel.showMinLabel');
var showMaxLabel = axisModel.get('axisLabel.showMaxLabel');
for (var i = 0; i < ticksCoords.length; ++i) { for (var i = 0; i < ticksCoords.length; ++i) {
if (ifIgnoreOnTick( var tickCoord = axis.toGlobalCoord(ticksCoords[i].coord);
axis, i, lineInterval, ticksCoords.length,
showMinLabel, showMaxLabel
)) {
continue;
}
var tickCoord = axis.toGlobalCoord(ticksCoords[i]);
if (isHorizontal) { if (isHorizontal) {
p1[0] = tickCoord; p1[0] = tickCoord;
p1[1] = gridRect.y; p1[1] = gridRect.y;
......
import * as graphic from '../../util/graphic'; import * as graphic from '../../util/graphic';
import BaseAxisPointer from './BaseAxisPointer'; import BaseAxisPointer from './BaseAxisPointer';
import * as viewHelper from './viewHelper'; import * as viewHelper from './viewHelper';
import * as cartesianAxisHelper from '../axis/cartesianAxisHelper'; import * as cartesianAxisHelper from '../../coord/cartesian/cartesianAxisHelper';
import AxisView from '../axis/AxisView'; import AxisView from '../axis/AxisView';
var CartesianAxisPointer = BaseAxisPointer.extend({ var CartesianAxisPointer = BaseAxisPointer.extend({
......
import * as graphic from '../../util/graphic'; import * as graphic from '../../util/graphic';
import BaseAxisPointer from './BaseAxisPointer'; import BaseAxisPointer from './BaseAxisPointer';
import * as viewHelper from './viewHelper'; import * as viewHelper from './viewHelper';
import * as singleAxisHelper from '../axis/singleAxisHelper'; import * as singleAxisHelper from '../../coord/single/singleAxisHelper';
import AxisView from '../axis/AxisView'; import AxisView from '../axis/AxisView';
var XY = ['x', 'y']; var XY = ['x', 'y'];
......
...@@ -80,7 +80,7 @@ export default echarts.extendComponentView({ ...@@ -80,7 +80,7 @@ export default echarts.extendComponentView({
shape: { shape: {
cx: cx, cx: cx,
cy: cy, cy: cy,
r: ticksRadius[i] r: ticksRadius[i].coord
} }
})); }));
} }
...@@ -90,8 +90,8 @@ export default echarts.extendComponentView({ ...@@ -90,8 +90,8 @@ export default echarts.extendComponentView({
shape: { shape: {
cx: cx, cx: cx,
cy: cy, cy: cy,
r0: ticksRadius[i], r0: ticksRadius[i].coord,
r: ticksRadius[i + 1] r: ticksRadius[i + 1].coord
} }
})); }));
} }
...@@ -106,7 +106,7 @@ export default echarts.extendComponentView({ ...@@ -106,7 +106,7 @@ export default echarts.extendComponentView({
? ticksCoords.length - 1 ? ticksCoords.length - 1
: Math.min(ticksCoords.length - 1, realSplitNumber); : Math.min(ticksCoords.length - 1, realSplitNumber);
return zrUtil.map(ticksCoords, function (tickCoord) { return zrUtil.map(ticksCoords, function (tickCoord) {
return radar.coordToPoint(tickCoord, idx); return radar.coordToPoint(tickCoord.coord, idx);
}); });
}); });
......
...@@ -287,9 +287,16 @@ export default TimelineView.extend({ ...@@ -287,9 +287,16 @@ export default TimelineView.extend({
var axisType = timelineModel.get('axisType'); var axisType = timelineModel.get('axisType');
var scale = axisHelper.createScaleByModel(timelineModel, axisType); var scale = axisHelper.createScaleByModel(timelineModel, axisType);
// Customize scale. The `tickValue` is `dataIndex`.
scale.getTicks = function () {
return data.mapArray(['value'], function (value) {
return value;
});
};
var dataExtent = data.getDataExtent('value'); var dataExtent = data.getDataExtent('value');
scale.setExtent(dataExtent[0], dataExtent[1]); scale.setExtent(dataExtent[0], dataExtent[1]);
this._customizeScale(scale, data);
scale.niceTicks(); scale.niceTicks();
var axis = new TimelineAxis('value', scale, layoutInfo.axisExtent, axisType); var axis = new TimelineAxis('value', scale, layoutInfo.axisExtent, axisType);
...@@ -298,19 +305,6 @@ export default TimelineView.extend({ ...@@ -298,19 +305,6 @@ export default TimelineView.extend({
return axis; return axis;
}, },
_customizeScale: function (scale, data) {
scale.getTicks = function () {
return data.mapArray(['value'], function (value) {
return value;
});
};
scale.getTicksLabels = function () {
return zrUtil.map(this.getTicks(), scale.getLabel, scale);
};
},
_createGroup: function (name) { _createGroup: function (name) {
var newGroup = this['_' + name] = new graphic.Group(); var newGroup = this['_' + name] = new graphic.Group();
this.group.add(newGroup); this.group.add(newGroup);
...@@ -343,23 +337,24 @@ export default TimelineView.extend({ ...@@ -343,23 +337,24 @@ export default TimelineView.extend({
*/ */
_renderAxisTick: function (layoutInfo, group, axis, timelineModel) { _renderAxisTick: function (layoutInfo, group, axis, timelineModel) {
var data = timelineModel.getData(); var data = timelineModel.getData();
// Show all ticks, despite ignoring strategy.
var ticks = axis.scale.getTicks(); var ticks = axis.scale.getTicks();
each(ticks, function (value, dataIndex) { // The value is dataIndex, see the costomized scale.
each(ticks, function (value) {
var tickCoord = axis.dataToCoord(value); var tickCoord = axis.dataToCoord(value);
var itemModel = data.getItemModel(dataIndex); var itemModel = data.getItemModel(value);
var itemStyleModel = itemModel.getModel('itemStyle'); var itemStyleModel = itemModel.getModel('itemStyle');
var hoverStyleModel = itemModel.getModel('emphasis.itemStyle'); var hoverStyleModel = itemModel.getModel('emphasis.itemStyle');
var symbolOpt = { var symbolOpt = {
position: [tickCoord, 0], position: [tickCoord, 0],
onclick: bind(this._changeTimeline, this, dataIndex) onclick: bind(this._changeTimeline, this, value)
}; };
var el = giveSymbol(itemModel, itemStyleModel, group, symbolOpt); var el = giveSymbol(itemModel, itemStyleModel, group, symbolOpt);
graphic.setHoverStyle(el, hoverStyleModel.getItemStyle()); graphic.setHoverStyle(el, hoverStyleModel.getItemStyle());
if (itemModel.get('tooltip')) { if (itemModel.get('tooltip')) {
el.dataIndex = dataIndex; el.dataIndex = value;
el.dataModel = timelineModel; el.dataModel = timelineModel;
} }
else { else {
...@@ -373,28 +368,23 @@ export default TimelineView.extend({ ...@@ -373,28 +368,23 @@ export default TimelineView.extend({
* @private * @private
*/ */
_renderAxisLabel: function (layoutInfo, group, axis, timelineModel) { _renderAxisLabel: function (layoutInfo, group, axis, timelineModel) {
var labelModel = timelineModel.getModel('label'); var labelModel = axis.getLabelModel();
if (!labelModel.get('show')) { if (!labelModel.get('show')) {
return; return;
} }
var data = timelineModel.getData(); var data = timelineModel.getData();
var ticks = axis.scale.getTicks(); var labels = axis.getViewLabels();
var labels = axisHelper.getFormattedLabels(
axis, labelModel.get('formatter')
);
var labelInterval = axis.getLabelInterval();
each(ticks, function (tick, dataIndex) { each(labels, function (labelItem) {
if (axis.isLabelIgnored(dataIndex, labelInterval)) { // The tickValue is dataIndex, see the costomized scale.
return; var dataIndex = labelItem.tickValue;
}
var itemModel = data.getItemModel(dataIndex); var itemModel = data.getItemModel(dataIndex);
var normalLabelModel = itemModel.getModel('label'); var normalLabelModel = itemModel.getModel('label');
var hoverLabelModel = itemModel.getModel('emphasis.label'); var hoverLabelModel = itemModel.getModel('emphasis.label');
var tickCoord = axis.dataToCoord(tick); var tickCoord = axis.dataToCoord(labelItem.tickValue);
var textEl = new graphic.Text({ var textEl = new graphic.Text({
position: [tickCoord, 0], position: [tickCoord, 0],
rotation: layoutInfo.labelRotation - layoutInfo.rotation, rotation: layoutInfo.labelRotation - layoutInfo.rotation,
...@@ -402,7 +392,7 @@ export default TimelineView.extend({ ...@@ -402,7 +392,7 @@ export default TimelineView.extend({
silent: false silent: false
}); });
graphic.setTextStyle(textEl.style, normalLabelModel, { graphic.setTextStyle(textEl.style, normalLabelModel, {
text: labels[dataIndex], text: labelItem.formattedLabel,
textAlign: layoutInfo.labelAlign, textAlign: layoutInfo.labelAlign,
textVerticalAlign: layoutInfo.labelBaseline textVerticalAlign: layoutInfo.labelBaseline
}); });
......
import * as zrUtil from 'zrender/src/core/util'; import * as zrUtil from 'zrender/src/core/util';
import Axis from '../../coord/Axis'; import Axis from '../../coord/Axis';
import * as axisHelper from '../../coord/axisHelper';
/** /**
* Extend axis 2d * Extend axis 2d
...@@ -26,12 +25,6 @@ var TimelineAxis = function (dim, scale, coordExtent, axisType) { ...@@ -26,12 +25,6 @@ var TimelineAxis = function (dim, scale, coordExtent, axisType) {
*/ */
this.type = axisType || 'value'; this.type = axisType || 'value';
/**
* @private
* @type {number}
*/
this._autoLabelInterval;
/** /**
* Axis model * Axis model
* @param {module:echarts/component/TimelineModel} * @param {module:echarts/component/TimelineModel}
...@@ -44,47 +37,17 @@ TimelineAxis.prototype = { ...@@ -44,47 +37,17 @@ TimelineAxis.prototype = {
constructor: TimelineAxis, constructor: TimelineAxis,
/** /**
* @public * @override
* @return {number}
*/ */
getLabelInterval: function () { getLabelModel: function () {
var timelineModel = this.model; return this.model.getModel('label');
var labelModel = timelineModel.getModel('label');
var labelInterval = labelModel.get('interval');
if (labelInterval != null && labelInterval != 'auto') {
return labelInterval;
}
var labelInterval = this._autoLabelInterval;
if (!labelInterval) {
labelInterval = this._autoLabelInterval = axisHelper.getAxisLabelInterval(
zrUtil.map(this.scale.getTicks(), this.dataToCoord, this),
axisHelper.getFormattedLabels(this, labelModel.get('formatter')),
labelModel.getFont(),
timelineModel.get('orient') === 'horizontal' ? 0 : 90,
labelModel.get('rotate')
);
}
return labelInterval;
}, },
/** /**
* If label is ignored. * @override
* Automatically used when axis is category and label can not be all shown
* @public
* @param {number} idx
* @return {boolean}
*/ */
isLabelIgnored: function (idx) { isHorizontal: function () {
if (this.type === 'category') { return this.model.get('orient') === 'horizontal';
var labelInterval = this.getLabelInterval();
return ((typeof labelInterval === 'function')
&& !labelInterval(idx, this.scale.getLabel(idx)))
|| idx % (labelInterval + 1);
}
} }
}; };
......
import {each, map, createHashMap} from 'zrender/src/core/util';
import * as zrUtil from 'zrender/src/core/util'; import {linearMap, getPixelPrecision} from '../util/number';
import * as numberUtil from '../util/number';
import * as axisHelper from './axisHelper'; import * as axisHelper from './axisHelper';
var linearMap = numberUtil.linearMap; var NORMALIZED_EXTENT = [0, 1];
function fixExtentWithBands(extent, nTick) {
var size = extent[1] - extent[0];
var len = nTick;
var margin = size / len / 2;
extent[0] += margin;
extent[1] -= margin;
}
var normalizedExtent = [0, 1];
/** /**
* @name module:echarts/coord/CartesianAxis * Base class of Axis.
* @constructor * @constructor
*/ */
var Axis = function (dim, scale, extent) { var Axis = function (dim, scale, extent) {
/** /**
* Axis dimension. Such as 'x', 'y', 'z', 'angle', 'radius' * Axis dimension. Such as 'x', 'y', 'z', 'angle', 'radius'.
* @type {string} * @type {string}
*/ */
this.dim = dim; this.dim = dim;
...@@ -50,10 +40,12 @@ var Axis = function (dim, scale, extent) { ...@@ -50,10 +40,12 @@ var Axis = function (dim, scale, extent) {
this.onBand = false; this.onBand = false;
/** /**
* Key: tickCategoryInterval
* Value: {ticks, labels}
* @private * @private
* @type {number} * @type {HashMap}
*/ */
this._labelInterval; this._ticksCache = createHashMap();
}; };
Axis.prototype = { Axis.prototype = {
...@@ -95,7 +87,7 @@ Axis.prototype = { ...@@ -95,7 +87,7 @@ Axis.prototype = {
* @return {number} * @return {number}
*/ */
getPixelPrecision: function (dataExtent) { getPixelPrecision: function (dataExtent) {
return numberUtil.getPixelPrecision( return getPixelPrecision(
dataExtent || this.scale.getExtent(), dataExtent || this.scale.getExtent(),
this._extent this._extent
); );
...@@ -128,7 +120,7 @@ Axis.prototype = { ...@@ -128,7 +120,7 @@ Axis.prototype = {
fixExtentWithBands(extent, scale.count()); fixExtentWithBands(extent, scale.count());
} }
return linearMap(data, normalizedExtent, extent, clamp); return linearMap(data, NORMALIZED_EXTENT, extent, clamp);
}, },
/** /**
...@@ -146,7 +138,7 @@ Axis.prototype = { ...@@ -146,7 +138,7 @@ Axis.prototype = {
fixExtentWithBands(extent, scale.count()); fixExtentWithBands(extent, scale.count());
} }
var t = linearMap(coord, extent, normalizedExtent, clamp); var t = linearMap(coord, extent, NORMALIZED_EXTENT, clamp);
return this.scale.scale(t); return this.scale.scale(t);
}, },
...@@ -162,57 +154,58 @@ Axis.prototype = { ...@@ -162,57 +154,58 @@ Axis.prototype = {
}, },
/** /**
* @return {Array.<number>} * Different from `zrUtil.map(axis.getTicks(), axis.dataToCoord, axis)`,
* `axis.getTicksCoords` considers `onBand`, which is used by
* `boundaryGap:true` of category axis and splitLine and splitArea.
* @param {Object} [opt]
* @param {number} [opt.tickModel=axis.model.getModel('axisTick')]
* @param {boolean} [opt.clamp] If `false`, clip. If `true`, clamp.
* @return {Array.<Object>} [{
* coord: ...,
* tickValue: ...
* }, ...]
*/ */
getTicksCoords: function (alignWithLabel) { getTicksCoords: function (opt) {
if (this.onBand && !alignWithLabel) { opt = opt || {};
var bands = this.getBands();
var coords = []; var tickModel = opt.tickModel || this.model.getModel('axisTick');
for (var i = 0; i < bands.length; i++) { var alignWithLabel = tickModel.get('alignWithLabel');
coords.push(bands[i][0]); var tickCategoryInterval = tickModel.get('interval');
}
if (bands[i - 1]) { var result = axisHelper.createAxisTicksAndLabels(this, {
coords.push(bands[i - 1][1]); tickCategoryInterval: tickCategoryInterval
} });
return coords; var ticks = result.ticks;
}
else { var ticksCoords = map(ticks, function (tickValue) {
return zrUtil.map(this.scale.getTicks(), this.dataToCoord, this); return {
} coord: this.dataToCoord(tickValue),
tickValue: tickValue
};
}, this);
fixOnBandTicksCoords(
this, ticksCoords, result.tickCategoryInterval, alignWithLabel, opt.clamp
);
return ticksCoords;
}, },
/** /**
* Coords of labels are on the ticks or on the middle of bands * @return {Array.<Object>} [{
* @return {Array.<number>} * formattedLabel: string,
* rawLabel: axis.scale.getLabel(tickValue)
* tickValue: number
* }, ...]
*/ */
getLabelsCoords: function () { getViewLabels: function () {
return zrUtil.map(this.scale.getTicks(), this.dataToCoord, this); return axisHelper.createAxisTicksAndLabels(this, {
tickCategoryInterval: this.model.get('axisTick.interval')
}).labels;
}, },
/** getLabelModel: function () {
* Get bands. return this.model.getModel('axisLabel');
*
* If axis has labels [1, 2, 3, 4]. Bands on the axis are
* |---1---|---2---|---3---|---4---|.
*
* @return {Array}
*/
// FIXME Situation when labels is on ticks
getBands: function () {
var extent = this.getExtent();
var bands = [];
var len = this.scale.count();
var start = extent[0];
var end = extent[1];
var span = end - start;
for (var i = 0; i < len; i++) {
bands.push([
span * i / len + start,
span * (i + 1) / len + start
]);
}
return bands;
}, },
/** /**
...@@ -242,42 +235,64 @@ Axis.prototype = { ...@@ -242,42 +235,64 @@ Axis.prototype = {
* @abstract * @abstract
* @return {number} Get axis rotate, by degree. * @return {number} Get axis rotate, by degree.
*/ */
getRotate: null, getRotate: null
/** };
* Get interval of the axis label.
* To get precise result, at least one of `getRotate` and `isHorizontal` function fixExtentWithBands(extent, nTick) {
* should be implemented. var size = extent[1] - extent[0];
* @return {number} var len = nTick;
*/ var margin = size / len / 2;
getLabelInterval: function () { extent[0] += margin;
var labelInterval = this._labelInterval; extent[1] -= margin;
if (!labelInterval) { }
var axisModel = this.model;
var labelModel = axisModel.getModel('axisLabel'); // If axis has labels [1, 2, 3, 4]. Bands on the axis are
labelInterval = labelModel.get('interval'); // |---1---|---2---|---3---|---4---|.
// So the displayed ticks and splitLine/splitArea should between
if (this.type === 'category' // each data item, otherwise cause misleading (e.g., split tow bars
&& (labelInterval == null || labelInterval === 'auto') // of a single data item when there are two bar series).
) { // Also consider if tickCategoryInterval > 0 and onBand, ticks and
labelInterval = axisHelper.getAxisLabelInterval( // splitLine/spliteArea should layout appropriately corresponding
zrUtil.map(this.scale.getTicks(), this.dataToCoord, this), // to displayed labels. (So we should not use `getBandWidth` in this
axisModel.getFormattedLabels(), // case).
labelModel.getFont(), function fixOnBandTicksCoords(axis, ticksCoords, tickCategoryInterval, alignWithLabel, clamp) {
this.getRotate var ticksLen = ticksCoords.length;
? this.getRotate() if (axis.onBand && !alignWithLabel && ticksLen) {
: (this.isHorizontal && !this.isHorizontal()) var axisExtent = axis.getExtent();
? 90 var last;
: 0, if (ticksLen === 1) {
labelModel.get('rotate') ticksCoords[0].coord = axisExtent[0];
); last = ticksCoords[1] = {coord: axisExtent[0]};
} }
else {
this._labelInterval = labelInterval; var shift = (ticksCoords[1].coord - ticksCoords[0].coord);
each(ticksCoords, function (ticksItem) {
ticksItem.coord -= shift / 2;
var tickCategoryInterval = tickCategoryInterval || 0;
// Avoid split a single data item when odd interval.
if (tickCategoryInterval % 2 > 0) {
ticksItem.coord -= shift / ((tickCategoryInterval + 1) * 2);
}
});
last = {coord: ticksCoords[ticksLen - 1].coord + shift};
ticksCoords.push(last);
} }
return labelInterval;
}
}; var inverse = axisExtent[0] > axisExtent[1];
if (inverse
? ticksCoords[0].coord > axisExtent[0]
: ticksCoords[0].coord < axisExtent[0]
) {
clamp ? (ticksCoords[0].coord = axisExtent[0]) : ticksCoords.shift();
}
if (inverse
? last.coord < axisExtent[1]
: last.coord > axisExtent[1]
) {
clamp ? (last.coord = axisExtent[1]) : ticksCoords.pop();
}
}
}
export default Axis; export default Axis;
\ No newline at end of file
...@@ -6,10 +6,14 @@ import IntervalScale from '../scale/Interval'; ...@@ -6,10 +6,14 @@ import IntervalScale from '../scale/Interval';
import Scale from '../scale/Scale'; import Scale from '../scale/Scale';
import * as numberUtil from '../util/number'; import * as numberUtil from '../util/number';
import {calBarWidthAndOffset} from '../layout/barGrid'; import {calBarWidthAndOffset} from '../layout/barGrid';
import {makeInner} from '../util/model';
import BoundingRect from 'zrender/src/core/BoundingRect';
import '../scale/Time'; import '../scale/Time';
import '../scale/Log'; import '../scale/Log';
var inner = makeInner();
/** /**
* Get axis scale extent before niced. * Get axis scale extent before niced.
* Item of returned array can only be number (including Infinity and NaN). * Item of returned array can only be number (including Infinity and NaN).
...@@ -253,94 +257,413 @@ export function ifAxisCrossZero(axis) { ...@@ -253,94 +257,413 @@ export function ifAxisCrossZero(axis) {
} }
/** /**
* @param {Array.<number>} tickCoords In axis self coordinate. * @param {module:echarts/coord/Axis} axis
* @param {Array.<string>} labels * @return {Function} Label formatter function.
* @param {string} font * param: {number} tickValue,
* @param {number} axisRotate 0: towards right horizontally, clock-wise is negative. * param: {number} idx, the index in all ticks.
* @param {number} [labelRotate=0] 0: towards right horizontally, clock-wise is negative. * If category axis, this param is not requied.
* return: {string} label string.
*/
function makeLabelFormatter(axis) {
var labelFormatter = axis.getLabelModel().get('formatter');
var categoryTickStart = axis.type === 'category' ? axis.scale.getExtent()[0] : null;
if (typeof labelFormatter === 'string') {
labelFormatter = (function (tpl) {
return function (val) {
return tpl.replace('{value}', val != null ? val : '');
};
})(labelFormatter);
// Consider empty array
return labelFormatter;
}
else if (typeof labelFormatter === 'function') {
return function (tickValue, idx) {
// The original intention of `idx` is "the index of the tick in all ticks".
// But the previous implementation of category axis do not consider the
// `axisLabel.interval`, which cause that, for example, the `interval` is
// `1`, then the ticks "name5", "name7", "name9" are displayed, where the
// corresponding `idx` are `0`, `2`, `4`, but not `0`, `1`, `2`. So we keep
// the definition here for back compatibility.
if (categoryTickStart != null) {
idx = tickValue - categoryTickStart;
}
return labelFormatter(getAxisRawValue(axis, tickValue), idx);
};
}
else {
return function (tick) {
return axis.scale.getLabel(tick);
};
}
}
export function getAxisRawValue(axis, value) {
// In category axis with data zoom, tick is not the original
// index of axis.data. So tick should not be exposed to user
// in category axis.
return axis.type === 'category' ? axis.scale.getLabel(value) : value;
}
/**
* Performance sensible in the large category data case.
* @param {module:echats/coord/Axis} axis
* @param {Object} opt
* @param {number} [opt.tickCategoryInterval] Can be null/'auto'. Can also be
* axisTick.interval, splitLine.interval, splitArea.interval.
* @return {Object} {
* ticks: [number, ...]
* labels: [{
* formattedLabel: string,
* rawLabel: string,
* tickValue: number
* }, ...],
* labelCategoryInterval,
* tickCategoryInterval
* }
*/
export function createAxisTicksAndLabels(axis, opt) {
// Only ordinal scale support tick interval
return axis.type === 'category'
? createCategoryTicksAndLabels(axis, opt)
: createRealNumberTicksAndLabels(axis, opt);
}
function createCategoryTicksAndLabels(axis, opt) {
var labelModel = axis.getLabelModel();
// (1) Only add min max label here but leave overlap checking
// to render stage, which also ensure the returned list
// suitable for splitLine and splitArea rendering.
// (2) Scales except category always contain min max label so
// do not need to perform this process.
var showMinMax = {
min: labelModel.get('showMinLabel'),
max: labelModel.get('showMaxLabel')
};
// Large category data calculation is performence sensitive, and ticks and label
// probably be fetched by multiple times. So we cache the result.
// axis is created each time during a ec process, so we do not need to clear cache.
var ticksCache = getListCache(axis, 'ticks');
var labelsCache = getListCache(axis, 'labels');
var labelCategoryInterval = normalizeAuto(labelModel.get('interval'));
var labels = listCacheGet(labelsCache, labelCategoryInterval);
if (!labels) {
if (zrUtil.isFunction(labelCategoryInterval)) {
labels = makeLabelsByCustomizedCategoryInterval(axis, labelCategoryInterval);
}
else {
if (labelCategoryInterval === 'auto') {
labelCategoryInterval = calculateAutoCategoryInterval(axis);
}
labels = makeLabelsByNumericCategoryInterval(axis, labelCategoryInterval, showMinMax);
}
listCacheSet(labelsCache, labelCategoryInterval, labels);
}
var tickCategoryInterval = normalizeAuto(opt.tickCategoryInterval);
var ticks = listCacheGet(ticksCache, tickCategoryInterval);
if (!ticks) {
if (zrUtil.isFunction(tickCategoryInterval)) {
ticks = makeLabelsByCustomizedCategoryInterval(axis, tickCategoryInterval, true);
}
else if (tickCategoryInterval === 'auto' || tickCategoryInterval === labelCategoryInterval) {
// Always use label interval by default.
tickCategoryInterval = labelCategoryInterval;
ticks = zrUtil.map(labels, function (labelItem) {
return labelItem.tickValue;
});
}
else {
ticks = makeLabelsByNumericCategoryInterval(axis, tickCategoryInterval, showMinMax, true);
}
listCacheSet(ticksCache, tickCategoryInterval, ticks);
}
return {
ticks: ticks,
labels: labels,
labelCategoryInterval: labelCategoryInterval,
tickCategoryInterval: tickCategoryInterval
};
}
function createRealNumberTicksAndLabels(axis, opt) {
var ticks = axis.scale.getTicks();
var labelFormatter = makeLabelFormatter(axis);
var labels = zrUtil.map(ticks, function (tickValue, idx) {
return {
formattedLabel: labelFormatter(tickValue, idx),
rawLabel: axis.scale.getLabel(tickValue),
tickValue: tickValue
};
});
return {ticks: ticks, labels: labels};
}
function getListCache(axis, prop) {
// Because key can be funciton, and cache size always be small, we use array cache.
return inner(axis)[prop] || (inner(axis)[prop] = []);
}
function listCacheGet(cache, key) {
for (var i = 0; i < cache.length; i++) {
if (cache[i].key === key) {
return cache[i].value;
}
}
}
function listCacheSet(cache, key, value) {
cache.push({key: key, value: value});
}
/**
* Performance sensitive for large category data.
* Get interval of the axis label.
* To get precise result, at least one of `getRotate` and `isHorizontal`
* should be implemented.
* @param {module:echarts/coord/Axis} axis
* @return {number} * @return {number}
*/ */
export function getAxisLabelInterval(tickCoords, labels, font, axisRotate, labelRotate) { function calculateAutoCategoryInterval(axis) {
var textSpaceTakenRect; var params = fetchAutoCategoryIntervalCalculationParams(axis);
var autoLabelInterval = 0; var labelFormatter = makeLabelFormatter(axis);
var accumulatedLabelInterval = 0; var rotation = (params.axisRotate - params.labelRotate) / 180 * Math.PI;
var rotation = (axisRotate - labelRotate) / 180 * Math.PI;
var ordinalScale = axis.scale;
var ordinalExtent = ordinalScale.getExtent();
// Providing this method is for optimization:
// avoid generating a long array by `getTicks`
// in large category data case.
var tickCount = ordinalScale.count();
var step = 1; var step = 1;
if (labels.length > 40) { // Simple optimization. Empirical value: tick count less 40.
// Simple optimization for large amount of labels if (tickCount > 40) {
step = Math.floor(labels.length / 40); step = Math.max(1, Math.floor(tickCount / 40));
} }
for (var i = 0; i < tickCoords.length; i += step) { var textSpaceTakenRect;
var tickCoord = tickCoords[i]; var accumulatedLabelInterval = 0;
for (var tickValue = ordinalExtent[0]; tickValue <= ordinalExtent[1]; ) {
var formattedLabel = labelFormatter(tickValue);
// Not precise, do not consider align and vertical align // Not precise, do not consider align and vertical align
// and each distance from axis line yet. // and each distance from axis line yet.
var rect = textContain.getBoundingRect( var rect = textContain.getBoundingRect(
labels[i], font, 'center', 'top' formattedLabel, params.font, 'center', 'top'
); );
// Polar is also calculated in assumptive linear layout here.
var tickCoord = axis.dataToCoord(tickValue);
rect.x += tickCoord * Math.cos(rotation); rect.x += tickCoord * Math.cos(rotation);
rect.y += tickCoord * Math.sin(rotation); rect.y += tickCoord * Math.sin(rotation);
// Magic number // Magic number
rect.width *= 1.3; rect.width *= 1.3;
rect.height *= 1.3; rect.height *= 1.3;
if (!textSpaceTakenRect) { if (!textSpaceTakenRect) {
textSpaceTakenRect = rect.clone(); textSpaceTakenRect = rect;
tickValue += step;
} }
// There is no space for current label; // There is no space for current label.
else if (textSpaceTakenRect.intersect(rect)) { else if (textSpaceTakenRect.intersect(rect)) {
accumulatedLabelInterval++; accumulatedLabelInterval++;
autoLabelInterval = Math.max(autoLabelInterval, accumulatedLabelInterval); tickValue++;
} }
else { else {
textSpaceTakenRect.union(rect); textSpaceTakenRect.union(rect);
// Reset if (accumulatedLabelInterval) {
accumulatedLabelInterval = 0; // Optimize: add step to escape uncessary loop.
step += accumulatedLabelInterval;
accumulatedLabelInterval = 0;
}
tickValue += step;
} }
} }
if (autoLabelInterval === 0 && step > 1) {
return step; if (accumulatedLabelInterval) {
step += accumulatedLabelInterval;
} }
return (autoLabelInterval + 1) * step - 1;
var cache = inner(axis.model);
var lastStep = cache.lastStep;
var lastTickCount = cache.lastTickCount;
// Use cache to keep interval stable while moving zoom window,
// otherwise the calculated interval might jitter when the zoom
// window size is close to the interval-changing size.
if (lastStep != null
&& lastTickCount != null
&& Math.abs(lastStep - step) <= 1
&& Math.abs(lastTickCount - tickCount) <= 1
// Always choose the bigger one, otherwise the critical
// point is not the same when zooming in or zooming out.
&& lastStep > step
) {
step = lastStep;
}
// Only update cache if cache not used, otherwise the
// changing of interval is too insensitive.
else {
cache.lastTickCount = tickCount;
cache.lastStep = step;
}
return step - 1;
}
function fetchAutoCategoryIntervalCalculationParams(axis) {
var labelModel = axis.getLabelModel();
return {
axisRotate: axis.getRotate
? axis.getRotate()
: (axis.isHorizontal && !axis.isHorizontal())
? 90
: 0,
labelRotate: labelModel.get('rotate') || 0,
font: labelModel.getFont()
};
}
function makeLabelsByNumericCategoryInterval(axis, categoryInterval, showMinMax, onlyTick) {
var labelFormatter = makeLabelFormatter(axis);
var ordinalScale = axis.scale;
var ordinalExtent = ordinalScale.getExtent();
var result = [];
// TODO: axisType: ordinalTime, pick the tick from each month/day/year/...
var step = Math.max((categoryInterval || 0) + 1, 1);
var startTick = ordinalExtent[0];
var tickCount = ordinalScale.count();
// Calculate start tick based on zero if possible to keep label consistent
// while zooming and moving while interval > 0. Otherwise the selection
// of displayable ticks and symbols probably keep changing.
// 3 is empirical value.
if (startTick !== 0 && step > 1 && tickCount / step > 2) {
startTick = Math.round(Math.ceil(startTick / step) * step);
}
if (showMinMax.min && startTick !== ordinalExtent[0]) {
addItem(ordinalExtent[0]);
}
// Optimize: avoid generating large array by `ordinalScale.getTicks()`.
var tickValue = startTick;
for (; tickValue <= ordinalExtent[1]; tickValue += step) {
addItem(tickValue);
}
if (showMinMax.max && tickValue !== ordinalExtent[1]) {
addItem(ordinalExtent[1]);
}
function addItem(tVal) {
result.push(onlyTick
? tVal
: {
formattedLabel: labelFormatter(tVal),
rawLabel: ordinalScale.getLabel(tVal),
tickValue: tVal
}
);
}
return result;
}
// When interval is function, the result `false` means ignore the tick.
// It is time consuming for large category data.
function makeLabelsByCustomizedCategoryInterval(axis, categoryInterval, onlyTick) {
var ordinalScale = axis.scale;
var labelFormatter = makeLabelFormatter(axis);
var result = [];
zrUtil.each(ordinalScale.getTicks(), function (tickValue) {
var rawLabel = ordinalScale.getLabel(tickValue);
if (categoryInterval(tickValue, rawLabel)) {
result.push(onlyTick
? tickValue
: {
formattedLabel: labelFormatter(tickValue),
rawLabel: rawLabel,
tickValue: tickValue
}
);
}
});
return result;
}
// Can be null|'auto'
function normalizeAuto(setting) {
return setting == null ? 'auto' : setting;
} }
/** /**
* @param {Object} axis * @param {module:echarts/coord/Axis} axis
* @param {Function} labelFormatter * @return {module:zrender/core/BoundingRect} Be null/undefined if no labels.
* @return {Array.<string>}
*/ */
export function getFormattedLabels(axis, labelFormatter) { export function estimateLabelUnionRect(axis) {
var scale = axis.scale; var axisModel = axis.model;
var labels = scale.getTicksLabels();
var ticks = scale.getTicks(); if (!axisModel.get('axisLabel.show')) {
if (typeof labelFormatter === 'string') { return;
labelFormatter = (function (tpl) {
return function (val) {
return tpl.replace('{value}', val != null ? val : '');
};
})(labelFormatter);
// Consider empty array
return zrUtil.map(labels, labelFormatter);
} }
else if (typeof labelFormatter === 'function') {
return zrUtil.map(ticks, function (tick, idx) { var scale = axis.scale;
return labelFormatter( var isCategory = axis.type === 'category';
getAxisRawValue(axis, tick),
idx var realNumberScaleTicks;
); var tickCount;
}, this); var categoryScaleExtent = scale.getExtent();
// Optimize for large category data, avoid call `getTicks()`.
if (isCategory) {
tickCount = scale.count();
} }
else { else {
return labels; realNumberScaleTicks = scale.getTicks();
tickCount = realNumberScaleTicks.length;
} }
var axisLabelModel = axis.getLabelModel();
var labelFormatter = makeLabelFormatter(axis);
var rect;
var step = 1;
// Simple optimization for large amount of labels
if (tickCount > 40) {
step = Math.ceil(tickCount / 40);
}
for (var i = 0; i < tickCount; i += step) {
var tickValue = realNumberScaleTicks ? realNumberScaleTicks[i] : categoryScaleExtent[0] + i;
var label = labelFormatter(tickValue);
var unrotatedSingleRect = axisLabelModel.getTextRect(label);
var singleRect = rotateTextRect(unrotatedSingleRect, axisLabelModel.get('rotate') || 0);
rect ? rect.union(singleRect) : (rect = singleRect);
}
return rect;
} }
export function getAxisRawValue(axis, value) { function rotateTextRect(textRect, rotate) {
// In category axis with data zoom, tick is not the original var rotateRadians = rotate * Math.PI / 180;
// index of axis.data. So tick should not be exposed to user var boundingBox = textRect.plain();
// in category axis. var beforeWidth = boundingBox.width;
return axis.type === 'category' ? axis.scale.getLabel(value) : value; var beforeHeight = boundingBox.height;
var afterWidth = beforeWidth * Math.cos(rotateRadians) + beforeHeight * Math.sin(rotateRadians);
var afterHeight = beforeWidth * Math.sin(rotateRadians) + beforeHeight * Math.cos(rotateRadians);
var rotatedRect = new BoundingRect(boundingBox.x, boundingBox.y, afterWidth, afterHeight);
return rotatedRect;
} }
...@@ -3,17 +3,6 @@ import * as axisHelper from './axisHelper'; ...@@ -3,17 +3,6 @@ import * as axisHelper from './axisHelper';
export default { export default {
/**
* Format labels
* @return {Array.<string>}
*/
getFormattedLabels: function () {
return axisHelper.getFormattedLabels(
this.axis,
this.get('axisLabel.formatter')
);
},
/** /**
* @param {boolean} origin * @param {boolean} origin
* @return {number|string} min value or 'dataMin' or null/undefined (means auto) or NaN * @return {number|string} min value or 'dataMin' or null/undefined (means auto) or NaN
......
...@@ -81,21 +81,6 @@ Axis2D.prototype = { ...@@ -81,21 +81,6 @@ Axis2D.prototype = {
this.grid.getOtherAxis(); this.grid.getOtherAxis();
}, },
/**
* If label is ignored.
* Automatically used when axis is category and label can not be all shown
* @param {number} idx
* @return {boolean}
*/
isLabelIgnored: function (idx) {
if (this.type === 'category') {
var labelInterval = this.getLabelInterval();
return ((typeof labelInterval === 'function')
&& !labelInterval(idx, this.scale.getLabel(idx)))
|| idx % (labelInterval + 1);
}
},
/** /**
* @override * @override
*/ */
......
...@@ -5,10 +5,14 @@ ...@@ -5,10 +5,14 @@
*/ */
import {__DEV__} from '../../config'; import {__DEV__} from '../../config';
import * as zrUtil from 'zrender/src/core/util'; import {isObject, each, map, indexOf, retrieve} from 'zrender/src/core/util';
import BoundingRect from 'zrender/src/core/BoundingRect';
import {getLayoutRect} from '../../util/layout'; import {getLayoutRect} from '../../util/layout';
import * as axisHelper from '../../coord/axisHelper'; import {
createScaleByModel,
ifAxisCrossZero,
niceScaleExtent,
estimateLabelUnionRect
} from '../../coord/axisHelper';
import Cartesian2D from './Cartesian2D'; import Cartesian2D from './Cartesian2D';
import Axis2D from './Axis2D'; import Axis2D from './Axis2D';
import CoordinateSystem from '../../CoordinateSystem'; import CoordinateSystem from '../../CoordinateSystem';
...@@ -16,10 +20,6 @@ import CoordinateSystem from '../../CoordinateSystem'; ...@@ -16,10 +20,6 @@ import CoordinateSystem from '../../CoordinateSystem';
// Depends on GridModel, AxisModel, which performs preprocess. // Depends on GridModel, AxisModel, which performs preprocess.
import './GridModel'; import './GridModel';
var each = zrUtil.each;
var ifAxisCrossZero = axisHelper.ifAxisCrossZero;
var niceScaleExtent = axisHelper.niceScaleExtent;
/** /**
* Check if the axis is used in the specified grid * Check if the axis is used in the specified grid
* @inner * @inner
...@@ -28,40 +28,6 @@ function isAxisUsedInTheGrid(axisModel, gridModel, ecModel) { ...@@ -28,40 +28,6 @@ function isAxisUsedInTheGrid(axisModel, gridModel, ecModel) {
return axisModel.getCoordSysModel() === gridModel; return axisModel.getCoordSysModel() === gridModel;
} }
function rotateTextRect(textRect, rotate) {
var rotateRadians = rotate * Math.PI / 180;
var boundingBox = textRect.plain();
var beforeWidth = boundingBox.width;
var beforeHeight = boundingBox.height;
var afterWidth = beforeWidth * Math.cos(rotateRadians) + beforeHeight * Math.sin(rotateRadians);
var afterHeight = beforeWidth * Math.sin(rotateRadians) + beforeHeight * Math.cos(rotateRadians);
var rotatedRect = new BoundingRect(boundingBox.x, boundingBox.y, afterWidth, afterHeight);
return rotatedRect;
}
function getLabelUnionRect(axis) {
var axisModel = axis.model;
var labels = axisModel.get('axisLabel.show') ? axisModel.getFormattedLabels() : [];
var axisLabelModel = axisModel.getModel('axisLabel');
var rect;
var step = 1;
var labelCount = labels.length;
if (labelCount > 40) {
// Simple optimization for large amount of labels
step = Math.ceil(labelCount / 40);
}
for (var i = 0; i < labelCount; i += step) {
if (!axis.isLabelIgnored(i)) {
var unrotatedSingleRect = axisLabelModel.getTextRect(labels[i]);
var singleRect = rotateTextRect(unrotatedSingleRect, axisLabelModel.get('rotate') || 0);
rect ? rect.union(singleRect) : (rect = singleRect);
}
}
return rect;
}
function Grid(gridModel, ecModel, api) { function Grid(gridModel, ecModel, api) {
/** /**
* @type {Object.<string, module:echarts/coord/cartesian/Cartesian2D>} * @type {Object.<string, module:echarts/coord/cartesian/Cartesian2D>}
...@@ -191,7 +157,7 @@ gridProto.resize = function (gridModel, api, ignoreContainLabel) { ...@@ -191,7 +157,7 @@ gridProto.resize = function (gridModel, api, ignoreContainLabel) {
if (!ignoreContainLabel && gridModel.get('containLabel')) { if (!ignoreContainLabel && gridModel.get('containLabel')) {
each(axesList, function (axis) { each(axesList, function (axis) {
if (!axis.model.get('axisLabel.inside')) { if (!axis.model.get('axisLabel.inside')) {
var labelUnionRect = getLabelUnionRect(axis); var labelUnionRect = estimateLabelUnionRect(axis);
if (labelUnionRect) { if (labelUnionRect) {
var dim = axis.isHorizontal() ? 'height' : 'width'; var dim = axis.isHorizontal() ? 'height' : 'width';
var margin = axis.model.get('axisLabel.margin'); var margin = axis.model.get('axisLabel.margin');
...@@ -262,7 +228,7 @@ gridProto.getCartesian = function (xAxisIndex, yAxisIndex) { ...@@ -262,7 +228,7 @@ gridProto.getCartesian = function (xAxisIndex, yAxisIndex) {
return this._coordsMap[key]; return this._coordsMap[key];
} }
if (zrUtil.isObject(xAxisIndex)) { if (isObject(xAxisIndex)) {
yAxisIndex = xAxisIndex.yAxisIndex; yAxisIndex = xAxisIndex.yAxisIndex;
xAxisIndex = xAxisIndex.xAxisIndex; xAxisIndex = xAxisIndex.xAxisIndex;
} }
...@@ -324,7 +290,7 @@ gridProto._findConvertTarget = function (ecModel, finder) { ...@@ -324,7 +290,7 @@ gridProto._findConvertTarget = function (ecModel, finder) {
if (seriesModel) { if (seriesModel) {
cartesian = seriesModel.coordinateSystem; cartesian = seriesModel.coordinateSystem;
zrUtil.indexOf(coordsList, cartesian) < 0 && (cartesian = null); indexOf(coordsList, cartesian) < 0 && (cartesian = null);
} }
else if (xAxisModel && yAxisModel) { else if (xAxisModel && yAxisModel) {
cartesian = this.getCartesian(xAxisModel.componentIndex, yAxisModel.componentIndex); cartesian = this.getCartesian(xAxisModel.componentIndex, yAxisModel.componentIndex);
...@@ -438,7 +404,7 @@ gridProto._initCartesian = function (gridModel, ecModel, api) { ...@@ -438,7 +404,7 @@ gridProto._initCartesian = function (gridModel, ecModel, api) {
axisPositionUsed[axisPosition] = true; axisPositionUsed[axisPosition] = true;
var axis = new Axis2D( var axis = new Axis2D(
axisType, axisHelper.createScaleByModel(axisModel), axisType, createScaleByModel(axisModel),
[0, 0], [0, 0],
axisModel.get('type'), axisModel.get('type'),
axisPosition axisPosition
...@@ -475,7 +441,7 @@ gridProto._initCartesian = function (gridModel, ecModel, api) { ...@@ -475,7 +441,7 @@ gridProto._initCartesian = function (gridModel, ecModel, api) {
*/ */
gridProto._updateScale = function (ecModel, gridModel) { gridProto._updateScale = function (ecModel, gridModel) {
// Reset scale // Reset scale
zrUtil.each(this._axesList, function (axis) { each(this._axesList, function (axis) {
axis.scale.setExtent(Infinity, -Infinity); axis.scale.setExtent(Infinity, -Infinity);
}); });
ecModel.eachSeries(function (seriesModel) { ecModel.eachSeries(function (seriesModel) {
...@@ -523,8 +489,8 @@ gridProto.getTooltipAxes = function (dim) { ...@@ -523,8 +489,8 @@ gridProto.getTooltipAxes = function (dim) {
var baseAxis = (dim != null && dim !== 'auto') var baseAxis = (dim != null && dim !== 'auto')
? cartesian.getAxis(dim) : cartesian.getBaseAxis(); ? cartesian.getAxis(dim) : cartesian.getBaseAxis();
var otherAxis = cartesian.getOtherAxis(baseAxis); var otherAxis = cartesian.getOtherAxis(baseAxis);
zrUtil.indexOf(baseAxes, baseAxis) < 0 && baseAxes.push(baseAxis); indexOf(baseAxes, baseAxis) < 0 && baseAxes.push(baseAxis);
zrUtil.indexOf(otherAxes, otherAxis) < 0 && otherAxes.push(otherAxis); indexOf(otherAxes, otherAxis) < 0 && otherAxes.push(otherAxis);
}); });
return {baseAxes: baseAxes, otherAxes: otherAxes}; return {baseAxes: baseAxes, otherAxes: otherAxes};
...@@ -559,12 +525,12 @@ var axesTypes = ['xAxis', 'yAxis']; ...@@ -559,12 +525,12 @@ var axesTypes = ['xAxis', 'yAxis'];
* @inner * @inner
*/ */
function findAxesModels(seriesModel, ecModel) { function findAxesModels(seriesModel, ecModel) {
return zrUtil.map(axesTypes, function (axisType) { return map(axesTypes, function (axisType) {
var axisModel = seriesModel.getReferringComponents(axisType)[0]; var axisModel = seriesModel.getReferringComponents(axisType)[0];
if (__DEV__) { if (__DEV__) {
if (!axisModel) { if (!axisModel) {
throw new Error(axisType + ' "' + zrUtil.retrieve( throw new Error(axisType + ' "' + retrieve(
seriesModel.get(axisType + 'Index'), seriesModel.get(axisType + 'Index'),
seriesModel.get(axisType + 'Id'), seriesModel.get(axisType + 'Id'),
0 0
...@@ -611,7 +577,7 @@ Grid.create = function (ecModel, api) { ...@@ -611,7 +577,7 @@ Grid.create = function (ecModel, api) {
if (__DEV__) { if (__DEV__) {
if (!gridModel) { if (!gridModel) {
throw new Error( throw new Error(
'Grid "' + zrUtil.retrieve( 'Grid "' + retrieve(
xAxisModel.get('gridIndex'), xAxisModel.get('gridIndex'),
xAxisModel.get('gridId'), xAxisModel.get('gridId'),
0 0
......
import * as zrUtil from 'zrender/src/core/util'; import * as zrUtil from 'zrender/src/core/util';
/** /**
* Can only be called after coordinate system creation stage.
* (Can be called before coordinate system update stage).
*
* @param {Object} opt {labelInside} * @param {Object} opt {labelInside}
* @return {Object} { * @return {Object} {
* position, rotation, labelDirection, labelOffset, * position, rotation, labelDirection, labelOffset,
* tickDirection, labelRotate, labelInterval, z2 * tickDirection, labelRotate, z2
* } * }
*/ */
export function layout(gridModel, axisModel, opt) { export function layout(gridModel, axisModel, opt) {
...@@ -58,9 +61,6 @@ export function layout(gridModel, axisModel, opt) { ...@@ -58,9 +61,6 @@ export function layout(gridModel, axisModel, opt) {
var labelRotate = axisModel.get('axisLabel.rotate'); var labelRotate = axisModel.get('axisLabel.rotate');
layout.labelRotate = axisPosition === 'top' ? -labelRotate : labelRotate; layout.labelRotate = axisPosition === 'top' ? -labelRotate : labelRotate;
// label interval when auto mode.
layout.labelInterval = axis.getLabelInterval();
// Over splitLine and splitArea // Over splitLine and splitArea
layout.z2 = 1; layout.z2 = 1;
......
...@@ -302,8 +302,7 @@ Parallel.prototype = { ...@@ -302,8 +302,7 @@ Parallel.prototype = {
axisLabelShow: posInfo.axisLabelShow, axisLabelShow: posInfo.axisLabelShow,
nameTruncateMaxWidth: posInfo.nameTruncateMaxWidth, nameTruncateMaxWidth: posInfo.nameTruncateMaxWidth,
tickDirection: 1, tickDirection: 1,
labelDirection: 1, labelDirection: 1
labelInterval: axes.get(dim).getLabelInterval()
}; };
}, this); }, this);
}, },
......
...@@ -42,11 +42,6 @@ var SingleAxis = function (dim, scale, coordExtent, axisType, position) { ...@@ -42,11 +42,6 @@ var SingleAxis = function (dim, scale, coordExtent, axisType, position) {
*/ */
this.orient = null; this.orient = null;
/**
* @type {number}
*/
this._labelInterval = null;
}; };
SingleAxis.prototype = { SingleAxis.prototype = {
......
...@@ -4,10 +4,10 @@ import * as zrUtil from 'zrender/src/core/util'; ...@@ -4,10 +4,10 @@ import * as zrUtil from 'zrender/src/core/util';
* @param {Object} opt {labelInside} * @param {Object} opt {labelInside}
* @return {Object} { * @return {Object} {
* position, rotation, labelDirection, labelOffset, * position, rotation, labelDirection, labelOffset,
* tickDirection, labelRotate, labelInterval, z2 * tickDirection, labelRotate, z2
* } * }
*/ */
export function layout (axisModel, opt) { export function layout(axisModel, opt) {
opt = opt || {}; opt = opt || {};
var single = axisModel.coordinateSystem; var single = axisModel.coordinateSystem;
var axis = axisModel.axis; var axis = axisModel.axis;
...@@ -54,8 +54,6 @@ export function layout (axisModel, opt) { ...@@ -54,8 +54,6 @@ export function layout (axisModel, opt) {
labelRotation == null && (labelRotation = axisModel.get('axisLabel.rotate')); labelRotation == null && (labelRotation = axisModel.get('axisLabel.rotate'));
layout.labelRotation = axisPosition === 'top' ? -labelRotation : labelRotation; layout.labelRotation = axisPosition === 'top' ? -labelRotation : labelRotation;
layout.labelInterval = axis.getLabelInterval();
layout.z2 = 1; layout.z2 = 1;
return layout; return layout;
......
...@@ -23,11 +23,12 @@ export default function (seriesType) { ...@@ -23,11 +23,12 @@ export default function (seriesType) {
}).slice(0, 2); }).slice(0, 2);
var dimLen = dims.length; var dimLen = dims.length;
var stackResultDim = data.getCalculationInfo('stackResultDimension');
if (isDimensionStacked(data, dims[0], dims[1])) { if (isDimensionStacked(data, dims[0], dims[1])) {
dims[0] = data.getCalculationInfo('stackResultDimension'); dims[0] = stackResultDim;
} }
if (isDimensionStacked(data, dims[1], dims[0])) { if (isDimensionStacked(data, dims[1], dims[0])) {
dims[1] = data.getCalculationInfo('stackResultDimension'); dims[1] = stackResultDim;
} }
function progress(params, data) { function progress(params, data) {
......
...@@ -70,18 +70,6 @@ var IntervalScale = Scale.extend({ ...@@ -70,18 +70,6 @@ var IntervalScale = Scale.extend({
); );
}, },
/**
* @return {Array.<string>}
*/
getTicksLabels: function () {
var labels = [];
var ticks = this.getTicks();
for (var i = 0; i < ticks.length; i++) {
labels.push(this.getLabel(ticks[i]));
}
return labels;
},
/** /**
* @param {number} data * @param {number} data
* @param {Object} [opt] * @param {Object} [opt]
......
...@@ -117,18 +117,6 @@ Scale.prototype.setExtent = function (start, end) { ...@@ -117,18 +117,6 @@ Scale.prototype.setExtent = function (start, end) {
} }
}; };
/**
* @return {Array.<string>}
*/
Scale.prototype.getTicksLabels = function () {
var labels = [];
var ticks = this.getTicks();
for (var i = 0; i < ticks.length; i++) {
labels.push(this.getLabel(ticks[i]));
}
return labels;
};
/** /**
* When axis extent depends on data and no data exists, * When axis extent depends on data and no data exists,
* axis ticks should not be drawn, which is named 'blank'. * axis ticks should not be drawn, which is named 'blank'.
...@@ -145,6 +133,13 @@ Scale.prototype.setBlank = function (isBlank) { ...@@ -145,6 +133,13 @@ Scale.prototype.setBlank = function (isBlank) {
this._isBlank = isBlank; this._isBlank = isBlank;
}; };
/**
* @abstract
* @param {*} tick
* @return {string} label of the tick.
*/
Scale.prototype.getLabel = null;
clazzUtil.enableClassExtend(Scale); clazzUtil.enableClassExtend(Scale);
clazzUtil.enableClassManagement(Scale, { clazzUtil.enableClassManagement(Scale, {
......
<!DOCTYPE>
<html>
<head>
<meta charset="utf-8">
<script src="lib/esl.js"></script>
<script src="lib/config.js"></script>
<script src="lib/jquery.min.js"></script>
<script src="lib/facePrint.js"></script>
<script src="lib/testHelper.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="lib/reset.css">
</head>
<body>
<style>
.test-title {
background: #b8d4ff;
color: #000;
}
</style>
<div class="chart" id="main0"></div>
<div class="chart" id="main1"></div>
<script>
require([
'echarts'
], function (echarts) {
var xAxisData = [];
var data1 = [];
var data3 = [];
for (var i = 0; i < 100; i++) {
xAxisData.push('category' + i);
data1.push((Math.random() * 5).toFixed(2) * 1e6);
data3.push((Math.random() + 0.5).toFixed(2) * 1e6);
}
var option = {
backgroundColor: '#fe9',
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
xAxis: {
id: 'xx',
data: xAxisData,
axisTick: {
interval: 4,
alignWithLabel: true
},
axisLabel: {
},
splitArea: {
show: true
}
},
yAxis: {
id: 'yy',
axisTick: {
show: false
},
splitArea: {
show: false
}
},
grid: {
left: 0,
top: 0,
bottom: 0,
right: 0,
containLabel: true
},
dataZoom: [{
type: 'inside',
startValue: 17,
endValue: 24
}],
series: [{
name: 'bar',
type: 'bar',
stack: 'one',
cursor: 'move',
data: data1
}, {
name: 'bar3',
type: 'bar',
stack: 'two',
data: data3
}]
};
var chart = testHelper.create(echarts, 'main0', {
title: [
'Check containLabel'
],
option: option,
info: {grid: option.grid},
});
var rotate = 0;
chart && next();
function next() {
var nextInterval = rotate % 90 === 0 ? 2000: 70;
rotate = (rotate + 1) % 90;
setTimeout(function () {
chart.setOption({
xAxis: {
id: 'xx',
axisLabel: {
rotate: rotate
}
},
yAxis: {
id: 'yy',
axisLabel: {
rotate: rotate
}
}
});
next();
}, nextInterval);
}
});
</script>
<script>
require([
'echarts'
], function (echarts) {
var xAxisData = [];
var data1 = [];
var data3 = [];
for (var i = 0; i < 100; i++) {
xAxisData.push('category' + i);
data1.push((Math.random() * 5).toFixed(2) * 1e6);
data3.push((Math.random() + 0.5).toFixed(2) * 1e6);
}
var option = {
backgroundColor: '#fe9',
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
xAxis: [{
id: 'x0',
data: xAxisData,
axisTick: {
interval: 4,
alignWithLabel: true
},
axisLabel: {
},
splitArea: {
show: true
}
}, {
id: 'x1',
data: xAxisData,
axisTick: {
interval: 4,
alignWithLabel: true
},
axisLabel: {
},
splitArea: {
show: true
}
}],
yAxis: [{
id: 'y0',
axisTick: {
show: false
},
splitArea: {
show: false
}
}, {
id: 'y1',
axisTick: {
show: false
},
splitArea: {
show: false
}
}],
grid: {
left: 0,
top: 0,
bottom: 0,
right: 0,
containLabel: true
},
dataZoom: [{
type: 'inside',
startValue: 17,
endValue: 24
}],
series: [{
name: 'bar',
type: 'bar',
stack: 'one',
cursor: 'move',
data: data1
}, {
name: 'bar3',
xAxisIndex: 1,
yAxisIndex: 1,
type: 'bar',
stack: 'two',
data: data3
}]
};
var chart = testHelper.create(echarts, 'main1', {
title: [
'Check containLabel'
],
option: option,
info: {grid: option.grid},
});
var rotate = 0;
chart && next();
function next() {
var nextInterval = rotate % 90 === 0 ? 2000: 70;
rotate = (rotate + 1) % 90;
setTimeout(function () {
chart.setOption({
xAxis: [
{id: 'x0', axisLabel: {rotate: rotate}},
{id: 'x1', axisLabel: {rotate: rotate}}
],
yAxis: [
{id: 'y0', axisLabel: {rotate: rotate}},
{id: 'y1', axisLabel: {rotate: rotate}}
]
});
next();
}, nextInterval);
}
});
</script>
</body>
</html>
\ No newline at end of file
...@@ -38,22 +38,6 @@ ...@@ -38,22 +38,6 @@
require([ require([
'echarts' 'echarts'
// 'echarts/chart/line',
// 'echarts/chart/bar',
// 'echarts/chart/pie',
// 'echarts/chart/scatter',
// 'echarts/chart/map',
// 'echarts/chart/parallel',
// 'echarts/chart/radar',
// 'echarts/component/grid',
// 'echarts/component/polar',
// 'echarts/component/geo',
// 'echarts/component/singleAxis',
// 'echarts/component/legend',
// 'echarts/component/tooltip',
// 'echarts/component/toolbox',
// 'echarts/component/visualMap',
// 'echarts/component/dataZoom'
], function (echarts) { ], function (echarts) {
option = { option = {
......
此差异已折叠。
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<script src="lib/esl.js"></script> <script src="lib/esl.js"></script>
<script src="lib/config.js"></script> <script src="lib/config.js"></script>
<script src="lib/facePrint.js"></script> <script src="lib/facePrint.js"></script>
<script src="lib/testHelper.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="lib/reset.css" /> <link rel="stylesheet" href="lib/reset.css" />
</head> </head>
...@@ -18,19 +19,14 @@ ...@@ -18,19 +19,14 @@
font-size: 14px; font-size: 14px;
margin: 0; margin: 0;
} }
.chart {
height: 350px;
}
</style> </style>
<h1>xAxis: {showMinLabel: null, showMaxLabel: null (auto)}. The last x label should not be displayed (overlap).</h1>
<div class="chart" id="chart-1"></div>
<h1>xAxis: {showMinLabel: null, showMaxLabel: null (auto)}. The last x label shoule be displayed (not overlap).</h1>
<div class="chart" id="chart0"></div>
<h1>xAxis: {showMinLabel: true, showMaxLabel: true}, yAxis: {showMaxLabel: false}. The last x label should be displayed. 100 on y should not be displayed.</h1> <div class="chart" id="chart-1"></div>
<div class="chart" id="chart0"></div>
<div class="chart" id="chart1"></div> <div class="chart" id="chart1"></div>
<div class="chart" id="chart2"></div>
...@@ -46,26 +42,12 @@ ...@@ -46,26 +42,12 @@
require([ require([
'data/rainfall.json', 'data/rainfall.json',
'echarts' 'echarts'
// 'echarts/chart/line',
// 'echarts/component/legend',
// 'echarts/component/grid',
// 'echarts/component/tooltip',
// 'echarts/component/title',
// 'echarts/component/dataZoom',
// 'echarts/scale/Time'
], function (rainfallData, echarts) { ], function (rainfallData, echarts) {
var chart = echarts.init(document.getElementById('chart-1'), null, { var option = {
});
chart.setOption({
tooltip : { tooltip : {
trigger: 'axis' trigger: 'axis'
}, },
grid: {
bottom: 150
},
dataZoom: { dataZoom: {
show: true, show: true,
realtime: true, realtime: true,
...@@ -99,6 +81,15 @@ ...@@ -99,6 +81,15 @@
}) })
} }
] ]
};
var chart = testHelper.create(echarts, 'chart-1', {
title: [
'The last x label should not be displayed (overlap).'
],
option: option,
info: option.xAxis,
infoKey: 'xAxis'
}); });
}) })
...@@ -116,20 +107,13 @@ ...@@ -116,20 +107,13 @@
require([ require([
'data/rainfall.json', 'data/rainfall.json',
'echarts' 'echarts'
// 'echarts/chart/line',
// 'echarts/component/legend',
// 'echarts/component/grid',
// 'echarts/component/tooltip',
// 'echarts/component/title',
// 'echarts/component/dataZoom',
// 'echarts/scale/Time'
], function (rainfallData, echarts) { ], function (rainfallData, echarts) {
var chart = echarts.init(document.getElementById('chart0'), null, { var chart = echarts.init(document.getElementById('chart0'), null, {
}); });
chart.setOption({ var option = {
tooltip : { tooltip : {
trigger: 'axis' trigger: 'axis'
}, },
...@@ -170,6 +154,15 @@ ...@@ -170,6 +154,15 @@
}) })
} }
] ]
};
var chart = testHelper.create(echarts, 'chart0', {
title: [
'The last x label shoule be displayed (not overlap).'
],
option: option,
info: option.xAxis,
infoKey: 'xAxis'
}); });
}) })
...@@ -188,26 +181,16 @@ ...@@ -188,26 +181,16 @@
require([ require([
'data/rainfall.json', 'data/rainfall.json',
'echarts' 'echarts'
// 'echarts/chart/line',
// 'echarts/component/legend',
// 'echarts/component/grid',
// 'echarts/component/tooltip',
// 'echarts/component/title',
// 'echarts/component/dataZoom',
// 'echarts/scale/Time'
], function (rainfallData, echarts) { ], function (rainfallData, echarts) {
var chart = echarts.init(document.getElementById('chart1'), null, { var chart = echarts.init(document.getElementById('chart1'), null, {
}); });
chart.setOption({ var option = {
tooltip : { tooltip : {
trigger: 'axis' trigger: 'axis'
}, },
grid: {
bottom: 150
},
dataZoom: { dataZoom: {
show: true, show: true,
realtime: true, realtime: true,
...@@ -249,6 +232,17 @@ ...@@ -249,6 +232,17 @@
}) })
} }
] ]
};
var chart = testHelper.create(echarts, 'chart1', {
title: [
'The last x label should be displayed. The top tick on y should not be displayed.'
],
option: option,
info: {
yAxis: option.yAxis,
xAxis: option.xAxis
}
}); });
}) })
...@@ -259,5 +253,89 @@ ...@@ -259,5 +253,89 @@
<script>
require([
'data/rainfall.json',
'echarts'
], function (rainfallData, echarts) {
var chart = echarts.init(document.getElementById('chart1'), null, {
});
var option = {
tooltip: {
trigger: 'axis'
},
dataZoom: {
show: true,
realtime: true,
startValue: '2009-09-20 12:00',
end: 100
},
xAxis: {
axisTick: {
alignWithLabel: true
},
axisLabel: {
showMaxLabel: true,
showMinLabel: true,
formatter: function (value) {
return echarts.format.formatTime('yyyy-MM-dd hh:mm:ss', value);
}
},
data: rainfallData.flow.map(function (val, idx) {
return rainfallData.category[idx];
})
},
yAxis: {
name: '流量(m^3/s)',
axisLabel: {
inside: true,
showMaxLabel: false,
formatter: '{value}\n'
}
},
series: [
{
name: '流量',
type: 'line',
symbol: 'none',
itemStyle: {normal: {areaStyle: {type: 'default'}}},
data: rainfallData.flow.map(function (val, idx) {
return val;
})
}
]
};
var chart = testHelper.create(echarts, 'chart2', {
title: [
'category xAxis:The min and max x label should be displayed.'
],
option: option,
info: {
axisLabel: option.xAxis.axisLabel,
axisTick: option.xAxis.axisTick
},
infoKey: 'xAxis'
});
})
</script>
</body> </body>
</html> </html>
\ No newline at end of file
...@@ -174,6 +174,9 @@ ...@@ -174,6 +174,9 @@
// }, // },
axisLine: { axisLine: {
onZero: true onZero: true
// lineStyle: {
// width: 5
// }
}, },
splitLine: { splitLine: {
show: true show: true
...@@ -187,6 +190,11 @@ ...@@ -187,6 +190,11 @@
// axisLabel: { // axisLabel: {
// show: false // show: false
// }, // },
// axisLine: {
// lineStyle: {
// width: 5
// }
// },
axisTick: { axisTick: {
show: false show: false
}, },
......
...@@ -49,8 +49,6 @@ ...@@ -49,8 +49,6 @@
xAxisData.push('类目' + i); xAxisData.push('类目' + i);
} }
if (i < 5 && i > 1) { if (i < 5 && i > 1) {
data1.push(0); data1.push(0);
} }
...@@ -80,25 +78,27 @@ ...@@ -80,25 +78,27 @@
}; };
chart.setOption({ chart.setOption({
title: { title: {
text: '折线图{a|asdf}Step line', text: 'tick 14 and 20 should be red (has textStyle)'
subtext: 'subtitle',
backgroundColor: '#ee99aa',
borderRadius: 5,
padding: 10,
textStyle: {
rich: {
a: {
color: '#338844',
fontSize: 30,
borderColor: '#119955',
borderWidth: 3,
backgroundColor: '#445566'
}
}
}
}, },
// title: {
// text: '折线图{a|asdf}Step line',
// subtext: 'subtitle',
// backgroundColor: '#ee99aa',
// borderRadius: 5,
// padding: 10,
// textStyle: {
// rich: {
// a: {
// color: '#338844',
// fontSize: 30,
// borderColor: '#119955',
// borderWidth: 3,
// backgroundColor: '#445566'
// }
// }
// }
// },
legend: { legend: {
data: ['line', 'line2', 'line3'] data: ['line', 'line2', 'line3']
...@@ -122,8 +122,8 @@ ...@@ -122,8 +122,8 @@
show: false show: false
}, },
axisLabel: { axisLabel: {
showMaxLabel: true, // showMaxLabel: true,
showMinLabel: true // showMinLabel: true
} }
}, },
grid: { grid: {
...@@ -140,11 +140,17 @@ ...@@ -140,11 +140,17 @@
show: true show: true
} }
}, },
dataZoom: { dataZoom: [{
type: 'inside', type: 'inside',
start: 10, // start: 10,
end: 30 // end: 30
}, startValue: 11,
endValue: 85
}, {
type: 'slider',
startValue: 11,
endValue: 85
}],
// animation: false, // animation: false,
series: [null, // 用于测试 option 中含有null的情况。 series: [null, // 用于测试 option 中含有null的情况。
{ {
......
...@@ -32,14 +32,9 @@ ...@@ -32,14 +32,9 @@
require([ require([
'echarts' 'echarts'
// 'zrender/core/util',
// 'echarts/chart/bar',
// 'echarts/component/legend',
// 'echarts/component/grid',
// 'echarts/component/tooltip',
// 'echarts/component/timeline'
], function (echarts) { ], function (echarts) {
var zrUtil = echarts.util; var zrUtil = echarts.util;
makeChart({ makeChart({
timeline: { timeline: {
label: { label: {
...@@ -63,7 +58,8 @@ ...@@ -63,7 +58,8 @@
symbolRotate: 30 symbolRotate: 30
} }
}); });
makeChart({timeline: {inverse: true, controlStyle: {position: 'right'}}});
makeChart({timeline: {inverse: true, controlStyle: {position: 'right'}}, width: 400});
makeChart({timeline: {orient: 'vertical', x: 0, y: 10, width: 55, height: '80%'}}); makeChart({timeline: {orient: 'vertical', x: 0, y: 10, width: 55, height: '80%'}});
makeChart({timeline: {orient: 'vertical', inverse: true, rewind: true, x: 0, y: 10, width: 55, height: '80%'}}); makeChart({timeline: {orient: 'vertical', inverse: true, rewind: true, x: 0, y: 10, width: 55, height: '80%'}});
...@@ -118,7 +114,11 @@ ...@@ -118,7 +114,11 @@
var containerEl = document.getElementById('main'); var containerEl = document.getElementById('main');
var el = document.createElement('div'); var el = document.createElement('div');
el.className = 'block'; el.className = 'block';
el.innerHTML = '<div class="ec"></div><label>' var widthString = '';
if (opt.width != null) {
widthString = ' style="width:' + opt.width + 'px" ';
}
el.innerHTML = '<div class="ec" ' + widthString + '></div><label>'
+ encodeHTML(JSON.stringify(opt)) + '</label>'; + encodeHTML(JSON.stringify(opt)) + '</label>';
containerEl.appendChild(el); containerEl.appendChild(el);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册