Update flotr2 to most recent version. Replace bars in graphs with line to have mouse tracking on each dataset. Change line graphs colors and reformat label shown on mouse over graph data.
This commit is contained in:
parent
c556c9b384
commit
86669adc45
|
@ -40,6 +40,9 @@ $RM_PROG = "/bin/rm";
|
|||
# DNS Cache
|
||||
my %CACHE = {};
|
||||
|
||||
# Color used to draw grpahs
|
||||
my @GRAPH_COLORS = ('#6e9dc9', '#f4ab3a', '#ac7fa8', '#8dbd0f');
|
||||
|
||||
# Default translation srings
|
||||
my %Translate = (
|
||||
'CharSet' => 'utf-8',
|
||||
|
@ -3545,83 +3548,55 @@ sub flotr2_bargraph
|
|||
{
|
||||
my ($self, $buttonid, $divid, $xtype, $title, $xtitle, $ytitle, $data1, $legend1, $data2, $legend2, $data3, $legend3, $data4, $legend4) = @_;
|
||||
|
||||
$data1 = "var d1 = [$data1];" if ($data1);
|
||||
$data2 = "var d2 = [$data2];";
|
||||
$data3 = "var d3 = [$data3];";
|
||||
$data4 = "var d4 = [$data4];";
|
||||
my @legend = ();
|
||||
my @data = ();
|
||||
|
||||
my $i = 0;
|
||||
push(@data, "var d1 = [$data1];\n") if ($data1);
|
||||
push(@legend, "{ data: d1, label: \"$legend1\", color: \"$GRAPH_COLORS[$i++]\", mouse:{track:true} },\n") if ($data1);
|
||||
push(@data, "var d2 = [$data2];\n") if ($data2);
|
||||
push(@legend, "{ data: d2, label: \"$legend2\", color: \"$GRAPH_COLORS[$i++]\", mouse:{track:true} },\n") if ($data2);
|
||||
push(@data, "var d3 = [$data3];\n") if ($data3);
|
||||
push(@legend, "{ data: d3, label: \"$legend3\", color: \"$GRAPH_COLORS[$i++]\", mouse:{track:true} },\n") if ($data3);
|
||||
push(@data, "var d4 = [$data4];\n") if ($data4);
|
||||
push(@legend, "{ data: d4, label: \"$legend4\", color: \"$GRAPH_COLORS[$i++]\", mouse:{track:true} },\n") if ($data4);
|
||||
|
||||
|
||||
my $month_array = '';
|
||||
my $xlabel = '';
|
||||
my $numticks = 0;
|
||||
if ($xtype eq 'month') {
|
||||
$xlabel = qq{var months = [ "$Translate{'01'}", "$Translate{'02'}", "$Translate{'03'}", "$Translate{'04'}", "$Translate{'05'}", "$Translate{'06'}", "$Translate{'07'}", "$Translate{'08'}", "$Translate{'09'}", "$Translate{'10'}", "$Translate{'11'}", "$Translate{'12'}" ];
|
||||
return months[(x -1) % 12];
|
||||
$month_array = qq{var months = [ '$Translate{"01"}', '$Translate{"02"}', '$Translate{"03"}', '$Translate{"04"}', '$Translate{"05"}', '$Translate{"06"}', '$Translate{"07"}', '$Translate{"08"}', '$Translate{"09"}', '$Translate{"10"}', '$Translate{"11"}', '$Translate{"12"}' ];
|
||||
};
|
||||
$xlabel = qq{return months[(pos -1) % 12];};
|
||||
$numticks = 12;
|
||||
} elsif ($xtype eq 'day') {
|
||||
$xlabel = qq{var days = [01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31];
|
||||
return days[(x - 1) % 31];
|
||||
return days[(pos - 1) % 31];
|
||||
};
|
||||
$numticks = 31;
|
||||
} else {
|
||||
$xlabel = qq{var hours = [00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19,20,21,22,23];
|
||||
return hours[x % 24];
|
||||
return hours[pos % 24];
|
||||
};
|
||||
$numticks = 24;
|
||||
}
|
||||
return <<EOF;
|
||||
<div id="$divid"></div>
|
||||
<script type="text/javascript">
|
||||
$month_array
|
||||
(function mouse_zoom(container) {
|
||||
|
||||
//document.writeln('<table class="tbbutton"><tr><td><input type="button" class="dldButton" value="To Image" id="toimage$buttonid" onclick="return false;">'+
|
||||
// '<input type="button" class="dldButton" value="Download" id="download$buttonid" onclick="return false;">' +
|
||||
// '<input type="button" class="dldButton" value="Reset" id="reset$buttonid" onclick="return false;"></td></tr><tr><td> </td></tr></table>'
|
||||
// );
|
||||
$data1
|
||||
$data2
|
||||
$data3
|
||||
$data4
|
||||
var bars = {
|
||||
data: d1,
|
||||
label: "$legend1",
|
||||
bars: {
|
||||
show: true,
|
||||
barWidth: 0.8,
|
||||
shadowSize: 5,
|
||||
lineWidth: 1,
|
||||
fillColor: {
|
||||
colors: ["#76add2", "#fff"],
|
||||
start: "top",
|
||||
end: "bottom"
|
||||
},
|
||||
fillOpacity: 0.8
|
||||
}
|
||||
},
|
||||
lines1 = {
|
||||
data: d2,
|
||||
label: "$legend2",
|
||||
lines: {
|
||||
show: true,
|
||||
}
|
||||
},
|
||||
lines2 = {
|
||||
data: d3,
|
||||
label: "$legend3",
|
||||
lines: {
|
||||
show: true,
|
||||
}
|
||||
};
|
||||
lines3 = {
|
||||
data: d4,
|
||||
label: "$legend4",
|
||||
lines: {
|
||||
show: true,
|
||||
}
|
||||
};
|
||||
@data
|
||||
var options = {
|
||||
mouse: {
|
||||
track: true,
|
||||
relative: true
|
||||
relative: true,
|
||||
trackFormatter: function(obj){ return dateTracker(obj,'$xtype') },
|
||||
},
|
||||
yaxis: {
|
||||
min: 0,
|
||||
|
@ -3633,7 +3608,7 @@ sub flotr2_bargraph
|
|||
mode: "normal",
|
||||
noTicks: $numticks,
|
||||
tickFormatter: function(x) {
|
||||
var x = parseInt(x);
|
||||
var pos = parseInt(x);
|
||||
$xlabel
|
||||
},
|
||||
title: "$xtitle",
|
||||
|
@ -3652,10 +3627,7 @@ sub flotr2_bargraph
|
|||
return Flotr.draw(
|
||||
container,
|
||||
[
|
||||
bars,
|
||||
lines1,
|
||||
lines2,
|
||||
lines3
|
||||
@legend
|
||||
],
|
||||
o
|
||||
);
|
||||
|
@ -3756,7 +3728,8 @@ sub flotr2_piegraph
|
|||
},
|
||||
mouse: {
|
||||
track: true,
|
||||
trackFormatter: function(obj){ return obj.series.label +' (' + obj.y +')'; },
|
||||
trackFormatter: function(obj){ return pieTracker(obj) },
|
||||
relative: true
|
||||
},
|
||||
legend: {
|
||||
position: "sw",
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
var round = Math.round;
|
||||
|
||||
function toggle(idButton, idDiv, label) {
|
||||
if(document.getElementById(idDiv)) {
|
||||
if(document.getElementById(idDiv).style.display == 'none') {
|
||||
|
@ -10,6 +12,70 @@ function toggle(idButton, idDiv, label) {
|
|||
}
|
||||
}
|
||||
|
||||
function dateTracker(obj, dtype, gtype)
|
||||
{
|
||||
var dateToDisplay = obj.x;
|
||||
if (dtype == 'month') {
|
||||
var pos = parseInt(obj.x);
|
||||
dateToDisplay = months[(pos-1)%12];
|
||||
}
|
||||
return dateToDisplay+', '+obj.series.label+': '+round(obj.y);
|
||||
}
|
||||
|
||||
function pretty_print_number(val, type)
|
||||
{
|
||||
if (type == 'size') {
|
||||
if (val >= 1125899906842624) {
|
||||
val = (val / 1125899906842624);
|
||||
val = val.toFixed(2) + " PiB";
|
||||
} else if (val >= 1099511627776) {
|
||||
val = (val / 1099511627776);
|
||||
val = val.toFixed(2) + " TiB";
|
||||
} else if (val >= 1073741824) {
|
||||
val = (val / 1073741824);
|
||||
val = val.toFixed(2) + " GiB";
|
||||
} else if (val >= 1048576) {
|
||||
val = (val / 1048576);
|
||||
val = val.toFixed(2) + " MiB";
|
||||
} else if (val >= 1024) {
|
||||
val = (val / 1024);
|
||||
val = val.toFixed(2) + " KiB";
|
||||
} else {
|
||||
val = val + " B";
|
||||
}
|
||||
} else if (type == 'duration') {
|
||||
if (val >= 1000) {
|
||||
val = (val / 1000);
|
||||
val = val.toFixed(3) + " sec";
|
||||
} else {
|
||||
val = val + " ms";
|
||||
}
|
||||
} else {
|
||||
if (val >= 1000000000000000) {
|
||||
val = (val / 1000000000000000);
|
||||
val = val.toFixed(2) + " P";
|
||||
} else if (val >= 1000000000000) {
|
||||
val = (val / 1000000000000);
|
||||
val = val.toFixed(2) + " T";
|
||||
} else if (val >= 1000000000) {
|
||||
val = (val / 1000000000);
|
||||
val = val.toFixed(2) + " G";
|
||||
} else if (val >= 1000000) {
|
||||
val = (val / 1000000);
|
||||
val = val.toFixed(2) + " M";
|
||||
} else if (val >= 1000) {
|
||||
val = (val / 1000);
|
||||
val = val.toFixed(2) + " K";
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
function pieTracker(obj)
|
||||
{
|
||||
return obj.series.label+': '+round(obj.y);
|
||||
}
|
||||
|
||||
/*!
|
||||
* bean.js - copyright Jacob Thornton 2011
|
||||
* https://github.com/fat/bean
|
||||
|
@ -1693,7 +1759,7 @@ Flotr.defaultOptions = {
|
|||
mouse: {
|
||||
track: false, // => true to track the mouse, no tracking otherwise
|
||||
trackAll: false,
|
||||
position: 'se', // => position of the value box (default south-east)
|
||||
position: 'se', // => position of the value box (default south-east). False disables.
|
||||
relative: false, // => next to the mouse cursor
|
||||
trackFormatter: Flotr.defaultTrackFormatter, // => formats the values in the value box
|
||||
margin: 5, // => margin in pixels of the valuebox
|
||||
|
@ -2515,22 +2581,30 @@ Graph.prototype = {
|
|||
if (x.options.margin === false) {
|
||||
p.bottom = 0;
|
||||
p.top = 0;
|
||||
} else {
|
||||
} else
|
||||
if (x.options.margin === true) {
|
||||
p.bottom += (options.grid.circular ? 0 : (x.used && x.options.showLabels ? (x.maxLabel.height + margin) : 0)) +
|
||||
(x.used && x.options.title ? (x.titleSize.height + margin) : 0) + maxOutset;
|
||||
|
||||
p.top += (options.grid.circular ? 0 : (x2.used && x2.options.showLabels ? (x2.maxLabel.height + margin) : 0)) +
|
||||
(x2.used && x2.options.title ? (x2.titleSize.height + margin) : 0) + this.subtitleHeight + this.titleHeight + maxOutset;
|
||||
} else {
|
||||
p.bottom = x.options.margin;
|
||||
p.top = x.options.margin;
|
||||
}
|
||||
if (y.options.margin === false) {
|
||||
p.left = 0;
|
||||
p.right = 0;
|
||||
} else {
|
||||
} else
|
||||
if (y.options.margin === true) {
|
||||
p.left += (options.grid.circular ? 0 : (y.used && y.options.showLabels ? (y.maxLabel.width + margin) : 0)) +
|
||||
(y.used && y.options.title ? (y.titleSize.width + margin) : 0) + maxOutset;
|
||||
|
||||
p.right += (options.grid.circular ? 0 : (y2.used && y2.options.showLabels ? (y2.maxLabel.width + margin) : 0)) +
|
||||
(y2.used && y2.options.title ? (y2.titleSize.width + margin) : 0) + maxOutset;
|
||||
} else {
|
||||
p.left = y.options.margin;
|
||||
p.right = y.options.margin;
|
||||
}
|
||||
|
||||
p.top = Math.floor(p.top); // In order the outline not to be blured
|
||||
|
@ -2781,7 +2855,17 @@ Graph.prototype = {
|
|||
|
||||
ctx = ctx || this.ctx;
|
||||
|
||||
if (flotr.isIE && flotr.isIE < 9) {
|
||||
if (
|
||||
flotr.isIE && flotr.isIE < 9 && // IE w/o canvas
|
||||
!flotr.isFlashCanvas // But not flash canvas
|
||||
) {
|
||||
|
||||
// Do not clip excanvas on overlay context
|
||||
// Allow hits to overflow.
|
||||
if (ctx === this.octx) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Clipping for excanvas :-(
|
||||
ctx.save();
|
||||
ctx.fillStyle = this.processColor(this.options.ieBackgroundColor);
|
||||
|
@ -2869,8 +2953,8 @@ Graph.prototype = {
|
|||
observe(this.overlay, 'mousedown', _.bind(this.mouseDownHandler, this)).
|
||||
observe(el, 'mousemove', _.bind(this.mouseMoveHandler, this)).
|
||||
observe(this.overlay, 'click', _.bind(this.clickHandler, this)).
|
||||
observe(el, 'mouseout', function () {
|
||||
E.fire(el, 'flotr:mouseout');
|
||||
observe(el, 'mouseout', function (e) {
|
||||
E.fire(el, 'flotr:mouseout', e);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -2929,6 +3013,7 @@ Graph.prototype = {
|
|||
canvas = D.create('canvas');
|
||||
if (typeof FlashCanvas != "undefined" && typeof canvas.getContext === 'function') {
|
||||
FlashCanvas.initElement(canvas);
|
||||
this.isFlashCanvas = true;
|
||||
}
|
||||
canvas.className = 'flotr-'+name;
|
||||
canvas.style.cssText = 'position:absolute;left:0px;top:0px;';
|
||||
|
@ -3550,7 +3635,7 @@ Flotr.addType('lines', {
|
|||
// To allow empty values
|
||||
if (data[i][1] === null || data[i+1][1] === null) {
|
||||
if (options.fill) {
|
||||
if (i > 0 && data[i][1]) {
|
||||
if (i > 0 && data[i][1] !== null) {
|
||||
context.stroke();
|
||||
fill();
|
||||
start = null;
|
||||
|
@ -3572,21 +3657,17 @@ Flotr.addType('lines', {
|
|||
if (start === null) start = data[i];
|
||||
|
||||
if (stack) {
|
||||
|
||||
stack1 = stack.values[data[i][0]] || 0;
|
||||
stack2 = stack.values[data[i+1][0]] || stack.values[data[i][0]] || 0;
|
||||
|
||||
y1 = yScale(data[i][1] + stack1);
|
||||
y2 = yScale(data[i+1][1] + stack2);
|
||||
|
||||
if(incStack){
|
||||
stack.values[data[i][0]] = data[i][1]+stack1;
|
||||
|
||||
if(i == length-1)
|
||||
stack.values[data[i+1][0]] = data[i+1][1]+stack2;
|
||||
if (incStack) {
|
||||
stack.values[data[i][0]] = data[i][1] + stack1;
|
||||
if (i == length-1) {
|
||||
stack.values[data[i+1][0]] = data[i+1][1] + stack2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
y1 = yScale(data[i][1]);
|
||||
y2 = yScale(data[i+1][1]);
|
||||
}
|
||||
|
@ -3598,8 +3679,9 @@ Flotr.addType('lines', {
|
|||
(x1 > width && x2 > width)
|
||||
) continue;
|
||||
|
||||
if((prevx != x1) || (prevy != y1 + shadowOffset))
|
||||
if ((prevx != x1) || (prevy != y1 + shadowOffset)) {
|
||||
context.moveTo(x1, y1 + shadowOffset);
|
||||
}
|
||||
|
||||
prevx = x2;
|
||||
prevy = y2 + shadowOffset;
|
||||
|
@ -4297,7 +4379,6 @@ Flotr.addType('candles', {
|
|||
context.lineTo(x, y);
|
||||
} else {
|
||||
context.strokeRect(left, top2 + lineWidth, right - left, bottom2 - top2);
|
||||
|
||||
context.moveTo(x, Math.floor(top2 + lineWidth));
|
||||
context.lineTo(x, Math.floor(top + lineWidth));
|
||||
context.moveTo(x, Math.floor(bottom2 + lineWidth));
|
||||
|
@ -4309,6 +4390,72 @@ Flotr.addType('candles', {
|
|||
}
|
||||
}
|
||||
},
|
||||
|
||||
hit : function (options) {
|
||||
var
|
||||
xScale = options.xScale,
|
||||
yScale = options.yScale,
|
||||
data = options.data,
|
||||
args = options.args,
|
||||
mouse = args[0],
|
||||
width = options.candleWidth / 2,
|
||||
n = args[1],
|
||||
x = mouse.relX,
|
||||
y = mouse.relY,
|
||||
length = data.length,
|
||||
i, datum,
|
||||
high, low,
|
||||
left, right, top, bottom;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
datum = data[i],
|
||||
high = datum[2];
|
||||
low = datum[3];
|
||||
left = xScale(datum[0] - width);
|
||||
right = xScale(datum[0] + width);
|
||||
bottom = yScale(low);
|
||||
top = yScale(high);
|
||||
|
||||
if (x > left && x < right && y > top && y < bottom) {
|
||||
n.x = datum[0];
|
||||
n.index = i;
|
||||
n.seriesIndex = options.index;
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
drawHit : function (options) {
|
||||
var
|
||||
context = options.context;
|
||||
context.save();
|
||||
this.plot(
|
||||
_.defaults({
|
||||
fill : !!options.fillColor,
|
||||
upFillColor : options.color,
|
||||
downFillColor : options.color,
|
||||
data : [options.data[options.args.index]]
|
||||
}, options)
|
||||
);
|
||||
context.restore();
|
||||
},
|
||||
|
||||
clearHit : function (options) {
|
||||
var
|
||||
args = options.args,
|
||||
context = options.context,
|
||||
xScale = options.xScale,
|
||||
yScale = options.yScale,
|
||||
lineWidth = options.lineWidth,
|
||||
width = options.candleWidth / 2,
|
||||
bar = options.data[args.index],
|
||||
left = xScale(bar[0] - width) - lineWidth,
|
||||
right = xScale(bar[0] + width) + lineWidth,
|
||||
top = yScale(bar[2]),
|
||||
bottom = yScale(bar[3]) + lineWidth;
|
||||
context.clearRect(left, top, right - left, bottom - top);
|
||||
},
|
||||
|
||||
extendXRange: function (axis, data, options) {
|
||||
if (axis.options.max === null) {
|
||||
axis.max = Math.max(axis.datamax + 0.5, axis.max);
|
||||
|
@ -4676,7 +4823,7 @@ Flotr.addType('markers', {
|
|||
context.strokeRect(left, top, dim.width, dim.height);
|
||||
|
||||
if (isImage(label))
|
||||
context.drawImage(label, left+margin, top+margin);
|
||||
context.drawImage(label, parseInt(left+margin, 10), parseInt(top+margin, 10));
|
||||
else
|
||||
Flotr.drawText(context, label, left+margin, top+margin, {textBaseline: 'top', textAlign: 'left', size: options.fontSize, color: options.color});
|
||||
}
|
||||
|
@ -4724,11 +4871,9 @@ Flotr.addType('pie', {
|
|||
draw : function (options) {
|
||||
|
||||
// TODO 3D charts what?
|
||||
|
||||
var
|
||||
data = options.data,
|
||||
context = options.context,
|
||||
canvas = context.canvas,
|
||||
lineWidth = options.lineWidth,
|
||||
shadowSize = options.shadowSize,
|
||||
sizeRatio = options.sizeRatio,
|
||||
|
@ -4738,7 +4883,7 @@ Flotr.addType('pie', {
|
|||
color = options.color,
|
||||
fill = options.fill,
|
||||
fillStyle = options.fillStyle,
|
||||
radius = Math.min(canvas.width, canvas.height) * sizeRatio / 2,
|
||||
radius = Math.min(width, height) * sizeRatio / 2,
|
||||
value = data[0][1],
|
||||
html = [],
|
||||
vScale = 1,//Math.cos(series.pie.viewAngle);
|
||||
|
@ -4812,7 +4957,7 @@ Flotr.addType('pie', {
|
|||
this.startAngle = endAngle;
|
||||
this.slices = this.slices || [];
|
||||
this.slices.push({
|
||||
radius : Math.min(canvas.width, canvas.height) * sizeRatio / 2,
|
||||
radius : radius,
|
||||
x : x,
|
||||
y : y,
|
||||
explode : explode,
|
||||
|
@ -4980,7 +5125,8 @@ Flotr.addType('radar', {
|
|||
lineWidth: 2, // => line width in pixels
|
||||
fill: true, // => true to fill the area from the line to the x axis, false for (transparent) no fill
|
||||
fillOpacity: 0.4, // => opacity of the fill color, set to 1 for a solid fill, 0 hides the fill
|
||||
radiusRatio: 0.90 // => ratio of the radar, against the plot size
|
||||
radiusRatio: 0.90, // => ratio of the radar, against the plot size
|
||||
sensibility: 2 // => the lower this number, the more precise you have to aim to show a value.
|
||||
},
|
||||
draw : function (options) {
|
||||
var
|
||||
|
@ -5029,6 +5175,91 @@ Flotr.addType('radar', {
|
|||
if (options.fill) context.fill();
|
||||
context.stroke();
|
||||
},
|
||||
getGeometry : function (point, options) {
|
||||
var
|
||||
radius = Math.min(options.height, options.width) * options.radiusRatio / 2,
|
||||
step = 2 * Math.PI / options.data.length,
|
||||
angle = -Math.PI / 2,
|
||||
ratio = point[1] / this.max;
|
||||
|
||||
return {
|
||||
x : (Math.cos(point[0] * step + angle) * radius * ratio) + options.width / 2,
|
||||
y : (Math.sin(point[0] * step + angle) * radius * ratio) + options.height / 2
|
||||
};
|
||||
},
|
||||
hit : function (options) {
|
||||
var
|
||||
args = options.args,
|
||||
mouse = args[0],
|
||||
n = args[1],
|
||||
relX = mouse.relX,
|
||||
relY = mouse.relY,
|
||||
distance,
|
||||
geometry,
|
||||
dx, dy;
|
||||
|
||||
for (var i = 0; i < n.series.length; i++) {
|
||||
var serie = n.series[i];
|
||||
var data = serie.data;
|
||||
|
||||
for (var j = data.length; j--;) {
|
||||
geometry = this.getGeometry(data[j], options);
|
||||
|
||||
dx = geometry.x - relX;
|
||||
dy = geometry.y - relY;
|
||||
distance = Math.sqrt(dx * dx + dy * dy);
|
||||
|
||||
if (distance < options.sensibility*2) {
|
||||
n.x = data[j][0];
|
||||
n.y = data[j][1];
|
||||
n.index = j;
|
||||
n.seriesIndex = i;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
drawHit : function (options) {
|
||||
var step = 2 * Math.PI / options.data.length;
|
||||
var angle = -Math.PI / 2;
|
||||
var radius = Math.min(options.height, options.width) * options.radiusRatio / 2;
|
||||
|
||||
var s = options.args.series;
|
||||
var point_radius = s.points.hitRadius || s.points.radius || s.mouse.radius;
|
||||
|
||||
var context = options.context;
|
||||
|
||||
context.translate(options.width / 2, options.height / 2);
|
||||
|
||||
var j = options.args.index;
|
||||
var ratio = options.data[j][1] / this.max;
|
||||
var x = Math.cos(j * step + angle) * radius * ratio;
|
||||
var y = Math.sin(j * step + angle) * radius * ratio;
|
||||
context.beginPath();
|
||||
context.arc(x, y, point_radius , 0, 2 * Math.PI, true);
|
||||
context.closePath();
|
||||
context.stroke();
|
||||
},
|
||||
clearHit : function (options) {
|
||||
var step = 2 * Math.PI / options.data.length;
|
||||
var angle = -Math.PI / 2;
|
||||
var radius = Math.min(options.height, options.width) * options.radiusRatio / 2;
|
||||
|
||||
var context = options.context;
|
||||
|
||||
var
|
||||
s = options.args.series,
|
||||
lw = (s.points ? s.points.lineWidth : 1);
|
||||
offset = (s.points.hitRadius || s.points.radius || s.mouse.radius) + lw;
|
||||
|
||||
context.translate(options.width / 2, options.height / 2);
|
||||
|
||||
var j = options.args.index;
|
||||
var ratio = options.data[j][1] / this.max;
|
||||
var x = Math.cos(j * step + angle) * radius * ratio;
|
||||
var y = Math.sin(j * step + angle) * radius * ratio;
|
||||
context.clearRect(x-offset,y-offset,offset*2,offset*2);
|
||||
},
|
||||
extendYRange : function (axis, data) {
|
||||
this.max = Math.max(axis.max, this.max || -Number.MAX_VALUE);
|
||||
}
|
||||
|
@ -5216,21 +5447,34 @@ var
|
|||
D = Flotr.DOM,
|
||||
_ = Flotr._;
|
||||
|
||||
function getImage (type, canvas, width, height) {
|
||||
function getImage (type, canvas, context, width, height, background) {
|
||||
|
||||
// TODO add scaling for w / h
|
||||
var
|
||||
mime = 'image/'+type,
|
||||
data = canvas.toDataURL(mime),
|
||||
data = context.getImageData(0, 0, width, height),
|
||||
image = new Image();
|
||||
image.src = data;
|
||||
|
||||
context.save();
|
||||
context.globalCompositeOperation = 'destination-over';
|
||||
context.fillStyle = background;
|
||||
context.fillRect(0, 0, width, height);
|
||||
image.src = canvas.toDataURL(mime);
|
||||
context.restore();
|
||||
|
||||
context.clearRect(0, 0, width, height);
|
||||
context.putImageData(data, 0, 0);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
Flotr.addPlugin('download', {
|
||||
|
||||
saveImage: function (type, width, height, replaceCanvas) {
|
||||
var image = null;
|
||||
var
|
||||
grid = this.options.grid,
|
||||
image;
|
||||
|
||||
if (Flotr.isIE && Flotr.isIE < 9) {
|
||||
image = '<html><body>'+this.canvas.firstChild.innerHTML+'</body></html>';
|
||||
return window.open().document.write(image);
|
||||
|
@ -5238,7 +5482,11 @@ Flotr.addPlugin('download', {
|
|||
|
||||
if (type !== 'jpeg' && type !== 'png') return;
|
||||
|
||||
image = getImage(type, this.canvas, width, height);
|
||||
image = getImage(
|
||||
type, this.canvas, this.ctx,
|
||||
this.canvasWidth, this.canvasHeight,
|
||||
grid && grid.backgroundColor || '#ffffff'
|
||||
);
|
||||
|
||||
if (_.isElement(image) && replaceCanvas) {
|
||||
this.download.restoreCanvas();
|
||||
|
@ -5477,7 +5725,7 @@ var
|
|||
D = Flotr.DOM,
|
||||
_ = Flotr._,
|
||||
flotr = Flotr,
|
||||
S_MOUSETRACK = 'opacity:0.7;background-color:#000;color:#fff;display:none;position:absolute;padding:2px 8px;-moz-border-radius:4px;border-radius:4px;white-space:nowrap;';
|
||||
S_MOUSETRACK = 'opacity:0.7;background-color:#000;color:#fff;position:absolute;padding:2px 8px;-moz-border-radius:4px;border-radius:4px;white-space:nowrap;';
|
||||
|
||||
Flotr.addPlugin('hit', {
|
||||
callbacks: {
|
||||
|
@ -5487,12 +5735,17 @@ Flotr.addPlugin('hit', {
|
|||
'flotr:click': function(pos) {
|
||||
var
|
||||
hit = this.hit.track(pos);
|
||||
_.defaults(pos, hit);
|
||||
if (hit && !_.isUndefined(hit.index)) pos.hit = hit;
|
||||
},
|
||||
'flotr:mouseout': function() {
|
||||
this.hit.clearHit();
|
||||
'flotr:mouseout': function(e) {
|
||||
if (e.relatedTarget !== this.mouseTrack) {
|
||||
this.hit.clearHit();
|
||||
}
|
||||
},
|
||||
'flotr:destroy': function() {
|
||||
if (this.options.mouse.container) {
|
||||
D.remove(this.mouseTrack);
|
||||
}
|
||||
this.mouseTrack = null;
|
||||
}
|
||||
},
|
||||
|
@ -5517,7 +5770,7 @@ Flotr.addPlugin('hit', {
|
|||
|
||||
function e(s, index) {
|
||||
_.each(_.keys(flotr.graphTypes), function (type) {
|
||||
if (s[type] && s[type].show && this[type][method]) {
|
||||
if (s[type] && s[type].show && !s.hide && this[type][method]) {
|
||||
options = this.getOptions(s, type);
|
||||
|
||||
options.fill = !!s.mouse.fillColor;
|
||||
|
@ -5617,7 +5870,8 @@ Flotr.addPlugin('hit', {
|
|||
relX : mouse.relX,
|
||||
relY : mouse.relY,
|
||||
absX : mouse.absX,
|
||||
absY : mouse.absY
|
||||
absY : mouse.absY,
|
||||
series: this.series
|
||||
};
|
||||
|
||||
if (options.mouse.trackY &&
|
||||
|
@ -5708,6 +5962,8 @@ Flotr.addPlugin('hit', {
|
|||
mouseX = serie.xaxis.p2d(relX);
|
||||
mouseY = serie.yaxis.p2d(relY);
|
||||
|
||||
if (serie.hide) continue;
|
||||
|
||||
for (j = data.length; j--;) {
|
||||
|
||||
x = data[j][0];
|
||||
|
@ -5759,21 +6015,58 @@ Flotr.addPlugin('hit', {
|
|||
bottom = plotOffset.bottom,
|
||||
top = plotOffset.top,
|
||||
decimals = n.mouse.trackDecimals,
|
||||
options = this.options;
|
||||
options = this.options,
|
||||
container = options.mouse.container,
|
||||
oTop = 0,
|
||||
oLeft = 0,
|
||||
offset, size, content;
|
||||
|
||||
// Create
|
||||
if (!mouseTrack) {
|
||||
mouseTrack = D.node('<div class="flotr-mouse-value"></div>');
|
||||
mouseTrack = D.node('<div class="flotr-mouse-value" style="'+elStyle+'"></div>');
|
||||
this.mouseTrack = mouseTrack;
|
||||
D.insert(this.el, mouseTrack);
|
||||
D.insert(container || this.el, mouseTrack);
|
||||
}
|
||||
|
||||
// Fill tracker:
|
||||
if (!decimals || decimals < 0) decimals = 0;
|
||||
if (x && x.toFixed) x = x.toFixed(decimals);
|
||||
if (y && y.toFixed) y = y.toFixed(decimals);
|
||||
content = n.mouse.trackFormatter({
|
||||
x: x,
|
||||
y: y,
|
||||
series: n.series,
|
||||
index: n.index,
|
||||
nearest: n,
|
||||
fraction: n.fraction
|
||||
});
|
||||
if (_.isNull(content) || _.isUndefined(content)) {
|
||||
D.hide(mouseTrack);
|
||||
return;
|
||||
} else {
|
||||
mouseTrack.innerHTML = content;
|
||||
D.show(mouseTrack);
|
||||
}
|
||||
|
||||
// Positioning
|
||||
if (!p) {
|
||||
return;
|
||||
}
|
||||
size = D.size(mouseTrack);
|
||||
if (container) {
|
||||
offset = D.position(this.el);
|
||||
oTop = offset.top;
|
||||
oLeft = offset.left;
|
||||
}
|
||||
|
||||
if (!n.mouse.relative) { // absolute to the canvas
|
||||
|
||||
if (p.charAt(0) == 'n') pos += 'top:' + (m + top) + 'px;bottom:auto;';
|
||||
else if (p.charAt(0) == 's') pos += 'bottom:' + (m + bottom) + 'px;top:auto;';
|
||||
if (p.charAt(1) == 'e') pos += 'right:' + (m + right) + 'px;left:auto;';
|
||||
else if (p.charAt(1) == 'w') pos += 'left:' + (m + left) + 'px;right:auto;';
|
||||
pos += 'top:';
|
||||
if (p.charAt(0) == 'n') pos += (oTop + m + top);
|
||||
else if (p.charAt(0) == 's') pos += (oTop - m + top + this.plotHeight - size.height);
|
||||
pos += 'px;bottom:auto;left:';
|
||||
if (p.charAt(1) == 'e') pos += (oLeft - m + left + this.plotWidth - size.width);
|
||||
else if (p.charAt(1) == 'w') pos += (oLeft + m + left);
|
||||
pos += 'px;right:auto;';
|
||||
|
||||
// Pie
|
||||
} else if (s.pie && s.pie.show) {
|
||||
|
@ -5788,42 +6081,29 @@ Flotr.addPlugin('hit', {
|
|||
pos += 'left:' + (m + left + center.x + Math.cos(bisection) * radius/2) + 'px;right:auto;';
|
||||
|
||||
// Default
|
||||
} else {
|
||||
if (/n/.test(p)) pos += 'bottom:' + (m - top - n.yaxis.d2p(n.y) + this.canvasHeight) + 'px;top:auto;';
|
||||
else pos += 'top:' + (m + top + n.yaxis.d2p(n.y)) + 'px;bottom:auto;';
|
||||
if (/w/.test(p)) pos += 'right:' + (m - left - n.xaxis.d2p(n.x) + this.canvasWidth) + 'px;left:auto;';
|
||||
else pos += 'left:' + (m + left + n.xaxis.d2p(n.x)) + 'px;right:auto;';
|
||||
} else {
|
||||
pos += 'top:';
|
||||
if (/n/.test(p)) pos += (oTop - m + top + n.yaxis.d2p(n.y) - size.height);
|
||||
else pos += (oTop + m + top + n.yaxis.d2p(n.y));
|
||||
pos += 'px;bottom:auto;left:';
|
||||
if (/w/.test(p)) pos += (oLeft - m + left + n.xaxis.d2p(n.x) - size.width);
|
||||
else pos += (oLeft + m + left + n.xaxis.d2p(n.x));
|
||||
pos += 'px;right:auto;';
|
||||
}
|
||||
|
||||
elStyle += pos;
|
||||
mouseTrack.style.cssText = elStyle;
|
||||
if (!decimals || decimals < 0) decimals = 0;
|
||||
|
||||
if (x && x.toFixed) x = x.toFixed(decimals);
|
||||
|
||||
if (y && y.toFixed) y = y.toFixed(decimals);
|
||||
|
||||
mouseTrack.innerHTML = n.mouse.trackFormatter({
|
||||
x: x ,
|
||||
y: y,
|
||||
series: n.series,
|
||||
index: n.index,
|
||||
nearest: n,
|
||||
fraction: n.fraction
|
||||
});
|
||||
|
||||
D.show(mouseTrack);
|
||||
// Set position
|
||||
mouseTrack.style.cssText = elStyle + pos;
|
||||
|
||||
if (n.mouse.relative) {
|
||||
if (!/[ew]/.test(p)) {
|
||||
// Center Horizontally
|
||||
mouseTrack.style.left =
|
||||
(left + n.xaxis.d2p(n.x) - D.size(mouseTrack).width / 2) + 'px';
|
||||
(oLeft + left + n.xaxis.d2p(n.x) - D.size(mouseTrack).width / 2) + 'px';
|
||||
} else
|
||||
if (!/[ns]/.test(p)) {
|
||||
// Center Vertically
|
||||
mouseTrack.style.top =
|
||||
(top + n.yaxis.d2p(n.y) - D.size(mouseTrack).height / 2) + 'px';
|
||||
(oTop + top + n.yaxis.d2p(n.y) - D.size(mouseTrack).height / 2) + 'px';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7005,3 +7285,4 @@ Flotr.addPlugin('titles', {
|
|||
}
|
||||
});
|
||||
})();
|
||||
|
||||
|
|
Loading…
Reference in New Issue