mirror of https://github.com/grafana/grafana
Adding support for dashed lines using jquery.flot.dashes.jspull/7760/merge
parent
9e13c93379
commit
1a3bc60e69
@ -0,0 +1,236 @@ |
|||||||
|
/* |
||||||
|
* jQuery.flot.dashes |
||||||
|
* |
||||||
|
* options = { |
||||||
|
* series: { |
||||||
|
* dashes: { |
||||||
|
* |
||||||
|
* // show
|
||||||
|
* // default: false
|
||||||
|
* // Whether to show dashes for the series.
|
||||||
|
* show: <boolean>, |
||||||
|
* |
||||||
|
* // lineWidth
|
||||||
|
* // default: 2
|
||||||
|
* // The width of the dashed line in pixels.
|
||||||
|
* lineWidth: <number>, |
||||||
|
* |
||||||
|
* // dashLength
|
||||||
|
* // default: 10
|
||||||
|
* // Controls the length of the individual dashes and the amount of
|
||||||
|
* // space between them.
|
||||||
|
* // If this is a number, the dashes and spaces will have that length.
|
||||||
|
* // If this is an array, it is read as [ dashLength, spaceLength ]
|
||||||
|
* dashLength: <number> or <array[2]> |
||||||
|
* } |
||||||
|
* } |
||||||
|
* } |
||||||
|
*/ |
||||||
|
(function($){ |
||||||
|
|
||||||
|
function init(plot) { |
||||||
|
|
||||||
|
plot.hooks.processDatapoints.push(function(plot, series, datapoints) { |
||||||
|
|
||||||
|
if (!series.dashes.show) return; |
||||||
|
|
||||||
|
plot.hooks.draw.push(function(plot, ctx) { |
||||||
|
|
||||||
|
var plotOffset = plot.getPlotOffset(), |
||||||
|
axisx = series.xaxis, |
||||||
|
axisy = series.yaxis; |
||||||
|
|
||||||
|
function plotDashes(xoffset, yoffset) { |
||||||
|
|
||||||
|
var points = datapoints.points, |
||||||
|
ps = datapoints.pointsize, |
||||||
|
prevx = null, |
||||||
|
prevy = null, |
||||||
|
dashRemainder = 0, |
||||||
|
dashOn = true, |
||||||
|
dashOnLength, |
||||||
|
dashOffLength; |
||||||
|
|
||||||
|
if (series.dashes.dashLength[0]) { |
||||||
|
dashOnLength = series.dashes.dashLength[0]; |
||||||
|
if (series.dashes.dashLength[1]) { |
||||||
|
dashOffLength = series.dashes.dashLength[1]; |
||||||
|
} else { |
||||||
|
dashOffLength = dashOnLength; |
||||||
|
} |
||||||
|
} else { |
||||||
|
dashOffLength = dashOnLength = series.dashes.dashLength; |
||||||
|
} |
||||||
|
|
||||||
|
ctx.beginPath(); |
||||||
|
|
||||||
|
for (var i = ps; i < points.length; i += ps) { |
||||||
|
|
||||||
|
var x1 = points[i - ps], |
||||||
|
y1 = points[i - ps + 1], |
||||||
|
x2 = points[i], |
||||||
|
y2 = points[i + 1]; |
||||||
|
|
||||||
|
if (x1 == null || x2 == null) continue; |
||||||
|
|
||||||
|
// clip with ymin
|
||||||
|
if (y1 <= y2 && y1 < axisy.min) { |
||||||
|
if (y2 < axisy.min) continue; // line segment is outside
|
||||||
|
// compute new intersection point
|
||||||
|
x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; |
||||||
|
y1 = axisy.min; |
||||||
|
} else if (y2 <= y1 && y2 < axisy.min) { |
||||||
|
if (y1 < axisy.min) continue; |
||||||
|
x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; |
||||||
|
y2 = axisy.min; |
||||||
|
} |
||||||
|
|
||||||
|
// clip with ymax
|
||||||
|
if (y1 >= y2 && y1 > axisy.max) { |
||||||
|
if (y2 > axisy.max) continue; |
||||||
|
x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; |
||||||
|
y1 = axisy.max; |
||||||
|
} else if (y2 >= y1 && y2 > axisy.max) { |
||||||
|
if (y1 > axisy.max) continue; |
||||||
|
x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; |
||||||
|
y2 = axisy.max; |
||||||
|
} |
||||||
|
|
||||||
|
// clip with xmin
|
||||||
|
if (x1 <= x2 && x1 < axisx.min) { |
||||||
|
if (x2 < axisx.min) continue; |
||||||
|
y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; |
||||||
|
x1 = axisx.min; |
||||||
|
} else if (x2 <= x1 && x2 < axisx.min) { |
||||||
|
if (x1 < axisx.min) continue; |
||||||
|
y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; |
||||||
|
x2 = axisx.min; |
||||||
|
} |
||||||
|
|
||||||
|
// clip with xmax
|
||||||
|
if (x1 >= x2 && x1 > axisx.max) { |
||||||
|
if (x2 > axisx.max) continue; |
||||||
|
y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; |
||||||
|
x1 = axisx.max; |
||||||
|
} else if (x2 >= x1 && x2 > axisx.max) { |
||||||
|
if (x1 > axisx.max) continue; |
||||||
|
y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; |
||||||
|
x2 = axisx.max; |
||||||
|
} |
||||||
|
|
||||||
|
if (x1 != prevx || y1 != prevy) { |
||||||
|
ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset); |
||||||
|
} |
||||||
|
|
||||||
|
var ax1 = axisx.p2c(x1) + xoffset, |
||||||
|
ay1 = axisy.p2c(y1) + yoffset, |
||||||
|
ax2 = axisx.p2c(x2) + xoffset, |
||||||
|
ay2 = axisy.p2c(y2) + yoffset, |
||||||
|
dashOffset; |
||||||
|
|
||||||
|
function lineSegmentOffset(segmentLength) { |
||||||
|
|
||||||
|
var c = Math.sqrt(Math.pow(ax2 - ax1, 2) + Math.pow(ay2 - ay1, 2)); |
||||||
|
|
||||||
|
if (c <= segmentLength) { |
||||||
|
return { |
||||||
|
deltaX: ax2 - ax1, |
||||||
|
deltaY: ay2 - ay1, |
||||||
|
distance: c, |
||||||
|
remainder: segmentLength - c |
||||||
|
} |
||||||
|
} else { |
||||||
|
var xsign = ax2 > ax1 ? 1 : -1, |
||||||
|
ysign = ay2 > ay1 ? 1 : -1; |
||||||
|
return { |
||||||
|
deltaX: xsign * Math.sqrt(Math.pow(segmentLength, 2) / (1 + Math.pow((ay2 - ay1)/(ax2 - ax1), 2))), |
||||||
|
deltaY: ysign * Math.sqrt(Math.pow(segmentLength, 2) - Math.pow(segmentLength, 2) / (1 + Math.pow((ay2 - ay1)/(ax2 - ax1), 2))), |
||||||
|
distance: segmentLength, |
||||||
|
remainder: 0 |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
||||||
|
//-end lineSegmentOffset
|
||||||
|
|
||||||
|
do { |
||||||
|
|
||||||
|
dashOffset = lineSegmentOffset( |
||||||
|
dashRemainder > 0 ? dashRemainder : |
||||||
|
dashOn ? dashOnLength : dashOffLength); |
||||||
|
|
||||||
|
if (dashOffset.deltaX != 0 || dashOffset.deltaY != 0) { |
||||||
|
if (dashOn) { |
||||||
|
ctx.lineTo(ax1 + dashOffset.deltaX, ay1 + dashOffset.deltaY); |
||||||
|
} else { |
||||||
|
ctx.moveTo(ax1 + dashOffset.deltaX, ay1 + dashOffset.deltaY); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
dashOn = !dashOn; |
||||||
|
dashRemainder = dashOffset.remainder; |
||||||
|
ax1 += dashOffset.deltaX; |
||||||
|
ay1 += dashOffset.deltaY; |
||||||
|
|
||||||
|
} while (dashOffset.distance > 0); |
||||||
|
|
||||||
|
prevx = x2; |
||||||
|
prevy = y2; |
||||||
|
} |
||||||
|
|
||||||
|
ctx.stroke(); |
||||||
|
} |
||||||
|
//-end plotDashes
|
||||||
|
|
||||||
|
ctx.save(); |
||||||
|
ctx.translate(plotOffset.left, plotOffset.top); |
||||||
|
ctx.lineJoin = 'round'; |
||||||
|
|
||||||
|
var lw = series.dashes.lineWidth, |
||||||
|
sw = series.shadowSize; |
||||||
|
|
||||||
|
// FIXME: consider another form of shadow when filling is turned on
|
||||||
|
if (lw > 0 && sw > 0) { |
||||||
|
// draw shadow as a thick and thin line with transparency
|
||||||
|
ctx.lineWidth = sw; |
||||||
|
ctx.strokeStyle = "rgba(0,0,0,0.1)"; |
||||||
|
// position shadow at angle from the mid of line
|
||||||
|
var angle = Math.PI/18; |
||||||
|
plotDashes(Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2)); |
||||||
|
ctx.lineWidth = sw/2; |
||||||
|
plotDashes(Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4)); |
||||||
|
} |
||||||
|
|
||||||
|
ctx.lineWidth = lw; |
||||||
|
ctx.strokeStyle = series.color; |
||||||
|
|
||||||
|
if (lw > 0) { |
||||||
|
plotDashes(0, 0); |
||||||
|
} |
||||||
|
|
||||||
|
ctx.restore(); |
||||||
|
|
||||||
|
}); |
||||||
|
//-end draw hook
|
||||||
|
|
||||||
|
}); |
||||||
|
//-end processDatapoints hook
|
||||||
|
|
||||||
|
} |
||||||
|
//-end init
|
||||||
|
|
||||||
|
$.plot.plugins.push({ |
||||||
|
init: init, |
||||||
|
options: { |
||||||
|
series: { |
||||||
|
dashes: { |
||||||
|
show: false, |
||||||
|
lineWidth: 2, |
||||||
|
dashLength: 10 |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
name: 'dashes', |
||||||
|
version: '0.1' |
||||||
|
}); |
||||||
|
|
||||||
|
})(jQuery) |
||||||
Loading…
Reference in new issue