mirror of
https://github.com/chartjs/Chart.js.git
synced 2026-03-14 12:16:52 +01:00
178 lines
5.0 KiB
JavaScript
178 lines
5.0 KiB
JavaScript
"use strict";
|
|
|
|
module.exports = function(Chart) {
|
|
|
|
var helpers = Chart.helpers;
|
|
var globalDefaults = Chart.defaults.global;
|
|
|
|
Chart.defaults.global.elements.line = {
|
|
tension: 0.4,
|
|
backgroundColor: globalDefaults.defaultColor,
|
|
borderWidth: 3,
|
|
borderColor: globalDefaults.defaultColor,
|
|
borderCapStyle: 'butt',
|
|
borderDash: [],
|
|
borderDashOffset: 0.0,
|
|
borderJoinStyle: 'miter',
|
|
capBezierPoints: true,
|
|
fill: true // do we fill in the area between the line and its base axis
|
|
};
|
|
|
|
Chart.elements.Line = Chart.Element.extend({
|
|
draw: function() {
|
|
var me = this;
|
|
var vm = me._view;
|
|
var spanGaps = vm.spanGaps;
|
|
var scaleZero = vm.scaleZero;
|
|
var loop = me._loop;
|
|
|
|
var ctx = me._chart.ctx;
|
|
ctx.save();
|
|
|
|
// Helper function to draw a line to a point
|
|
function lineToPoint(previousPoint, point) {
|
|
var vm = point._view;
|
|
if (point._view.steppedLine === true) {
|
|
ctx.lineTo(point._view.x, previousPoint._view.y);
|
|
ctx.lineTo(point._view.x, point._view.y);
|
|
} else if (point._view.tension === 0) {
|
|
ctx.lineTo(vm.x, vm.y);
|
|
} else {
|
|
ctx.bezierCurveTo(
|
|
previousPoint._view.controlPointNextX,
|
|
previousPoint._view.controlPointNextY,
|
|
vm.controlPointPreviousX,
|
|
vm.controlPointPreviousY,
|
|
vm.x,
|
|
vm.y
|
|
);
|
|
}
|
|
}
|
|
|
|
var points = me._children.slice(); // clone array
|
|
var lastDrawnIndex = -1;
|
|
|
|
// If we are looping, adding the first point again
|
|
if (loop && points.length) {
|
|
points.push(points[0]);
|
|
}
|
|
|
|
// Fill Line
|
|
if (points.length && vm.fill) {
|
|
ctx.beginPath();
|
|
|
|
for (var index = 0; index < points.length; ++index) {
|
|
var current = points[index];
|
|
var previous = helpers.previousItem(points, index);
|
|
|
|
var currentVM = current._view;
|
|
|
|
// First point moves to it's starting position no matter what
|
|
if (index === 0) {
|
|
if (loop) {
|
|
ctx.moveTo(scaleZero.x, scaleZero.y);
|
|
} else {
|
|
ctx.moveTo(currentVM.x, scaleZero);
|
|
}
|
|
|
|
if (!currentVM.skip) {
|
|
lastDrawnIndex = index;
|
|
ctx.lineTo(currentVM.x, currentVM.y);
|
|
}
|
|
} else {
|
|
previous = lastDrawnIndex === -1 ? previous : points[lastDrawnIndex];
|
|
|
|
if (currentVM.skip) {
|
|
// Only do this if this is the first point that is skipped
|
|
if (!spanGaps && lastDrawnIndex === (index - 1)) {
|
|
if (loop) {
|
|
ctx.lineTo(scaleZero.x, scaleZero.y);
|
|
} else {
|
|
ctx.lineTo(previous._view.x, scaleZero);
|
|
}
|
|
}
|
|
} else {
|
|
if (lastDrawnIndex !== (index - 1)) {
|
|
// There was a gap and this is the first point after the gap. If we've never drawn a point, this is a special case.
|
|
// If the first data point is NaN, then there is no real gap to skip
|
|
if (spanGaps && lastDrawnIndex !== -1) {
|
|
// We are spanning the gap, so simple draw a line to this point
|
|
lineToPoint(previous, current)
|
|
} else {
|
|
if (loop) {
|
|
ctx.lineTo(currentVM.x, currentVM.y);
|
|
} else {
|
|
ctx.lineTo(currentVM.x, scaleZero);
|
|
ctx.lineTo(currentVM.x, currentVM.y);
|
|
}
|
|
}
|
|
} else {
|
|
// Line to next point
|
|
lineToPoint(previous, current);
|
|
}
|
|
lastDrawnIndex = index;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!loop) {
|
|
ctx.lineTo(points[points.length - 1]._view.x, scaleZero);
|
|
}
|
|
|
|
ctx.fillStyle = vm.backgroundColor || globalDefaults.defaultColor;
|
|
ctx.closePath();
|
|
ctx.fill();
|
|
}
|
|
|
|
// Stroke Line Options
|
|
var globalOptionLineElements = globalDefaults.elements.line;
|
|
ctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle;
|
|
|
|
// IE 9 and 10 do not support line dash
|
|
if (ctx.setLineDash) {
|
|
ctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash);
|
|
}
|
|
|
|
ctx.lineDashOffset = vm.borderDashOffset || globalOptionLineElements.borderDashOffset;
|
|
ctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle;
|
|
ctx.lineWidth = vm.borderWidth || globalOptionLineElements.borderWidth;
|
|
ctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor;
|
|
|
|
// Stroke Line
|
|
ctx.beginPath();
|
|
lastDrawnIndex = -1;
|
|
|
|
for (var index = 0; index < points.length; ++index) {
|
|
var current = points[index];
|
|
var previous = helpers.previousItem(points, index);
|
|
var currentVM = current._view;
|
|
|
|
// First point moves to it's starting position no matter what
|
|
if (index === 0) {
|
|
if (currentVM.skip) {
|
|
|
|
} else {
|
|
ctx.moveTo(currentVM.x, currentVM.y);
|
|
lastDrawnIndex = index;
|
|
}
|
|
} else {
|
|
previous = lastDrawnIndex === -1 ? previous : points[lastDrawnIndex];
|
|
|
|
if (!currentVM.skip) {
|
|
if (lastDrawnIndex !== (index - 1) && !spanGaps) {
|
|
// There was a gap and this is the first point after the gap
|
|
ctx.moveTo(currentVM.x, currentVM.y);
|
|
} else {
|
|
// Line to next point
|
|
lineToPoint(previous, current);
|
|
}
|
|
lastDrawnIndex = index;
|
|
}
|
|
}
|
|
}
|
|
|
|
ctx.stroke();
|
|
ctx.restore();
|
|
}
|
|
});
|
|
}; |