src/chart/line/poly.js
function drawNonMono(
    ctx, points, start, segLen, allLen,
    dir, smoothMin, smoothMax, smooth, smoothMonotone, connectNulls
) {
    var prevIdx = 0;
    var idx = start;
    for (var k = 0; k < segLen; k++) {
        var p = points[idx];
        if (idx >= allLen || idx < 0) {
            break;
        }
        if (isPointNull(p)) {
            if (connectNulls) {
                idx += dir;
                continue;
            }
            break;
        }

        if (idx === start) {
            ctx[dir > 0 ? 'moveTo' : 'lineTo'](p[0], p[1]);
            v2Copy(cp0, p);
        }
        else {
            if (smooth > 0) {
                var nextIdx = idx + dir;
                var nextP = points[nextIdx];
                if (connectNulls) {
                    // Find next point not null
                    while (nextP && isPointNull(points[nextIdx])) {
                        nextIdx += dir;
                        nextP = points[nextIdx];
                    }
                }

                var ratioNextSeg = 0.5;
                var prevP = points[prevIdx];
                var nextP = points[nextIdx];
                // Last point
                if (!nextP || isPointNull(nextP)) {
                    v2Copy(cp1, p);
                }
                else {
                    // If next data is null in not connect case
                    if (isPointNull(nextP) && !connectNulls) {
                        nextP = p;
                    }

                    vec2.sub(v, nextP, prevP);

                    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);
                vec2Max(cp0, cp0, smoothMin);
                vec2Min(cp1, cp1, smoothMax);
                vec2Max(cp1, cp1, smoothMin);

                ctx.bezierCurveTo(
                    cp0[0], cp0[1],
                    cp1[0], cp1[1],
                    p[0], p[1]
                );
                // cp0 of next segment
                scaleAndAdd(cp0, p, v, smooth * ratioNextSeg);
            }
            else {
                ctx.lineTo(p[0], p[1]);
            }
        }

        prevIdx = idx;
        idx += dir;
    }

    return k;
}
function drawNonMono(
    ctx, points, start, segLen, allLen,
    dir, smoothMin, smoothMax, smooth, smoothMonotone, connectNulls
) {
    var prevIdx = 0;
    var idx = start;
    for (var k = 0; k < segLen; k++) {
        var p = points[idx];
        if (idx >= allLen || idx < 0) {
            break;
        }
        if (isPointNull(p)) {
            if (connectNulls) {
                idx += dir;
                continue;
            }
            break;
        }

        if (idx === start) {
            ctx[dir > 0 ? 'moveTo' : 'lineTo'](p[0], p[1]);
            v2Copy(cp0, p);
        }
        else {
            if (smooth > 0) {
                var nextIdx = idx + dir;
                var nextP = points[nextIdx];
                if (connectNulls) {
                    // Find next point not null
                    while (nextP && isPointNull(points[nextIdx])) {
                        nextIdx += dir;
                        nextP = points[nextIdx];
                    }
                }

                var ratioNextSeg = 0.5;
                var prevP = points[prevIdx];
                var nextP = points[nextIdx];
                // Last point
                if (!nextP || isPointNull(nextP)) {
                    v2Copy(cp1, p);
                }
                else {
                    // If next data is null in not connect case
                    if (isPointNull(nextP) && !connectNulls) {
                        nextP = p;
                    }

                    vec2.sub(v, nextP, prevP);

                    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);
                vec2Max(cp0, cp0, smoothMin);
                vec2Min(cp1, cp1, smoothMax);
                vec2Max(cp1, cp1, smoothMin);

                ctx.bezierCurveTo(
                    cp0[0], cp0[1],
                    cp1[0], cp1[1],
                    p[0], p[1]
                );
                // cp0 of next segment
                scaleAndAdd(cp0, p, v, smooth * ratioNextSeg);
            }
            else {
                ctx.lineTo(p[0], p[1]);
            }
        }

        prevIdx = idx;
        idx += dir;
    }

    return k;
}
function drawNonMono ( ctx , points , start , segLen , allLen , dir , smoothMin , smoothMax , smooth , smoothMonotone , connectNulls ) { var prevIdx = 0 ; var idx = start ; for ( var k = 0 ; k < segLen ; k ++ ) { var p = points [ idx ] ; if ( idx >= allLen || idx < 0 ) { break ; } if ( isPointNull ( p ) ) { if ( connectNulls ) { idx += dir ; continue ; } break ; } if ( idx === start ) { ctx [ dir > 0 ? 'moveTo' : 'lineTo' ] ( p [ 0 ] , p [ 1 ] ) ; v2Copy ( cp0 , p ) ; } else { if ( smooth > 0 ) { var nextIdx = idx + dir ; var nextP = points [ nextIdx ] ; if ( connectNulls ) { // Find next point not null while ( nextP && isPointNull ( points [ nextIdx ] ) ) { nextIdx += dir ; nextP = points [ nextIdx ] ; } } var ratioNextSeg = 0.5 ; var prevP = points [ prevIdx ] ; var nextP = points [ nextIdx ] ; // Last point if ( ! nextP || isPointNull ( nextP ) ) { v2Copy ( cp1 , p ) ; } else { // If next data is null in not connect case if ( isPointNull ( nextP ) && ! connectNulls ) { nextP = p ; } vec2 . sub ( v , nextP , prevP ) ; 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 ) ; vec2Max ( cp0 , cp0 , smoothMin ) ; vec2Min ( cp1 , cp1 , smoothMax ) ; vec2Max ( cp1 , cp1 , smoothMin ) ; ctx . bezierCurveTo ( cp0 [ 0 ] , cp0 [ 1 ] , cp1 [ 0 ] , cp1 [ 1 ] , p [ 0 ] , p [ 1 ] ) ; // cp0 of next segment scaleAndAdd ( cp0 , p , v , smooth * ratioNextSeg ) ; } else { ctx . lineTo ( p [ 0 ] , p [ 1 ] ) ; } } prevIdx = idx ; idx += dir ; } return k ; }
Draw smoothed line in non-monotone, in may cause undesired curve in extreme
situations. This should be used when points are non-monotone neither in x or
y dimension.
Draw smoothed line in non - monotone in may cause undesired curve in extreme situations . This should be used when points are non - monotone neither in x or y dimension .