jQWidgets Forums
jQuery UI Widgets › Forums › Navigation › Tabs › flot graph not displayed in jqxTab
Tagged: jQuery Tabs, jqxTabs, tab control, tab flot
This topic contains 6 replies, has 2 voices, and was last updated by mim 12 years, 7 months ago.
-
Author
-
Hi,
tried desparately to get a Flot graph plotted in a tab via the following code.
Can anybody have a look at it? Displayed is just the plot frame without any grid and plot…Kr,
MichaelThis demo demonstrates the jqxDateTimeInput’s range selection mode. Click on a date to select the start date and then click on another cell to select the end date.
<link rel="stylesheet" href="/jqx.base.css” type=”text/css” />
<script type="text/javascript" src="/gettheme.js”>
<script type="text/javascript" src="./jquery-1.8.0.min.js”><script type="text/javascript" src="/jqxcore.js”>
<script type="text/javascript" src="./jqxtabs.js”><script language="javascript" type="text/javascript" src="/jquery.flot.js”>
<?php
if ( !mysql_connect("localhost",,) ) die ( “Error! “.mysql_error() );
mysql_select_db(“Database”);
$db = “Data”;
$query = “SELECT * FROM $db ORDER BY dt”;
$result = mysql_query($query);
while ($row = mysql_fetch_array($result,MYSQL_ASSOC)) {
$Array[] = array( strtotime($row[‘dt’])*1000, floatval($row[$val]) );
} // Eo while
?>$(document).ready(function () {
var dataset = {
“Graph”:{ label: “Plot”,
data:
}
}; // Eo datasetvar options = {
series: { lines: { show: true },
points: { show: false },
},
legend: { noColumns: 2, position: “sw” },
xaxis: { mode: “time”,
timeformat: “%0d.%0m.%y %h:%M”,
minTickSize: [30, “minute”],
}
}; // Eo options// create jqxtabs.
$(‘#jqxtabs’).jqxTabs({ width: 600, height: 400 });$(“#jqxtab”).bind(‘tabsload’, function(event) {
loadChart($(“#plot”), dataset, options);
});function loadChart(chart, chartData,chartOptions) {
if (chart != null) {
var plot = $.plot(chart,chartData,chartOptions);
}
} // Eo loadChart});
Plot
OtherOther ContentHi mim,
I suggest you to take a look at the source of this sample: integration.htm.
Best Wishes,
Peter StoevjQWidgets Team
http://www.jqwidgets.comHi Peter,
I did what you’ve proposed.
But same tab behaviour as described about showed up: chart frame showed, but no grid/chart inside…
The one and only .js I have added was the jquery.flot.js…
Additionally I had to change the initChart function to my needs, changes marked in bold blue:So, what may hinder the plotting of the Chart?
The mysql query and data provisiong works correctly without jqx framework…Kr,
MichaelThis demo shows how to integrate jqxTabs with other widgets.
-->
$(document).ready(function () {
var theme = getTheme();var initGrid = function () {
var source =
{
datatype: "csv",
datafields: [
{ name: 'Date' },
{ name: 'S&P 500' },
{ name: 'NASDAQ' }
],
url: '../sampledata/nasdaq_vs_sp500.txt'
};var dataAdapter = new $.jqx.dataAdapter(source, { async: false, loadError: function (xhr, status, error) {
alert('Error loading "' + source.url + '" : ' + error); } });$("#jqxGrid").jqxGrid(
{
width: '100%',
height: '84%',
source: dataAdapter,
theme: theme,
columns: [
{ text: 'Date', datafield: 'Date', cellsformat: 'd', width: 250 },
{ text: 'S&P 500', datafield: 'S&P 500', width: 150 },
{ text: 'NASDAQ', datafield: 'NASDAQ' }
]
});
}var initChart = function () {
var plotContainer = $("#flotChart"); // plot containervar dataset = {
"Chart":{
label: "Chart",
data:
}
}; // Eo datasetvar options = {
series: { lines: { show: true },
points: { show: false },
},
legend: { noColumns: 1, position: "sw" },
xaxis: { mode: "time"}
}; // Eo optionsplot = $.plot(plotContainer, dataset, options);
} //Eo initChart
// init widgets.
var initWidgets = function (tab) {
switch (tab) {
case 0:
initGrid();
break;
case 1:
initChart();
break;
}
}$('#jqxTabs').jqxTabs({ width: 600, height: 560, theme: theme, initTabContent: initWidgets });
});US IndexesNASDAQ compared to S&P 500The S&P 500 index finished 2011 less than a point away from where it ended 2010
-- 0.04 points down to be exact. That's the smallest annual change in history. At
its peak in April, the S&P had climbed more than 8%. But by October, at the lowest
levels of the year, it was down more than 12%. The Nasdaq, meanwhile, lost 1.8%
for the year.<div id='flotChart' style="width: 100%; height: 100%">Here is for information the jquery.flot.js:
/*! Javascript plotting library for jQuery, v. 0.7.
*
* Released under the MIT license by IOLA, December 2007.
*
*/// first an inline dependency, jquery.colorhelpers.js, we inline it here
// for convenience/* Plugin for jQuery for working with colors.
*
* Version 1.1.
*
* Inspiration from jQuery color animation plugin by John Resig.
*
* Released under the MIT license by Ole Laursen, October 2009.
*
* Examples:
*
* $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString()
* var c = $.color.extract($("#mydiv"), 'background-color');
* console.log(c.r, c.g, c.b, c.a);
* $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)"
*
* Note that .scale() and .add() return the same modified object
* instead of making a new one.
*
* V. 1.1: Fix error handling so e.g. parsing an empty string does
* produce a color rather than just crashing.
*/
(function(B){B.color={};B.color.make=function(F,E,C,D){var G={};G.r=F||0;G.g=E||0;G.b=C||0;G.a=D!=null?D:1;G.add=function(J,I){for(var H=0;H<J.length;++H){G[J.charAt(H)]+=I}return G.normalize()};G.scale=function(J,I){for(var H=0;H=1){return"rgb("+[G.r,G.g,G.b].join(",")+")"}else{return"rgba("+[G.r,G.g,G.b,G.a].join(",")+")"}};G.normalize=function(){function H(J,K,I){return KI?I:K)}G.r=H(0,parseInt(G.r),255);G.g=H(0,parseInt(G.g),255);G.b=H(0,parseInt(G.b),255);G.a=H(0,G.a,1);return G};G.clone=function(){return B.color.make(G.r,G.b,G.g,G.a)};return G.normalize()};B.color.extract=function(D,C){var E;do{E=D.css(C).toLowerCase();if(E!=""&&E!="transparent"){break}D=D.parent()}while(!B.nodeName(D.get(0),"body"));if(E=="rgba(0, 0, 0, 0)"){E="transparent"}return B.color.parse(E)};B.color.parse=function(F){var E,C=B.color.make;if(E=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(F)){return C(parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10))}if(E=/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(F)){return C(parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10),parseFloat(E[4]))}if(E=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(F)){return C(parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55)}if(E=/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(F)){return C(parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55,parseFloat(E[4]))}if(E=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(F)){return C(parseInt(E[1],16),parseInt(E[2],16),parseInt(E[3],16))}if(E=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(F)){return C(parseInt(E[1]+E[1],16),parseInt(E[2]+E[2],16),parseInt(E[3]+E[3],16))}var D=B.trim(F).toLowerCase();if(D=="transparent"){return C(255,255,255,0)}else{E=A[D]||[0,0,0];return C(E[0],E[1],E[2])}};var A={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);// the actual Flot code
(function($) {
function Plot(placeholder, data_, options_, plugins) {
// data is on the form:
// [ series1, series2 ... ]
// where series is either just the data as [ [x1, y1], [x2, y2], ... ]
// or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... }var series = [],
options = {
// the color theme used for graphs
colors: ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"],
legend: {
show: true,
noColumns: 1, // number of colums in legend table
labelFormatter: null, // fn: string -> string
labelBoxBorderColor: "#ccc", // border color for the little label boxes
container: null, // container (as jQuery object) to put legend in, null means default on top of graph
position: "ne", // position of default legend container within plot
margin: 5, // distance from grid edge to default legend container within plot
backgroundColor: null, // null means auto-detect
backgroundOpacity: 0.85 // set to 0 to avoid background
},
xaxis: {
show: null, // null = auto-detect, true = always, false = never
position: "bottom", // or "top"
mode: null, // null or "time"
//NEW
timezone: null, // "browser" for local to the client
color: null, // base color, labels, ticks
tickColor: null, // possibly different color of ticks, e.g. "rgba(0,0,0,0.15)"
transform: null, // null or f: number -> number to transform axis
inverseTransform: null, // if transform is set, this should be the inverse function
min: null, // min. value to show, null means set automatically
max: null, // max. value to show, null means set automatically
autoscaleMargin: null, // margin in % to add if auto-setting min/max
ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks
tickFormatter: null, // fn: number -> string
labelWidth: null, // size of tick labels in pixels
labelHeight: null,
reserveSpace: null, // whether to reserve space even if axis isn't shown
tickLength: null, // size in pixels of ticks, or "full" for whole line
alignTicksWithAxis: null, // axis number or null for no sync// mode specific options
tickDecimals: null, // no. of decimals, null means auto
tickSize: null, // number or [number, "unit"]
minTickSize: null, // number or [number, "unit"]
monthNames: null, // list of names of months
timeformat: null, // format string to use
twelveHourClock: false // 12 or 24 time in time mode
},
yaxis: {
autoscaleMargin: 0.02,
position: "left" // or "right"
},
xaxes: [],
yaxes: [],
series: {
points: {
show: false,
radius: 3,
lineWidth: 2, // in pixels
fill: true,
fillColor: "#ffffff",
symbol: "circle" // or callback
},
lines: {
// we don't put in show: false so we can see
// whether lines were actively disabled
lineWidth: 2, // in pixels
fill: false,
fillColor: null,
steps: false
},
bars: {
show: false,
lineWidth: 2, // in pixels
barWidth: 1, // in units of the x axis
fill: true,
fillColor: null,
align: "left", // or "center"
horizontal: false
},
shadowSize: 3
},
grid: {
show: true,
aboveData: false,
color: "#545454", // primary color used for outline and labels
backgroundColor: null, // null for transparent, else color
borderColor: null, // set if different from the grid color
tickColor: null, // color for the ticks, e.g. "rgba(0,0,0,0.15)"
labelMargin: 5, // in pixels
axisMargin: 8, // in pixels
borderWidth: 2, // in pixels
minBorderMargin: null, // in pixels, null means taken from points radius
markings: null, // array of ranges or fn: axes -> array of ranges
markingsColor: "#f4f4f4",
markingsLineWidth: 2,
// interactive stuff
clickable: false,
hoverable: false,
autoHighlight: true, // highlight in case mouse is near
mouseActiveRadius: 10 // how far the mouse can be away to activate an item
},
hooks: {}
},
canvas = null, // the canvas for the plot itself
overlay = null, // canvas for interactive stuff on top of plot
eventHolder = null, // jQuery object that events should be bound to
ctx = null, octx = null,
xaxes = [], yaxes = [],
plotOffset = { left: 0, right: 0, top: 0, bottom: 0},
canvasWidth = 0, canvasHeight = 0,
plotWidth = 0, plotHeight = 0,
hooks = {
processOptions: [],
processRawData: [],
processDatapoints: [],
drawSeries: [],
draw: [],
bindEvents: [],
drawOverlay: [],
shutdown: []
},
plot = this;// public functions
plot.setData = setData;
plot.setupGrid = setupGrid;
plot.draw = draw;
plot.getPlaceholder = function() { return placeholder; };
plot.getCanvas = function() { return canvas; };
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),
top: parseInt(yaxes[axisNumber(point, "y") - 1].p2c(+point.y) + plotOffset.top)
};
};
plot.shutdown = shutdown;
plot.resize = function () {
getCanvasDimensions();
resizeCanvas(canvas);
resizeCanvas(overlay);
};// public attributes
plot.hooks = hooks;// initialize
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() {
for (var i = 0; i < plugins.length; ++i) {
var p = plugins[i];
p.init(plot);
if (p.options)
$.extend(true, options, p.options);
}
}function parseOptions(opts) {
var i;$.extend(true, options, opts);
if (options.xaxis.color == null)
options.xaxis.color = options.grid.color;
if (options.yaxis.color == null)
options.yaxis.color = options.grid.color;if (options.xaxis.tickColor == null) // backwards-compatibility
options.xaxis.tickColor = options.grid.tickColor;
if (options.yaxis.tickColor == null) // backwards-compatibility
options.yaxis.tickColor = options.grid.tickColor;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();// fill in defaults in axes, copy at least always the
// first as the rest of the code assumes it'll be there
for (i = 0; i < Math.max(1, options.xaxes.length); ++i)
options.xaxes[i] = $.extend(true, {}, options.xaxis, options.xaxes[i]);
for (i = 0; i < Math.max(1, options.yaxes.length); ++i)
options.yaxes[i] = $.extend(true, {}, options.yaxis, options.yaxes[i]);// backwards compatibility, to be removed in future
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.y2axis) {
options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis);
options.yaxes[1].position = "right";
}
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;// save options on axes for future reference
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];// add hooks from options
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; // move the data instead of deep-copy
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") // if we got a real axis, extract number
a = a.n;
if (typeof a != "number")
a = 1; // default to first axis
return a;
}function allAxes() {
// return flat array without annoying null entries
return $.grep(xaxes.concat(yaxes), function (a) { return a; });
}function canvasToAxisCoords(pos) {
// return an object with x/y corresponding to all used axes
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) {
// get canvas coords from the first pair of x/y found in 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, // save the number for future reference
direction: axes == xaxes ? "x" : "y",
options: $.extend(true, {}, axes == xaxes ? options.xaxis : options.yaxis)
};return axes[number - 1];
}function fillInSeriesOptions() {
var i;// collect what we already got of colors
var neededColors = series.length,
usedColors = [],
assignedColors = [];
for (i = 0; i < series.length; ++i) {
var sc = series[i].color;
if (sc != null) {
--neededColors;
if (typeof sc == "number")
assignedColors.push(sc);
else
usedColors.push($.color.parse(series[i].color));
}
}// we might need to generate more colors if higher indices
// are assigned
for (i = 0; i < assignedColors.length; ++i) {
neededColors = Math.max(neededColors, assignedColors[i] + 1);
}// produce colors as needed
var colors = [], variation = 0;
i = 0;
while (colors.length = options.colors.length) {
i = 0;
++variation;
}
}// fill in the options
var colori = 0, s;
for (i = 0; i < series.length; ++i) {
s = series[i];// assign colors
if (s.color == null) {
s.color = colors[colori].toString();
++colori;
}
else if (typeof s.color == "number")
s.color = colors[s.color].toString();// turn on lines automatically in case nothing is set
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;
}// setup axes
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;function updateAxis(axis, min, max) {
if (min axis.datamax && max != fakeInfinity)
axis.datamax = max;
}$.each(allAxes(), function (_, axis) {
// init 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 ]);
}// first pass: clean and copy data
for (i = 0; i < series.length; ++i) {
s = series[i];var data = s.data, format = s.datapoints.format;
if (!format) {
format = [];
// find out how to copy
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)) {
format.push({ y: true, number: true, required: false, defaultValue: 0 });
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; // already filled ins.datapoints.pointsize = format.length;
ps = s.datapoints.pointsize;
points = s.datapoints.points;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; // convert to number
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 0
&& points[k - ps] != null
&& points[k - ps] != points[k]
&& points[k - ps + 1] != points[k + 1]) {
// copy the point to make room for a middle point
for (m = 0; m < ps; ++m)
points[k + ps + m] = points[k + m];// middle point has same y
points[k + 1] = points[k - ps + 1];// we've added a point, better reflect that
k += ps;
}
}
}
}// give the hooks a chance to run
for (i = 0; i < series.length; ++i) {
s = series[i];executeHooks(hooks.processDatapoints, [ s, s.datapoints]);
}// second pass: find datamax/datamin for auto-scaling
for (i = 0; i < series.length; ++i) {
s = series[i];
points = s.datapoints.points,
ps = s.datapoints.pointsize;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 || val == fakeInfinity || val == -fakeInfinity)
continue;if (f.x) {
if (val xmax)
xmax = val;
}
if (f.y) {
if (val ymax)
ymax = val;
}
}
}if (s.bars.show) {
// make sure we got room for the bar on the dancing floor
var delta = s.bars.align == "left" ? 0 : -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 makeCanvas(skipPositioning, cls) {
var c = document.createElement('canvas');
c.className = cls;
c.width = canvasWidth;
c.height = canvasHeight;if (!skipPositioning)
$(c).css({ position: 'absolute', left: 0, top: 0 });$(c).appendTo(placeholder);
if (!c.getContext) // excanvas hack
c = window.G_vmlCanvasManager.initElement(c);// used for resetting in case we get replotted
c.getContext("2d").save();return c;
}function getCanvasDimensions() {
canvasWidth = placeholder.width();
canvasHeight = placeholder.height();if (canvasWidth <= 0 || canvasHeight <= 0)
throw "Invalid dimensions for plot, width = " + canvasWidth + ", height = " + canvasHeight;
}function resizeCanvas(c) {
// resizing should reset the state (excanvas seems to be
// buggy though)
if (c.width != canvasWidth)
c.width = canvasWidth;if (c.height != canvasHeight)
c.height = canvasHeight;// so try to get back to the initial state (even if it's
// gone now, this should be safe according to the spec)
var cctx = c.getContext("2d");
cctx.restore();// and save again
cctx.save();
}function setupCanvases() {
var reused,
existingCanvas = placeholder.children("canvas.base"),
existingOverlay = placeholder.children("canvas.overlay");if (existingCanvas.length == 0 || existingOverlay == 0) {
// init everythingplaceholder.html(""); // make sure placeholder is clear
placeholder.css({ padding: 0 }); // padding messes up the positioning
if (placeholder.css("position") == 'static')
placeholder.css("position", "relative"); // for positioning labels and overlaygetCanvasDimensions();
canvas = makeCanvas(true, "base");
overlay = makeCanvas(false, "overlay"); // overlay canvas for interactive featuresreused = false;
}
else {
// reuse existing elementscanvas = existingCanvas.get(0);
overlay = existingOverlay.get(0);reused = true;
}ctx = canvas.getContext("2d");
octx = overlay.getContext("2d");// we include the canvas in the event holder too, because IE 7
// sometimes has trouble with the stacking order
eventHolder = $([overlay, canvas]);if (reused) {
// run shutdown in the old plot object
placeholder.data("plot").shutdown();// reset reused canvases
plot.resize();// make sure overlay pixels are cleared (canvas is cleared when we redraw)
octx.clearRect(0, 0, canvasWidth, canvasHeight);// then whack any remaining obvious garbage left
eventHolder.unbind();
placeholder.children().not([canvas, overlay]).remove();
}// save in case we get replotted
placeholder.data("plot", plot);
}function bindEvents() {
// bind events
if (options.grid.hoverable) {
eventHolder.mousemove(onMouseMove);
eventHolder.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) {
// set helper functions on the axis, assumes plot area
// has been computed alreadyfunction identity(x) { return x; }
var s, m, t = axis.options.transform || identity,
it = axis.options.inverseTransform;// precompute how much the axis is scaling a point
// in canvas space
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));
}// data point to canvas coordinate
if (t == identity) // slight optimization
axis.p2c = function (p) { return (p - m) * s; };
else
axis.p2c = function (p) { return (t(p) - m) * s; };
// canvas coordinate to data point
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, i, ticks = axis.ticks || [], labels = [],
l, w = opts.labelWidth, h = opts.labelHeight, dummyDiv;function makeDummyDiv(labels, width) {
return $('' +
''
+ labels.join("") + '')
.appendTo(placeholder);
}if (axis.direction == "x") {
// to avoid measuring the widths of the labels (it's slow), we
// construct fixed-size boxes and put the labels inside
// them, we don't need the exact figures and the
// fixed-size box content is easy to center
if (w == null)
w = Math.floor(canvasWidth / (ticks.length > 0 ? ticks.length : 1));// measure x label heights
if (h == null) {
labels = [];
for (i = 0; i < ticks.length; ++i) {
l = ticks[i].label;
if (l)
labels.push('' + l + '');
}if (labels.length > 0) {
// stick them all in the same div and measure
// collective height
labels.push('');
dummyDiv = makeDummyDiv(labels, "width:10000px;");
h = dummyDiv.height();
dummyDiv.remove();
}
}
}
else if (w == null || h == null) {
// calculate y label dimensions
for (i = 0; i < ticks.length; ++i) {
l = ticks[i].label;
if (l)
labels.push('' + l + '');
}if (labels.length > 0) {
dummyDiv = makeDummyDiv(labels, "");
if (w == null)
w = dummyDiv.children().width();
if (h == null)
h = dummyDiv.find("div.tickLabel").height();
dummyDiv.remove();
}
}if (w == null)
w = 0;
if (h == null)
h = 0;axis.labelWidth = w;
axis.labelHeight = h;
}function allocateAxisBoxFirstPhase(axis) {
// find the bounding box of the axis by looking at label
// widths/heights and ticks, make room by diminishing the
// plotOffsetvar lw = axis.labelWidth,
lh = axis.labelHeight,
pos = axis.options.position,
tickLength = axis.options.tickLength,
axismargin = options.grid.axisMargin,
padding = options.grid.labelMargin,
all = axis.direction == "x" ? xaxes : yaxes,
index;// determine axis margin
var samePosition = $.grep(all, function (a) {
return a && a.options.position == pos && a.reserveSpace;
});
if ($.inArray(axis, samePosition) == samePosition.length - 1)
axismargin = 0; // outermost// determine tick length - if we're innermost, we can use "full"
if (tickLength == null)
tickLength = "full";var sameDirection = $.grep(all, function (a) {
return a && a.reserveSpace;
});var innermost = $.inArray(axis, sameDirection) == 0;
if (!innermost && tickLength == "full")
tickLength = 5;if (!isNaN(+tickLength))
padding += +tickLength;// compute box
if (axis.direction == "x") {
lh += padding;if (pos == "bottom") {
plotOffset.bottom += lh + axismargin;
axis.box = { top: canvasHeight - 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: canvasWidth - plotOffset.right, width: lw };
}
}// save for future reference
axis.position = pos;
axis.tickLength = tickLength;
axis.box.padding = padding;
axis.innermost = innermost;
}function allocateAxisBoxSecondPhase(axis) {
// set remaining bounding box coordinates
if (axis.direction == "x") {
axis.box.left = plotOffset.left;
axis.box.width = plotWidth;
}
else {
axis.box.top = plotOffset.top;
axis.box.height = plotHeight;
}
}function setupGrid() {
var i, axes = allAxes();// first calculate the plot and axis box dimensions
$.each(axes, function (_, axis) {
axis.show = axis.options.show;
if (axis.show == null)
axis.show = axis.used; // by default an axis is visible if it's got dataaxis.reserveSpace = axis.show || axis.options.reserveSpace;
setRange(axis);
});allocatedAxes = $.grep(axes, function (axis) { return axis.reserveSpace; });
plotOffset.left = plotOffset.right = plotOffset.top = plotOffset.bottom = 0;
if (options.grid.show) {
$.each(allocatedAxes, function (_, axis) {
// make the ticks
setupTickGeneration(axis);
setTicks(axis);
snapRangeToTicks(axis, axis.ticks);// find labelWidth/Height for axis
measureTickLabels(axis);
});// with all dimensions in house, we can compute the
// axis boxes, start from the outside (reverse order)
for (i = allocatedAxes.length - 1; i >= 0; --i)
allocateAxisBoxFirstPhase(allocatedAxes[i]);// make sure we've got enough space for things that
// might stick out
var minMargin = options.grid.minBorderMargin;
if (minMargin == null) {
minMargin = 0;
for (i = 0; i < series.length; ++i)
minMargin = Math.max(minMargin, series[i].points.radius + series[i].points.lineWidth/2);
}for (var a in plotOffset) {
plotOffset[a] += options.grid.borderWidth;
plotOffset[a] = Math.max(minMargin, plotOffset[a]);
}
}plotWidth = canvasWidth - plotOffset.left - plotOffset.right;
plotHeight = canvasHeight - plotOffset.bottom - plotOffset.top;// now we got the proper plotWidth/Height, we can compute the scaling
$.each(axes, function (_, axis) {
setTransformationHelpers(axis);
});if (options.grid.show) {
$.each(allocatedAxes, function (_, axis) {
allocateAxisBoxSecondPhase(axis);
});insertAxisLabels();
}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) {
// degenerate case
var widen = max == 0 ? 1 : 0.01;if (opts.min == null)
min -= widen;
// always widen max if we couldn't widen min to ensure we
// don't fall into min == max which doesn't work
if (opts.max == null || opts.min != null)
max += widen;
}
else {
// consider autoscaling
var margin = opts.autoscaleMargin;
if (margin != null) {
if (opts.min == null) {
min -= delta * margin;
// make sure we don't go below zero if all values
// are positive
if (min = 0)
min = 0;
}
if (opts.max == null) {
max += delta * margin;
if (max > 0 && axis.datamax != null && axis.datamax 0)
noTicks = opts.ticks;
else
// heuristic based on the model a*sqrt(x) fitted to
// some data points that seemed reasonable
noTicks = 0.3 * Math.sqrt(axis.direction == "x" ? canvasWidth : canvasHeight);var delta = (axis.max - axis.min) / noTicks,
size, generator, unit, formatter, i, magn, norm;if (opts.mode == "time") {
// pretty handling of time// To have a consistent view of time based data independent of which time zone the
// client happens to be in we need a date-like object intependent of time zones. This
// is done through a wrapper that only calls the UTC versions of the accessor methods.
function makeUtcWrapper(d) {function addProxyMethod(sourceObj, sourceMethod, targetObj, targetMethod) {
sourceObj[sourceMethod] = function() {
return targetObj[targetMethod].apply(targetObj, arguments);
}
};
var utc = {
date: d
};
addProxyMethod(utc, "getTime", d, "getTime");
addProxyMethod(utc, "setTime", d, "setTime");
var props = [ "Date", "Day", "FullYear", "Hours", "Milliseconds", "Minutes", "Month", "Seconds" ];
for (var p = 0; p < props.length; p++) {
addProxyMethod(utc, "get" + props[p], d, "getUTC" + props[p]);
addProxyMethod(utc, "set" + props[p], d, "setUTC" + props[p]);
}
return utc;
};// select time zone strategy. This returns a date-like object tied to the desired timezone
function dateGenerator(ts) {if (opts.timezone == "browser") {
return new Date(ts);
} else if (!opts.timezone || opts.timezone == "utc") {
return makeUtcWrapper(new Date(ts));
} else if (typeof timezoneJS != "undefined" && typeof timezoneJS.Date != "undefined") {
var d = new timezoneJS.Date();
// timezone-js is fickle, so be sure to set the time zone before setting the time.
d.setTimezone(opts.timezone);
d.setTime(ts);
return d;
} else {
return makeUtcWrapper(new Date(ts));
}
}// map of app. size of time units in milliseconds
var timeUnitSize = {
"second": 1000,
"minute": 60 * 1000,
"hour": 60 * 60 * 1000,
"day": 24 * 60 * 60 * 1000,
"month": 30 * 24 * 60 * 60 * 1000,
"year": 365.2425 * 24 * 60 * 60 * 1000
};// the allowed tick sizes, after 1 year we use
// an integer algorithm
var spec = [
[1, "second"], [2, "second"], [5, "second"], [10, "second"],
[30, "second"],
[1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"],
[30, "minute"],
[1, "hour"], [2, "hour"], [4, "hour"],
[8, "hour"], [12, "hour"],
[1, "day"], [2, "day"], [3, "day"],
[0.25, "month"], [0.5, "month"], [1, "month"],
[2, "month"], [3, "month"], [6, "month"],
[1, "year"]
];var minSize = 0;
if (opts.minTickSize != null) {
if (typeof opts.tickSize == "number")
minSize = opts.tickSize;
else
minSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]];
}for (var i = 0; i < spec.length - 1; ++i)
if (delta = minSize)
break;
size = spec[i][0];
unit = spec[i][1];// special-case the possibility of several years
if (unit == "year") {
magn = Math.pow(10, Math.floor(Math.log(delta / timeUnitSize.year) / Math.LN10));
norm = (delta / timeUnitSize.year) / magn;
if (norm < 1.5)
size = 1;
else if (norm < 3)
size = 2;
else if (norm = timeUnitSize.minute)
// d.setUTCSeconds(0);
d.setSeconds(0);
if (step >= timeUnitSize.hour)
// d.setUTCMinutes(0);
d.setMinutes(0);
if (step >= timeUnitSize.day)
// d.setUTCHours(0);
d.setHours(0);
if (step >= timeUnitSize.day * 4)
// d.setUTCDate(1);
d.setDate(1);
if (step >= timeUnitSize.year)
// d.setUTCMonth(0);
d.setMonth(0);/*
if (unit == "second")
d.setUTCSeconds(floorInBase(d.getUTCSeconds(), tickSize));
if (unit == "minute")
d.setUTCMinutes(floorInBase(d.getUTCMinutes(), tickSize));
if (unit == "hour")
d.setUTCHours(floorInBase(d.getUTCHours(), tickSize));
if (unit == "month")
d.setUTCMonth(floorInBase(d.getUTCMonth(), tickSize));
if (unit == "year")
d.setUTCFullYear(floorInBase(d.getUTCFullYear(), tickSize));// reset smaller components
d.setUTCMilliseconds(0);
if (step >= timeUnitSize.minute)
d.setUTCSeconds(0);
if (step >= timeUnitSize.hour)
d.setUTCMinutes(0);
if (step >= timeUnitSize.day)
d.setUTCHours(0);
if (step >= timeUnitSize.day * 4)
d.setUTCDate(1);
if (step >= timeUnitSize.year)
d.setUTCMonth(0);
*/var carry = 0, v = Number.NaN, prev;
do {
prev = v;
v = d.getTime();
ticks.push(v);
if (unit == "month") {
if (tickSize < 1) {
// a bit complicated - we'll divide the month
// up but we need to take care of fractions
// so we don't end up in the middle of a day
d.setUTCDate(1);
d.setDate(1);
var start = d.getTime();
// d.setUTCMonth(d.getUTCMonth() + 1);
d.setMonth(d.getMonth() + 1);
var end = d.getTime();
d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize);
// carry = d.getUTCHours();
// d.setUTCHours(0);
carry = d.getHours();
d.setHours(0);}
else
// d.setUTCMonth(d.getUTCMonth() + tickSize);
d.setMonth(d.getMonth() + tickSize);
}
else if (unit == "year") {
// d.setUTCFullYear(d.getUTCFullYear() + tickSize);
d.setFullYear(d.getFullYear() + tickSize);
}
else
d.setTime(v + step);} while (v < axis.max && v != prev);
return ticks;
};formatter = function (v, axis) {
// var d = new Date(v);
var d = dateGenerator(v);// first check global format
if (opts.timeformat != null)
return $.plot.formatDate(d, opts.timeformat, opts.monthNames);var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]];
var span = axis.max - axis.min;
var suffix = (opts.twelveHourClock) ? " %p" : "";if (t < timeUnitSize.minute)
fmt = "%h:%M:%S" + suffix;
else if (t < timeUnitSize.day) {
if (span < 2 * timeUnitSize.day)
fmt = "%h:%M" + suffix;
else
fmt = "%b %d %h:%M" + suffix;
}
else if (t < timeUnitSize.month)
fmt = "%b %d";
else if (t < timeUnitSize.year) {
if (span maxDec)
dec = maxDec;magn = Math.pow(10, -dec);
norm = delta / magn; // norm is between 1.0 and 10.0if (norm < 1.5)
size = 1;
else 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.tickDecimals = Math.max(0, maxDec != null ? maxDec : dec);
axis.tickSize = opts.tickSize || size;generator = function (axis) {
var ticks = [];// spew out all possible ticks
var 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 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]);
}generator = function (axis) {
// copy ticks, scaled to this axis
var ticks = [], v, i;
for (i = 0; i 1 && /\..*0$/.test((ts[1] - ts[0]).toFixed(extraDec))))
axis.tickDecimals = extraDec;
}
}
}axis.tickGenerator = generator;
if ($.isFunction(opts.tickFormatter))
axis.tickFormatter = function (v, axis) { return "" + opts.tickFormatter(v, axis); };
else
axis.tickFormatter = formatter;
}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))
// generate the ticks
ticks = oticks({ min: axis.min, max: axis.max });
else
ticks = oticks;
}// clean up/labelify the supplied ticks, copy them over
var i, v;
axis.ticks = [];
for (i = 0; i 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) {
// snap to ticks
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() {
ctx.clearRect(0, 0, canvasWidth, canvasHeight);var grid = options.grid;
// draw background, if any
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();
}function extractRange(ranges, coord) {
var axis, from, to, key, axes = allAxes();for (i = 0; i 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;ctx.save();
ctx.translate(plotOffset.left, plotOffset.top);// draw markings
var markings = options.grid.markings;
if (markings) {
if ($.isFunction(markings)) {
var axes = plot.getAxes();
// xmin etc. is backwards compatibility, to be
// removed in the future
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");// fill in missing
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;// clip
if (xrange.to xrange.axis.max ||
yrange.to 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);if (xrange.from == xrange.to && yrange.from == yrange.to)
continue;// then draw
xrange.from = xrange.axis.p2c(xrange.from);
xrange.to = xrange.axis.p2c(xrange.to);
yrange.from = yrange.axis.p2c(yrange.from);
yrange.to = yrange.axis.p2c(yrange.to);if (xrange.from == xrange.to || yrange.from == yrange.to) {
// draw line
ctx.beginPath();
ctx.strokeStyle = m.color || options.grid.markingsColor;
ctx.lineWidth = m.lineWidth || options.grid.markingsLineWidth;
ctx.moveTo(xrange.from, yrange.from);
ctx.lineTo(xrange.to, yrange.to);
ctx.stroke();
}
else {
// fill area
ctx.fillStyle = m.color || options.grid.markingsColor;
ctx.fillRect(xrange.from, yrange.to,
xrange.to - xrange.from,
yrange.from - yrange.to);
}
}
}// draw the ticks
var 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)
continuectx.strokeStyle = axis.options.tickColor || $.color.parse(axis.options.color).scale('a', 0.22).toString();
ctx.lineWidth = 1;// find the edges
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);
}// draw tick bar
if (!axis.innermost) {
ctx.beginPath();
xoff = yoff = 0;
if (axis.direction == "x")
xoff = plotWidth;
else
yoff = plotHeight;if (ctx.lineWidth == 1) {
x = Math.floor(x) + 0.5;
y = Math.floor(y) + 0.5;
}ctx.moveTo(x, y);
ctx.lineTo(x + xoff, y + yoff);
ctx.stroke();
}// draw ticks
ctx.beginPath();
for (i = 0; i < axis.ticks.length; ++i) {
var v = axis.ticks[i].v;xoff = yoff = 0;
if (v axis.max
// skip those lying on the axes if we got a border
|| (t == "full" && 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();
}// draw border
if (bw) {
ctx.lineWidth = bw;
ctx.strokeStyle = options.grid.borderColor;
ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw);
}ctx.restore();
}function insertAxisLabels() {
placeholder.find(".tickLabels").remove();var html = ['
'];var axes = allAxes();
for (var j = 0; j < axes.length; ++j) {
var axis = axes[j], box = axis.box;
if (!axis.show)
continue;
//debug: html.push('')
html.push('');
for (var i = 0; i < axis.ticks.length; ++i) {
var tick = axis.ticks[i];
if (!tick.label || tick.v axis.max)
continue;var pos = {}, align;
if (axis.direction == "x") {
align = "center";
pos.left = Math.round(plotOffset.left + axis.p2c(tick.v) - axis.labelWidth/2);
if (axis.position == "bottom")
pos.top = box.top + box.padding;
else
pos.bottom = canvasHeight - (box.top + box.height - box.padding);
}
else {
pos.top = Math.round(plotOffset.top + axis.p2c(tick.v) - axis.labelHeight/2);
if (axis.position == "left") {
pos.right = canvasWidth - (box.left + box.width - box.padding)
align = "right";
}
else {
pos.left = box.left + box.padding;
align = "left";
}
}pos.width = axis.labelWidth;
var style = ["position:absolute", "text-align:" + align ];
for (var a in pos)
style.push(a + ":" + pos[a] + "px")html.push('
' + tick.label + '');
}
html.push('');
}html.push('
');
placeholder.append(html.join(""));
}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;// 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 = 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 = 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;// we process each segment in two turns, first forward
// direction to sketch out top, then once we hit the
// end we go backwards to sketch the bottom
while (true) {
if (ps > 0 && i > points.length + ps)
break;i += ps; // ps is negative if going backwards
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) {
// at turning point
segmentEnd = i;
ps = -ps;
ypos = 2;
continue;
}if (ps < 0 && i == segmentStart + ps) {
// done with the reverse sweep
ctx.fill();
areaOpen = false;
ps = -ps;
ypos = 1;
i = segmentStart = segmentEnd + ps;
continue;
}
}if (x1 == null || x2 == null)
continue;// clip x values
// 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 = 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) {
// open area
ctx.beginPath();
ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom));
areaOpen = true;
}// now first check the case where both is outside
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;
}// else it's a bit more complicated, there might
// be a flat maxed out rectangle first, then a
// triangular cutout or reverse; to find these
// keep track of the current x values
var x1old = x1, x2old = x2;// clip the y values, without shortcutting, we
// go through all cases in turn// clip with ymin
if (y1 <= y2 && y1 = axisy.min) {
x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
y1 = axisy.min;
}
else if (y2 <= y1 && y2 = axisy.min) {
x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
y2 = axisy.min;
}// clip with ymax
if (y1 >= y2 && y1 > axisy.max && y2 = y1 && y2 > axisy.max && y1 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;
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.max || 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 && sw > 0) {
// draw shadow in two steps
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, offset, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth) {
var left, right, bottom, top,
drawLeft, drawRight, drawTop, drawBottom,
tmp;// in horizontal mode, we start the bar from the left
// instead of from the bottom so it appears to be
// horizontal rather than vertical
if (horizontal) {
drawBottom = drawRight = drawTop = true;
drawLeft = false;
left = b;
right = x;
top = y + barLeft;
bottom = y + barRight;// account for negative bars
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;// account for negative bars
if (top < bottom) {
tmp = top;
top = bottom;
bottom = tmp;
drawBottom = true;
drawTop = false;
}
}// clip
if (right axisx.max ||
top axisy.max)
return;if (left axisx.max) {
right = axisx.max;
drawRight = false;
}if (bottom axisy.max) {
top = axisy.max;
drawTop = false;
}left = axisx.p2c(left);
bottom = axisy.p2c(bottom);
right = axisx.p2c(right);
top = axisy.p2c(top);// fill the bar
if (fillStyleCallback) {
c.beginPath();
c.moveTo(left, bottom);
c.lineTo(left, top);
c.lineTo(right, top);
c.lineTo(right, bottom);
c.fillStyle = fillStyleCallback(bottom, top);
c.fill();
}// draw outline
if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) {
c.beginPath();// FIXME: inline moveTo is buggy with excanvas
c.moveTo(left, bottom + offset);
if (drawLeft)
c.lineTo(left, top + offset);
else
c.moveTo(left, top + offset);
if (drawTop)
c.lineTo(right, top + offset);
else
c.moveTo(right, top + offset);
if (drawRight)
c.lineTo(right, bottom + offset);
else
c.moveTo(right, bottom + offset);
if (drawBottom)
c.lineTo(left, bottom + offset);
else
c.moveTo(left, bottom + offset);
c.stroke();
}
}function drawSeriesBars(series) {
function plotBars(datapoints, barLeft, barRight, offset, 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, offset, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth);
}
}ctx.save();
ctx.translate(plotOffset.left, plotOffset.top);// FIXME: figure out a way to add shadows (for instance along the right edge)
ctx.lineWidth = series.bars.lineWidth;
ctx.strokeStyle = series.color;
var barLeft = series.bars.align == "left" ? 0 : -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, 0, 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() {
placeholder.find(".legend").remove();if (!options.legend.show)
return;var fragments = [], rowStarted = false,
lf = options.legend.labelFormatter, s, label;
for (var i = 0; i < series.length; ++i) {
s = series[i];
label = s.label;
if (!label)
continue;if (i % options.legend.noColumns == 0) {
if (rowStarted)
fragments.push('');
fragments.push('');
rowStarted = true;
}if (lf)
label = lf(label, s);fragments.push(
'' +
'' + 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) {
// put in the transparent background
// separately to avoid blended labels and
// label boxes
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);
}
}
}// interactive features
var highlights = [],
redrawTimeout = null;// returns the data item the mouse is over, or null if none is found
function findNearbyItem(mouseX, mouseY, seriesFilter) {
var maxDistance = options.grid.mouseActiveRadius,
smallestDistance = maxDistance * maxDistance + 1,
item = null, foundPoint = false, i, j;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,
ps = s.datapoints.pointsize,
mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster
my = axisy.c2p(mouseY),
maxx = maxDistance / axisx.scale,
maxy = maxDistance / axisy.scale;// with inverse transforms, we can't use the maxx/maxy
// optimization, sadly
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 maxx || x - mx maxy || y - my < -maxy)
continue;// We have to calculate distances in pixels, not in
// data units, because the scales of the axes may be different
var dx = Math.abs(axisx.p2c(x) - mouseX),
dy = Math.abs(axisy.p2c(y) - mouseY),
dist = dx * dx + dy * dy; // we save the sqrt// use <= to ensure last point takes precedence
// (last generally means on top of)
if (dist < smallestDistance) {
smallestDistance = dist;
item = [i, j / ps];
}
}
}if (s.bars.show && !item) { // no other point can be nearby
var barLeft = s.bars.align == "left" ? 0 : -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;// for a bar graph, the cursor must be inside the bar
if (series[i].bars.horizontal ?
(mx = Math.min(b, x) &&
my >= y + barLeft && my = x + barLeft && mx = 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; });
}// trigger click or hover event (they send the same parameters
// so we share their code)
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) {
// fill in mouse pos for any listeners out there
item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left);
item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top);
}if (options.grid.autoHighlight) {
// clear auto-highlights
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() {
if (!redrawTimeout)
redrawTimeout = setTimeout(drawOverlay, 30);
}function drawOverlay() {
redrawTimeout = null;// draw highlights
octx.save();
octx.clearRect(0, 0, canvasWidth, canvasHeight);
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();
}if (typeof s == "number")
s = series[s];if (typeof point == "number")
point = s.data[point];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;if (x axisx.max || y axisy.max)
return;var pointRadius = series.points.radius + series.points.lineWidth / 2;
octx.lineWidth = pointRadius;
octx.strokeStyle = $.color.parse(series.color).scale('a', 0.5).toString();
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) {
octx.lineWidth = series.bars.lineWidth;
octx.strokeStyle = $.color.parse(series.color).scale('a', 0.5).toString();
var fillStyle = $.color.parse(series.color).scale('a', 0.5).toString();
var barLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2;
drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth,
0, 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 {
// assume this is a gradient spec; IE currently only
// supports a simple vertical gradient properly, so that's
// what we support too
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 t0 = new Date();
var plot = new Plot($(placeholder), data, options, $.plot.plugins);
//(window.console ? console.log : alert)("time used (msecs): " + ((new Date()).getTime() - t0.getTime()));
return plot;
};$.plot.version = "0.7";
$.plot.plugins = [];
// returns a string with the date d formatted according to fmt
$.plot.formatDate = function(d, fmt, monthNames) {
var leftPad = function(n) {
n = "" + n;
return n.length == 1 ? "0" + n : n;
};var r = [];
var escape = false, padNext = false;
// var hours = d.getUTCHours();
var hours = d.getHours();
var isAM = hours 12) {
hours = hours - 12;
} else if (hours == 0) {
hours = 12;
}
}
for (var i = 0; i < fmt.length; ++i) {
var c = fmt.charAt(i);if (escape) {
switch (c) {
case 'h': c = "" + hours; break;
case 'H': c = leftPad(hours); break;
/* case 'M': c = leftPad(d.getUTCMinutes()); break;
case 'S': c = leftPad(d.getUTCSeconds()); break;
case 'd': c = "" + d.getUTCDate(); break;
case 'm': c = "" + (d.getUTCMonth() + 1); break;
case 'y': c = "" + d.getUTCFullYear(); break;
case 'b': c = "" + monthNames[d.getUTCMonth()]; break; */
case 'M': c = leftPad(d.getMinutes()); break;
case 'S': c = leftPad(d.getSeconds()); break;
case 'd': c = "" + d.getDate(); break;
case 'm': c = "" + (d.getMonth() + 1); break;
case 'y': c = "" + d.getFullYear(); break;
case 'b': c = "" + monthNames[d.getMonth()]; break;
case 'p': c = (isAM) ? ("" + "am") : ("" + "pm"); break;
case 'P': c = (isAM) ? ("" + "AM") : ("" + "PM"); break;
case '0': c = ""; padNext = true; break;
}
if (c && padNext) {
c = leftPad(c);
padNext = false;
}
r.push(c);
if (!padNext)
escape = false;
}
else {
if (c == "%")
escape = true;
else
r.push(c);
}
}
return r.join("");
};// round to nearby lower multiple of base
function floorInBase(n, base) {
return base * Math.floor(n / base);
}})(jQuery);
oh interesting:
theag removed the php part of the code!
....bw: scrollable boxes for the code would be nicer...;-)
Hi mim,
For code formatting in the Forum posts, please see: http://www.jqwidgets.com/community/topic/code-formatting/
The sample I sent you works with our widgets. I am afraid that I am not familiar with the rendering of other third-party widgets and unfortunately, I will not be able to help you about the integration with them.
Best Wishes,
Peter StoevjQWidgets Team
http://www.jqwidgets.comok, well, anyhow…
one step furtherby changing just
from
var plot = $.plot(plotContainer, dataset, options);
to
var plot = $.plot(plotContainer, [dataset], options);
a pure scaling from -1.00 to 1.00 (yaxis) and 0:00:00 an th xaxis shows up….so my assumption is
that the data series is not interpreted in the right way, although it works fine stand alone without jqxTab…at least any thoughts on that?
kr,
michael….and here comes the solution, but I have no explaination to it:
changed the file suffix from html to php….and the graph is shown…???!!!
-
AuthorPosts
You must be logged in to reply to this topic.