Skip to content

Commit

Permalink
Optimize line smooth, add smoothMonotone configuration to keep monoto…
Browse files Browse the repository at this point in the history
…ne one on axis after smoothed. Fix #2612
  • Loading branch information
pissang committed Feb 19, 2016
1 parent 50eb1da commit eb71c3d
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 21 deletions.
1 change: 1 addition & 0 deletions src/chart/line/LineSeries.js
Expand Up @@ -66,6 +66,7 @@ define(function(require) {
// areaStyle: {
// },
// smooth: false,
// smoothMonotone: null,
// 拐点图形类型
symbol: 'emptyCircle',
// 拐点图形大小
Expand Down
13 changes: 9 additions & 4 deletions src/chart/line/LineView.js
Expand Up @@ -294,10 +294,12 @@ define(function(require) {

var smooth = seriesModel.get('smooth');
smooth = getSmooth(seriesModel.get('smooth'));
polyline.shape.smooth = smooth;
polyline.setShape({
smooth: smooth,
smoothMonotone: seriesModel.get('smoothMonotone')
});

if (polygon) {
var polygonShape = polygon.shape;
var stackedOn = data.stackedOn;
var stackedOnSmooth = 0;

Expand All @@ -309,14 +311,17 @@ define(function(require) {
lineJoin: 'bevel'
}
));
polygonShape.smooth = smooth;

if (stackedOn) {
var stackedOnSeries = stackedOn.hostModel;
stackedOnSmooth = getSmooth(stackedOnSeries.get('smooth'));
}

polygonShape.stackedOnSmooth = stackedOnSmooth;
polygon.setShape({
smooth: smooth,
stackedOnSmooth: stackedOnSmooth,
smoothMonotone: seriesModel.get('smoothMonotone')
});
}

this._data = data;
Expand Down
61 changes: 44 additions & 17 deletions src/chart/line/poly.js
Expand Up @@ -4,8 +4,6 @@ define(function (require) {
var Path = require('zrender/graphic/Path');
var vec2 = require('zrender/core/vector');

var mathMin = Math.min;
var mathMax = Math.max;
var vec2Min = vec2.min;
var vec2Max = vec2.max;

Expand All @@ -18,13 +16,13 @@ define(function (require) {
var cp1 = [];

function drawSegment(
ctx, points, start, allLen, segLen,
dir, smoothMin, smoothMax, smooth
ctx, points, start, stop, len,
dir, smoothMin, smoothMax, smooth, smoothMonotone
) {
var idx = start;
for (var k = 0; k < segLen; k++) {
for (var k = 0; k < len; k++) {
var p = points[idx];
if (idx >= allLen || idx < 0 || isNaN(p[0]) || isNaN(p[1])) {
if (idx >= stop || idx < 0 || isNaN(p[0]) || isNaN(p[1])) {
break;
}

Expand All @@ -36,23 +34,40 @@ define(function (require) {
if (smooth > 0) {
var prevIdx = idx - dir;
var nextIdx = idx + dir;

var ratioNextSeg = 0.5;
var prevP = points[prevIdx];
var nextP = points[nextIdx];
// Last point
if ((dir > 0 && idx === allLen - 1)
|| (dir <= 0 && idx === 0)
if ((dir > 0 && (idx === len - 1 || isNaN(nextP[0]) || isNaN(nextP[1])))
|| (dir <= 0 && (idx === 0 || isNaN(nextP[0]) || isNaN(nextP[1])))
) {
v2Copy(cp1, p);
}
else {
var prevP = points[prevIdx];
var nextP = points[nextIdx];
// If next data is null
if (isNaN(nextP[0]) || isNaN(nextP[1])) {
nextP = p;
}

vec2.sub(v, nextP, prevP);

scaleAndAdd(cp1, p, v, -smooth / 2);
var lenPrevSeg;
var lenNextSeg;
if (smoothMonotone === 'x' || smoothMonotone === 'y') {
var dim = smoothMonotone === 'x' ? 0 : 1;
lenPrevSeg = Math.abs(p[dim] - prevP[dim]);
lenNextSeg = Math.abs(p[dim] - nextP[dim]);
}
else {
lenPrevSeg = vec2.dist(p, prevP);
lenNextSeg = vec2.dist(p, nextP);
}

// Use ratio of seg length
ratioNextSeg = lenNextSeg / (lenNextSeg + lenPrevSeg);

scaleAndAdd(cp1, p, v, -smooth * (1 - ratioNextSeg));
}
// Smooth constraint
vec2Min(cp0, cp0, smoothMax);
Expand All @@ -66,7 +81,7 @@ define(function (require) {
p[0], p[1]
);
// cp0 of next segment
scaleAndAdd(cp0, p, v, smooth / 2);
scaleAndAdd(cp0, p, v, smooth * ratioNextSeg);
}
else {
ctx.lineTo(p[0], p[1]);
Expand Down Expand Up @@ -108,7 +123,9 @@ define(function (require) {

smooth: 0,

smoothConstraint: true
smoothConstraint: true,

smoothMonotone: null
},

style: {
Expand All @@ -128,7 +145,8 @@ define(function (require) {
while (i < len) {
i += drawSegment(
ctx, points, i, len, len,
1, result.min, result.max, shape.smooth
1, result.min, result.max, shape.smooth,
shape.smoothMonotone
) + 1;
}
}
Expand All @@ -140,11 +158,17 @@ define(function (require) {

shape: {
points: [],

// Offset between stacked base points and points
stackedOnPoints: [],

smooth: 0,

stackedOnSmooth: 0,
smoothConstraint: true

smoothConstraint: true,

smoothMonotone: null
},

buildPath: function (ctx, shape) {
Expand All @@ -153,16 +177,19 @@ define(function (require) {

var i = 0;
var len = points.length;
var smoothMonotone = shape.smoothMonotone;
var bbox = getBoundingBox(points, shape.smoothConstraint);
var stackedOnBBox = getBoundingBox(stackedOnPoints, shape.smoothConstraint);
while (i < len) {
var k = drawSegment(
ctx, points, i, len, len,
1, bbox.min, bbox.max, shape.smooth
1, bbox.min, bbox.max, shape.smooth,
smoothMonotone
);
drawSegment(
ctx, stackedOnPoints, i + k - 1, len, k,
-1, stackedOnBBox.min, stackedOnBBox.max, shape.stackedOnSmooth
-1, stackedOnBBox.min, stackedOnBBox.max, shape.stackedOnSmooth,
smoothMonotone
);
i += k + 1;

Expand Down

0 comments on commit eb71c3d

Please sign in to comment.