Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
res.lib.flot.jquery.flot.js Maven / Gradle / Ivy
(function ($ ) {$.color={};$.color.make=function (r,g,b,a ) {var o={};o.r=r||0 ;o.g=g||0 ;o.b=b||0 ;o.a=a!=null ?a:1 ;o.add=function (c,d ) {for (var i=0 ;i=1 ){return "rgb(" +[o.r,o.g,o.b].join("," )+")" }else {return "rgba(" +[o.r,o.g,o.b,o.a].join("," )+")" }};o.normalize=function ( ) {function clamp (min,value,max ) {return valuemax?max:value}o.r=clamp(0 ,parseInt (o.r),255 );o.g=clamp(0 ,parseInt (o.g),255 );o.b=clamp(0 ,parseInt (o.b),255 );o.a=clamp(0 ,o.a,1 );return o};o.clone=function ( ) {return $.color.make(o.r,o.b,o.g,o.a)};return o.normalize()};$.color.extract=function (elem,css ) {var c;do {c=elem.css(css).toLowerCase();if (c!="" &&c!="transparent" )break ;elem=elem.parent()}while (elem.length&&!$.nodeName(elem.get(0 ),"body" ));if (c=="rgba(0, 0, 0, 0)" )c="transparent" ;return $.color.parse(c)};$.color.parse=function (str ) {var res,m=$.color.make;if (res=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/ .exec(str))return m(parseInt (res[1 ],10 ),parseInt (res[2 ],10 ),parseInt (res[3 ],10 ));if (res=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/ .exec(str))return m(parseInt (res[1 ],10 ),parseInt (res[2 ],10 ),parseInt (res[3 ],10 ),parseFloat (res[4 ]));if (res=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/ .exec(str))return m(parseFloat (res[1 ])*2.55 ,parseFloat (res[2 ])*2.55 ,parseFloat (res[3 ])*2.55 );if (res=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/ .exec(str))return m(parseFloat (res[1 ])*2.55 ,parseFloat (res[2 ])*2.55 ,parseFloat (res[3 ])*2.55 ,parseFloat (res[4 ]));if (res=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/ .exec(str))return m(parseInt (res[1 ],16 ),parseInt (res[2 ],16 ),parseInt (res[3 ],16 ));if (res=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/ .exec(str))return m(parseInt (res[1 ]+res[1 ],16 ),parseInt (res[2 ]+res[2 ],16 ),parseInt (res[3 ]+res[3 ],16 ));var name=$.trim(str).toLowerCase();if (name=="transparent" )return m(255 ,255 ,255 ,0 );else {res=lookupColors[name]||[0 ,0 ,0 ];return m(res[0 ],res[1 ],res[2 ])}};var lookupColors={aqua :[0 ,255 ,255 ],azure :[240 ,255 ,255 ],beige :[245 ,245 ,220 ],black :[0 ,0 ,0 ],blue :[0 ,0 ,255 ],brown :[165 ,42 ,42 ],cyan :[0 ,255 ,255 ],darkblue :[0 ,0 ,139 ],darkcyan :[0 ,139 ,139 ],darkgrey :[169 ,169 ,169 ],darkgreen :[0 ,100 ,0 ],darkkhaki :[189 ,183 ,107 ],darkmagenta :[139 ,0 ,139 ],darkolivegreen :[85 ,107 ,47 ],darkorange :[255 ,140 ,0 ],darkorchid :[153 ,50 ,204 ],darkred :[139 ,0 ,0 ],darksalmon :[233 ,150 ,122 ],darkviolet :[148 ,0 ,211 ],fuchsia :[255 ,0 ,255 ],gold :[255 ,215 ,0 ],green :[0 ,128 ,0 ],indigo :[75 ,0 ,130 ],khaki :[240 ,230 ,140 ],lightblue :[173 ,216 ,230 ],lightcyan :[224 ,255 ,255 ],lightgreen :[144 ,238 ,144 ],lightgrey :[211 ,211 ,211 ],lightpink :[255 ,182 ,193 ],lightyellow :[255 ,255 ,224 ],lime :[0 ,255 ,0 ],magenta :[255 ,0 ,255 ],maroon :[128 ,0 ,0 ],navy :[0 ,0 ,128 ],olive :[128 ,128 ,0 ],orange :[255 ,165 ,0 ],pink :[255 ,192 ,203 ],purple :[128 ,0 ,128 ],violet :[128 ,0 ,128 ],red :[255 ,0 ,0 ],silver :[192 ,192 ,192 ],white :[255 ,255 ,255 ],yellow :[255 ,255 ,0 ]}})(jQuery);
(function ($ ) {
var hasOwnProperty = Object .prototype.hasOwnProperty;
if (!$.fn.detach) {
$.fn.detach = function ( ) {
return this .each(function ( ) {
if (this .parentNode) {
this .parentNode.removeChild( this );
}
});
};
}
function Canvas (cls, container ) {
var element = container.children("." + cls)[0 ];
if (element == null ) {
element = document .createElement("canvas" );
element.className = cls;
$(element).css({ direction : "ltr" , position : "absolute" , left : 0 , top : 0 })
.appendTo(container);
if (!element.getContext) {
if (window .G_vmlCanvasManager) {
element = window .G_vmlCanvasManager.initElement(element);
} else {
throw new Error ("Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode." );
}
}
}
this .element = element;
var context = this .context = element.getContext("2d" );
var devicePixelRatio = window .devicePixelRatio || 1 ,
backingStoreRatio =
context.webkitBackingStorePixelRatio ||
context.mozBackingStorePixelRatio ||
context.msBackingStorePixelRatio ||
context.oBackingStorePixelRatio ||
context.backingStorePixelRatio || 1 ;
this .pixelRatio = devicePixelRatio / backingStoreRatio;
this .resize(container.width(), container.height());
this .textContainer = null ;
this .text = {};
this ._textCache = {};
}
Canvas.prototype.resize = function (width, height ) {
if (width <= 0 || height <= 0 ) {
throw new Error ("Invalid dimensions for plot, width = " + width + ", height = " + height);
}
var element = this .element,
context = this .context,
pixelRatio = this .pixelRatio;
if (this .width != width) {
element.width = width * pixelRatio;
element.style.width = width + "px" ;
this .width = width;
}
if (this .height != height) {
element.height = height * pixelRatio;
element.style.height = height + "px" ;
this .height = height;
}
context.restore();
context.save();
context.scale(pixelRatio, pixelRatio);
};
Canvas.prototype.clear = function ( ) {
this .context.clearRect(0 , 0 , this .width, this .height);
};
Canvas.prototype.render = function ( ) {
var cache = this ._textCache;
for (var layerKey in cache) {
if (hasOwnProperty.call(cache, layerKey)) {
var layer = this .getTextLayer(layerKey),
layerCache = cache[layerKey];
layer.hide();
for (var styleKey in layerCache) {
if (hasOwnProperty.call(layerCache, styleKey)) {
var styleCache = layerCache[styleKey];
for (var key in styleCache) {
if (hasOwnProperty.call(styleCache, key)) {
var positions = styleCache[key].positions;
for (var i = 0 , position; position = positions[i]; i++) {
if (position.active) {
if (!position.rendered) {
layer.append(position.element);
position.rendered = true ;
}
} else {
positions.splice(i--, 1 );
if (position.rendered) {
position.element.detach();
}
}
}
if (positions.length == 0 ) {
delete styleCache[key];
}
}
}
}
}
layer.show();
}
}
};
Canvas.prototype.getTextLayer = function (classes ) {
var layer = this .text[classes];
if (layer == null ) {
if (this .textContainer == null ) {
this .textContainer = $("
" )
.css({
position : "absolute" ,
top : 0 ,
left : 0 ,
bottom : 0 ,
right : 0 ,
'font-size' : "smaller" ,
color : "#545454"
})
.insertAfter(this .element);
}
layer = this .text[classes] = $("
" )
.addClass(classes)
.css({
position : "absolute" ,
top : 0 ,
left : 0 ,
bottom : 0 ,
right : 0
})
.appendTo(this .textContainer);
}
return layer;
};
Canvas.prototype.getTextInfo = function (layer, text, font, angle, width ) {
var textStyle, layerCache, styleCache, info;
text = "" + text;
if (typeof font === "object" ) {
textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px/" + font.lineHeight + "px " + font.family;
} else {
textStyle = font;
}
layerCache = this ._textCache[layer];
if (layerCache == null ) {
layerCache = this ._textCache[layer] = {};
}
styleCache = layerCache[textStyle];
if (styleCache == null ) {
styleCache = layerCache[textStyle] = {};
}
info = styleCache[text];
if (info == null ) {
var element = $("
" ).html(text)
.css({
position : "absolute" ,
'max-width' : width,
top : -9999
})
.appendTo(this .getTextLayer(layer));
if (typeof font === "object" ) {
element.css({
font : textStyle,
color : font.color
});
} else if (typeof font === "string" ) {
element.addClass(font);
}
info = styleCache[text] = {
width : element.outerWidth(true ),
height : element.outerHeight(true ),
element : element,
positions : []
};
element.detach();
}
return info;
};
Canvas.prototype.addText = function (layer, x, y, text, font, angle, width, halign, valign ) {
var info = this .getTextInfo(layer, text, font, angle, width),
positions = info.positions;
if (halign == "center" ) {
x -= info.width / 2 ;
} else if (halign == "right" ) {
x -= info.width;
}
if (valign == "middle" ) {
y -= info.height / 2 ;
} else if (valign == "bottom" ) {
y -= info.height;
}
for (var i = 0 , position; position = positions[i]; i++) {
if (position.x == x && position.y == y) {
position.active = true ;
return ;
}
}
position = {
active : true ,
rendered : false ,
element : positions.length ? info.element.clone() : info.element,
x : x,
y : y
};
positions.push(position);
position.element.css({
top : Math .round(y),
left : Math .round(x),
'text-align' : halign
});
};
Canvas.prototype.removeText = function (layer, x, y, text, font, angle ) {
if (text == null ) {
var layerCache = this ._textCache[layer];
if (layerCache != null ) {
for (var styleKey in layerCache) {
if (hasOwnProperty.call(layerCache, styleKey)) {
var styleCache = layerCache[styleKey];
for (var key in styleCache) {
if (hasOwnProperty.call(styleCache, key)) {
var positions = styleCache[key].positions;
for (var i = 0 , position; position = positions[i]; i++) {
position.active = false ;
}
}
}
}
}
}
} else {
var positions = this .getTextInfo(layer, text, font, angle).positions;
for (var i = 0 , position; position = positions[i]; i++) {
if (position.x == x && position.y == y) {
position.active = false ;
}
}
}
};
function Plot (placeholder, data_, options_, plugins ) {
var series = [],
options = {
colors: ["#edc240" , "#afd8f8" , "#cb4b4b" , "#4da74d" , "#9440ed" ],
legend : {
show : true ,
noColumns : 1 ,
labelFormatter: null ,
labelBoxBorderColor: "#ccc" ,
container: null ,
position: "ne" ,
margin: 5 ,
backgroundColor: null ,
backgroundOpacity: 0.85 ,
sorted: null
},
xaxis : {
show : null ,
position: "bottom" ,
mode: null ,
font: null ,
color: null ,
tickColor: null ,
transform: null ,
inverseTransform: null ,
min: null ,
max: null ,
autoscaleMargin: null ,
ticks: null ,
tickFormatter: null ,
labelWidth: null ,
labelHeight: null ,
reserveSpace : null ,
tickLength: null ,
alignTicksWithAxis: null ,
tickDecimals: null ,
tickSize: null ,
minTickSize: null
},
yaxis : {
autoscaleMargin : 0.02 ,
position : "left"
},
xaxes : [],
yaxes : [],
series : {
points : {
show : false ,
radius : 3 ,
lineWidth : 2 ,
fill: true ,
fillColor : "#ffffff" ,
symbol : "circle"
},
lines : {
lineWidth: 2 ,
fill: false ,
fillColor : null ,
steps : false
},
bars : {
show : false ,
lineWidth : 2 ,
barWidth: 1 ,
fill: true ,
fillColor : null ,
align : "left" ,
horizontal: false ,
zero : true
},
shadowSize : 3 ,
highlightColor : null
},
grid : {
show : true ,
aboveData : false ,
color : "#545454" ,
backgroundColor: null ,
borderColor: null ,
tickColor: null ,
margin: 0 ,
labelMargin: 5 ,
axisMargin: 8 ,
borderWidth: 2 ,
minBorderMargin: null ,
markings: null ,
markingsColor: "#f4f4f4" ,
markingsLineWidth : 2 ,
clickable: false ,
hoverable : false ,
autoHighlight : true ,
mouseActiveRadius: 10
},
interaction : {
redrawOverlayInterval : 1000 /60
},
hooks : {}
},
surface = null ,
overlay = null ,
eventHolder = null ,
ctx = null , octx = null ,
xaxes = [], yaxes = [],
plotOffset = { left : 0 , right : 0 , top : 0 , bottom : 0 },
plotWidth = 0 , plotHeight = 0 ,
hooks = {
processOptions : [],
processRawData : [],
processDatapoints : [],
processOffset : [],
drawBackground : [],
drawSeries : [],
draw : [],
bindEvents : [],
drawOverlay : [],
shutdown : []
},
plot = this ;
plot.setData = setData;
plot.setupGrid = setupGrid;
plot.draw = draw;
plot.getPlaceholder = function ( ) { return placeholder; };
plot.getCanvas = function ( ) { return surface.element; };
plot.getPlotOffset = function ( ) { return plotOffset; };
plot.width = function ( ) { return plotWidth; };
plot.height = function ( ) { return plotHeight; };
plot.offset = function ( ) {
var o = eventHolder.offset();
o.left += plotOffset.left;
o.top += plotOffset.top;
return o;
};
plot.getData = function ( ) { return series; };
plot.getAxes = function ( ) {
var res = {}, i;
$.each(xaxes.concat(yaxes), function (_, axis ) {
if (axis)
res[axis.direction + (axis.n != 1 ? axis.n : "" ) + "axis" ] = axis;
});
return res;
};
plot.getXAxes = function ( ) { return xaxes; };
plot.getYAxes = function ( ) { return yaxes; };
plot.c2p = canvasToAxisCoords;
plot.p2c = axisToCanvasCoords;
plot.getOptions = function ( ) { return options; };
plot.highlight = highlight;
plot.unhighlight = unhighlight;
plot.triggerRedrawOverlay = triggerRedrawOverlay;
plot.pointOffset = function (point ) {
return {
left : parseInt (xaxes[axisNumber(point, "x" ) - 1 ].p2c(+point.x) + plotOffset.left, 10 ),
top : parseInt (yaxes[axisNumber(point, "y" ) - 1 ].p2c(+point.y) + plotOffset.top, 10 )
};
};
plot.shutdown = shutdown;
plot.destroy = function ( ) {
shutdown();
placeholder.removeData("plot" ).empty();
series = [];
options = null ;
surface = null ;
overlay = null ;
eventHolder = null ;
ctx = null ;
octx = null ;
xaxes = [];
yaxes = [];
hooks = null ;
highlights = [];
plot = null ;
};
plot.resize = function ( ) {
var width = placeholder.width(),
height = placeholder.height();
surface.resize(width, height);
overlay.resize(width, height);
};
plot.hooks = hooks;
initPlugins(plot);
parseOptions(options_);
setupCanvases();
setData(data_);
setupGrid();
draw();
bindEvents();
function executeHooks (hook, args ) {
args = [plot].concat(args);
for (var i = 0 ; i < hook.length; ++i)
hook[i].apply(this , args);
}
function initPlugins ( ) {
var classes = {
Canvas : Canvas
};
for (var i = 0 ; i < plugins.length; ++i) {
var p = plugins[i];
p.init(plot, classes);
if (p.options)
$.extend(true , options, p.options);
}
}
function parseOptions (opts ) {
$.extend(true , options, opts);
if (opts && opts.colors) {
options.colors = opts.colors;
}
if (options.xaxis.color == null )
options.xaxis.color = $.color.parse(options.grid.color).scale('a' , 0.22 ).toString();
if (options.yaxis.color == null )
options.yaxis.color = $.color.parse(options.grid.color).scale('a' , 0.22 ).toString();
if (options.xaxis.tickColor == null )
options.xaxis.tickColor = options.grid.tickColor || options.xaxis.color;
if (options.yaxis.tickColor == null )
options.yaxis.tickColor = options.grid.tickColor || options.yaxis.color;
if (options.grid.borderColor == null )
options.grid.borderColor = options.grid.color;
if (options.grid.tickColor == null )
options.grid.tickColor = $.color.parse(options.grid.color).scale('a' , 0.22 ).toString();
var i, axisOptions, axisCount,
fontSize = placeholder.css("font-size" ),
fontSizeDefault = fontSize ? +fontSize.replace("px" , "" ) : 13 ,
fontDefaults = {
style : placeholder.css("font-style" ),
size : Math .round(0.8 * fontSizeDefault),
variant : placeholder.css("font-variant" ),
weight : placeholder.css("font-weight" ),
family : placeholder.css("font-family" )
};
axisCount = options.xaxes.length || 1 ;
for (i = 0 ; i < axisCount; ++i) {
axisOptions = options.xaxes[i];
if (axisOptions && !axisOptions.tickColor) {
axisOptions.tickColor = axisOptions.color;
}
axisOptions = $.extend(true , {}, options.xaxis, axisOptions);
options.xaxes[i] = axisOptions;
if (axisOptions.font) {
axisOptions.font = $.extend({}, fontDefaults, axisOptions.font);
if (!axisOptions.font.color) {
axisOptions.font.color = axisOptions.color;
}
if (!axisOptions.font.lineHeight) {
axisOptions.font.lineHeight = Math .round(axisOptions.font.size * 1.15 );
}
}
}
axisCount = options.yaxes.length || 1 ;
for (i = 0 ; i < axisCount; ++i) {
axisOptions = options.yaxes[i];
if (axisOptions && !axisOptions.tickColor) {
axisOptions.tickColor = axisOptions.color;
}
axisOptions = $.extend(true , {}, options.yaxis, axisOptions);
options.yaxes[i] = axisOptions;
if (axisOptions.font) {
axisOptions.font = $.extend({}, fontDefaults, axisOptions.font);
if (!axisOptions.font.color) {
axisOptions.font.color = axisOptions.color;
}
if (!axisOptions.font.lineHeight) {
axisOptions.font.lineHeight = Math .round(axisOptions.font.size * 1.15 );
}
}
}
if (options.xaxis.noTicks && options.xaxis.ticks == null )
options.xaxis.ticks = options.xaxis.noTicks;
if (options.yaxis.noTicks && options.yaxis.ticks == null )
options.yaxis.ticks = options.yaxis.noTicks;
if (options.x2axis) {
options.xaxes[1 ] = $.extend(true , {}, options.xaxis, options.x2axis);
options.xaxes[1 ].position = "top" ;
if (options.x2axis.min == null ) {
options.xaxes[1 ].min = null ;
}
if (options.x2axis.max == null ) {
options.xaxes[1 ].max = null ;
}
}
if (options.y2axis) {
options.yaxes[1 ] = $.extend(true , {}, options.yaxis, options.y2axis);
options.yaxes[1 ].position = "right" ;
if (options.y2axis.min == null ) {
options.yaxes[1 ].min = null ;
}
if (options.y2axis.max == null ) {
options.yaxes[1 ].max = null ;
}
}
if (options.grid.coloredAreas)
options.grid.markings = options.grid.coloredAreas;
if (options.grid.coloredAreasColor)
options.grid.markingsColor = options.grid.coloredAreasColor;
if (options.lines)
$.extend(true , options.series.lines, options.lines);
if (options.points)
$.extend(true , options.series.points, options.points);
if (options.bars)
$.extend(true , options.series.bars, options.bars);
if (options.shadowSize != null )
options.series.shadowSize = options.shadowSize;
if (options.highlightColor != null )
options.series.highlightColor = options.highlightColor;
for (i = 0 ; i < options.xaxes.length; ++i)
getOrCreateAxis(xaxes, i + 1 ).options = options.xaxes[i];
for (i = 0 ; i < options.yaxes.length; ++i)
getOrCreateAxis(yaxes, i + 1 ).options = options.yaxes[i];
for (var n in hooks)
if (options.hooks[n] && options.hooks[n].length)
hooks[n] = hooks[n].concat(options.hooks[n]);
executeHooks(hooks.processOptions, [options]);
}
function setData (d ) {
series = parseData(d);
fillInSeriesOptions();
processData();
}
function parseData (d ) {
var res = [];
for (var i = 0 ; i < d.length; ++i) {
var s = $.extend(true , {}, options.series);
if (d[i].data != null ) {
s.data = d[i].data;
delete d[i].data;
$.extend(true , s, d[i]);
d[i].data = s.data;
}
else
s.data = d[i];
res.push(s);
}
return res;
}
function axisNumber (obj, coord ) {
var a = obj[coord + "axis" ];
if (typeof a == "object" )
a = a.n;
if (typeof a != "number" )
a = 1 ;
return a;
}
function allAxes ( ) {
return $.grep(xaxes.concat(yaxes), function (a ) { return a; });
}
function canvasToAxisCoords (pos ) {
var res = {}, i, axis;
for (i = 0 ; i < xaxes.length; ++i) {
axis = xaxes[i];
if (axis && axis.used)
res["x" + axis.n] = axis.c2p(pos.left);
}
for (i = 0 ; i < yaxes.length; ++i) {
axis = yaxes[i];
if (axis && axis.used)
res["y" + axis.n] = axis.c2p(pos.top);
}
if (res.x1 !== undefined )
res.x = res.x1;
if (res.y1 !== undefined )
res.y = res.y1;
return res;
}
function axisToCanvasCoords (pos ) {
var res = {}, i, axis, key;
for (i = 0 ; i < xaxes.length; ++i) {
axis = xaxes[i];
if (axis && axis.used) {
key = "x" + axis.n;
if (pos[key] == null && axis.n == 1 )
key = "x" ;
if (pos[key] != null ) {
res.left = axis.p2c(pos[key]);
break ;
}
}
}
for (i = 0 ; i < yaxes.length; ++i) {
axis = yaxes[i];
if (axis && axis.used) {
key = "y" + axis.n;
if (pos[key] == null && axis.n == 1 )
key = "y" ;
if (pos[key] != null ) {
res.top = axis.p2c(pos[key]);
break ;
}
}
}
return res;
}
function getOrCreateAxis (axes, number ) {
if (!axes[number - 1 ])
axes[number - 1 ] = {
n : number,
direction: axes == xaxes ? "x" : "y" ,
options : $.extend(true , {}, axes == xaxes ? options.xaxis : options.yaxis)
};
return axes[number - 1 ];
}
function fillInSeriesOptions ( ) {
var neededColors = series.length, maxIndex = -1 , i;
for (i = 0 ; i < series.length; ++i) {
var sc = series[i].color;
if (sc != null ) {
neededColors--;
if (typeof sc == "number" && sc > maxIndex) {
maxIndex = sc;
}
}
}
if (neededColors <= maxIndex) {
neededColors = maxIndex + 1 ;
}
var c, colors = [], colorPool = options.colors,
colorPoolSize = colorPool.length, variation = 0 ;
for (i = 0 ; i < neededColors; i++) {
c = $.color.parse(colorPool[i % colorPoolSize] || "#666" );
if (i % colorPoolSize == 0 && i) {
if (variation >= 0 ) {
if (variation < 0.5 ) {
variation = -variation - 0.2 ;
} else variation = 0 ;
} else variation = -variation;
}
colors[i] = c.scale('rgb' , 1 + variation);
}
var colori = 0 , s;
for (i = 0 ; i < series.length; ++i) {
s = series[i];
if (s.color == null ) {
s.color = colors[colori].toString();
++colori;
}
else if (typeof s.color == "number" )
s.color = colors[s.color].toString();
if (s.lines.show == null ) {
var v, show = true ;
for (v in s)
if (s[v] && s[v].show) {
show = false ;
break ;
}
if (show)
s.lines.show = true ;
}
if (s.lines.zero == null ) {
s.lines.zero = !!s.lines.fill;
}
s.xaxis = getOrCreateAxis(xaxes, axisNumber(s, "x" ));
s.yaxis = getOrCreateAxis(yaxes, axisNumber(s, "y" ));
}
}
function processData ( ) {
var topSentry = Number .POSITIVE_INFINITY,
bottomSentry = Number .NEGATIVE_INFINITY,
fakeInfinity = Number .MAX_VALUE,
i, j, k, m, length,
s, points, ps, x, y, axis, val, f, p,
data, format;
function updateAxis (axis, min, max ) {
if (min < axis.datamin && min != -fakeInfinity)
axis.datamin = min;
if (max > axis.datamax && max != fakeInfinity)
axis.datamax = max;
}
$.each(allAxes(), function (_, axis ) {
axis.datamin = topSentry;
axis.datamax = bottomSentry;
axis.used = false ;
});
for (i = 0 ; i < series.length; ++i) {
s = series[i];
s.datapoints = { points : [] };
executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]);
}
for (i = 0 ; i < series.length; ++i) {
s = series[i];
data = s.data;
format = s.datapoints.format;
if (!format) {
format = [];
format.push({ x : true , number : true , required : true });
format.push({ y : true , number : true , required : true });
if (s.bars.show || (s.lines.show && s.lines.fill)) {
var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero));
format.push({ y : true , number : true , required : false , defaultValue : 0 , autoscale : autoscale });
if (s.bars.horizontal) {
delete format[format.length - 1 ].y;
format[format.length - 1 ].x = true ;
}
}
s.datapoints.format = format;
}
if (s.datapoints.pointsize != null )
continue ;
s.datapoints.pointsize = format.length;
ps = s.datapoints.pointsize;
points = s.datapoints.points;
var insertSteps = s.lines.show && s.lines.steps;
s.xaxis.used = s.yaxis.used = true ;
for (j = k = 0 ; j < data.length; ++j, k += ps) {
p = data[j];
var nullify = p == null ;
if (!nullify) {
for (m = 0 ; m < ps; ++m) {
val = p[m];
f = format[m];
if (f) {
if (f.number && val != null ) {
val = +val;
if (isNaN (val))
val = null ;
else if (val == Infinity )
val = fakeInfinity;
else if (val == -Infinity )
val = -fakeInfinity;
}
if (val == null ) {
if (f.required)
nullify = true ;
if (f.defaultValue != null )
val = f.defaultValue;
}
}
points[k + m] = val;
}
}
if (nullify) {
for (m = 0 ; m < ps; ++m) {
val = points[k + m];
if (val != null ) {
f = format[m];
if (f.autoscale !== false ) {
if (f.x) {
updateAxis(s.xaxis, val, val);
}
if (f.y) {
updateAxis(s.yaxis, val, val);
}
}
}
points[k + m] = null ;
}
}
else {
if (insertSteps && k > 0
&& points[k - ps] != null
&& points[k - ps] != points[k]
&& points[k - ps + 1 ] != points[k + 1 ]) {
for (m = 0 ; m < ps; ++m)
points[k + ps + m] = points[k + m];
points[k + 1 ] = points[k - ps + 1 ];
k += ps;
}
}
}
}
for (i = 0 ; i < series.length; ++i) {
s = series[i];
executeHooks(hooks.processDatapoints, [ s, s.datapoints]);
}
for (i = 0 ; i < series.length; ++i) {
s = series[i];
points = s.datapoints.points;
ps = s.datapoints.pointsize;
format = s.datapoints.format;
var xmin = topSentry, ymin = topSentry,
xmax = bottomSentry, ymax = bottomSentry;
for (j = 0 ; j < points.length; j += ps) {
if (points[j] == null )
continue ;
for (m = 0 ; m < ps; ++m) {
val = points[j + m];
f = format[m];
if (!f || f.autoscale === false || val == fakeInfinity || val == -fakeInfinity)
continue ;
if (f.x) {
if (val < xmin)
xmin = val;
if (val > xmax)
xmax = val;
}
if (f.y) {
if (val < ymin)
ymin = val;
if (val > ymax)
ymax = val;
}
}
}
if (s.bars.show) {
var delta;
switch (s.bars.align) {
case "left" :
delta = 0 ;
break ;
case "right" :
delta = -s.bars.barWidth;
break ;
default :
delta = -s.bars.barWidth / 2 ;
}
if (s.bars.horizontal) {
ymin += delta;
ymax += delta + s.bars.barWidth;
}
else {
xmin += delta;
xmax += delta + s.bars.barWidth;
}
}
updateAxis(s.xaxis, xmin, xmax);
updateAxis(s.yaxis, ymin, ymax);
}
$.each(allAxes(), function (_, axis ) {
if (axis.datamin == topSentry)
axis.datamin = null ;
if (axis.datamax == bottomSentry)
axis.datamax = null ;
});
}
function setupCanvases ( ) {
placeholder.css("padding" , 0 )
.children().filter(function ( ) {
return !$(this ).hasClass("flot-overlay" ) && !$(this ).hasClass('flot-base' );
}).remove();
if (placeholder.css("position" ) == 'static' )
placeholder.css("position" , "relative" );
surface = new Canvas("flot-base" , placeholder);
overlay = new Canvas("flot-overlay" , placeholder);
ctx = surface.context;
octx = overlay.context;
eventHolder = $(overlay.element).unbind();
var existing = placeholder.data("plot" );
if (existing) {
existing.shutdown();
overlay.clear();
}
placeholder.data("plot" , plot);
}
function bindEvents ( ) {
if (options.grid.hoverable) {
eventHolder.mousemove(onMouseMove);
eventHolder.bind("mouseleave" , onMouseLeave);
}
if (options.grid.clickable)
eventHolder.click(onClick);
executeHooks(hooks.bindEvents, [eventHolder]);
}
function shutdown ( ) {
if (redrawTimeout)
clearTimeout(redrawTimeout);
eventHolder.unbind("mousemove" , onMouseMove);
eventHolder.unbind("mouseleave" , onMouseLeave);
eventHolder.unbind("click" , onClick);
executeHooks(hooks.shutdown, [eventHolder]);
}
function setTransformationHelpers (axis ) {
function identity (x ) { return x; }
var s, m, t = axis.options.transform || identity,
it = axis.options.inverseTransform;
if (axis.direction == "x" ) {
s = axis.scale = plotWidth / Math .abs(t(axis.max) - t(axis.min));
m = Math .min(t(axis.max), t(axis.min));
}
else {
s = axis.scale = plotHeight / Math .abs(t(axis.max) - t(axis.min));
s = -s;
m = Math .max(t(axis.max), t(axis.min));
}
if (t == identity)
axis.p2c = function (p ) { return (p - m) * s; };
else
axis.p2c = function (p ) { return (t(p) - m) * s; };
if (!it)
axis.c2p = function (c ) { return m + c / s; };
else
axis.c2p = function (c ) { return it(m + c / s); };
}
function measureTickLabels (axis ) {
var opts = axis.options,
ticks = axis.ticks || [],
labelWidth = opts.labelWidth || 0 ,
labelHeight = opts.labelHeight || 0 ,
maxWidth = labelWidth || (axis.direction == "x" ? Math .floor(surface.width / (ticks.length || 1 )) : null ),
legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis" ,
layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles,
font = opts.font || "flot-tick-label tickLabel" ;
for (var i = 0 ; i < ticks.length; ++i) {
var t = ticks[i];
if (!t.label)
continue ;
var info = surface.getTextInfo(layer, t.label, font, null , maxWidth);
labelWidth = Math .max(labelWidth, info.width);
labelHeight = Math .max(labelHeight, info.height);
}
axis.labelWidth = opts.labelWidth || labelWidth;
axis.labelHeight = opts.labelHeight || labelHeight;
}
function allocateAxisBoxFirstPhase (axis ) {
var lw = axis.labelWidth,
lh = axis.labelHeight,
pos = axis.options.position,
isXAxis = axis.direction === "x" ,
tickLength = axis.options.tickLength,
axisMargin = options.grid.axisMargin,
padding = options.grid.labelMargin,
innermost = true ,
outermost = true ,
first = true ,
found = false ;
$.each(isXAxis ? xaxes : yaxes, function (i, a ) {
if (a && (a.show || a.reserveSpace)) {
if (a === axis) {
found = true ;
} else if (a.options.position === pos) {
if (found) {
outermost = false ;
} else {
innermost = false ;
}
}
if (!found) {
first = false ;
}
}
});
if (outermost) {
axisMargin = 0 ;
}
if (tickLength == null ) {
tickLength = first ? "full" : 5 ;
}
if (!isNaN (+tickLength))
padding += +tickLength;
if (isXAxis) {
lh += padding;
if (pos == "bottom" ) {
plotOffset.bottom += lh + axisMargin;
axis.box = { top : surface.height - plotOffset.bottom, height : lh };
}
else {
axis.box = { top : plotOffset.top + axisMargin, height : lh };
plotOffset.top += lh + axisMargin;
}
}
else {
lw += padding;
if (pos == "left" ) {
axis.box = { left : plotOffset.left + axisMargin, width : lw };
plotOffset.left += lw + axisMargin;
}
else {
plotOffset.right += lw + axisMargin;
axis.box = { left : surface.width - plotOffset.right, width : lw };
}
}
axis.position = pos;
axis.tickLength = tickLength;
axis.box.padding = padding;
axis.innermost = innermost;
}
function allocateAxisBoxSecondPhase (axis ) {
if (axis.direction == "x" ) {
axis.box.left = plotOffset.left - axis.labelWidth / 2 ;
axis.box.width = surface.width - plotOffset.left - plotOffset.right + axis.labelWidth;
}
else {
axis.box.top = plotOffset.top - axis.labelHeight / 2 ;
axis.box.height = surface.height - plotOffset.bottom - plotOffset.top + axis.labelHeight;
}
}
function adjustLayoutForThingsStickingOut ( ) {
var minMargin = options.grid.minBorderMargin,
axis, i;
if (minMargin == null ) {
minMargin = 0 ;
for (i = 0 ; i < series.length; ++i)
minMargin = Math .max(minMargin, 2 * (series[i].points.radius + series[i].points.lineWidth/2 ));
}
var margins = {
left : minMargin,
right : minMargin,
top : minMargin,
bottom : minMargin
};
$.each(allAxes(), function (_, axis ) {
if (axis.reserveSpace && axis.ticks && axis.ticks.length) {
if (axis.direction === "x" ) {
margins.left = Math .max(margins.left, axis.labelWidth / 2 );
margins.right = Math .max(margins.right, axis.labelWidth / 2 );
} else {
margins.bottom = Math .max(margins.bottom, axis.labelHeight / 2 );
margins.top = Math .max(margins.top, axis.labelHeight / 2 );
}
}
});
plotOffset.left = Math .ceil(Math .max(margins.left, plotOffset.left));
plotOffset.right = Math .ceil(Math .max(margins.right, plotOffset.right));
plotOffset.top = Math .ceil(Math .max(margins.top, plotOffset.top));
plotOffset.bottom = Math .ceil(Math .max(margins.bottom, plotOffset.bottom));
}
function setupGrid ( ) {
var i, axes = allAxes(), showGrid = options.grid.show;
for (var a in plotOffset) {
var margin = options.grid.margin || 0 ;
plotOffset[a] = typeof margin == "number" ? margin : margin[a] || 0 ;
}
executeHooks(hooks.processOffset, [plotOffset]);
for (var a in plotOffset) {
if (typeof (options.grid.borderWidth) == "object" ) {
plotOffset[a] += showGrid ? options.grid.borderWidth[a] : 0 ;
}
else {
plotOffset[a] += showGrid ? options.grid.borderWidth : 0 ;
}
}
$.each(axes, function (_, axis ) {
var axisOpts = axis.options;
axis.show = axisOpts.show == null ? axis.used : axisOpts.show;
axis.reserveSpace = axisOpts.reserveSpace == null ? axis.show : axisOpts.reserveSpace;
setRange(axis);
});
if (showGrid) {
var allocatedAxes = $.grep(axes, function (axis ) {
return axis.show || axis.reserveSpace;
});
$.each(allocatedAxes, function (_, axis ) {
setupTickGeneration(axis);
setTicks(axis);
snapRangeToTicks(axis, axis.ticks);
measureTickLabels(axis);
});
for (i = allocatedAxes.length - 1 ; i >= 0 ; --i)
allocateAxisBoxFirstPhase(allocatedAxes[i]);
adjustLayoutForThingsStickingOut();
$.each(allocatedAxes, function (_, axis ) {
allocateAxisBoxSecondPhase(axis);
});
}
plotWidth = surface.width - plotOffset.left - plotOffset.right;
plotHeight = surface.height - plotOffset.bottom - plotOffset.top;
$.each(axes, function (_, axis ) {
setTransformationHelpers(axis);
});
if (showGrid) {
drawAxisLabels();
}
insertLegend();
}
function setRange (axis ) {
var opts = axis.options,
min = +(opts.min != null ? opts.min : axis.datamin),
max = +(opts.max != null ? opts.max : axis.datamax),
delta = max - min;
if (delta == 0.0 ) {
var widen = max == 0 ? 1 : 0.01 ;
if (opts.min == null )
min -= widen;
if (opts.max == null || opts.min != null )
max += widen;
}
else {
var margin = opts.autoscaleMargin;
if (margin != null ) {
if (opts.min == null ) {
min -= delta * margin;
if (min < 0 && axis.datamin != null && axis.datamin >= 0 )
min = 0 ;
}
if (opts.max == null ) {
max += delta * margin;
if (max > 0 && axis.datamax != null && axis.datamax <= 0 )
max = 0 ;
}
}
}
axis.min = min;
axis.max = max;
}
function setupTickGeneration (axis ) {
var opts = axis.options;
var noTicks;
if (typeof opts.ticks == "number" && opts.ticks > 0 )
noTicks = opts.ticks;
else
noTicks = 0.3 * Math .sqrt(axis.direction == "x" ? surface.width : surface.height);
var delta = (axis.max - axis.min) / noTicks,
dec = -Math .floor(Math .log(delta) / Math .LN10),
maxDec = opts.tickDecimals;
if (maxDec != null && dec > maxDec) {
dec = maxDec;
}
var magn = Math .pow(10 , -dec),
norm = delta / magn,
size;
if (norm < 1.5 ) {
size = 1 ;
} else if (norm < 3 ) {
size = 2 ;
if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) {
size = 2.5 ;
++dec;
}
} else if (norm < 7.5 ) {
size = 5 ;
} else {
size = 10 ;
}
size *= magn;
if (opts.minTickSize != null && size < opts.minTickSize) {
size = opts.minTickSize;
}
axis.delta = delta;
axis.tickDecimals = Math .max(0 , maxDec != null ? maxDec : dec);
axis.tickSize = opts.tickSize || size;
if (opts.mode == "time" && !axis.tickGenerator) {
throw new Error ("Time mode requires the flot.time plugin." );
}
if (!axis.tickGenerator) {
axis.tickGenerator = function (axis ) {
var ticks = [],
start = floorInBase(axis.min, axis.tickSize),
i = 0 ,
v = Number .NaN,
prev;
do {
prev = v;
v = start + i * axis.tickSize;
ticks.push(v);
++i;
} while (v < axis.max && v != prev);
return ticks;
};
axis.tickFormatter = function (value, axis ) {
var factor = axis.tickDecimals ? Math .pow(10 , axis.tickDecimals) : 1 ;
var formatted = "" + Math .round(value * factor) / factor;
if (axis.tickDecimals != null ) {
var decimal = formatted.indexOf("." );
var precision = decimal == -1 ? 0 : formatted.length - decimal - 1 ;
if (precision < axis.tickDecimals) {
return (precision ? formatted : formatted + "." ) + ("" + factor).substr(1 , axis.tickDecimals - precision);
}
}
return formatted;
};
}
if ($.isFunction(opts.tickFormatter))
axis.tickFormatter = function (v, axis ) { return "" + opts.tickFormatter(v, axis); };
if (opts.alignTicksWithAxis != null ) {
var otherAxis = (axis.direction == "x" ? xaxes : yaxes)[opts.alignTicksWithAxis - 1 ];
if (otherAxis && otherAxis.used && otherAxis != axis) {
var niceTicks = axis.tickGenerator(axis);
if (niceTicks.length > 0 ) {
if (opts.min == null )
axis.min = Math .min(axis.min, niceTicks[0 ]);
if (opts.max == null && niceTicks.length > 1 )
axis.max = Math .max(axis.max, niceTicks[niceTicks.length - 1 ]);
}
axis.tickGenerator = function (axis ) {
var ticks = [], v, i;
for (i = 0 ; i < otherAxis.ticks.length; ++i) {
v = (otherAxis.ticks[i].v - otherAxis.min) / (otherAxis.max - otherAxis.min);
v = axis.min + v * (axis.max - axis.min);
ticks.push(v);
}
return ticks;
};
if (!axis.mode && opts.tickDecimals == null ) {
var extraDec = Math .max(0 , -Math .floor(Math .log(axis.delta) / Math .LN10) + 1 ),
ts = axis.tickGenerator(axis);
if (!(ts.length > 1 && /\..*0$/ .test((ts[1 ] - ts[0 ]).toFixed(extraDec))))
axis.tickDecimals = extraDec;
}
}
}
}
function setTicks (axis ) {
var oticks = axis.options.ticks, ticks = [];
if (oticks == null || (typeof oticks == "number" && oticks > 0 ))
ticks = axis.tickGenerator(axis);
else if (oticks) {
if ($.isFunction(oticks))
ticks = oticks(axis);
else
ticks = oticks;
}
var i, v;
axis.ticks = [];
for (i = 0 ; i < ticks.length; ++i) {
var label = null ;
var t = ticks[i];
if (typeof t == "object" ) {
v = +t[0 ];
if (t.length > 1 )
label = t[1 ];
}
else
v = +t;
if (label == null )
label = axis.tickFormatter(v, axis);
if (!isNaN (v))
axis.ticks.push({ v : v, label : label });
}
}
function snapRangeToTicks (axis, ticks ) {
if (axis.options.autoscaleMargin && ticks.length > 0 ) {
if (axis.options.min == null )
axis.min = Math .min(axis.min, ticks[0 ].v);
if (axis.options.max == null && ticks.length > 1 )
axis.max = Math .max(axis.max, ticks[ticks.length - 1 ].v);
}
}
function draw ( ) {
surface.clear();
executeHooks(hooks.drawBackground, [ctx]);
var grid = options.grid;
if (grid.show && grid.backgroundColor)
drawBackground();
if (grid.show && !grid.aboveData) {
drawGrid();
}
for (var i = 0 ; i < series.length; ++i) {
executeHooks(hooks.drawSeries, [ctx, series[i]]);
drawSeries(series[i]);
}
executeHooks(hooks.draw, [ctx]);
if (grid.show && grid.aboveData) {
drawGrid();
}
surface.render();
triggerRedrawOverlay();
}
function extractRange (ranges, coord ) {
var axis, from , to, key, axes = allAxes();
for (var i = 0 ; i < axes.length; ++i) {
axis = axes[i];
if (axis.direction == coord) {
key = coord + axis.n + "axis" ;
if (!ranges[key] && axis.n == 1 )
key = coord + "axis" ;
if (ranges[key]) {
from = ranges[key].from;
to = ranges[key].to;
break ;
}
}
}
if (!ranges[key]) {
axis = coord == "x" ? xaxes[0 ] : yaxes[0 ];
from = ranges[coord + "1" ];
to = ranges[coord + "2" ];
}
if (from != null && to != null && from > to) {
var tmp = from ;
from = to;
to = tmp;
}
return { from : from , to : to, axis : axis };
}
function drawBackground ( ) {
ctx.save();
ctx.translate(plotOffset.left, plotOffset.top);
ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0 , "rgba(255, 255, 255, 0)" );
ctx.fillRect(0 , 0 , plotWidth, plotHeight);
ctx.restore();
}
function drawGrid ( ) {
var i, axes, bw, bc;
ctx.save();
ctx.translate(plotOffset.left, plotOffset.top);
var markings = options.grid.markings;
if (markings) {
if ($.isFunction(markings)) {
axes = plot.getAxes();
axes.xmin = axes.xaxis.min;
axes.xmax = axes.xaxis.max;
axes.ymin = axes.yaxis.min;
axes.ymax = axes.yaxis.max;
markings = markings(axes);
}
for (i = 0 ; i < markings.length; ++i) {
var m = markings[i],
xrange = extractRange(m, "x" ),
yrange = extractRange(m, "y" );
if (xrange.from == null )
xrange.from = xrange.axis.min;
if (xrange.to == null )
xrange.to = xrange.axis.max;
if (yrange.from == null )
yrange.from = yrange.axis.min;
if (yrange.to == null )
yrange.to = yrange.axis.max;
if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max ||
yrange.to < yrange.axis.min || yrange.from > yrange.axis.max)
continue ;
xrange.from = Math .max(xrange.from, xrange.axis.min);
xrange.to = Math .min(xrange.to, xrange.axis.max);
yrange.from = Math .max(yrange.from, yrange.axis.min);
yrange.to = Math .min(yrange.to, yrange.axis.max);
var xequal = xrange.from === xrange.to,
yequal = yrange.from === yrange.to;
if (xequal && yequal) {
continue ;
}
xrange.from = Math .floor(xrange.axis.p2c(xrange.from));
xrange.to = Math .floor(xrange.axis.p2c(xrange.to));
yrange.from = Math .floor(yrange.axis.p2c(yrange.from));
yrange.to = Math .floor(yrange.axis.p2c(yrange.to));
if (xequal || yequal) {
var lineWidth = m.lineWidth || options.grid.markingsLineWidth,
subPixel = lineWidth % 2 ? 0.5 : 0 ;
ctx.beginPath();
ctx.strokeStyle = m.color || options.grid.markingsColor;
ctx.lineWidth = lineWidth;
if (xequal) {
ctx.moveTo(xrange.to + subPixel, yrange.from);
ctx.lineTo(xrange.to + subPixel, yrange.to);
} else {
ctx.moveTo(xrange.from, yrange.to + subPixel);
ctx.lineTo(xrange.to, yrange.to + subPixel);
}
ctx.stroke();
} else {
ctx.fillStyle = m.color || options.grid.markingsColor;
ctx.fillRect(xrange.from, yrange.to,
xrange.to - xrange.from,
yrange.from - yrange.to);
}
}
}
axes = allAxes();
bw = options.grid.borderWidth;
for (var j = 0 ; j < axes.length; ++j) {
var axis = axes[j], box = axis.box,
t = axis.tickLength, x, y, xoff, yoff;
if (!axis.show || axis.ticks.length == 0 )
continue ;
ctx.lineWidth = 1 ;
if (axis.direction == "x" ) {
x = 0 ;
if (t == "full" )
y = (axis.position == "top" ? 0 : plotHeight);
else
y = box.top - plotOffset.top + (axis.position == "top" ? box.height : 0 );
}
else {
y = 0 ;
if (t == "full" )
x = (axis.position == "left" ? 0 : plotWidth);
else
x = box.left - plotOffset.left + (axis.position == "left" ? box.width : 0 );
}
if (!axis.innermost) {
ctx.strokeStyle = axis.options.color;
ctx.beginPath();
xoff = yoff = 0 ;
if (axis.direction == "x" )
xoff = plotWidth + 1 ;
else
yoff = plotHeight + 1 ;
if (ctx.lineWidth == 1 ) {
if (axis.direction == "x" ) {
y = Math .floor(y) + 0.5 ;
} else {
x = Math .floor(x) + 0.5 ;
}
}
ctx.moveTo(x, y);
ctx.lineTo(x + xoff, y + yoff);
ctx.stroke();
}
ctx.strokeStyle = axis.options.tickColor;
ctx.beginPath();
for (i = 0 ; i < axis.ticks.length; ++i) {
var v = axis.ticks[i].v;
xoff = yoff = 0 ;
if (isNaN (v) || v < axis.min || v > axis.max
|| (t == "full"
&& ((typeof bw == "object" && bw[axis.position] > 0 ) || bw > 0 )
&& (v == axis.min || v == axis.max)))
continue ;
if (axis.direction == "x" ) {
x = axis.p2c(v);
yoff = t == "full" ? -plotHeight : t;
if (axis.position == "top" )
yoff = -yoff;
}
else {
y = axis.p2c(v);
xoff = t == "full" ? -plotWidth : t;
if (axis.position == "left" )
xoff = -xoff;
}
if (ctx.lineWidth == 1 ) {
if (axis.direction == "x" )
x = Math .floor(x) + 0.5 ;
else
y = Math .floor(y) + 0.5 ;
}
ctx.moveTo(x, y);
ctx.lineTo(x + xoff, y + yoff);
}
ctx.stroke();
}
if (bw) {
bc = options.grid.borderColor;
if (typeof bw == "object" || typeof bc == "object" ) {
if (typeof bw !== "object" ) {
bw = {top : bw, right : bw, bottom : bw, left : bw};
}
if (typeof bc !== "object" ) {
bc = {top : bc, right : bc, bottom : bc, left : bc};
}
if (bw.top > 0 ) {
ctx.strokeStyle = bc.top;
ctx.lineWidth = bw.top;
ctx.beginPath();
ctx.moveTo(0 - bw.left, 0 - bw.top/2 );
ctx.lineTo(plotWidth, 0 - bw.top/2 );
ctx.stroke();
}
if (bw.right > 0 ) {
ctx.strokeStyle = bc.right;
ctx.lineWidth = bw.right;
ctx.beginPath();
ctx.moveTo(plotWidth + bw.right / 2 , 0 - bw.top);
ctx.lineTo(plotWidth + bw.right / 2 , plotHeight);
ctx.stroke();
}
if (bw.bottom > 0 ) {
ctx.strokeStyle = bc.bottom;
ctx.lineWidth = bw.bottom;
ctx.beginPath();
ctx.moveTo(plotWidth + bw.right, plotHeight + bw.bottom / 2 );
ctx.lineTo(0 , plotHeight + bw.bottom / 2 );
ctx.stroke();
}
if (bw.left > 0 ) {
ctx.strokeStyle = bc.left;
ctx.lineWidth = bw.left;
ctx.beginPath();
ctx.moveTo(0 - bw.left/2 , plotHeight + bw.bottom);
ctx.lineTo(0 - bw.left/2 , 0 );
ctx.stroke();
}
}
else {
ctx.lineWidth = bw;
ctx.strokeStyle = options.grid.borderColor;
ctx.strokeRect(-bw/2 , -bw/2 , plotWidth + bw, plotHeight + bw);
}
}
ctx.restore();
}
function drawAxisLabels ( ) {
$.each(allAxes(), function (_, axis ) {
var box = axis.box,
legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis" ,
layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles,
font = axis.options.font || "flot-tick-label tickLabel" ,
tick, x, y, halign, valign;
surface.removeText(layer);
if (!axis.show || axis.ticks.length == 0 )
return ;
for (var i = 0 ; i < axis.ticks.length; ++i) {
tick = axis.ticks[i];
if (!tick.label || tick.v < axis.min || tick.v > axis.max)
continue ;
if (axis.direction == "x" ) {
halign = "center" ;
x = plotOffset.left + axis.p2c(tick.v);
if (axis.position == "bottom" ) {
y = box.top + box.padding;
} else {
y = box.top + box.height - box.padding;
valign = "bottom" ;
}
} else {
valign = "middle" ;
y = plotOffset.top + axis.p2c(tick.v);
if (axis.position == "left" ) {
x = box.left + box.width - box.padding;
halign = "right" ;
} else {
x = box.left + box.padding;
}
}
surface.addText(layer, x, y, tick.label, font, null , null , halign, valign);
}
});
}
function drawSeries (series ) {
if (series.lines.show)
drawSeriesLines(series);
if (series.bars.show)
drawSeriesBars(series);
if (series.points.show)
drawSeriesPoints(series);
}
function drawSeriesLines (series ) {
function plotLine (datapoints, xoffset, yoffset, axisx, axisy ) {
var points = datapoints.points,
ps = datapoints.pointsize,
prevx = null , prevy = null ;
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 ;
if (y1 <= y2 && y1 < axisy.min) {
if (y2 < axisy.min)
continue ;
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;
}
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;
}
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;
}
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);
prevx = x2;
prevy = y2;
ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset);
}
ctx.stroke();
}
function plotLineArea (datapoints, axisx, axisy ) {
var points = datapoints.points,
ps = datapoints.pointsize,
bottom = Math .min(Math .max(0 , axisy.min), axisy.max),
i = 0 , top, areaOpen = false ,
ypos = 1 , segmentStart = 0 , segmentEnd = 0 ;
while (true ) {
if (ps > 0 && i > points.length + ps)
break ;
i += ps;
var x1 = points[i - ps],
y1 = points[i - ps + ypos],
x2 = points[i], y2 = points[i + ypos];
if (areaOpen) {
if (ps > 0 && x1 != null && x2 == null ) {
segmentEnd = i;
ps = -ps;
ypos = 2 ;
continue ;
}
if (ps < 0 && i == segmentStart + ps) {
ctx.fill();
areaOpen = false ;
ps = -ps;
ypos = 1 ;
i = segmentStart = segmentEnd + ps;
continue ;
}
}
if (x1 == null || x2 == null )
continue ;
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;
}
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 (!areaOpen) {
ctx.beginPath();
ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom));
areaOpen = true ;
}
if (y1 >= axisy.max && y2 >= axisy.max) {
ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max));
ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max));
continue ;
}
else if (y1 <= axisy.min && y2 <= axisy.min) {
ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min));
ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min));
continue ;
}
var x1old = x1, x2old = x2;
if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) {
x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
y1 = axisy.min;
}
else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) {
x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
y2 = axisy.min;
}
if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) {
x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
y1 = axisy.max;
}
else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) {
x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
y2 = axisy.max;
}
if (x1 != x1old) {
ctx.lineTo(axisx.p2c(x1old), axisy.p2c(y1));
}
ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1));
ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
if (x2 != x2old) {
ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
ctx.lineTo(axisx.p2c(x2old), axisy.p2c(y2));
}
}
}
ctx.save();
ctx.translate(plotOffset.left, plotOffset.top);
ctx.lineJoin = "round" ;
var lw = series.lines.lineWidth,
sw = series.shadowSize;
if (lw > 0 && sw > 0 ) {
ctx.lineWidth = sw;
ctx.strokeStyle = "rgba(0,0,0,0.1)" ;
var angle = Math .PI/18 ;
plotLine(series.datapoints, Math .sin(angle) * (lw/2 + sw/2 ), Math .cos(angle) * (lw/2 + sw/2 ), series.xaxis, series.yaxis);
ctx.lineWidth = sw/2 ;
plotLine(series.datapoints, Math .sin(angle) * (lw/2 + sw/4 ), Math .cos(angle) * (lw/2 + sw/4 ), series.xaxis, series.yaxis);
}
ctx.lineWidth = lw;
ctx.strokeStyle = series.color;
var fillStyle = getFillStyle(series.lines, series.color, 0 , plotHeight);
if (fillStyle) {
ctx.fillStyle = fillStyle;
plotLineArea(series.datapoints, series.xaxis, series.yaxis);
}
if (lw > 0 )
plotLine(series.datapoints, 0 , 0 , series.xaxis, series.yaxis);
ctx.restore();
}
function drawSeriesPoints (series ) {
function plotPoints (datapoints, radius, fillStyle, offset, shadow, axisx, axisy, symbol ) {
var points = datapoints.points, ps = datapoints.pointsize;
for (var i = 0 ; i < points.length; i += ps) {
var x = points[i], y = points[i + 1 ];
if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
continue ;
ctx.beginPath();
x = axisx.p2c(x);
y = axisy.p2c(y) + offset;
if (symbol == "circle" )
ctx.arc(x, y, radius, 0 , shadow ? Math .PI : Math .PI * 2 , false );
else
symbol(ctx, x, y, radius, shadow);
ctx.closePath();
if (fillStyle) {
ctx.fillStyle = fillStyle;
ctx.fill();
}
ctx.stroke();
}
}
ctx.save();
ctx.translate(plotOffset.left, plotOffset.top);
var lw = series.points.lineWidth,
sw = series.shadowSize,
radius = series.points.radius,
symbol = series.points.symbol;
if ( lw == 0 )
lw = 0.0001 ;
if (lw > 0 && sw > 0 ) {
var w = sw / 2 ;
ctx.lineWidth = w;
ctx.strokeStyle = "rgba(0,0,0,0.1)" ;
plotPoints(series.datapoints, radius, null , w + w/2 , true ,
series.xaxis, series.yaxis, symbol);
ctx.strokeStyle = "rgba(0,0,0,0.2)" ;
plotPoints(series.datapoints, radius, null , w/2 , true ,
series.xaxis, series.yaxis, symbol);
}
ctx.lineWidth = lw;
ctx.strokeStyle = series.color;
plotPoints(series.datapoints, radius,
getFillStyle(series.points, series.color), 0 , false ,
series.xaxis, series.yaxis, symbol);
ctx.restore();
}
function drawBar (x, y, b, barLeft, barRight, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth ) {
var left, right, bottom, top,
drawLeft, drawRight, drawTop, drawBottom,
tmp;
if (horizontal) {
drawBottom = drawRight = drawTop = true ;
drawLeft = false ;
left = b;
right = x;
top = y + barLeft;
bottom = y + barRight;
if (right < left) {
tmp = right;
right = left;
left = tmp;
drawLeft = true ;
drawRight = false ;
}
}
else {
drawLeft = drawRight = drawTop = true ;
drawBottom = false ;
left = x + barLeft;
right = x + barRight;
bottom = b;
top = y;
if (top < bottom) {
tmp = top;
top = bottom;
bottom = tmp;
drawBottom = true ;
drawTop = false ;
}
}
if (right < axisx.min || left > axisx.max ||
top < axisy.min || bottom > axisy.max)
return ;
if (left < axisx.min) {
left = axisx.min;
drawLeft = false ;
}
if (right > axisx.max) {
right = axisx.max;
drawRight = false ;
}
if (bottom < axisy.min) {
bottom = axisy.min;
drawBottom = false ;
}
if (top > axisy.max) {
top = axisy.max;
drawTop = false ;
}
left = axisx.p2c(left);
bottom = axisy.p2c(bottom);
right = axisx.p2c(right);
top = axisy.p2c(top);
if (fillStyleCallback) {
c.fillStyle = fillStyleCallback(bottom, top);
c.fillRect(left, top, right - left, bottom - top)
}
if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) {
c.beginPath();
c.moveTo(left, bottom);
if (drawLeft)
c.lineTo(left, top);
else
c.moveTo(left, top);
if (drawTop)
c.lineTo(right, top);
else
c.moveTo(right, top);
if (drawRight)
c.lineTo(right, bottom);
else
c.moveTo(right, bottom);
if (drawBottom)
c.lineTo(left, bottom);
else
c.moveTo(left, bottom);
c.stroke();
}
}
function drawSeriesBars (series ) {
function plotBars (datapoints, barLeft, barRight, fillStyleCallback, axisx, axisy ) {
var points = datapoints.points, ps = datapoints.pointsize;
for (var i = 0 ; i < points.length; i += ps) {
if (points[i] == null )
continue ;
drawBar(points[i], points[i + 1 ], points[i + 2 ], barLeft, barRight, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth);
}
}
ctx.save();
ctx.translate(plotOffset.left, plotOffset.top);
ctx.lineWidth = series.bars.lineWidth;
ctx.strokeStyle = series.color;
var barLeft;
switch (series.bars.align) {
case "left" :
barLeft = 0 ;
break ;
case "right" :
barLeft = -series.bars.barWidth;
break ;
default :
barLeft = -series.bars.barWidth / 2 ;
}
var fillStyleCallback = series.bars.fill ? function (bottom, top ) { return getFillStyle(series.bars, series.color, bottom, top); } : null ;
plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, fillStyleCallback, series.xaxis, series.yaxis);
ctx.restore();
}
function getFillStyle (filloptions, seriesColor, bottom, top ) {
var fill = filloptions.fill;
if (!fill)
return null ;
if (filloptions.fillColor)
return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor);
var c = $.color.parse(seriesColor);
c.a = typeof fill == "number" ? fill : 0.4 ;
c.normalize();
return c.toString();
}
function insertLegend ( ) {
if (options.legend.container != null ) {
$(options.legend.container).html("" );
} else {
placeholder.find(".legend" ).remove();
}
if (!options.legend.show) {
return ;
}
var fragments = [], entries = [], rowStarted = false ,
lf = options.legend.labelFormatter, s, label;
for (var i = 0 ; i < series.length; ++i) {
s = series[i];
if (s.label) {
label = lf ? lf(s.label, s) : s.label;
if (label) {
entries.push({
label : label,
color : s.color
});
}
}
}
if (options.legend.sorted) {
if ($.isFunction(options.legend.sorted)) {
entries.sort(options.legend.sorted);
} else if (options.legend.sorted == "reverse" ) {
entries.reverse();
} else {
var ascending = options.legend.sorted != "descending" ;
entries.sort(function (a, b ) {
return a.label == b.label ? 0 : (
(a.label < b.label) != ascending ? 1 : -1
);
});
}
}
for (var i = 0 ; i < entries.length; ++i) {
var entry = entries[i];
if (i % options.legend.noColumns == 0 ) {
if (rowStarted)
fragments.push('' );
fragments.push('' );
rowStarted = true ;
}
fragments.push(
' ' +
'' + entry.label + ''
);
}
if (rowStarted)
fragments.push('' );
if (fragments.length == 0 )
return ;
var table = '' + fragments.join("" ) + ' ' ;
if (options.legend.container != null )
$(options.legend.container).html(table);
else {
var pos = "" ,
p = options.legend.position,
m = options.legend.margin;
if (m[0 ] == null )
m = [m, m];
if (p.charAt(0 ) == "n" )
pos += 'top:' + (m[1 ] + plotOffset.top) + 'px;' ;
else if (p.charAt(0 ) == "s" )
pos += 'bottom:' + (m[1 ] + plotOffset.bottom) + 'px;' ;
if (p.charAt(1 ) == "e" )
pos += 'right:' + (m[0 ] + plotOffset.right) + 'px;' ;
else if (p.charAt(1 ) == "w" )
pos += 'left:' + (m[0 ] + plotOffset.left) + 'px;' ;
var legend = $(' ' + table.replace('style="' , 'style="position:absolute;' + pos +';' ) + '
' ).appendTo(placeholder);
if (options.legend.backgroundOpacity != 0.0 ) {
var c = options.legend.backgroundColor;
if (c == null ) {
c = options.grid.backgroundColor;
if (c && typeof c == "string" )
c = $.color.parse(c);
else
c = $.color.extract(legend, 'background-color' );
c.a = 1 ;
c = c.toString();
}
var div = legend.children();
$('
' ).prependTo(legend).css('opacity' , options.legend.backgroundOpacity);
}
}
}
var highlights = [],
redrawTimeout = null ;
function findNearbyItem (mouseX, mouseY, seriesFilter ) {
var maxDistance = options.grid.mouseActiveRadius,
smallestDistance = maxDistance * maxDistance + 1 ,
item = null , foundPoint = false , i, j, ps;
for (i = series.length - 1 ; i >= 0 ; --i) {
if (!seriesFilter(series[i]))
continue ;
var s = series[i],
axisx = s.xaxis,
axisy = s.yaxis,
points = s.datapoints.points,
mx = axisx.c2p(mouseX),
my = axisy.c2p(mouseY),
maxx = maxDistance / axisx.scale,
maxy = maxDistance / axisy.scale;
ps = s.datapoints.pointsize;
if (axisx.options.inverseTransform)
maxx = Number .MAX_VALUE;
if (axisy.options.inverseTransform)
maxy = Number .MAX_VALUE;
if (s.lines.show || s.points.show) {
for (j = 0 ; j < points.length; j += ps) {
var x = points[j], y = points[j + 1 ];
if (x == null )
continue ;
if (x - mx > maxx || x - mx < -maxx ||
y - my > maxy || y - my < -maxy)
continue ;
var dx = Math .abs(axisx.p2c(x) - mouseX),
dy = Math .abs(axisy.p2c(y) - mouseY),
dist = dx * dx + dy * dy;
if (dist < smallestDistance) {
smallestDistance = dist;
item = [i, j / ps];
}
}
}
if (s.bars.show && !item) {
var barLeft, barRight;
switch (s.bars.align) {
case "left" :
barLeft = 0 ;
break ;
case "right" :
barLeft = -s.bars.barWidth;
break ;
default :
barLeft = -s.bars.barWidth / 2 ;
}
barRight = barLeft + s.bars.barWidth;
for (j = 0 ; j < points.length; j += ps) {
var x = points[j], y = points[j + 1 ], b = points[j + 2 ];
if (x == null )
continue ;
if (series[i].bars.horizontal ?
(mx <= Math .max(b, x) && mx >= Math .min(b, x) &&
my >= y + barLeft && my <= y + barRight) :
(mx >= x + barLeft && mx <= x + barRight &&
my >= Math .min(b, y) && my <= Math .max(b, y)))
item = [i, j / ps];
}
}
}
if (item) {
i = item[0 ];
j = item[1 ];
ps = series[i].datapoints.pointsize;
return { datapoint : series[i].datapoints.points.slice(j * ps, (j + 1 ) * ps),
dataIndex : j,
series : series[i],
seriesIndex : i };
}
return null ;
}
function onMouseMove (e ) {
if (options.grid.hoverable)
triggerClickHoverEvent("plothover" , e,
function (s ) { return s["hoverable" ] != false ; });
}
function onMouseLeave (e ) {
if (options.grid.hoverable)
triggerClickHoverEvent("plothover" , e,
function (s ) { return false ; });
}
function onClick (e ) {
triggerClickHoverEvent("plotclick" , e,
function (s ) { return s["clickable" ] != false ; });
}
function triggerClickHoverEvent (eventname, event, seriesFilter ) {
var offset = eventHolder.offset(),
canvasX = event.pageX - offset.left - plotOffset.left,
canvasY = event.pageY - offset.top - plotOffset.top,
pos = canvasToAxisCoords({ left : canvasX, top : canvasY });
pos.pageX = event.pageX;
pos.pageY = event.pageY;
var item = findNearbyItem(canvasX, canvasY, seriesFilter);
if (item) {
item.pageX = parseInt (item.series.xaxis.p2c(item.datapoint[0 ]) + offset.left + plotOffset.left, 10 );
item.pageY = parseInt (item.series.yaxis.p2c(item.datapoint[1 ]) + offset.top + plotOffset.top, 10 );
}
if (options.grid.autoHighlight) {
for (var i = 0 ; i < highlights.length; ++i) {
var h = highlights[i];
if (h.auto == eventname &&
!(item && h.series == item.series &&
h.point[0 ] == item.datapoint[0 ] &&
h.point[1 ] == item.datapoint[1 ]))
unhighlight(h.series, h.point);
}
if (item)
highlight(item.series, item.datapoint, eventname);
}
placeholder.trigger(eventname, [ pos, item ]);
}
function triggerRedrawOverlay ( ) {
var t = options.interaction.redrawOverlayInterval;
if (t == -1 ) {
drawOverlay();
return ;
}
if (!redrawTimeout)
redrawTimeout = setTimeout(drawOverlay, t);
}
function drawOverlay ( ) {
redrawTimeout = null ;
octx.save();
overlay.clear();
octx.translate(plotOffset.left, plotOffset.top);
var i, hi;
for (i = 0 ; i < highlights.length; ++i) {
hi = highlights[i];
if (hi.series.bars.show)
drawBarHighlight(hi.series, hi.point);
else
drawPointHighlight(hi.series, hi.point);
}
octx.restore();
executeHooks(hooks.drawOverlay, [octx]);
}
function highlight (s, point, auto ) {
if (typeof s == "number" )
s = series[s];
if (typeof point == "number" ) {
var ps = s.datapoints.pointsize;
point = s.datapoints.points.slice(ps * point, ps * (point + 1 ));
}
var i = indexOfHighlight(s, point);
if (i == -1 ) {
highlights.push({ series : s, point : point, auto : auto });
triggerRedrawOverlay();
}
else if (!auto)
highlights[i].auto = false ;
}
function unhighlight (s, point ) {
if (s == null && point == null ) {
highlights = [];
triggerRedrawOverlay();
return ;
}
if (typeof s == "number" )
s = series[s];
if (typeof point == "number" ) {
var ps = s.datapoints.pointsize;
point = s.datapoints.points.slice(ps * point, ps * (point + 1 ));
}
var i = indexOfHighlight(s, point);
if (i != -1 ) {
highlights.splice(i, 1 );
triggerRedrawOverlay();
}
}
function indexOfHighlight (s, p ) {
for (var i = 0 ; i < highlights.length; ++i) {
var h = highlights[i];
if (h.series == s && h.point[0 ] == p[0 ]
&& h.point[1 ] == p[1 ])
return i;
}
return -1 ;
}
function drawPointHighlight (series, point ) {
var x = point[0 ], y = point[1 ],
axisx = series.xaxis, axisy = series.yaxis,
highlightColor = (typeof series.highlightColor === "string" ) ? series.highlightColor : $.color.parse(series.color).scale('a' , 0.5 ).toString();
if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
return ;
var pointRadius = series.points.radius + series.points.lineWidth / 2 ;
octx.lineWidth = pointRadius;
octx.strokeStyle = highlightColor;
var radius = 1.5 * pointRadius;
x = axisx.p2c(x);
y = axisy.p2c(y);
octx.beginPath();
if (series.points.symbol == "circle" )
octx.arc(x, y, radius, 0 , 2 * Math .PI, false );
else
series.points.symbol(octx, x, y, radius, false );
octx.closePath();
octx.stroke();
}
function drawBarHighlight (series, point ) {
var highlightColor = (typeof series.highlightColor === "string" ) ? series.highlightColor : $.color.parse(series.color).scale('a' , 0.5 ).toString(),
fillStyle = highlightColor,
barLeft;
switch (series.bars.align) {
case "left" :
barLeft = 0 ;
break ;
case "right" :
barLeft = -series.bars.barWidth;
break ;
default :
barLeft = -series.bars.barWidth / 2 ;
}
octx.lineWidth = series.bars.lineWidth;
octx.strokeStyle = highlightColor;
drawBar(point[0 ], point[1 ], point[2 ] || 0 , barLeft, barLeft + series.bars.barWidth,
function ( ) { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal, series.bars.lineWidth);
}
function getColorOrGradient (spec, bottom, top, defaultColor ) {
if (typeof spec == "string" )
return spec;
else {
var gradient = ctx.createLinearGradient(0 , top, 0 , bottom);
for (var i = 0 , l = spec.colors.length; i < l; ++i) {
var c = spec.colors[i];
if (typeof c != "string" ) {
var co = $.color.parse(defaultColor);
if (c.brightness != null )
co = co.scale('rgb' , c.brightness);
if (c.opacity != null )
co.a *= c.opacity;
c = co.toString();
}
gradient.addColorStop(i / (l - 1 ), c);
}
return gradient;
}
}
}
$.plot = function (placeholder, data, options ) {
var plot = new Plot($(placeholder), data, options, $.plot.plugins);
return plot;
};
$.plot.version = "0.8.3" ;
$.plot.plugins = [];
$.fn.plot = function (data, options ) {
return this .each(function ( ) {
$.plot(this , data, options);
});
};
function floorInBase (n, base ) {
return base * Math .floor(n / base);
}
})(jQuery);