mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat(dashed lines): Implementing dashed lines
Adding support for dashed lines using jquery.flot.dashes.js
This commit is contained in:
parent
9e13c93379
commit
1a3bc60e69
@ -35,6 +35,7 @@ export default class TimeSeries {
|
|||||||
isOutsideRange: boolean;
|
isOutsideRange: boolean;
|
||||||
|
|
||||||
lines: any;
|
lines: any;
|
||||||
|
dashes: any;
|
||||||
bars: any;
|
bars: any;
|
||||||
points: any;
|
points: any;
|
||||||
yaxis: any;
|
yaxis: any;
|
||||||
@ -61,6 +62,9 @@ export default class TimeSeries {
|
|||||||
|
|
||||||
applySeriesOverrides(overrides) {
|
applySeriesOverrides(overrides) {
|
||||||
this.lines = {};
|
this.lines = {};
|
||||||
|
this.dashes = {
|
||||||
|
dashLength: []
|
||||||
|
};
|
||||||
this.points = {};
|
this.points = {};
|
||||||
this.bars = {};
|
this.bars = {};
|
||||||
this.yaxis = 1;
|
this.yaxis = 1;
|
||||||
@ -74,11 +78,20 @@ export default class TimeSeries {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (override.lines !== void 0) { this.lines.show = override.lines; }
|
if (override.lines !== void 0) { this.lines.show = override.lines; }
|
||||||
|
if (override.dashes !== void 0) {
|
||||||
|
this.dashes.show = override.dashes;
|
||||||
|
this.lines.lineWidth = 0;
|
||||||
|
}
|
||||||
if (override.points !== void 0) { this.points.show = override.points; }
|
if (override.points !== void 0) { this.points.show = override.points; }
|
||||||
if (override.bars !== void 0) { this.bars.show = override.bars; }
|
if (override.bars !== void 0) { this.bars.show = override.bars; }
|
||||||
if (override.fill !== void 0) { this.lines.fill = translateFillOption(override.fill); }
|
if (override.fill !== void 0) { this.lines.fill = translateFillOption(override.fill); }
|
||||||
if (override.stack !== void 0) { this.stack = override.stack; }
|
if (override.stack !== void 0) { this.stack = override.stack; }
|
||||||
if (override.linewidth !== void 0) { this.lines.lineWidth = override.linewidth; }
|
if (override.linewidth !== void 0) {
|
||||||
|
this.lines.lineWidth = override.linewidth;
|
||||||
|
this.dashes.lineWidth = override.linewidth;
|
||||||
|
}
|
||||||
|
if (override.dashLength !== void 0) { this.dashes.dashLength[0] = override.dashLength; }
|
||||||
|
if (override.spaceLength !== void 0) { this.dashes.dashLength[1] = override.spaceLength; }
|
||||||
if (override.nullPointMode !== void 0) { this.nullPointMode = override.nullPointMode; }
|
if (override.nullPointMode !== void 0) { this.nullPointMode = override.nullPointMode; }
|
||||||
if (override.pointradius !== void 0) { this.points.radius = override.pointradius; }
|
if (override.pointradius !== void 0) { this.points.radius = override.pointradius; }
|
||||||
if (override.steppedLine !== void 0) { this.lines.steps = override.steppedLine; }
|
if (override.steppedLine !== void 0) { this.lines.steps = override.steppedLine; }
|
||||||
|
@ -7,6 +7,7 @@ import 'jquery.flot.stack';
|
|||||||
import 'jquery.flot.stackpercent';
|
import 'jquery.flot.stackpercent';
|
||||||
import 'jquery.flot.fillbelow';
|
import 'jquery.flot.fillbelow';
|
||||||
import 'jquery.flot.crosshair';
|
import 'jquery.flot.crosshair';
|
||||||
|
import 'jquery.flot.dashes';
|
||||||
import './jquery.flot.events';
|
import './jquery.flot.events';
|
||||||
|
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
@ -215,6 +216,9 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv, popoverSrv) {
|
|||||||
// give space to alert editing
|
// give space to alert editing
|
||||||
thresholdManager.prepare(elem, data);
|
thresholdManager.prepare(elem, data);
|
||||||
|
|
||||||
|
// un-check dashes if lines are unchecked
|
||||||
|
panel.dashes = panel.lines ? panel.dashes : false;
|
||||||
|
|
||||||
var stack = panel.stack ? true : null;
|
var stack = panel.stack ? true : null;
|
||||||
|
|
||||||
// Populate element
|
// Populate element
|
||||||
@ -231,9 +235,14 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv, popoverSrv) {
|
|||||||
show: panel.lines,
|
show: panel.lines,
|
||||||
zero: false,
|
zero: false,
|
||||||
fill: translateFillOption(panel.fill),
|
fill: translateFillOption(panel.fill),
|
||||||
lineWidth: panel.linewidth,
|
lineWidth: panel.dashes ? 0 : panel.linewidth,
|
||||||
steps: panel.steppedLine
|
steps: panel.steppedLine
|
||||||
},
|
},
|
||||||
|
dashes: {
|
||||||
|
show: panel.dashes,
|
||||||
|
lineWidth: panel.linewidth,
|
||||||
|
dashLength: [panel.dashLength, panel.spaceLength]
|
||||||
|
},
|
||||||
bars: {
|
bars: {
|
||||||
show: panel.bars,
|
show: panel.bars,
|
||||||
fill: 1,
|
fill: 1,
|
||||||
|
@ -67,6 +67,12 @@ class GraphCtrl extends MetricsPanelCtrl {
|
|||||||
fill : 1,
|
fill : 1,
|
||||||
// line width in pixels
|
// line width in pixels
|
||||||
linewidth : 1,
|
linewidth : 1,
|
||||||
|
// show/hide dashed line
|
||||||
|
dashes : false,
|
||||||
|
// length of a dash
|
||||||
|
dashLength : 10,
|
||||||
|
// length of space between two dashes
|
||||||
|
spaceLength : 10,
|
||||||
// show hide points
|
// show hide points
|
||||||
points : false,
|
points : false,
|
||||||
// point radius in pixels
|
// point radius in pixels
|
||||||
|
@ -100,6 +100,9 @@ define([
|
|||||||
$scope.addOverrideOption('Null point mode', 'nullPointMode', ['connected', 'null', 'null as zero']);
|
$scope.addOverrideOption('Null point mode', 'nullPointMode', ['connected', 'null', 'null as zero']);
|
||||||
$scope.addOverrideOption('Fill below to', 'fillBelowTo', $scope.getSeriesNames());
|
$scope.addOverrideOption('Fill below to', 'fillBelowTo', $scope.getSeriesNames());
|
||||||
$scope.addOverrideOption('Staircase line', 'steppedLine', [true, false]);
|
$scope.addOverrideOption('Staircase line', 'steppedLine', [true, false]);
|
||||||
|
$scope.addOverrideOption('Dashes', 'dashes', [true, false]);
|
||||||
|
$scope.addOverrideOption('Dash Length', 'dashLength', [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]);
|
||||||
|
$scope.addOverrideOption('Dash Space', 'spaceLength', [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]);
|
||||||
$scope.addOverrideOption('Points', 'points', [true, false]);
|
$scope.addOverrideOption('Points', 'points', [true, false]);
|
||||||
$scope.addOverrideOption('Points Radius', 'pointradius', [1,2,3,4,5]);
|
$scope.addOverrideOption('Points Radius', 'pointradius', [1,2,3,4,5]);
|
||||||
$scope.addOverrideOption('Stack', 'stack', [true, false, 'A', 'B', 'C', 'D']);
|
$scope.addOverrideOption('Stack', 'stack', [true, false, 'A', 'B', 'C', 'D']);
|
||||||
|
@ -153,6 +153,20 @@ describe('grafanaGraph', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
graphScenario('dashed lines options', function(ctx) {
|
||||||
|
ctx.setup(function(ctrl) {
|
||||||
|
ctrl.panel.lines = true;
|
||||||
|
ctrl.panel.linewidth = 2;
|
||||||
|
ctrl.panel.dashes = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should configure dashed plot with correct options', function() {
|
||||||
|
expect(ctx.plotOptions.series.lines.show).to.be(true);
|
||||||
|
expect(ctx.plotOptions.series.dashes.lineWidth).to.be(2);
|
||||||
|
expect(ctx.plotOptions.series.dashes.show).to.be(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
graphScenario('should use timeStep for barWidth', function(ctx) {
|
graphScenario('should use timeStep for barWidth', function(ctx) {
|
||||||
ctx.setup(function(ctrl, data) {
|
ctx.setup(function(ctrl, data) {
|
||||||
ctrl.panel.bars = true;
|
ctrl.panel.bars = true;
|
||||||
|
@ -32,12 +32,28 @@
|
|||||||
<select class="gf-form-input" ng-model="ctrl.panel.fill" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10]" ng-change="ctrl.render()"></select>
|
<select class="gf-form-input" ng-model="ctrl.panel.fill" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10]" ng-change="ctrl.render()"></select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form" ng-show="ctrl.panel.lines">
|
<div class="gf-form" ng-show="(ctrl.panel.lines || ctrl.panel.dashes)">
|
||||||
<label class="gf-form-label width-8">Line Width</label>
|
<label class="gf-form-label width-8">Line Width</label>
|
||||||
<div class="gf-form-select-wrapper max-width-5">
|
<div class="gf-form-select-wrapper max-width-5">
|
||||||
<select class="gf-form-input" ng-model="ctrl.panel.linewidth" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10]" ng-change="ctrl.render()"></select>
|
<select class="gf-form-input" ng-model="ctrl.panel.linewidth" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10]" ng-change="ctrl.render()"></select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<gf-form-switch class="gf-form" ng-show="ctrl.panel.lines"
|
||||||
|
label="Dashes" label-class="width-8"
|
||||||
|
checked="ctrl.panel.dashes" on-change="ctrl.render()">
|
||||||
|
</gf-form-switch>
|
||||||
|
<div class="gf-form" ng-show="ctrl.panel.dashes">
|
||||||
|
<label class="gf-form-label width-8">Dash Length</label>
|
||||||
|
<div class="gf-form-select-wrapper max-width-5">
|
||||||
|
<select class="gf-form-input" ng-model="ctrl.panel.dashLength" ng-options="f for f in [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]" ng-change="ctrl.render()"></select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="gf-form" ng-show="ctrl.panel.dashes">
|
||||||
|
<label class="gf-form-label width-8">Dash Space</label>
|
||||||
|
<div class="gf-form-select-wrapper max-width-5">
|
||||||
|
<select class="gf-form-input" ng-model="ctrl.panel.spaceLength" ng-options="f for f in [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]" ng-change="ctrl.render()"></select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<gf-form-switch ng-show="ctrl.panel.lines" class="gf-form" label="Staircase" label-class="width-8" checked="ctrl.panel.steppedLine" on-change="ctrl.render()">
|
<gf-form-switch ng-show="ctrl.panel.lines" class="gf-form" label="Staircase" label-class="width-8" checked="ctrl.panel.steppedLine" on-change="ctrl.render()">
|
||||||
</gf-form-switch>
|
</gf-form-switch>
|
||||||
<div class="gf-form" ng-show="ctrl.panel.points">
|
<div class="gf-form" ng-show="ctrl.panel.points">
|
||||||
|
@ -31,7 +31,8 @@ System.config({
|
|||||||
"jquery.flot.crosshair": "vendor/flot/jquery.flot.crosshair",
|
"jquery.flot.crosshair": "vendor/flot/jquery.flot.crosshair",
|
||||||
"jquery.flot.fillbelow": "vendor/flot/jquery.flot.fillbelow",
|
"jquery.flot.fillbelow": "vendor/flot/jquery.flot.fillbelow",
|
||||||
"jquery.flot.gauge": "vendor/flot/jquery.flot.gauge",
|
"jquery.flot.gauge": "vendor/flot/jquery.flot.gauge",
|
||||||
"d3": "vendor/d3/d3.js"
|
"d3": "vendor/d3/d3.js",
|
||||||
|
"jquery.flot.dashes": "vendor/flot/jquery.flot.dashes"
|
||||||
},
|
},
|
||||||
|
|
||||||
packages: {
|
packages: {
|
||||||
|
@ -82,6 +82,9 @@
|
|||||||
"lines": true,
|
"lines": true,
|
||||||
"fill": 1,
|
"fill": 1,
|
||||||
"linewidth": 2,
|
"linewidth": 2,
|
||||||
|
"dashes": false,
|
||||||
|
"dashLength": 10,
|
||||||
|
"spaceLength": 10,
|
||||||
"points": false,
|
"points": false,
|
||||||
"pointradius": 5,
|
"pointradius": 5,
|
||||||
"bars": false,
|
"bars": false,
|
||||||
|
@ -50,6 +50,9 @@
|
|||||||
"lines": true,
|
"lines": true,
|
||||||
"fill": 1,
|
"fill": 1,
|
||||||
"linewidth": 1,
|
"linewidth": 1,
|
||||||
|
"dashes": false,
|
||||||
|
"dashLength": 10,
|
||||||
|
"spaceLength": 10,
|
||||||
"points": false,
|
"points": false,
|
||||||
"pointradius": 5,
|
"pointradius": 5,
|
||||||
"bars": false,
|
"bars": false,
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
"jquery.flot.fillbelow": "vendor/flot/jquery.flot.fillbelow",
|
"jquery.flot.fillbelow": "vendor/flot/jquery.flot.fillbelow",
|
||||||
"jquery.flot.gauge": "vendor/flot/jquery.flot.gauge",
|
"jquery.flot.gauge": "vendor/flot/jquery.flot.gauge",
|
||||||
"d3": "vendor/d3/d3.js",
|
"d3": "vendor/d3/d3.js",
|
||||||
|
"jquery.flot.dashes": "vendor/flot/jquery.flot.dashes"
|
||||||
},
|
},
|
||||||
|
|
||||||
packages: {
|
packages: {
|
||||||
|
236
public/vendor/flot/jquery.flot.dashes.js
vendored
Normal file
236
public/vendor/flot/jquery.flot.dashes.js
vendored
Normal file
@ -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
Block a user