Skip to content

Commit

Permalink
(1) Some refactor about axisTick, axisLabel, splitLine, splitArea int…
Browse files Browse the repository at this point in the history
…erval 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.
  • Loading branch information
100pah committed Apr 13, 2018
1 parent a8ef183 commit 748f33e
Show file tree
Hide file tree
Showing 30 changed files with 2,001 additions and 631 deletions.
17 changes: 14 additions & 3 deletions src/chart/line/LineView.js
Original file line number Diff line number Diff line change
Expand Up @@ -605,15 +605,26 @@ export default ChartView.extend({
this._polygon = polygon;
return polygon;
},

/**
* @private
*/
_getSymbolIgnoreFunc: function (data, coordSys) {
var categoryAxis = coordSys.getAxesByScale('ordinal')[0];
// `getLabelInterval` is provided by echarts/component/axis
if (categoryAxis && categoryAxis.isLabelIgnored) {
return zrUtil.bind(categoryAxis.isLabelIgnored, categoryAxis);
if (!categoryAxis) {
return;
}

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));
};
},

/**
Expand Down
63 changes: 39 additions & 24 deletions src/component/axis/AngleAxisView.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ function getRadiusIdx(polar) {
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({

type: 'angleAxis',
Expand All @@ -38,18 +50,22 @@ export default AxisView.extend({
var angleAxis = angleAxisModel.axis;
var polar = angleAxis.polar;
var radiusExtent = polar.getRadiusAxis().getExtent();

var ticksAngles = angleAxis.getTicksCoords();
var labels = angleAxis.getViewLabels();

if (angleAxis.type !== 'category') {
// Remove the last tick which will overlap the first tick
ticksAngles.pop();
}
zrUtil.each(labels, function (labelItem) {
labelItem.coord = angleAxis.dataToCoord(labelItem.tickValue);
});

fixAngleOverlap(labels);
fixAngleOverlap(ticksAngles);

zrUtil.each(elementList, function (name) {
if (angleAxisModel.get(name +'.show')
&& (!angleAxis.scale.isBlank() || name === 'axisLine')
) {
this['_' + name](angleAxisModel, polar, ticksAngles, radiusExtent);
this['_' + name](angleAxisModel, polar, ticksAngles, radiusExtent, labels);
}
}, this);
},
Expand Down Expand Up @@ -84,9 +100,9 @@ export default AxisView.extend({
var tickLen = (tickModel.get('inside') ? -1 : 1) * tickModel.get('length');
var radius = radiusExtent[getRadiusIdx(polar)];

var lines = zrUtil.map(ticksAngles, function (tickAngle) {
var lines = zrUtil.map(ticksAngles, function (tickAngleItem) {
return new graphic.Line({
shape: getAxisLineShape(polar, [radius, radius + tickLen], tickAngle)
shape: getAxisLineShape(polar, [radius, radius + tickLen], tickAngleItem.coord)
});
});
this.group.add(graphic.mergePath(
Expand All @@ -104,24 +120,20 @@ export default AxisView.extend({
/**
* @private
*/
_axisLabel: function (angleAxisModel, polar, ticksAngles, radiusExtent) {
var axis = angleAxisModel.axis;

_axisLabel: function (angleAxisModel, polar, ticksAngles, radiusExtent, labels) {
var rawCategoryData = angleAxisModel.getCategories(true);

var commonLabelModel = angleAxisModel.getModel('axisLabel');
var labels = angleAxisModel.getFormattedLabels();

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
for (var i = 0; i < ticks.length; i++) {
zrUtil.each(labels, function (labelItem, idx) {
var labelModel = commonLabelModel;
var tickVal = ticks[i];
var tickValue = labelItem.tickValue;

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 cy = polar.cy;

Expand All @@ -130,8 +142,8 @@ export default AxisView.extend({
var labelTextVerticalAlign = Math.abs(p[1] - cy) / r < 0.3
? 'middle' : (p[1] > cy ? 'top' : 'bottom');

if (rawCategoryData && rawCategoryData[tickVal] && rawCategoryData[tickVal].textStyle) {
labelModel = new Model(rawCategoryData[tickVal].textStyle, commonLabelModel, commonLabelModel.ecModel);
if (rawCategoryData && rawCategoryData[tickValue] && rawCategoryData[tickValue].textStyle) {
labelModel = new Model(rawCategoryData[tickValue].textStyle, commonLabelModel, commonLabelModel.ecModel);
}

var textEl = new graphic.Text({silent: true});
Expand All @@ -140,11 +152,11 @@ export default AxisView.extend({
x: p[0],
y: p[1],
textFill: labelModel.getTextColor() || angleAxisModel.get('axisLine.lineStyle.color'),
text: labels[i],
text: labelItem.formattedLabel,
textAlign: labelTextAlign,
textVerticalAlign: labelTextVerticalAlign
});
}
}, this);
},

/**
Expand All @@ -164,7 +176,7 @@ export default AxisView.extend({
var colorIndex = (lineCount++) % lineColors.length;
splitLines[colorIndex] = splitLines[colorIndex] || [];
splitLines[colorIndex].push(new graphic.Line({
shape: getAxisLineShape(polar, radiusExtent, ticksAngles[i])
shape: getAxisLineShape(polar, radiusExtent, ticksAngles[i].coord)
}));
}

Expand All @@ -185,6 +197,9 @@ export default AxisView.extend({
* @private
*/
_splitArea: function (angleAxisModel, polar, ticksAngles, radiusExtent) {
if (!ticksAngles.length) {
return;
}

var splitAreaModel = angleAxisModel.getModel('splitArea');
var areaStyleModel = splitAreaModel.getModel('areaStyle');
Expand All @@ -196,7 +211,7 @@ export default AxisView.extend({
var splitAreas = [];

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 r1 = Math.max(radiusExtent[0], radiusExtent[1]);

Expand All @@ -212,12 +227,12 @@ export default AxisView.extend({
r0: r0,
r: r1,
startAngle: prevAngle,
endAngle: -ticksAngles[i] * RADIAN,
endAngle: -ticksAngles[i].coord * RADIAN,
clockwise: clockwise
},
silent: true
}));
prevAngle = -ticksAngles[i] * RADIAN;
prevAngle = -ticksAngles[i].coord * RADIAN;
}

// Simple optimization
Expand Down
110 changes: 23 additions & 87 deletions src/component/axis/AxisBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ function makeAxisEventDataBase(axisModel) {
* @param {string} [opt.axisName] default get from axisModel.
* @param {number} [opt.axisNameAvailableWidth]
* @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.nameTruncateMaxWidth]
*/
Expand Down Expand Up @@ -542,48 +540,6 @@ function isNameLocationCenter(nameLocation) {
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) {
var axis = axisModel.axis;

Expand All @@ -596,32 +552,16 @@ function buildAxisTick(axisBuilder, axisModel, opt) {
var lineStyleModel = tickModel.getModel('lineStyle');
var tickLen = tickModel.get('length');

var tickInterval = getInterval(tickModel, opt.labelInterval);
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 ticksCoords = axis.getTicksCoords();

var pt1 = [];
var pt2 = [];
var matrix = axisBuilder._transform;

var tickEls = [];

var ticksCnt = ticksCoords.length;
for (var i = 0; i < ticksCnt; i++) {
// Only ordinal scale support tick interval
if (ifIgnoreOnTick(
axis, i, tickInterval, ticksCnt,
showMinLabel, showMaxLabel
)) {
continue;
}

var tickCoord = ticksCoords[i];
for (var i = 0; i < ticksCoords.length; i++) {
var tickCoord = ticksCoords[i].coord;

pt1[0] = tickCoord;
pt1[1] = 0;
Expand All @@ -635,7 +575,7 @@ function buildAxisTick(axisBuilder, axisModel, opt) {
// Tick line, Not use group transform to have better line draw
var tickEl = new graphic.Line(graphic.subPixelOptimizeLine({
// Id for animation
anid: 'tick_' + ticks[i],
anid: 'tick_' + ticksCoords[i].tickValue,

shape: {
x1: pt1[0],
Expand Down Expand Up @@ -669,8 +609,7 @@ function buildAxisLabel(axisBuilder, axisModel, opt) {

var labelModel = axisModel.getModel('axisLabel');
var labelMargin = labelModel.get('margin');
var ticks = axis.scale.getTicks();
var labels = axisModel.getFormattedLabels();
var labels = axis.getViewLabels();

// Special label rotate.
var labelRotation = (
Expand All @@ -684,45 +623,38 @@ function buildAxisLabel(axisBuilder, axisModel, opt) {
var silent = isSilent(axisModel);
var triggerEvent = axisModel.get('triggerEvent');

var showMinLabel = axisModel.get('axisLabel.showMinLabel');
var showMaxLabel = axisModel.get('axisLabel.showMaxLabel');

each(ticks, function (tickVal, index) {
if (ifIgnoreOnTick(
axis, index, opt.labelInterval, ticks.length,
showMinLabel, showMaxLabel
)) {
return;
}
each(labels, function (labelItem, index) {
var tickValue = labelItem.tickValue;
var formattedLabel = labelItem.formattedLabel;
var rawLabel = labelItem.rawLabel;

var itemLabelModel = labelModel;
if (rawCategoryData && rawCategoryData[tickVal] && rawCategoryData[tickVal].textStyle) {
if (rawCategoryData && rawCategoryData[tickValue] && rawCategoryData[tickValue].textStyle) {
itemLabelModel = new Model(
rawCategoryData[tickVal].textStyle, labelModel, axisModel.ecModel
rawCategoryData[tickValue].textStyle, labelModel, axisModel.ecModel
);
}

var textColor = itemLabelModel.getTextColor()
|| axisModel.get('axisLine.lineStyle.color');

var tickCoord = axis.dataToCoord(tickVal);
var tickCoord = axis.dataToCoord(tickValue);
var pos = [
tickCoord,
opt.labelOffset + opt.labelDirection * labelMargin
];
var labelStr = axis.scale.getLabel(tickVal);

var textEl = new graphic.Text({
// Id for animation
anid: 'label_' + tickVal,
anid: 'label_' + tickValue,
position: pos,
rotation: labelLayout.rotation,
silent: silent,
z2: 10
});

graphic.setTextStyle(textEl.style, itemLabelModel, {
text: labels[index],
text: formattedLabel,
textAlign: itemLabelModel.getShallow('align', true)
|| labelLayout.textAlign,
textVerticalAlign: itemLabelModel.getShallow('verticalAlign', true)
Expand All @@ -733,11 +665,15 @@ function buildAxisLabel(axisBuilder, axisModel, opt) {
// (1) 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.
// (2) Compatible with previous version, which always returns labelStr.
// But in interval scale labelStr is like '223,445', which maked
// user repalce ','. So we modify it to return original val but remain
// (2) Compatible with previous version, which always use formatted label as
// input. But in interval scale the formatted label is like '223,445', which
// maked user repalce ','. So we modify it to return original val but remain
// 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
)
: textColor
Expand All @@ -747,7 +683,7 @@ function buildAxisLabel(axisBuilder, axisModel, opt) {
if (triggerEvent) {
textEl.eventData = makeAxisEventDataBase(axisModel);
textEl.eventData.targetType = 'axisLabel';
textEl.eventData.value = labelStr;
textEl.eventData.value = rawLabel;
}

// FIXME
Expand Down
Loading

0 comments on commit 748f33e

Please sign in to comment.