Commit 0d15280a authored by olau@iola.dk's avatar olau@iola.dk

Implemented plugin system, introduced experimental hooks system (three hooks...

Implemented plugin system, introduced experimental hooks system (three hooks defined at the moment), moved thresholding to plugin, new stack plugin for stacking charts, refactoring of data processing to support plugin writing, moved series specific global options, changed semantics of arguments to plothover event to reflect the situation with data transformations

git-svn-id: https://flot.googlecode.com/svn/trunk@157 1e0a6537-2640-0410-bfb7-f154510ff394
parent b1b1bde0
...@@ -40,7 +40,7 @@ E.g. ...@@ -40,7 +40,7 @@ E.g.
[ [1, 3], [2, 14.01], [3.5, 3.14] ] [ [1, 3], [2, 14.01], [3.5, 3.14] ]
Note that to simplify the internal logic in Flot both the x and y Note that to simplify the internal logic in Flot both the x and y
values must be numbers, even if specifying time series (see below for values must be numbers (even if specifying time series, see below for
how to do this). This is a common problem because you might retrieve how to do this). This is a common problem because you might retrieve
data from the database and serialize them directly to JSON without data from the database and serialize them directly to JSON without
noticing the wrong type. If you're getting mysterious errors, double noticing the wrong type. If you're getting mysterious errors, double
...@@ -49,7 +49,7 @@ check that you're inputting numbers and not strings. ...@@ -49,7 +49,7 @@ check that you're inputting numbers and not strings.
If a null is specified as a point or if one of the coordinates is null If a null is specified as a point or if one of the coordinates is null
or couldn't be converted to a number, the point is ignored when or couldn't be converted to a number, the point is ignored when
drawing. As a special case, a null value for lines is interpreted as a drawing. As a special case, a null value for lines is interpreted as a
line segment end, i.e. the point before and after the null value are line segment end, i.e. the points before and after the null value are
not connected. not connected.
Lines and points take two coordinates. For bars, you can specify a Lines and points take two coordinates. For bars, you can specify a
...@@ -64,7 +64,6 @@ The format of a single series object is as follows: ...@@ -64,7 +64,6 @@ The format of a single series object is as follows:
lines: specific lines options lines: specific lines options
bars: specific bars options bars: specific bars options
points: specific points options points: specific points options
threshold: specific threshold options
xaxis: 1 or 2 xaxis: 1 or 2
yaxis: 1 or 2 yaxis: 1 or 2
clickable: boolean clickable: boolean
...@@ -100,7 +99,7 @@ E.g., you can use this to make a dual axis plot by specifying ...@@ -100,7 +99,7 @@ E.g., you can use this to make a dual axis plot by specifying
"clickable" and "hoverable" can be set to false to disable "clickable" and "hoverable" can be set to false to disable
interactivity for specific series if interactivity is turned on in interactivity for specific series if interactivity is turned on in
plot, see below. the plot, see below.
The rest of the options are all documented below as they are the same The rest of the options are all documented below as they are the same
as the default options passed in via the options parameter in the plot as the default options passed in via the options parameter in the plot
...@@ -120,8 +119,10 @@ All options are completely optional. They are documented individually ...@@ -120,8 +119,10 @@ All options are completely optional. They are documented individually
below, to change them you just specify them in an object, e.g. below, to change them you just specify them in an object, e.g.
var options = { var options = {
lines: { show: true }, series: {
points: { show: true } lines: { show: true },
points: { show: true }
}
}; };
$.plot(placeholder, data, options); $.plot(placeholder, data, options);
...@@ -412,47 +413,51 @@ been produced with two days in-between. ...@@ -412,47 +413,51 @@ been produced with two days in-between.
Customizing the data series Customizing the data series
=========================== ===========================
lines, points, bars: { series: {
show: boolean lines, points, bars: {
lineWidth: number show: boolean
fill: boolean or number lineWidth: number
fillColor: null or color/gradient fill: boolean or number
} fillColor: null or color/gradient
}
points: {
radius: number
}
bars: {
barWidth: number
align: "left" or "center"
horizontal: boolean
}
lines: { points: {
steps: boolean radius: number
} }
colors: [ color1, color2, ... ] bars: {
barWidth: number
align: "left" or "center"
horizontal: boolean
}
shadowSize: number lines: {
steps: boolean
}
threshold: { shadowSize: number
below: number
color: color
} }
colors: [ color1, color2, ... ]
The options inside "series: {}" are copied to each of the series. So
you can specify that all series should have bars by putting it in the
global options, or override it for individual series by specifying
bars in a particular the series object in the array of data.
The most important options are "lines", "points" and "bars" that The most important options are "lines", "points" and "bars" that
specifies whether and how lines, points and bars should be shown for specify whether and how lines, points and bars should be shown for
each data series. In case you don't specify anything at all, Flot will each data series. In case you don't specify anything at all, Flot will
default to showing lines (you can turn this off with default to showing lines (you can turn this off with
lines: { show: false}). You can specify the various types lines: { show: false}). You can specify the various types
independently of each other, and Flot will happily draw each of them independently of each other, and Flot will happily draw each of them
in turn, e.g. in turn (this is probably only useful for lines and points), e.g.
var options = { var options = {
lines: { show: true, fill: true, fillColor: "rgba(255, 255, 255, 0.8)" }, series: {
points: { show: true, fill: false } lines: { show: true, fill: true, fillColor: "rgba(255, 255, 255, 0.8)" },
points: { show: true, fill: false }
}
}; };
"lineWidth" is the thickness of the line or outline in pixels. You can "lineWidth" is the thickness of the line or outline in pixels. You can
...@@ -481,7 +486,11 @@ bars first. ...@@ -481,7 +486,11 @@ bars first.
For lines, "steps" specifies whether two adjacent data points are For lines, "steps" specifies whether two adjacent data points are
connected with a straight (possibly diagonal) line or with first a connected with a straight (possibly diagonal) line or with first a
horizontal and then a vertical line. horizontal and then a vertical line. Note that this transforms the
data by adding extra points.
"shadowSize" is the default size of shadows in pixels. Set it to 0 to
remove shadows.
The "colors" array specifies a default color theme to get colors for The "colors" array specifies a default color theme to get colors for
the data series from. You can specify as many colors as you like, like the data series from. You can specify as many colors as you like, like
...@@ -492,13 +501,6 @@ this: ...@@ -492,13 +501,6 @@ this:
If there are more data series than colors, Flot will try to generate If there are more data series than colors, Flot will try to generate
extra colors by lightening and darkening colors in the theme. extra colors by lightening and darkening colors in the theme.
"shadowSize" is the default size of shadows in pixels. Set it to 0 to
remove shadows.
"threshold" specifies that the data points below "below" should be
drawn with the specified color. This makes it easy to mark points
below 0, e.g. for budget data.
Customizing the grid Customizing the grid
==================== ====================
...@@ -595,7 +597,7 @@ You can use "plotclick" and "plothover" events like this: ...@@ -595,7 +597,7 @@ You can use "plotclick" and "plothover" events like this:
The item object in this example is either null or a nearby object on the form: The item object in this example is either null or a nearby object on the form:
item: { item: {
datapoint: the point as you specified it in the data, e.g. [0, 2] datapoint: the point, e.g. [0, 2]
dataIndex: the index of the point in the data array dataIndex: the index of the point in the data array
series: the series object series: the series object
seriesIndex: the index of the series seriesIndex: the index of the series
...@@ -606,10 +608,12 @@ For instance, if you have specified the data like this ...@@ -606,10 +608,12 @@ For instance, if you have specified the data like this
$.plot($("#placeholder"), [ { label: "Foo", data: [[0, 10], [7, 3]] } ], ...); $.plot($("#placeholder"), [ { label: "Foo", data: [[0, 10], [7, 3]] } ], ...);
and the mouse is near the point (7, 3), "datapoint" is the [7, 3] we and the mouse is near the point (7, 3), "datapoint" is [7, 3],
specified, "dataIndex" will be 1, "series" is a normalized series "dataIndex" will be 1, "series" is a normalized series object with
object with among other things the "Foo" label in series.label and the among other things the "Foo" label in series.label and the color in
color in series.color, and "seriesIndex" is 0. series.color, and "seriesIndex" is 0. Note that plugins and options
that transform the data can shift the indexes from what you specified
in the original data array.
If you use the above events to update some other information and want If you use the above events to update some other information and want
to clear out that info in case the mouse goes away, you'll probably to clear out that info in case the mouse goes away, you'll probably
...@@ -746,12 +750,17 @@ can call: ...@@ -746,12 +750,17 @@ can call:
Highlight a specific datapoint in the data series. You can either Highlight a specific datapoint in the data series. You can either
specify the actual objects, e.g. if you got them from a specify the actual objects, e.g. if you got them from a
"plotclick" event, or you can specify the indices, e.g. "plotclick" event, or you can specify the indices, e.g.
highlight(1, 3) to highlight the fourth point in the second series. highlight(1, 3) to highlight the fourth point in the second series
(remember, zero-based indexing).
- unhighlight(series, datapoint) - unhighlight(series, datapoint) or unhighlight()
Remove the highlighting of the point, same parameters as
highlight.
Remove the highlighting of the point, same parameters as highlight. If you call unhighlight with no parameters, e.g. as
plot.unhighlight(), all current highlights are removed.
- setData(data) - setData(data)
...@@ -788,7 +797,7 @@ Flot to keep track of its state, so be careful. ...@@ -788,7 +797,7 @@ Flot to keep track of its state, so be careful.
- getData() - getData()
Returns an array of the data series currently used on normalized Returns an array of the data series currently used in normalized
form with missing settings filled in according to the global form with missing settings filled in according to the global
options. So for instance to find out what color Flot has assigned options. So for instance to find out what color Flot has assigned
to the data series, you could do this: to the data series, you could do this:
...@@ -797,6 +806,10 @@ Flot to keep track of its state, so be careful. ...@@ -797,6 +806,10 @@ Flot to keep track of its state, so be careful.
for (var i = 0; i < series.length; ++i) for (var i = 0; i < series.length; ++i)
alert(series[i].color); alert(series[i].color);
A notable other interesting field besides color is datapoints
which has a field "points" with the normalized data points in a
flat array.
- getAxes() - getAxes()
...@@ -804,7 +817,7 @@ Flot to keep track of its state, so be careful. ...@@ -804,7 +817,7 @@ Flot to keep track of its state, so be careful.
y2axis }. Various things are stuffed inside an axis object, e.g. y2axis }. Various things are stuffed inside an axis object, e.g.
you could use getAxes().xaxis.ticks to find out what the ticks are you could use getAxes().xaxis.ticks to find out what the ticks are
for the xaxis. for the xaxis.
- getCanvas() - getCanvas()
...@@ -820,4 +833,100 @@ Flot to keep track of its state, so be careful. ...@@ -820,4 +833,100 @@ Flot to keep track of its state, so be careful.
placed at (left, top), its center will be at the top-most, left placed at (left, top), its center will be at the top-most, left
corner of the grid. corner of the grid.
- getOptions()
Gets the options for the plot, in a normalized format with default
values filled in.
Hooks
=====
In addition to the public methods, the Plot object also has some hooks
that can be used to modify the plotting process. You can install a
callback function at various points in the process, the function then
gets access to the internal data structures in Flot.
Here's an overview of the phases Flot goes through:
1. Plugin initialization, parsing options
2. Constructing the canvas used for drawing
3. Set data: parsing data specification, calculating colors,
copying raw data points into internal format,
normalizing them, finding max/min for axis auto-scaling
4. Grid setup: calculating axis spacing, ticks, inserting tick
labels, the legend
5. Draw: drawing the grid, drawing each of the series in turn
6. Setting up event handling for interactive features
7. Responding to events, if any
The hooks are simple arrays. They are available on the "hooks"
sub-object on the Plot object with the names mentioned below, e.g.
var plot = $.plot(...);
function f() { alert("hello!")};
plot.hooks.processDatapoints.push(f);
All hooks get the plot object as first parameter.
Currently available hooks (when in doubt, check the Flot source):
- processOptions [phase 1]
function(plot, options)
Called after Flot has parsed and merged options. Rarely useful, but
does allow customizations beyond simple merging of default values.
- processRawData [phase 3]
function(plot, series, data, datapoints)
Called before Flot copies and normalizes the raw data for the given
series. If the function fills in datapoints.points with normalized
points and sets datapoints.pointsize to the size of the points,
Flot will skip the copying/normalization step for this series.
- processDatapoints [phase 3]
function(plot, series, datapoints)
Called after normalization of the given series but before finding
min/max of the data points. This hook is useful for implementing data
transformations. "datapoints" contains the normalized data points in
a flat array as datapoints.points with the size of a single point
given in datapoints.pointsize. Here's a simple transform that
multiplies all y coordinates by 2:
function multiply(plot, series, datapoints) {
var points = datapoints.points, ps = datapoints.pointsize;
for (var i = 0; i < points.length; i += ps)
points[i + 1] *= 2;
}
Note that you must leave datapoints in a good condition as Flot
doesn't check it or do any normalization on it afterwards.
Plugins
-------
Plugins extend the functionality of Flot. To use a plugin, simply
include its Javascript file after Flot in the HTML page.
The plugin registers itself in the global array $.plot.plugins. When
you make a new plot object with $.plot, Flot goes through this array
calling the "init" function of each plugin and merging default options
from its "option" attribute. The init function gets a reference to the
plot object created and uses this to register hooks and add new public
methods if needed.
See the PLUGINS.txt file for details on how to write a plugin.
Flot 0.x Flot 0.x
-------- --------
API changes:
In the global options specified in the $.plot command,
"lines", "points", "bars" and "shadowSize" have been moved to a
sub-object called "series", i.e.
$.plot(placeholder, data, { lines: { show: true }})
becomes
$.plot(placeholder, data, { series: { lines: { show: true }}})
All future series-specific options will go into this sub-object (to
simplify plugin writing). Backward-compatibility hooks are in place,
so old code should not break.
"plothover" no longer provides the original data point, but instead a
normalized one, since there may be no corresponding original point.
Changes: Changes:
- Added support for disabling interactivity for specific data series - Added support for disabling interactivity for specific data series
...@@ -8,10 +28,11 @@ Changes: ...@@ -8,10 +28,11 @@ Changes:
- Flot now calls $() on the placeholder and optional legend container - Flot now calls $() on the placeholder and optional legend container
passed in so you can specify DOM elements or CSS expressions to make passed in so you can specify DOM elements or CSS expressions to make
it easier to use Flot with libraries like Prototype or Mootools. it easier to use Flot with libraries like Prototype or Mootools or
through raw JSON from Ajax responses.
- A new "plotselecting" event is now emitted while the user is making - A new "plotselecting" event is now emitted while the user is making
selection. a selection.
- Added a new crosshairs feature for tracing the mouse position on the - Added a new crosshairs feature for tracing the mouse position on the
axes, enable with crosshair { mode: "x"} (see the new tracking axes, enable with crosshair { mode: "x"} (see the new tracking
...@@ -49,10 +70,6 @@ Changes: ...@@ -49,10 +70,6 @@ Changes:
set to true connects the points with horizontal/vertical steps set to true connects the points with horizontal/vertical steps
instead of diagonal lines. instead of diagonal lines.
- Thresholding: you can set a threshold and a color, and the data
points below that threshold will then get the color. Useful for
marking data below 0, for instance.
- The legend labelFormatter now passes the series in addition to just - The legend labelFormatter now passes the series in addition to just
the label (suggestion by Vincent Lemeltier). the label (suggestion by Vincent Lemeltier).
...@@ -62,6 +79,22 @@ Changes: ...@@ -62,6 +79,22 @@ Changes:
don't have to start from the axis. This can be used to make stacked don't have to start from the axis. This can be used to make stacked
bars. bars.
- Plugin system: register an init method in the $.flot.plugins array
to get started, see PLUGINS.txt for details on how to write plugins.
- Hooks: you can register functions that are called while Flot is
crunching the data and doing the plot. This can be used to modify
Flot without changing the source, useful for writing plugins. At
this point only a few hooks are defined.
- Threshold plugin: you can set a threshold and a color, and the data
points below that threshold will then get the color. Useful for
marking data below 0, for instance.
- Stack plugin: you can specify a stack key for each series to have
them summed. This is useful for drawing additive/cumulative graphs
with bars and (currently unfilled) lines.
Bug fixes: Bug fixes:
- Fixed two corner-case bugs when drawing filled curves (report and - Fixed two corner-case bugs when drawing filled curves (report and
......
Writing plugins
---------------
To make a new plugin, create an init function and a set of options (if
needed), stuff it into an object and put it in the $.plot.plugins
array. For example:
function myCoolPluginInit(plot) { plot.coolstring = "Hello!" };
var myCoolOptions = { coolstuff: { show: true } }
$.plot.plugins.push({ init: myCoolPluginInit, options: myCoolOptions });
// now when $.plot is called, the returned object will have the
// attribute "coolstring"
Now, given that the plugin might run in many different places, it's
a good idea to avoid leaking names. We can avoid this by wrapping the
above lines in an anonymous function which we call immediately, like
this: (function () { inner code ... })(). To make it even more robust
in case $ is not bound to jQuery but some other Javascript library, we
can write it as
(function ($) {
// plugin definition
// ...
})(jQuery);
Here is a simple debug plugin which alerts each of the series in the
plot. It has a single option that control whether it is enabled and
how much info to output:
(function ($) {
function init(plot) {
var debugLevel = 1;
function checkDebugEnabled(args) {
if (args.options.debug) {
debugLevel = args.options.debug;
plot.hooks.processDatapoints.push(alertSeries);
}
}
function alertSeries(args) {
var series = args.series;
var msg = "series " + series.label;
if (debugLevel > 1)
msg += " with " + series.data.length + " points";
alert(msg);
}
plot.hooks.processOptions.push(checkDebugEnabled);
}
var options = { debug: 0 };
$.plot.plugins.push({
init: init,
options: options,
name: "simpledebug",
version: "0.1"
});
})(jQuery);
We also define "name" and "version". It's not used by Flot, but might
be helpful for other plugins in resolving dependencies.
Put the above in a file named "jquery.flot.debug.js", include it in an
HTML page and then it can be used with:
$.plot($("#placeholder"), [...], { debug: 2 });
This simple plugin illustrates a couple of points:
- It uses the anonymous function trick to ensure no namespace pollution.
- It can be enabled/disabled through an option.
- Variables in the init function can be used to store plot-specific
state between the hooks.
Options guidelines
==================
Plugins should always support appropriate options to enable/disable
them because the plugin user may have several plots on the same page
where only one should use the plugin.
If the plugin needs series-specific options, you can put them in
"series" in the options object, e.g.
var options = {
series: {
downsample: {
algorithm: null,
maxpoints: 1000
}
}
}
Then they will be copied by Flot into each series, providing the
defaults in case the plugin user doesn't specify any. Again, in most
cases it's probably a good idea if the plugin is turned off rather
than on per default, just like most of the powerful features in Flot.
Think hard and long about naming the options. These names are going to
be public API, and code is going to depend on them if the plugin is
succesful.
...@@ -15,12 +15,26 @@ ...@@ -15,12 +15,26 @@
<ul> <ul>
<li><a href="basic.html">Basic example</a></li> <li><a href="basic.html">Basic example</a></li>
<li><a href="graph-types.html">Different graph types</a> and <a href="setting-options.html">setting various options</a></li> <li><a href="graph-types.html">Different graph types</a></li>
<li><a href="turning-series.html">Turning series on/off</a> and <a href="thresholding.html">thresholding the data</a></li> <li><a href="setting-options.html">Setting various options</a></li>
</ul>
<p>Being interactive:</p>
<ul>
<li><a href="turning-series.html">Turning series on/off</a></li>
<li><a href="selection.html">Selection support and zooming</a> and <a href="zooming.html">zooming with overview</a></li> <li><a href="selection.html">Selection support and zooming</a> and <a href="zooming.html">zooming with overview</a></li>
<li><a href="interacting.html">Interacting with the data points</a></li>
</ul>
<p>Some more esoteric features:</p>
<ul>
<li><a href="time.html">Plotting time series</a> and <a href="visitors.html">visitors per day with zooming and weekends</a></li> <li><a href="time.html">Plotting time series</a> and <a href="visitors.html">visitors per day with zooming and weekends</a></li>
<li><a href="dual-axis.html">Dual axis support</a></li> <li><a href="dual-axis.html">Dual axis support</a></li>
<li><a href="interacting.html">Interacting with the data</a> and <a href="tracking.html">tracking curves with crosshair</a></li> <li><a href="thresholding.html">Thresholding the data</a> (with plugin)</li>
<li><a href="stacking.html">Stacked charts</a> (with plugin)</li>
<li><a href="tracking.html">Tracking curves with crosshair</a></li>
</ul> </ul>
</body> </body>
</html> </html>
...@@ -33,12 +33,14 @@ $(function () { ...@@ -33,12 +33,14 @@ $(function () {
} }
var plot = $.plot($("#placeholder"), var plot = $.plot($("#placeholder"),
[ { data: sin, label: "sin(x)"}, { data: cos, label: "cos(x)" } ], [ { data: sin, label: "sin(x)"}, { data: cos, label: "cos(x)" } ], {
{ lines: { show: true }, series: {
points: { show: true }, lines: { show: true },
selection: { mode: "xy" }, points: { show: true }
grid: { hoverable: true, clickable: true }, },
yaxis: { min: -1.2, max: 1.2 } selection: { mode: "xy" },
grid: { hoverable: true, clickable: true },
yaxis: { min: -1.2, max: 1.2 }
}); });
function showTooltip(x, y, contents) { function showTooltip(x, y, contents) {
......
...@@ -70,8 +70,10 @@ $(function () { ...@@ -70,8 +70,10 @@ $(function () {
]; ];
var options = { var options = {
lines: { show: true }, series: {
points: { show: true }, lines: { show: true },
points: { show: true }
},
legend: { noColumns: 2 }, legend: { noColumns: 2 },
xaxis: { tickDecimals: 0 }, xaxis: { tickDecimals: 0 },
yaxis: { min: 0 }, yaxis: { min: 0 },
......
...@@ -42,8 +42,10 @@ $(function () { ...@@ -42,8 +42,10 @@ $(function () {
{ label: "cos(x)", data: d2}, { label: "cos(x)", data: d2},
{ label: "tan(x)", data: d3} { label: "tan(x)", data: d3}
], { ], {
lines: { show: true }, series: {
points: { show: true }, lines: { show: true },
points: { show: true }
},
xaxis: { xaxis: {
ticks: [0, [Math.PI/2, "\u03c0/2"], [Math.PI, "\u03c0"], [Math.PI * 3/2, "3\u03c0/2"], [Math.PI * 2, "2\u03c0"]] ticks: [0, [Math.PI/2, "\u03c0/2"], [Math.PI, "\u03c0"], [Math.PI * 3/2, "3\u03c0/2"], [Math.PI * 2, "2\u03c0"]]
}, },
......
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples</title>
<link href="layout.css" rel="stylesheet" type="text/css"></link>
<!--[if IE]><script language="javascript" type="text/javascript" src="../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../jquery.flot.stack.js"></script>
</head>
<body>
<h1>Flot Examples</h1>
<div id="placeholder" style="width:600px;height:300px;"></div>
<p>With the stack plugin, you can have Flot stack the
series. This is useful if you wish to display both a total and the
constituents it is made of. The only requirement is that you provide
the input sorted on x.</p>
<p class="stackControls">
<input type="button" value="With stacking">
<input type="button" value="Without stacking">
</p>
<p class="graphControls">
<input type="button" value="Bars">
<input type="button" value="Lines">
<input type="button" value="Lines with steps">
</p>
<script id="source">
$(function () {
var d1 = [];
for (var i = 0; i <= 10; i += 1)
d1.push([i, parseInt(Math.random() * 30)]);
var d2 = [];
for (var i = 0; i <= 10; i += 1)
d2.push([i, parseInt(Math.random() * 30)]);
var d3 = [];
for (var i = 0; i <= 10; i += 1)
d3.push([i, parseInt(Math.random() * 30)]);
var stack = 0, bars = true, lines = false, steps = false;
function plotWithOptions() {
$.plot($("#placeholder"), [ d1, d2, d3 ], {
series: {
stack: stack,
lines: { show: lines, steps: steps },
bars: { show: bars, barWidth: 0.6 }
}
});
}
plotWithOptions();
$(".stackControls input").click(function (e) {
e.preventDefault();
stack = $(this).val() == "With stacking" ? true : null;
plotWithOptions();
});
$(".graphControls input").click(function (e) {
e.preventDefault();
bars = $(this).val().indexOf("Bars") != -1;
lines = $(this).val().indexOf("Lines") != -1;
steps = $(this).val().indexOf("steps") != -1;
plotWithOptions();
});
});
</script>
</body>
</html>
...@@ -7,15 +7,17 @@ ...@@ -7,15 +7,17 @@
<!--[if IE]><script language="javascript" type="text/javascript" src="../excanvas.min.js"></script><![endif]--> <!--[if IE]><script language="javascript" type="text/javascript" src="../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../jquery.js"></script> <script language="javascript" type="text/javascript" src="../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../jquery.flot.js"></script> <script language="javascript" type="text/javascript" src="../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../jquery.flot.threshold.js"></script>
</head> </head>
<body> <body>
<h1>Flot Examples</h1> <h1>Flot Examples</h1>
<div id="placeholder" style="width:600px;height:300px;"></div> <div id="placeholder" style="width:600px;height:300px;"></div>
<p>You can apply a specific color to the part of a data series <p>With the threshold plugin, you can apply a specific color to
below a threshold. This is can be useful for highlighting negative the part of a data series below a threshold. This is can be useful
values, e.g. when displaying net results or what's in stock.</p> for highlighting negative values, e.g. when displaying net results
or what's in stock.</p>
<p class="controls"> <p class="controls">
<input type="button" value="Threshold at 5"> <input type="button" value="Threshold at 5">
...@@ -29,7 +31,7 @@ $(function () { ...@@ -29,7 +31,7 @@ $(function () {
for (var i = 0; i <= 60; i += 1) for (var i = 0; i <= 60; i += 1)
d1.push([i, parseInt(Math.random() * 30 - 10)]); d1.push([i, parseInt(Math.random() * 30 - 10)]);
function doPlot(t) { function plotWithOptions(t) {
$.plot($("#placeholder"), [ { $.plot($("#placeholder"), [ {
data: d1, data: d1,
color: "rgb(30, 180, 20)", color: "rgb(30, 180, 20)",
...@@ -38,12 +40,12 @@ $(function () { ...@@ -38,12 +40,12 @@ $(function () {
} ]); } ]);
} }
doPlot(0); plotWithOptions(0);
$(".controls input").click(function (e) { $(".controls input").click(function (e) {
e.preventDefault(); e.preventDefault();
var t = parseFloat($(this).val().replace('Threshold at ', '')); var t = parseFloat($(this).val().replace('Threshold at ', ''));
doPlot(t); plotWithOptions(t);
}); });
}); });
</script> </script>
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
to the timestamps or simply pretend that the data was produced to the timestamps or simply pretend that the data was produced
in UTC instead of your local time zone.</p> in UTC instead of your local time zone.</p>
<script id="source" language="javascript" type="text/javascript"> <script id="source">
$(function () { $(function () {
var d = [[-373597200000, 315.71], [-370918800000, 317.45], [-368326800000, 317.50], [-363056400000, 315.86], [-360378000000, 314.93], [-357699600000, 313.19], [-352429200000, 313.34], [-349837200000, 314.67], [-347158800000, 315.58], [-344480400000, 316.47], [-342061200000, 316.65], [-339382800000, 317.71], [-336790800000, 318.29], [-334112400000, 318.16], [-331520400000, 316.55], [-328842000000, 314.80], [-326163600000, 313.84], [-323571600000, 313.34], [-320893200000, 314.81], [-318301200000, 315.59], [-315622800000, 316.43], [-312944400000, 316.97], [-310438800000, 317.58], [-307760400000, 319.03], [-305168400000, 320.03], [-302490000000, 319.59], [-299898000000, 318.18], [-297219600000, 315.91], [-294541200000, 314.16], [-291949200000, 313.83], [-289270800000, 315.00], [-286678800000, 316.19], [-284000400000, 316.89], [-281322000000, 317.70], [-278902800000, 318.54], [-276224400000, 319.48], [-273632400000, 320.58], [-270954000000, 319.78], [-268362000000, 318.58], [-265683600000, 316.79], [-263005200000, 314.99], [-260413200000, 315.31], [-257734800000, 316.10], [-255142800000, 317.01], [-252464400000, 317.94], [-249786000000, 318.56], [-247366800000, 319.69], [-244688400000, 320.58], [-242096400000, 321.01], [-239418000000, 320.61], [-236826000000, 319.61], [-234147600000, 317.40], [-231469200000, 316.26], [-228877200000, 315.42], [-226198800000, 316.69], [-223606800000, 317.69], [-220928400000, 318.74], [-218250000000, 319.08], [-215830800000, 319.86], [-213152400000, 321.39], [-210560400000, 322.24], [-207882000000, 321.47], [-205290000000, 319.74], [-202611600000, 317.77], [-199933200000, 316.21], [-197341200000, 315.99], [-194662800000, 317.07], [-192070800000, 318.36], [-189392400000, 319.57], [-178938000000, 322.23], [-176259600000, 321.89], [-173667600000, 320.44], [-170989200000, 318.70], [-168310800000, 316.70], [-165718800000, 316.87], [-163040400000, 317.68], [-160448400000, 318.71], [-157770000000, 319.44], [-155091600000, 320.44], [-152672400000, 320.89], [-149994000000, 322.13], [-147402000000, 322.16], [-144723600000, 321.87], [-142131600000, 321.21], [-139453200000, 318.87], [-136774800000, 317.81], [-134182800000, 317.30], [-131504400000, 318.87], [-128912400000, 319.42], [-126234000000, 320.62], [-123555600000, 321.59], [-121136400000, 322.39], [-118458000000, 323.70], [-115866000000, 324.07], [-113187600000, 323.75], [-110595600000, 322.40], [-107917200000, 320.37], [-105238800000, 318.64], [-102646800000, 318.10], [-99968400000, 319.79], [-97376400000, 321.03], [-94698000000, 322.33], [-92019600000, 322.50], [-89600400000, 323.04], [-86922000000, 324.42], [-84330000000, 325.00], [-81651600000, 324.09], [-79059600000, 322.55], [-76381200000, 320.92], [-73702800000, 319.26], [-71110800000, 319.39], [-68432400000, 320.72], [-65840400000, 321.96], [-63162000000, 322.57], [-60483600000, 323.15], [-57978000000, 323.89], [-55299600000, 325.02], [-52707600000, 325.57], [-50029200000, 325.36], [-47437200000, 324.14], [-44758800000, 322.11], [-42080400000, 320.33], [-39488400000, 320.25], [-36810000000, 321.32], [-34218000000, 322.90], [-31539600000, 324.00], [-28861200000, 324.42], [-26442000000, 325.64], [-23763600000, 326.66], [-21171600000, 327.38], [-18493200000, 326.70], [-15901200000, 325.89], [-13222800000, 323.67], [-10544400000, 322.38], [-7952400000, 321.78], [-5274000000, 322.85], [-2682000000, 324.12], [-3600000, 325.06], [2674800000, 325.98], [5094000000, 326.93], [7772400000, 328.13], [10364400000, 328.07], [13042800000, 327.66], [15634800000, 326.35], [18313200000, 324.69], [20991600000, 323.10], [23583600000, 323.07], [26262000000, 324.01], [28854000000, 325.13], [31532400000, 326.17], [34210800000, 326.68], [36630000000, 327.18], [39308400000, 327.78], [41900400000, 328.92], [44578800000, 328.57], [47170800000, 327.37], [49849200000, 325.43], [52527600000, 323.36], [55119600000, 323.56], [57798000000, 324.80], [60390000000, 326.01], [63068400000, 326.77], [65746800000, 327.63], [68252400000, 327.75], [70930800000, 329.72], [73522800000, 330.07], [76201200000, 329.09], [78793200000, 328.05], [81471600000, 326.32], [84150000000, 324.84], [86742000000, 325.20], [89420400000, 326.50], [92012400000, 327.55], [94690800000, 328.54], [97369200000, 329.56], [99788400000, 330.30], [102466800000, 331.50], [105058800000, 332.48], [107737200000, 332.07], [110329200000, 330.87], [113007600000, 329.31], [115686000000, 327.51], [118278000000, 327.18], [120956400000, 328.16], [123548400000, 328.64], [126226800000, 329.35], [128905200000, 330.71], [131324400000, 331.48], [134002800000, 332.65], [136594800000, 333.16], [139273200000, 332.06], [141865200000, 330.99], [144543600000, 329.17], [147222000000, 327.41], [149814000000, 327.20], [152492400000, 328.33], [155084400000, 329.50], [157762800000, 330.68], [160441200000, 331.41], [162860400000, 331.85], [165538800000, 333.29], [168130800000, 333.91], [170809200000, 333.40], [173401200000, 331.78], [176079600000, 329.88], [178758000000, 328.57], [181350000000, 328.46], [184028400000, 329.26], [189298800000, 331.71], [191977200000, 332.76], [194482800000, 333.48], [197161200000, 334.78], [199753200000, 334.78], [202431600000, 334.17], [205023600000, 332.78], [207702000000, 330.64], [210380400000, 328.95], [212972400000, 328.77], [215650800000, 330.23], [218242800000, 331.69], [220921200000, 332.70], [223599600000, 333.24], [226018800000, 334.96], [228697200000, 336.04], [231289200000, 336.82], [233967600000, 336.13], [236559600000, 334.73], [239238000000, 332.52], [241916400000, 331.19], [244508400000, 331.19], [247186800000, 332.35], [249778800000, 333.47], [252457200000, 335.11], [255135600000, 335.26], [257554800000, 336.60], [260233200000, 337.77], [262825200000, 338.00], [265503600000, 337.99], [268095600000, 336.48], [270774000000, 334.37], [273452400000, 332.27], [276044400000, 332.41], [278722800000, 333.76], [281314800000, 334.83], [283993200000, 336.21], [286671600000, 336.64], [289090800000, 338.12], [291769200000, 339.02], [294361200000, 339.02], [297039600000, 339.20], [299631600000, 337.58], [302310000000, 335.55], [304988400000, 333.89], [307580400000, 334.14], [310258800000, 335.26], [312850800000, 336.71], [315529200000, 337.81], [318207600000, 338.29], [320713200000, 340.04], [323391600000, 340.86], [325980000000, 341.47], [328658400000, 341.26], [331250400000, 339.29], [333928800000, 337.60], [336607200000, 336.12], [339202800000, 336.08], [341881200000, 337.22], [344473200000, 338.34], [347151600000, 339.36], [349830000000, 340.51], [352249200000, 341.57], [354924000000, 342.56], [357516000000, 343.01], [360194400000, 342.47], [362786400000, 340.71], [365464800000, 338.52], [368143200000, 336.96], [370738800000, 337.13], [373417200000, 338.58], [376009200000, 339.89], [378687600000, 340.93], [381366000000, 341.69], [383785200000, 342.69], [389052000000, 344.30], [391730400000, 343.43], [394322400000, 341.88], [397000800000, 339.89], [399679200000, 337.95], [402274800000, 338.10], [404953200000, 339.27], [407545200000, 340.67], [410223600000, 341.42], [412902000000, 342.68], [415321200000, 343.46], [417996000000, 345.10], [420588000000, 345.76], [423266400000, 345.36], [425858400000, 343.91], [428536800000, 342.05], [431215200000, 340.00], [433810800000, 340.12], [436489200000, 341.33], [439081200000, 342.94], [441759600000, 343.87], [444438000000, 344.60], [446943600000, 345.20], [452210400000, 347.36], [454888800000, 346.74], [457480800000, 345.41], [460159200000, 343.01], [462837600000, 341.23], [465433200000, 341.52], [468111600000, 342.86], [470703600000, 344.41], [473382000000, 345.09], [476060400000, 345.89], [478479600000, 347.49], [481154400000, 348.00], [483746400000, 348.75], [486424800000, 348.19], [489016800000, 346.54], [491695200000, 344.63], [494373600000, 343.03], [496969200000, 342.92], [499647600000, 344.24], [502239600000, 345.62], [504918000000, 346.43], [507596400000, 346.94], [510015600000, 347.88], [512690400000, 349.57], [515282400000, 350.35], [517960800000, 349.72], [520552800000, 347.78], [523231200000, 345.86], [525909600000, 344.84], [528505200000, 344.32], [531183600000, 345.67], [533775600000, 346.88], [536454000000, 348.19], [539132400000, 348.55], [541551600000, 349.52], [544226400000, 351.12], [546818400000, 351.84], [549496800000, 351.49], [552088800000, 349.82], [554767200000, 347.63], [557445600000, 346.38], [560041200000, 346.49], [562719600000, 347.75], [565311600000, 349.03], [567990000000, 350.20], [570668400000, 351.61], [573174000000, 352.22], [575848800000, 353.53], [578440800000, 354.14], [581119200000, 353.62], [583711200000, 352.53], [586389600000, 350.41], [589068000000, 348.84], [591663600000, 348.94], [594342000000, 350.04], [596934000000, 351.29], [599612400000, 352.72], [602290800000, 353.10], [604710000000, 353.65], [607384800000, 355.43], [609976800000, 355.70], [612655200000, 355.11], [615247200000, 353.79], [617925600000, 351.42], [620604000000, 349.81], [623199600000, 350.11], [625878000000, 351.26], [628470000000, 352.63], [631148400000, 353.64], [633826800000, 354.72], [636246000000, 355.49], [638920800000, 356.09], [641512800000, 357.08], [644191200000, 356.11], [646783200000, 354.70], [649461600000, 352.68], [652140000000, 351.05], [654735600000, 351.36], [657414000000, 352.81], [660006000000, 354.22], [662684400000, 354.85], [665362800000, 355.66], [667782000000, 357.04], [670456800000, 358.40], [673048800000, 359.00], [675727200000, 357.99], [678319200000, 356.00], [680997600000, 353.78], [683676000000, 352.20], [686271600000, 352.22], [688950000000, 353.70], [691542000000, 354.98], [694220400000, 356.09], [696898800000, 356.85], [699404400000, 357.73], [702079200000, 358.91], [704671200000, 359.45], [707349600000, 359.19], [709941600000, 356.72], [712620000000, 354.79], [715298400000, 352.79], [717894000000, 353.20], [720572400000, 354.15], [723164400000, 355.39], [725842800000, 356.77], [728521200000, 357.17], [730940400000, 358.26], [733615200000, 359.16], [736207200000, 360.07], [738885600000, 359.41], [741477600000, 357.44], [744156000000, 355.30], [746834400000, 353.87], [749430000000, 354.04], [752108400000, 355.27], [754700400000, 356.70], [757378800000, 358.00], [760057200000, 358.81], [762476400000, 359.68], [765151200000, 361.13], [767743200000, 361.48], [770421600000, 360.60], [773013600000, 359.20], [775692000000, 357.23], [778370400000, 355.42], [780966000000, 355.89], [783644400000, 357.41], [786236400000, 358.74], [788914800000, 359.73], [791593200000, 360.61], [794012400000, 361.58], [796687200000, 363.05], [799279200000, 363.62], [801957600000, 363.03], [804549600000, 361.55], [807228000000, 358.94], [809906400000, 357.93], [812502000000, 357.80], [815180400000, 359.22], [817772400000, 360.44], [820450800000, 361.83], [823129200000, 362.95], [825634800000, 363.91], [828309600000, 364.28], [830901600000, 364.94], [833580000000, 364.70], [836172000000, 363.31], [838850400000, 361.15], [841528800000, 359.40], [844120800000, 359.34], [846802800000, 360.62], [849394800000, 361.96], [852073200000, 362.81], [854751600000, 363.87], [857170800000, 364.25], [859845600000, 366.02], [862437600000, 366.46], [865116000000, 365.32], [867708000000, 364.07], [870386400000, 361.95], [873064800000, 360.06], [875656800000, 360.49], [878338800000, 362.19], [880930800000, 364.12], [883609200000, 364.99], [886287600000, 365.82], [888706800000, 366.95], [891381600000, 368.42], [893973600000, 369.33], [896652000000, 368.78], [899244000000, 367.59], [901922400000, 365.84], [904600800000, 363.83], [907192800000, 364.18], [909874800000, 365.34], [912466800000, 366.93], [915145200000, 367.94], [917823600000, 368.82], [920242800000, 369.46], [922917600000, 370.77], [925509600000, 370.66], [928188000000, 370.10], [930780000000, 369.08], [933458400000, 366.66], [936136800000, 364.60], [938728800000, 365.17], [941410800000, 366.51], [944002800000, 367.89], [946681200000, 369.04], [949359600000, 369.35], [951865200000, 370.38], [954540000000, 371.63], [957132000000, 371.32], [959810400000, 371.53], [962402400000, 369.75], [965080800000, 368.23], [967759200000, 366.87], [970351200000, 366.94], [973033200000, 368.27], [975625200000, 369.64], [978303600000, 370.46], [980982000000, 371.44], [983401200000, 372.37], [986076000000, 373.33], [988668000000, 373.77], [991346400000, 373.09], [993938400000, 371.51], [996616800000, 369.55], [999295200000, 368.12], [1001887200000, 368.38], [1004569200000, 369.66], [1007161200000, 371.11], [1009839600000, 372.36], [1012518000000, 373.09], [1014937200000, 373.81], [1017612000000, 374.93], [1020204000000, 375.58], [1022882400000, 375.44], [1025474400000, 373.86], [1028152800000, 371.77], [1030831200000, 370.73], [1033423200000, 370.50], [1036105200000, 372.18], [1038697200000, 373.70], [1041375600000, 374.92], [1044054000000, 375.62], [1046473200000, 376.51], [1049148000000, 377.75], [1051740000000, 378.54], [1054418400000, 378.20], [1057010400000, 376.68], [1059688800000, 374.43], [1062367200000, 373.11], [1064959200000, 373.10], [1067641200000, 374.77], [1070233200000, 375.97], [1072911600000, 377.03], [1075590000000, 377.87], [1078095600000, 378.88], [1080770400000, 380.42], [1083362400000, 380.62], [1086040800000, 379.70], [1088632800000, 377.43], [1091311200000, 376.32], [1093989600000, 374.19], [1096581600000, 374.47], [1099263600000, 376.15], [1101855600000, 377.51], [1104534000000, 378.43], [1107212400000, 379.70], [1109631600000, 380.92], [1112306400000, 382.18], [1114898400000, 382.45], [1117576800000, 382.14], [1120168800000, 380.60], [1122847200000, 378.64], [1125525600000, 376.73], [1128117600000, 376.84], [1130799600000, 378.29], [1133391600000, 380.06], [1136070000000, 381.40], [1138748400000, 382.20], [1141167600000, 382.66], [1143842400000, 384.69], [1146434400000, 384.94], [1149112800000, 384.01], [1151704800000, 382.14], [1154383200000, 380.31], [1157061600000, 378.81], [1159653600000, 379.03], [1162335600000, 380.17], [1164927600000, 381.85], [1167606000000, 382.94], [1170284400000, 383.86], [1172703600000, 384.49], [1175378400000, 386.37], [1177970400000, 386.54], [1180648800000, 385.98], [1183240800000, 384.36], [1185919200000, 381.85], [1188597600000, 380.74], [1191189600000, 381.15], [1193871600000, 382.38], [1196463600000, 383.94], [1199142000000, 385.44]]; var d = [[-373597200000, 315.71], [-370918800000, 317.45], [-368326800000, 317.50], [-363056400000, 315.86], [-360378000000, 314.93], [-357699600000, 313.19], [-352429200000, 313.34], [-349837200000, 314.67], [-347158800000, 315.58], [-344480400000, 316.47], [-342061200000, 316.65], [-339382800000, 317.71], [-336790800000, 318.29], [-334112400000, 318.16], [-331520400000, 316.55], [-328842000000, 314.80], [-326163600000, 313.84], [-323571600000, 313.34], [-320893200000, 314.81], [-318301200000, 315.59], [-315622800000, 316.43], [-312944400000, 316.97], [-310438800000, 317.58], [-307760400000, 319.03], [-305168400000, 320.03], [-302490000000, 319.59], [-299898000000, 318.18], [-297219600000, 315.91], [-294541200000, 314.16], [-291949200000, 313.83], [-289270800000, 315.00], [-286678800000, 316.19], [-284000400000, 316.89], [-281322000000, 317.70], [-278902800000, 318.54], [-276224400000, 319.48], [-273632400000, 320.58], [-270954000000, 319.78], [-268362000000, 318.58], [-265683600000, 316.79], [-263005200000, 314.99], [-260413200000, 315.31], [-257734800000, 316.10], [-255142800000, 317.01], [-252464400000, 317.94], [-249786000000, 318.56], [-247366800000, 319.69], [-244688400000, 320.58], [-242096400000, 321.01], [-239418000000, 320.61], [-236826000000, 319.61], [-234147600000, 317.40], [-231469200000, 316.26], [-228877200000, 315.42], [-226198800000, 316.69], [-223606800000, 317.69], [-220928400000, 318.74], [-218250000000, 319.08], [-215830800000, 319.86], [-213152400000, 321.39], [-210560400000, 322.24], [-207882000000, 321.47], [-205290000000, 319.74], [-202611600000, 317.77], [-199933200000, 316.21], [-197341200000, 315.99], [-194662800000, 317.07], [-192070800000, 318.36], [-189392400000, 319.57], [-178938000000, 322.23], [-176259600000, 321.89], [-173667600000, 320.44], [-170989200000, 318.70], [-168310800000, 316.70], [-165718800000, 316.87], [-163040400000, 317.68], [-160448400000, 318.71], [-157770000000, 319.44], [-155091600000, 320.44], [-152672400000, 320.89], [-149994000000, 322.13], [-147402000000, 322.16], [-144723600000, 321.87], [-142131600000, 321.21], [-139453200000, 318.87], [-136774800000, 317.81], [-134182800000, 317.30], [-131504400000, 318.87], [-128912400000, 319.42], [-126234000000, 320.62], [-123555600000, 321.59], [-121136400000, 322.39], [-118458000000, 323.70], [-115866000000, 324.07], [-113187600000, 323.75], [-110595600000, 322.40], [-107917200000, 320.37], [-105238800000, 318.64], [-102646800000, 318.10], [-99968400000, 319.79], [-97376400000, 321.03], [-94698000000, 322.33], [-92019600000, 322.50], [-89600400000, 323.04], [-86922000000, 324.42], [-84330000000, 325.00], [-81651600000, 324.09], [-79059600000, 322.55], [-76381200000, 320.92], [-73702800000, 319.26], [-71110800000, 319.39], [-68432400000, 320.72], [-65840400000, 321.96], [-63162000000, 322.57], [-60483600000, 323.15], [-57978000000, 323.89], [-55299600000, 325.02], [-52707600000, 325.57], [-50029200000, 325.36], [-47437200000, 324.14], [-44758800000, 322.11], [-42080400000, 320.33], [-39488400000, 320.25], [-36810000000, 321.32], [-34218000000, 322.90], [-31539600000, 324.00], [-28861200000, 324.42], [-26442000000, 325.64], [-23763600000, 326.66], [-21171600000, 327.38], [-18493200000, 326.70], [-15901200000, 325.89], [-13222800000, 323.67], [-10544400000, 322.38], [-7952400000, 321.78], [-5274000000, 322.85], [-2682000000, 324.12], [-3600000, 325.06], [2674800000, 325.98], [5094000000, 326.93], [7772400000, 328.13], [10364400000, 328.07], [13042800000, 327.66], [15634800000, 326.35], [18313200000, 324.69], [20991600000, 323.10], [23583600000, 323.07], [26262000000, 324.01], [28854000000, 325.13], [31532400000, 326.17], [34210800000, 326.68], [36630000000, 327.18], [39308400000, 327.78], [41900400000, 328.92], [44578800000, 328.57], [47170800000, 327.37], [49849200000, 325.43], [52527600000, 323.36], [55119600000, 323.56], [57798000000, 324.80], [60390000000, 326.01], [63068400000, 326.77], [65746800000, 327.63], [68252400000, 327.75], [70930800000, 329.72], [73522800000, 330.07], [76201200000, 329.09], [78793200000, 328.05], [81471600000, 326.32], [84150000000, 324.84], [86742000000, 325.20], [89420400000, 326.50], [92012400000, 327.55], [94690800000, 328.54], [97369200000, 329.56], [99788400000, 330.30], [102466800000, 331.50], [105058800000, 332.48], [107737200000, 332.07], [110329200000, 330.87], [113007600000, 329.31], [115686000000, 327.51], [118278000000, 327.18], [120956400000, 328.16], [123548400000, 328.64], [126226800000, 329.35], [128905200000, 330.71], [131324400000, 331.48], [134002800000, 332.65], [136594800000, 333.16], [139273200000, 332.06], [141865200000, 330.99], [144543600000, 329.17], [147222000000, 327.41], [149814000000, 327.20], [152492400000, 328.33], [155084400000, 329.50], [157762800000, 330.68], [160441200000, 331.41], [162860400000, 331.85], [165538800000, 333.29], [168130800000, 333.91], [170809200000, 333.40], [173401200000, 331.78], [176079600000, 329.88], [178758000000, 328.57], [181350000000, 328.46], [184028400000, 329.26], [189298800000, 331.71], [191977200000, 332.76], [194482800000, 333.48], [197161200000, 334.78], [199753200000, 334.78], [202431600000, 334.17], [205023600000, 332.78], [207702000000, 330.64], [210380400000, 328.95], [212972400000, 328.77], [215650800000, 330.23], [218242800000, 331.69], [220921200000, 332.70], [223599600000, 333.24], [226018800000, 334.96], [228697200000, 336.04], [231289200000, 336.82], [233967600000, 336.13], [236559600000, 334.73], [239238000000, 332.52], [241916400000, 331.19], [244508400000, 331.19], [247186800000, 332.35], [249778800000, 333.47], [252457200000, 335.11], [255135600000, 335.26], [257554800000, 336.60], [260233200000, 337.77], [262825200000, 338.00], [265503600000, 337.99], [268095600000, 336.48], [270774000000, 334.37], [273452400000, 332.27], [276044400000, 332.41], [278722800000, 333.76], [281314800000, 334.83], [283993200000, 336.21], [286671600000, 336.64], [289090800000, 338.12], [291769200000, 339.02], [294361200000, 339.02], [297039600000, 339.20], [299631600000, 337.58], [302310000000, 335.55], [304988400000, 333.89], [307580400000, 334.14], [310258800000, 335.26], [312850800000, 336.71], [315529200000, 337.81], [318207600000, 338.29], [320713200000, 340.04], [323391600000, 340.86], [325980000000, 341.47], [328658400000, 341.26], [331250400000, 339.29], [333928800000, 337.60], [336607200000, 336.12], [339202800000, 336.08], [341881200000, 337.22], [344473200000, 338.34], [347151600000, 339.36], [349830000000, 340.51], [352249200000, 341.57], [354924000000, 342.56], [357516000000, 343.01], [360194400000, 342.47], [362786400000, 340.71], [365464800000, 338.52], [368143200000, 336.96], [370738800000, 337.13], [373417200000, 338.58], [376009200000, 339.89], [378687600000, 340.93], [381366000000, 341.69], [383785200000, 342.69], [389052000000, 344.30], [391730400000, 343.43], [394322400000, 341.88], [397000800000, 339.89], [399679200000, 337.95], [402274800000, 338.10], [404953200000, 339.27], [407545200000, 340.67], [410223600000, 341.42], [412902000000, 342.68], [415321200000, 343.46], [417996000000, 345.10], [420588000000, 345.76], [423266400000, 345.36], [425858400000, 343.91], [428536800000, 342.05], [431215200000, 340.00], [433810800000, 340.12], [436489200000, 341.33], [439081200000, 342.94], [441759600000, 343.87], [444438000000, 344.60], [446943600000, 345.20], [452210400000, 347.36], [454888800000, 346.74], [457480800000, 345.41], [460159200000, 343.01], [462837600000, 341.23], [465433200000, 341.52], [468111600000, 342.86], [470703600000, 344.41], [473382000000, 345.09], [476060400000, 345.89], [478479600000, 347.49], [481154400000, 348.00], [483746400000, 348.75], [486424800000, 348.19], [489016800000, 346.54], [491695200000, 344.63], [494373600000, 343.03], [496969200000, 342.92], [499647600000, 344.24], [502239600000, 345.62], [504918000000, 346.43], [507596400000, 346.94], [510015600000, 347.88], [512690400000, 349.57], [515282400000, 350.35], [517960800000, 349.72], [520552800000, 347.78], [523231200000, 345.86], [525909600000, 344.84], [528505200000, 344.32], [531183600000, 345.67], [533775600000, 346.88], [536454000000, 348.19], [539132400000, 348.55], [541551600000, 349.52], [544226400000, 351.12], [546818400000, 351.84], [549496800000, 351.49], [552088800000, 349.82], [554767200000, 347.63], [557445600000, 346.38], [560041200000, 346.49], [562719600000, 347.75], [565311600000, 349.03], [567990000000, 350.20], [570668400000, 351.61], [573174000000, 352.22], [575848800000, 353.53], [578440800000, 354.14], [581119200000, 353.62], [583711200000, 352.53], [586389600000, 350.41], [589068000000, 348.84], [591663600000, 348.94], [594342000000, 350.04], [596934000000, 351.29], [599612400000, 352.72], [602290800000, 353.10], [604710000000, 353.65], [607384800000, 355.43], [609976800000, 355.70], [612655200000, 355.11], [615247200000, 353.79], [617925600000, 351.42], [620604000000, 349.81], [623199600000, 350.11], [625878000000, 351.26], [628470000000, 352.63], [631148400000, 353.64], [633826800000, 354.72], [636246000000, 355.49], [638920800000, 356.09], [641512800000, 357.08], [644191200000, 356.11], [646783200000, 354.70], [649461600000, 352.68], [652140000000, 351.05], [654735600000, 351.36], [657414000000, 352.81], [660006000000, 354.22], [662684400000, 354.85], [665362800000, 355.66], [667782000000, 357.04], [670456800000, 358.40], [673048800000, 359.00], [675727200000, 357.99], [678319200000, 356.00], [680997600000, 353.78], [683676000000, 352.20], [686271600000, 352.22], [688950000000, 353.70], [691542000000, 354.98], [694220400000, 356.09], [696898800000, 356.85], [699404400000, 357.73], [702079200000, 358.91], [704671200000, 359.45], [707349600000, 359.19], [709941600000, 356.72], [712620000000, 354.79], [715298400000, 352.79], [717894000000, 353.20], [720572400000, 354.15], [723164400000, 355.39], [725842800000, 356.77], [728521200000, 357.17], [730940400000, 358.26], [733615200000, 359.16], [736207200000, 360.07], [738885600000, 359.41], [741477600000, 357.44], [744156000000, 355.30], [746834400000, 353.87], [749430000000, 354.04], [752108400000, 355.27], [754700400000, 356.70], [757378800000, 358.00], [760057200000, 358.81], [762476400000, 359.68], [765151200000, 361.13], [767743200000, 361.48], [770421600000, 360.60], [773013600000, 359.20], [775692000000, 357.23], [778370400000, 355.42], [780966000000, 355.89], [783644400000, 357.41], [786236400000, 358.74], [788914800000, 359.73], [791593200000, 360.61], [794012400000, 361.58], [796687200000, 363.05], [799279200000, 363.62], [801957600000, 363.03], [804549600000, 361.55], [807228000000, 358.94], [809906400000, 357.93], [812502000000, 357.80], [815180400000, 359.22], [817772400000, 360.44], [820450800000, 361.83], [823129200000, 362.95], [825634800000, 363.91], [828309600000, 364.28], [830901600000, 364.94], [833580000000, 364.70], [836172000000, 363.31], [838850400000, 361.15], [841528800000, 359.40], [844120800000, 359.34], [846802800000, 360.62], [849394800000, 361.96], [852073200000, 362.81], [854751600000, 363.87], [857170800000, 364.25], [859845600000, 366.02], [862437600000, 366.46], [865116000000, 365.32], [867708000000, 364.07], [870386400000, 361.95], [873064800000, 360.06], [875656800000, 360.49], [878338800000, 362.19], [880930800000, 364.12], [883609200000, 364.99], [886287600000, 365.82], [888706800000, 366.95], [891381600000, 368.42], [893973600000, 369.33], [896652000000, 368.78], [899244000000, 367.59], [901922400000, 365.84], [904600800000, 363.83], [907192800000, 364.18], [909874800000, 365.34], [912466800000, 366.93], [915145200000, 367.94], [917823600000, 368.82], [920242800000, 369.46], [922917600000, 370.77], [925509600000, 370.66], [928188000000, 370.10], [930780000000, 369.08], [933458400000, 366.66], [936136800000, 364.60], [938728800000, 365.17], [941410800000, 366.51], [944002800000, 367.89], [946681200000, 369.04], [949359600000, 369.35], [951865200000, 370.38], [954540000000, 371.63], [957132000000, 371.32], [959810400000, 371.53], [962402400000, 369.75], [965080800000, 368.23], [967759200000, 366.87], [970351200000, 366.94], [973033200000, 368.27], [975625200000, 369.64], [978303600000, 370.46], [980982000000, 371.44], [983401200000, 372.37], [986076000000, 373.33], [988668000000, 373.77], [991346400000, 373.09], [993938400000, 371.51], [996616800000, 369.55], [999295200000, 368.12], [1001887200000, 368.38], [1004569200000, 369.66], [1007161200000, 371.11], [1009839600000, 372.36], [1012518000000, 373.09], [1014937200000, 373.81], [1017612000000, 374.93], [1020204000000, 375.58], [1022882400000, 375.44], [1025474400000, 373.86], [1028152800000, 371.77], [1030831200000, 370.73], [1033423200000, 370.50], [1036105200000, 372.18], [1038697200000, 373.70], [1041375600000, 374.92], [1044054000000, 375.62], [1046473200000, 376.51], [1049148000000, 377.75], [1051740000000, 378.54], [1054418400000, 378.20], [1057010400000, 376.68], [1059688800000, 374.43], [1062367200000, 373.11], [1064959200000, 373.10], [1067641200000, 374.77], [1070233200000, 375.97], [1072911600000, 377.03], [1075590000000, 377.87], [1078095600000, 378.88], [1080770400000, 380.42], [1083362400000, 380.62], [1086040800000, 379.70], [1088632800000, 377.43], [1091311200000, 376.32], [1093989600000, 374.19], [1096581600000, 374.47], [1099263600000, 376.15], [1101855600000, 377.51], [1104534000000, 378.43], [1107212400000, 379.70], [1109631600000, 380.92], [1112306400000, 382.18], [1114898400000, 382.45], [1117576800000, 382.14], [1120168800000, 380.60], [1122847200000, 378.64], [1125525600000, 376.73], [1128117600000, 376.84], [1130799600000, 378.29], [1133391600000, 380.06], [1136070000000, 381.40], [1138748400000, 382.20], [1141167600000, 382.66], [1143842400000, 384.69], [1146434400000, 384.94], [1149112800000, 384.01], [1151704800000, 382.14], [1154383200000, 380.31], [1157061600000, 378.81], [1159653600000, 379.03], [1162335600000, 380.17], [1164927600000, 381.85], [1167606000000, 382.94], [1170284400000, 383.86], [1172703600000, 384.49], [1175378400000, 386.37], [1177970400000, 386.54], [1180648800000, 385.98], [1183240800000, 384.36], [1185919200000, 381.85], [1188597600000, 380.74], [1191189600000, 381.15], [1193871600000, 382.38], [1196463600000, 383.94], [1199142000000, 385.44]];
...@@ -45,20 +45,24 @@ $(function () { ...@@ -45,20 +45,24 @@ $(function () {
}); });
$("#nineties").click(function () { $("#nineties").click(function () {
$.plot($("#placeholder"), [d], { xaxis: { $.plot($("#placeholder"), [d], {
mode: "time", xaxis: {
min: (new Date("1990/01/01")).getTime(), mode: "time",
max: (new Date("2000/01/01")).getTime() min: (new Date("1990/01/01")).getTime(),
} }); max: (new Date("2000/01/01")).getTime()
}
});
}); });
$("#ninetynine").click(function () { $("#ninetynine").click(function () {
$.plot($("#placeholder"), [d], { xaxis: { $.plot($("#placeholder"), [d], {
mode: "time", xaxis: {
minTickSize: [1, "month"], mode: "time",
min: (new Date("1999/01/01")).getTime(), minTickSize: [1, "month"],
max: (new Date("2000/01/01")).getTime() min: (new Date("1999/01/01")).getTime(),
} }); max: (new Date("2000/01/01")).getTime()
}
});
}); });
}); });
</script> </script>
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
<p>If you combine it with listening on hover events, you can use <p>If you combine it with listening on hover events, you can use
it to track the intersection on the curves by interpolating it to track the intersection on the curves by interpolating
the data points.</p> the data points (look at the legend).</p>
<p id="hoverdata"></p> <p id="hoverdata"></p>
...@@ -31,12 +31,15 @@ $(function () { ...@@ -31,12 +31,15 @@ $(function () {
} }
var plot = $.plot($("#placeholder"), var plot = $.plot($("#placeholder"),
[ { data: sin, label: "sin(x) = -0.00"}, { data: cos, label: "cos(x) = -0.00" } ], [ { data: sin, label: "sin(x) = -0.00"},
{ lines: { show: true }, { data: cos, label: "cos(x) = -0.00" } ], {
crosshair: { mode: "x" }, series: {
grid: { hoverable: true, autoHighlight: false }, lines: { show: true }
yaxis: { min: -1.2, max: 1.2 } },
}); crosshair: { mode: "x" },
grid: { hoverable: true, autoHighlight: false },
yaxis: { min: -1.2, max: 1.2 }
});
var legends = $("#placeholder .legendLabel"); var legends = $("#placeholder .legendLabel");
legends.each(function () { legends.each(function () {
// fix the widths so they don't jump around // fix the widths so they don't jump around
...@@ -73,7 +76,7 @@ $(function () { ...@@ -73,7 +76,7 @@ $(function () {
y = p1[1]; y = p1[1];
else else
y = p1[1] + (p2[1] - p1[1]) * (pos.x - p1[0]) / (p2[0] - p1[0]); y = p1[1] + (p2[1] - p1[1]) * (pos.x - p1[0]) / (p2[0] - p1[0]);
legends.eq(i).text(series.label.replace(/=.*/, "= " + y.toFixed(2))); legends.eq(i).text(series.label.replace(/=.*/, "= " + y.toFixed(2)));
} }
} }
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
<div id="overview" style="margin-left:50px;margin-top:20px;width:400px;height:50px"></div> <div id="overview" style="margin-left:50px;margin-top:20px;width:400px;height:50px"></div>
<script id="source" language="javascript" type="text/javascript"> <script id="source">
$(function () { $(function () {
var d = [[1196463600000, 0], [1196550000000, 0], [1196636400000, 0], [1196722800000, 77], [1196809200000, 3636], [1196895600000, 3575], [1196982000000, 2736], [1197068400000, 1086], [1197154800000, 676], [1197241200000, 1205], [1197327600000, 906], [1197414000000, 710], [1197500400000, 639], [1197586800000, 540], [1197673200000, 435], [1197759600000, 301], [1197846000000, 575], [1197932400000, 481], [1198018800000, 591], [1198105200000, 608], [1198191600000, 459], [1198278000000, 234], [1198364400000, 1352], [1198450800000, 686], [1198537200000, 279], [1198623600000, 449], [1198710000000, 468], [1198796400000, 392], [1198882800000, 282], [1198969200000, 208], [1199055600000, 229], [1199142000000, 177], [1199228400000, 374], [1199314800000, 436], [1199401200000, 404], [1199487600000, 253], [1199574000000, 218], [1199660400000, 476], [1199746800000, 462], [1199833200000, 448], [1199919600000, 442], [1200006000000, 403], [1200092400000, 204], [1200178800000, 194], [1200265200000, 327], [1200351600000, 374], [1200438000000, 507], [1200524400000, 546], [1200610800000, 482], [1200697200000, 283], [1200783600000, 221], [1200870000000, 483], [1200956400000, 523], [1201042800000, 528], [1201129200000, 483], [1201215600000, 452], [1201302000000, 270], [1201388400000, 222], [1201474800000, 439], [1201561200000, 559], [1201647600000, 521], [1201734000000, 477], [1201820400000, 442], [1201906800000, 252], [1201993200000, 236], [1202079600000, 525], [1202166000000, 477], [1202252400000, 386], [1202338800000, 409], [1202425200000, 408], [1202511600000, 237], [1202598000000, 193], [1202684400000, 357], [1202770800000, 414], [1202857200000, 393], [1202943600000, 353], [1203030000000, 364], [1203116400000, 215], [1203202800000, 214], [1203289200000, 356], [1203375600000, 399], [1203462000000, 334], [1203548400000, 348], [1203634800000, 243], [1203721200000, 126], [1203807600000, 157], [1203894000000, 288]]; var d = [[1196463600000, 0], [1196550000000, 0], [1196636400000, 0], [1196722800000, 77], [1196809200000, 3636], [1196895600000, 3575], [1196982000000, 2736], [1197068400000, 1086], [1197154800000, 676], [1197241200000, 1205], [1197327600000, 906], [1197414000000, 710], [1197500400000, 639], [1197586800000, 540], [1197673200000, 435], [1197759600000, 301], [1197846000000, 575], [1197932400000, 481], [1198018800000, 591], [1198105200000, 608], [1198191600000, 459], [1198278000000, 234], [1198364400000, 1352], [1198450800000, 686], [1198537200000, 279], [1198623600000, 449], [1198710000000, 468], [1198796400000, 392], [1198882800000, 282], [1198969200000, 208], [1199055600000, 229], [1199142000000, 177], [1199228400000, 374], [1199314800000, 436], [1199401200000, 404], [1199487600000, 253], [1199574000000, 218], [1199660400000, 476], [1199746800000, 462], [1199833200000, 448], [1199919600000, 442], [1200006000000, 403], [1200092400000, 204], [1200178800000, 194], [1200265200000, 327], [1200351600000, 374], [1200438000000, 507], [1200524400000, 546], [1200610800000, 482], [1200697200000, 283], [1200783600000, 221], [1200870000000, 483], [1200956400000, 523], [1201042800000, 528], [1201129200000, 483], [1201215600000, 452], [1201302000000, 270], [1201388400000, 222], [1201474800000, 439], [1201561200000, 559], [1201647600000, 521], [1201734000000, 477], [1201820400000, 442], [1201906800000, 252], [1201993200000, 236], [1202079600000, 525], [1202166000000, 477], [1202252400000, 386], [1202338800000, 409], [1202425200000, 408], [1202511600000, 237], [1202598000000, 193], [1202684400000, 357], [1202770800000, 414], [1202857200000, 393], [1202943600000, 353], [1203030000000, 364], [1203116400000, 215], [1203202800000, 214], [1203289200000, 356], [1203375600000, 399], [1203462000000, 334], [1203548400000, 348], [1203634800000, 243], [1203721200000, 126], [1203807600000, 157], [1203894000000, 288]];
...@@ -39,7 +39,7 @@ $(function () { ...@@ -39,7 +39,7 @@ $(function () {
d.setUTCHours(0); d.setUTCHours(0);
var i = d.getTime(); var i = d.getTime();
do { do {
// when we don't set yaxis the rectangle automatically // when we don't set yaxis, the rectangle automatically
// extends to infinity upwards and downwards // extends to infinity upwards and downwards
markings.push({ xaxis: { from: i, to: i + 2 * 24 * 60 * 60 * 1000 } }); markings.push({ xaxis: { from: i, to: i + 2 * 24 * 60 * 60 * 1000 } });
i += 7 * 24 * 60 * 60 * 1000; i += 7 * 24 * 60 * 60 * 1000;
...@@ -57,8 +57,10 @@ $(function () { ...@@ -57,8 +57,10 @@ $(function () {
var plot = $.plot($("#placeholder"), [d], options); var plot = $.plot($("#placeholder"), [d], options);
var overview = $.plot($("#overview"), [d], { var overview = $.plot($("#overview"), [d], {
lines: { show: true, lineWidth: 1 }, series: {
shadowSize: 0, lines: { show: true, lineWidth: 1 },
shadowSize: 0
},
xaxis: { ticks: [], mode: "time" }, xaxis: { ticks: [], mode: "time" },
yaxis: { ticks: [], min: 0, autoscaleMargin: 0.1 }, yaxis: { ticks: [], min: 0, autoscaleMargin: 0.1 },
selection: { mode: "x" } selection: { mode: "x" }
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
the small overview plot to the right has been connected to the large the small overview plot to the right has been connected to the large
plot. Try selecting a rectangle on either of them.</p> plot. Try selecting a rectangle on either of them.</p>
<script id="source" language="javascript" type="text/javascript"> <script id="source">
$(function () { $(function () {
// setup plot // setup plot
function getData(x1, x2) { function getData(x1, x2) {
...@@ -43,8 +43,10 @@ $(function () { ...@@ -43,8 +43,10 @@ $(function () {
var options = { var options = {
legend: { show: false }, legend: { show: false },
lines: { show: true }, series: {
points: { show: true }, lines: { show: true },
points: { show: true }
},
yaxis: { ticks: 10 }, yaxis: { ticks: 10 },
selection: { mode: "xy" } selection: { mode: "xy" }
}; };
...@@ -56,8 +58,10 @@ $(function () { ...@@ -56,8 +58,10 @@ $(function () {
// setup overview // setup overview
var overview = $.plot($("#overview"), startData, { var overview = $.plot($("#overview"), startData, {
legend: { show: true, container: $("#overviewLegend") }, legend: { show: true, container: $("#overviewLegend") },
lines: { show: true, lineWidth: 1 }, series: {
shadowSize: 0, lines: { show: true, lineWidth: 1 },
shadowSize: 0
},
xaxis: { ticks: 4 }, xaxis: { ticks: 4 },
yaxis: { ticks: 3, min: -2, max: 2 }, yaxis: { ticks: 3, min: -2, max: 2 },
grid: { color: "#999" }, grid: { color: "#999" },
......
...@@ -5,11 +5,11 @@ ...@@ -5,11 +5,11 @@
*/ */
(function($) { (function($) {
function Plot(target_, data_, options_) { function Plot(target, data_, options_, plugins) {
// data is on the form: // data is on the form:
// [ series1, series2 ... ] // [ series1, series2 ... ]
// where series is either just the data as [ [x1, y1], [x2, y2], ... ] // where series is either just the data as [ [x1, y1], [x2, y2], ... ]
// or { data: [ [x1, y1], [x2, y2], ... ], label: "some label" } // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... }
var series = [], var series = [],
options = { options = {
...@@ -51,32 +51,34 @@ ...@@ -51,32 +51,34 @@
}, },
y2axis: { y2axis: {
autoscaleMargin: 0.02 autoscaleMargin: 0.02
},
points: {
show: false,
radius: 3,
lineWidth: 2, // in pixels
fill: true,
fillColor: "#ffffff"
}, },
lines: { series: {
// we don't put in show: false so we can see points: {
// whether lines were actively disabled show: false,
lineWidth: 2, // in pixels radius: 3,
fill: false, lineWidth: 2, // in pixels
fillColor: null, fill: true,
steps: false fillColor: "#ffffff"
},
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 // when horizontal, left is now top
},
shadowSize: 3
}, },
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 // when horizontal, left is now top
},
threshold: null, // or { below: number, color: color spec}
grid: { grid: {
color: "#545454", // primary color used for outline and labels color: "#545454", // primary color used for outline and labels
backgroundColor: null, // null for transparent, else color backgroundColor: null, // null for transparent, else color
...@@ -100,70 +102,71 @@ ...@@ -100,70 +102,71 @@
crosshair: { crosshair: {
mode: null, // one of null, "x", "y" or "xy", mode: null, // one of null, "x", "y" or "xy",
color: "#aa0000" color: "#aa0000"
}, }
shadowSize: 3
}, },
canvas = null, // the canvas for the plot itself canvas = null, // the canvas for the plot itself
overlay = null, // canvas for interactive stuff on top of plot overlay = null, // canvas for interactive stuff on top of plot
eventHolder = null, // jQuery object that events should be bound to eventHolder = null, // jQuery object that events should be bound to
ctx = null, octx = null, ctx = null, octx = null,
target = $(target_),
axes = { xaxis: {}, yaxis: {}, x2axis: {}, y2axis: {} }, axes = { xaxis: {}, yaxis: {}, x2axis: {}, y2axis: {} },
plotOffset = { left: 0, right: 0, top: 0, bottom: 0}, plotOffset = { left: 0, right: 0, top: 0, bottom: 0},
canvasWidth = 0, canvasHeight = 0, canvasWidth = 0, canvasHeight = 0,
plotWidth = 0, plotHeight = 0, plotWidth = 0, plotHeight = 0,
hooks = {
processOptions: [],
processRawData: [],
processDatapoints: []
},
plot = this,
// dedicated to storing data for buggy standard compliance cases // dedicated to storing data for buggy standard compliance cases
workarounds = {}; workarounds = {};
this.setData = setData; // public functions
this.setupGrid = setupGrid; plot.setData = setData;
this.draw = draw; plot.setupGrid = setupGrid;
this.clearSelection = clearSelection; plot.draw = draw;
this.setSelection = setSelection; plot.clearSelection = clearSelection;
this.getCanvas = function() { return canvas; }; plot.setSelection = setSelection;
this.getPlotOffset = function() { return plotOffset; }; plot.getCanvas = function() { return canvas; };
this.getData = function() { return series; }; plot.getPlotOffset = function() { return plotOffset; };
this.getAxes = function() { return axes; }; plot.getData = function() { return series; };
this.setCrosshair = setCrosshair; plot.getAxes = function() { return axes; };
this.clearCrosshair = function () { setCrosshair(null); }; plot.getOptions = function() { return options; };
this.highlight = highlight; plot.setCrosshair = setCrosshair;
this.unhighlight = unhighlight; plot.clearCrosshair = function () { setCrosshair(null); };
plot.highlight = highlight;
plot.unhighlight = unhighlight;
// public attributes
plot.hooks = hooks;
// initialize // initialize
initPlugins(plot);
parseOptions(options_); parseOptions(options_);
setData(data_);
constructCanvas(); constructCanvas();
setData(data_);
setupGrid(); setupGrid();
draw(); draw();
bindEvents();
function setData(d) { function executeHooks(hook, args) {
series = parseData(d); args = [plot].concat(args);
for (var i = 0; i < hook.length; ++i)
fillInSeriesOptions(); hook[i].apply(this, args);
processData();
} }
function parseData(d) {
var res = [];
for (var i = 0; i < d.length; ++i) {
var s;
if (d[i].data) {
s = {};
for (var v in d[i])
s[v] = d[i][v];
}
else {
s = { data: d[i] };
}
res.push(s);
}
return res; 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(o) { function parseOptions(opts) {
$.extend(true, options, o); $.extend(true, options, opts);
if (options.grid.borderColor == null) if (options.grid.borderColor == null)
options.grid.borderColor = options.grid.color options.grid.borderColor = options.grid.color
// backwards compatibility, to be removed in future // backwards compatibility, to be removed in future
...@@ -175,8 +178,45 @@ ...@@ -175,8 +178,45 @@
options.grid.markings = options.grid.coloredAreas; options.grid.markings = options.grid.coloredAreas;
if (options.grid.coloredAreasColor) if (options.grid.coloredAreasColor)
options.grid.markingsColor = 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)
options.series.shadowSize = options.shadowSize;
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) {
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 fillInSeriesOptions() { function fillInSeriesOptions() {
var i; var i;
...@@ -231,7 +271,7 @@ ...@@ -231,7 +271,7 @@
var colori = 0, s; var colori = 0, s;
for (i = 0; i < series.length; ++i) { for (i = 0; i < series.length; ++i) {
s = series[i]; s = series[i];
// assign colors // assign colors
if (s.color == null) { if (s.color == null) {
s.color = colors[colori].toString(); s.color = colors[colori].toString();
...@@ -240,17 +280,11 @@ ...@@ -240,17 +280,11 @@
else if (typeof s.color == "number") else if (typeof s.color == "number")
s.color = colors[s.color].toString(); s.color = colors[s.color].toString();
// copy the rest
s.lines = $.extend(true, {}, options.lines, s.lines);
s.points = $.extend(true, {}, options.points, s.points);
s.bars = $.extend(true, {}, options.bars, s.bars);
// turn on lines automatically in case nothing is set // turn on lines automatically in case nothing is set
if (s.lines.show == null && !s.bars.show && !s.points.show) if (s.lines.show == null && !s.bars.show && !s.points.show)
s.lines.show = true; s.lines.show = true;
if (s.shadowSize == null)
s.shadowSize = options.shadowSize;
// setup axes
if (!s.xaxis) if (!s.xaxis)
s.xaxis = axes.xaxis; s.xaxis = axes.xaxis;
...@@ -266,17 +300,14 @@ ...@@ -266,17 +300,14 @@
s.yaxis = axes.yaxis; s.yaxis = axes.yaxis;
else if (s.yaxis == 2) else if (s.yaxis == 2)
s.yaxis = axes.y2axis; s.yaxis = axes.y2axis;
if (!s.threshold)
s.threshold = options.threshold;
s.subseries = null;
} }
} }
function processData() { function processData() {
var topSentry = Number.POSITIVE_INFINITY, var topSentry = Number.POSITIVE_INFINITY,
bottomSentry = Number.NEGATIVE_INFINITY, bottomSentry = Number.NEGATIVE_INFINITY,
axis, i, j, k, m, s; i, j, k, m, length,
s, points, ps, x, y;
for (axis in axes) { for (axis in axes) {
axes[axis].datamin = topSentry; axes[axis].datamin = topSentry;
...@@ -285,76 +316,141 @@ ...@@ -285,76 +316,141 @@
axes[axis].max = options[axis].max; axes[axis].max = options[axis].max;
axes[axis].used = false; axes[axis].used = false;
} }
function updateAxis(axis, min, max) {
if (min < axis.datamin)
axis.datamin = min;
if (max > axis.datamax)
axis.datamax = max;
}
for (i = 0; i < series.length; ++i) { for (i = 0; i < series.length; ++i) {
s = series[i]; s = series[i];
s.datapoints = { points: [], incr: 2 }; s.datapoints = { points: [] };
var data = s.data, executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]);
points = s.datapoints.points, }
axisx = s.xaxis, axisy = s.yaxis,
xmin = topSentry, xmax = bottomSentry, // first pass: clean and copy data
ymin = topSentry, ymax = bottomSentry, for (i = 0; i < series.length; ++i) {
x, y, p, incr, format = []; s = series[i];
if (s.datapoints.pointsize != null)
continue; // already filled in
// determine the increment var data = s.data, format = [], p;
// determine the point size
if (s.bars.show) { if (s.bars.show) {
s.datapoints.incr = 3; s.datapoints.pointsize = 3;
format.push({ d: 0 }); format.push({ d: 0 });
} }
else
s.datapoints.pointsize = 2;
/* /*
// examine data to find out how to copy // examine data to find out how to copy
for (j = 0; j < data.length; ++j) { for (j = 0; j < data.length; ++j) {
}*/ }*/
ps = s.datapoints.pointsize;
points = s.datapoints.points;
insertSteps = s.lines.show && s.lines.steps;
s.xaxis.used = s.yaxis.used = true;
axisx.used = axisy.used = true; for (j = k = 0; j < data.length; ++j, k += ps) {
incr = s.datapoints.incr;
for (j = k = 0; j < data.length; ++j, k += incr) {
p = data[j]; p = data[j];
x = null;
y = null;
if (data[j] != null) { if (p != null) {
x = p[0]; x = p[0];
y = p[1]; y = p[1];
} }
// convert to number
if (x != null && !isNaN(x = +x)) {
if (x < xmin)
xmin = x;
if (x > xmax)
xmax = x
}
else else
x = null; y = x = null;
if (y != null && !isNaN(y = +y)) { if (x != null) {
if (y < ymin) x = +x; // convert to number
ymin = y; if (isNaN(x))
if (y > ymax) x = null;
ymax = y;
} }
else
if (y != null) {
y = +y; // convert to number
if (isNaN(y))
y = null;
}
// check validity of point, making sure both are cleared
if (x == null && y != null) {
// extract min/max info before we whack
updateAxis(s.yaxis, y, y);
y = null; y = null;
}
if (x == null || y == null) if (y == null && x != null) {
x = y = null; // make sure everything is cleared updateAxis(s.xaxis, x, x);
x = null;
}
if (insertSteps && x != null && k > 0
&& points[k - ps] != null
&& points[k - ps] != x && points[k - ps + 1] != y) {
points[k + 1] = points[k - ps + 1];
points[k] = x;
// copy the remainding from real point
for (m = 2; m < ps; ++m)
points[k + m] = p[m] == null ? format[m-2].d : p[m];
k += ps;
}
for (m = 2; m < incr; ++m) for (m = 2; m < ps; ++m)
points[k + m] = p[m] == null ? format[m-2].d : p[m]; points[k + m] = p[m] == null ? format[m-2].d : p[m];
points[k + 1] = y;
points[k] = x; points[k] = x;
points[k + 1] = y;
} }
}
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) {
x = points[j];
if (x == null)
continue;
if (x < xmin)
xmin = x;
if (x > xmax)
xmax = x;
y = points[j + 1];
if (y < ymin)
ymin = y;
if (y > ymax)
ymax = y;
}
if (s.bars.show) { if (s.bars.show) {
// make sure we got room for the bar on the dancing floor // make sure we got room for the bar on the dancing floor
var delta = s.bars.align == "left" ? 0 : -s.bars.barWidth/2; var delta = s.bars.align == "left" ? 0 : -s.bars.barWidth/2;
if(s.bars.horizontal) { if (s.bars.horizontal) {
ymin += delta; ymin += delta;
ymax += delta + s.bars.barWidth; ymax += delta + s.bars.barWidth;
} }
...@@ -364,104 +460,8 @@ ...@@ -364,104 +460,8 @@
} }
} }
axisx.datamin = Math.min(axisx.datamin, xmin); updateAxis(s.xaxis, xmin, xmax);
axisx.datamax = Math.max(axisx.datamax, xmax); updateAxis(s.yaxis, ymin, ymax);
axisy.datamin = Math.min(axisy.datamin, ymin);
axisy.datamax = Math.max(axisy.datamax, ymax);
// step charts
if (s.lines.show && s.lines.steps) {
p = [];
// copy, inserting extra points to make steps
for (j = k = 0; j < points.length; j += incr, k += incr) {
x = points[j];
y = points[j + 1];
if (j > 0
&& points[j - incr] != null
&& x != null
&& points[j - incr + 1] != y) {
p[k] = x;
p[k + 1] = points[j - incr + 1];
k += incr;
}
p[k] = x;
p[k + 1] = y;
}
s.datapoints.linespoints = p;
}
// possibly split data points because of threshold
if (s.threshold) {
var orig = $.extend({}, s), thresholded = $.extend({}, s);
orig.datapoints = { points: [], incr: incr };
thresholded.datapoints = { points: [], incr: incr };
thresholded.color = s.threshold.color;
var below = s.threshold.below,
origpoints = orig.datapoints.points,
threspoints = thresholded.datapoints.points;
// ordinary points
for (j = 0; j < points.length; j += incr) {
x = points[j];
y = points[j + 1];
if (y < below)
p = threspoints;
else
p = origpoints;
p.push(x);
p.push(y);
for (m = 2; m < incr; ++m)
p.push(points[j + m]);
}
// possibly split lines
if (s.lines.show) {
var lp = s.datapoints.linespoints || points;
origpoints = [];
threspoints = [];
p = origpoints;
for (j = 0; j < lp.length; j += incr) {
x = lp[j];
y = lp[j + 1];
var prevp = p;
if (y != null) {
if (y < below)
p = threspoints;
else
p = origpoints;
}
if (p != prevp && x != null && j > 0 && lp[j - incr] != null) {
// find intersection and add it to both
k = (x - lp[j - incr]) / (y - lp[j - incr + 1]) * (below - y) + x;
prevp.push(k);
prevp.push(below);
p.push(null); // start new segment
p.push(null);
p.push(k);
p.push(below);
}
p.push(x);
p.push(y);
}
orig.datapoints.linespoints = origpoints
thresholded.datapoints.linespoints = threspoints;
}
s.subseries = [orig, thresholded];
}
} }
} }
...@@ -494,7 +494,9 @@ ...@@ -494,7 +494,9 @@
// overlay canvas for interactive features // overlay canvas for interactive features
overlay = $(makeCanvas(canvasWidth, canvasHeight)).css({ position: 'absolute', left: 0, top: 0 }).appendTo(target).get(0); overlay = $(makeCanvas(canvasWidth, canvasHeight)).css({ position: 'absolute', left: 0, top: 0 }).appendTo(target).get(0);
octx = overlay.getContext("2d"); octx = overlay.getContext("2d");
}
function bindEvents() {
// we include the canvas in the event holder too, because IE 7 // we include the canvas in the event holder too, because IE 7
// sometimes has trouble with the stacking order // sometimes has trouble with the stacking order
eventHolder = $([overlay, canvas]); eventHolder = $([overlay, canvas]);
...@@ -967,14 +969,8 @@ ...@@ -967,14 +969,8 @@
function draw() { function draw() {
drawGrid(); drawGrid();
for (var i = 0; i < series.length; ++i) { for (var i = 0; i < series.length; ++i)
var s = series[i]; drawSeries(series[i]);
if (s.subseries)
for (var j = 0; j < s.subseries.length; ++j)
drawSeries(s.subseries[j]);
else
drawSeries(s);
}
} }
function extractRange(ranges, coord) { function extractRange(ranges, coord) {
...@@ -1187,13 +1183,13 @@ ...@@ -1187,13 +1183,13 @@
function drawSeriesLines(series) { function drawSeriesLines(series) {
function plotLine(datapoints, xoffset, yoffset, axisx, axisy) { function plotLine(datapoints, xoffset, yoffset, axisx, axisy) {
var points = datapoints.linespoints || datapoints.points, var points = datapoints.points,
incr = datapoints.incr, ps = datapoints.pointsize,
prevx = null, prevy = null; prevx = null, prevy = null;
ctx.beginPath(); ctx.beginPath();
for (var i = incr; i < points.length; i += incr) { for (var i = ps; i < points.length; i += ps) {
var x1 = points[i - incr], y1 = points[i - incr + 1], var x1 = points[i - ps], y1 = points[i - ps + 1],
x2 = points[i], y2 = points[i + 1]; x2 = points[i], y2 = points[i + 1];
if (x1 == null || x2 == null) if (x1 == null || x2 == null)
...@@ -1267,13 +1263,13 @@ ...@@ -1267,13 +1263,13 @@
} }
function plotLineArea(datapoints, axisx, axisy) { function plotLineArea(datapoints, axisx, axisy) {
var points = datapoints.linespoints || datapoints.points, var points = datapoints.points,
incr = datapoints.incr, ps = datapoints.pointsize,
bottom = Math.min(Math.max(0, axisy.min), axisy.max), bottom = Math.min(Math.max(0, axisy.min), axisy.max),
top, lastX = 0, areaOpen = false; top, lastX = 0, areaOpen = false;
for (var i = incr; i < points.length; i += incr) { for (var i = ps; i < points.length; i += ps) {
var x1 = points[i - incr], y1 = points[i - incr + 1], var x1 = points[i - ps], y1 = points[i - ps + 1],
x2 = points[i], y2 = points[i + 1]; x2 = points[i], y2 = points[i + 1];
if (areaOpen && x1 != null && x2 == null) { if (areaOpen && x1 != null && x2 == null) {
...@@ -1434,9 +1430,9 @@ ...@@ -1434,9 +1430,9 @@
function drawSeriesPoints(series) { function drawSeriesPoints(series) {
function plotPoints(datapoints, radius, fillStyle, offset, circumference, axisx, axisy) { function plotPoints(datapoints, radius, fillStyle, offset, circumference, axisx, axisy) {
var points = datapoints.points, incr = datapoints.incr; var points = datapoints.points, ps = datapoints.pointsize;
for (var i = 0; i < points.length; i += incr) { for (var i = 0; i < points.length; i += ps) {
var x = points[i], y = points[i + 1]; var x = points[i], y = points[i + 1];
if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
continue; continue;
...@@ -1587,9 +1583,9 @@ ...@@ -1587,9 +1583,9 @@
function drawSeriesBars(series) { function drawSeriesBars(series) {
function plotBars(datapoints, barLeft, barRight, offset, fillStyleCallback, axisx, axisy) { function plotBars(datapoints, barLeft, barRight, offset, fillStyleCallback, axisx, axisy) {
var points = datapoints.points, incr = datapoints.incr; var points = datapoints.points, ps = datapoints.pointsize;
for (var i = 0; i < points.length; i += incr) { for (var i = 0; i < points.length; i += ps) {
if (points[i] == null) if (points[i] == null)
continue; continue;
drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, offset, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal); drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, offset, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal);
...@@ -1706,7 +1702,7 @@ ...@@ -1706,7 +1702,7 @@
redrawTimeout = null, redrawTimeout = null,
hoverTimeout = null; hoverTimeout = null;
// Returns the data item the mouse is over, or null if none is found // returns the data item the mouse is over, or null if none is found
function findNearbyItem(mouseX, mouseY, seriesFilter) { function findNearbyItem(mouseX, mouseY, seriesFilter) {
var maxDistance = options.grid.mouseActiveRadius, var maxDistance = options.grid.mouseActiveRadius,
lowestDistance = maxDistance * maxDistance + 1, lowestDistance = maxDistance * maxDistance + 1,
...@@ -1720,14 +1716,14 @@ ...@@ -1720,14 +1716,14 @@
axisx = s.xaxis, axisx = s.xaxis,
axisy = s.yaxis, axisy = s.yaxis,
points = s.datapoints.points, points = s.datapoints.points,
incr = s.datapoints.incr, ps = s.datapoints.pointsize,
mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster
my = axisy.c2p(mouseY), my = axisy.c2p(mouseY),
maxx = maxDistance / axisx.scale, maxx = maxDistance / axisx.scale,
maxy = maxDistance / axisy.scale; maxy = maxDistance / axisy.scale;
if (s.lines.show || s.points.show) { if (s.lines.show || s.points.show) {
for (j = 0; j < points.length; j += incr) { for (j = 0; j < points.length; j += ps) {
var x = points[j], y = points[j + 1]; var x = points[j], y = points[j + 1];
if (x == null) if (x == null)
continue; continue;
...@@ -1745,7 +1741,7 @@ ...@@ -1745,7 +1741,7 @@
dist = dx * dx + dy * dy; // no idea in taking sqrt dist = dx * dx + dy * dy; // no idea in taking sqrt
if (dist < lowestDistance) { if (dist < lowestDistance) {
lowestDistance = dist; lowestDistance = dist;
item = [i, j / incr]; item = [i, j / ps];
} }
} }
} }
...@@ -1754,7 +1750,7 @@ ...@@ -1754,7 +1750,7 @@
var barLeft = s.bars.align == "left" ? 0 : -s.bars.barWidth/2, var barLeft = s.bars.align == "left" ? 0 : -s.bars.barWidth/2,
barRight = barLeft + s.bars.barWidth; barRight = barLeft + s.bars.barWidth;
for (j = 0; j < points.length; j += incr) { for (j = 0; j < points.length; j += ps) {
var x = points[j], y = points[j + 1], b = points[j + 2]; var x = points[j], y = points[j + 1], b = points[j + 2];
if (x == null) if (x == null)
continue; continue;
...@@ -1765,7 +1761,7 @@ ...@@ -1765,7 +1761,7 @@
my >= y + barLeft && my <= y + barRight) : my >= y + barLeft && my <= y + barRight) :
(mx >= x + barLeft && mx <= x + barRight && (mx >= x + barLeft && mx <= x + barRight &&
my >= Math.min(b, y) && my <= Math.max(b, y))) my >= Math.min(b, y) && my <= Math.max(b, y)))
item = [i, j / incr]; item = [i, j / ps];
} }
} }
} }
...@@ -1774,10 +1770,10 @@ ...@@ -1774,10 +1770,10 @@
i = item[0]; i = item[0];
j = item[1]; j = item[1];
return { datapoint: series[i].data[j], return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps),
dataIndex: j, dataIndex: j,
series: series[i], series: series[i],
seriesIndex: i } seriesIndex: i };
} }
return null; return null;
...@@ -1989,6 +1985,11 @@ ...@@ -1989,6 +1985,11 @@
} }
function unhighlight(s, point) { function unhighlight(s, point) {
if (s == null && point == null) {
highlights = [];
triggerRedrawOverlay();
}
if (typeof s == "number") if (typeof s == "number")
s = series[s]; s = series[s];
...@@ -2201,9 +2202,9 @@ ...@@ -2201,9 +2202,9 @@
} }
} }
} }
$.plot = function(target, data, options) { $.plot = function(target, data, options) {
var plot = new Plot(target, data, options); var plot = new Plot($(target), data, options, $.plot.plugins);
/*var t0 = new Date(); /*var t0 = new Date();
var t1 = new Date(); var t1 = new Date();
var tstr = "time used (msecs): " + (t1.getTime() - t0.getTime()) var tstr = "time used (msecs): " + (t1.getTime() - t0.getTime())
...@@ -2214,6 +2215,8 @@ ...@@ -2214,6 +2215,8 @@
return plot; return plot;
}; };
$.plot.plugins = [];
// returns a string with the date d formatted according to fmt // returns a string with the date d formatted according to fmt
$.plot.formatDate = function(d, fmt, monthNames) { $.plot.formatDate = function(d, fmt, monthNames) {
var leftPad = function(n) { var leftPad = function(n) {
......
/*
Flot plugin for stacking data sets, i.e. putting them on top of each
other, for accumulative graphs. Note that the plugin assumes the data
is sorted on x. Also note that stacking a mix of positive and negative
values in most instances doesn't make sense (so it looks weird).
Two or more series are stacked when their "stack" attribute is set to
the same key (which can be any number or string or just "true"). To
specify the default stack, you can set
series: {
stack: null or true or key (number/string)
}
or specify it for a specific series
$.plot($("#placeholder"), [{ data: [ ... ], stack: true ])
The stacking order is determined by the order of the data series in
the array (later series end up on top of the previous).
Internally, the plugin modifies the datapoints in each series, adding
an offset to the y value. For line series, extra data points are
inserted through interpolation. For bar charts, the second y value is
also adjusted.
*/
(function ($) {
var options = {
series: { stack: null } // or number/string
};
function init(plot) {
function findMatchingSeries(s, allseries) {
var res = null
for (var i = 0; i < allseries.length; ++i) {
if (s == allseries[i])
break;
if (allseries[i].stack == s.stack)
res = allseries[i];
}
return res;
}
function stackData(plot, s, datapoints) {
if (s.stack == null)
return;
var other = findMatchingSeries(s, plot.getData());
if (!other)
return;
var ps = datapoints.pointsize,
points = datapoints.points,
otherps = other.datapoints.pointsize,
otherpoints = other.datapoints.points,
newpoints = [],
px, py, intery, qx, qy,
withlines = s.lines.show, withbars = s.bars.show,
withsteps = withlines && s.lines.steps,
i = 0, j = 0, l;
while (true) {
if (i >= points.length)
break;
l = newpoints.length;
if (j >= otherpoints.length
|| otherpoints[j] == null
|| points[i] == null) {
// degenerate cases
for (m = 0; m < ps; ++m)
newpoints.push(points[i + m]);
i += ps;
}
else {
// cases where we actually got two points
px = points[i];
py = points[i + 1];
qx = otherpoints[j];
qy = otherpoints[j + 1];
if (px == qx) {
for (m = 0; m < ps; ++m)
newpoints.push(points[i + m]);
newpoints[l + 1] += qy;
i += ps;
j += otherps;
}
else if (px > qx) {
// we got past point below, might need to
// insert interpolated extra point
if (withlines && i > 0 && points[i - ps] != null) {
intery = py + (points[i - ps + 1] - py) * (qx - px) / (points[i - ps] - px);
newpoints.push(qx);
newpoints.push(intery + qy)
for (m = 2; m < ps; ++m)
newpoints.push(points[i + m]);
}
j += otherps;
}
else {
for (m = 0; m < ps; ++m)
newpoints.push(points[i + m]);
// we might be able to interpolate a point below,
// this can give us a better y
if (withlines && j > 0 && otherpoints[j - ps] != null) {
intery = qy + (otherpoints[j - ps + 1] - qy) * (px - qx) / (otherpoints[j - ps] - qx);
newpoints[l + 1] += intery;
}
i += ps;
}
if (l != newpoints.length && withbars)
newpoints[l + 2] += qy;
}
// maintain the line steps invariant
if (withsteps && l != newpoints.length && l > 0
&& newpoints[l] != null
&& newpoints[l] != newpoints[l - ps]
&& newpoints[l + 1] != newpoints[l - ps + 1]) {
for (m = 0; m < ps; ++m)
newpoints[l + ps + m] = newpoints[l + m];
newpoints[l + 1] = newpoints[l - ps + 1];
}
}
datapoints.points = newpoints;
}
plot.hooks.processDatapoints.push(stackData);
}
$.plot.plugins.push({
init: init,
options: options,
name: 'stack',
version: '1.0'
});
})(jQuery);
/*
Flot plugin for thresholding data. Controlled through the option
"threshold" in either the global series options
series: {
threshold: {
below: number
color: colorspec
}
}
or in a specific series
$.plot($("#placeholder"), [{ data: [ ... ], threshold: { ... }}])
The data points below "below" are drawn with the specified color. This
makes it easy to mark points below 0, e.g. for budget data.
Internally, the plugin works by splitting the data into two series,
above and below the threshold. The extra series below the threshold
will have its label cleared and the special "originSeries" attribute
set to the original series. You may need to check for this in hover
events.
*/
(function ($) {
var options = {
series: { threshold: null } // or { below: number, color: color spec}
};
function init(plot) {
function thresholdData(plot, s, datapoints) {
if (!s.threshold)
return;
var ps = datapoints.pointsize, i, x, y, p, prevp,
thresholded = $.extend({}, s); // note: shallow copy
thresholded.datapoints = { points: [], pointsize: ps };
thresholded.label = null;
thresholded.color = s.threshold.color;
thresholded.threshold = null;
thresholded.originSeries = s;
thresholded.data = [];
var below = s.threshold.below,
origpoints = datapoints.points,
addCrossingPoints = s.lines.show;
threspoints = [];
newpoints = [];
for (i = 0; i < origpoints.length; i += ps) {
x = origpoints[i]
y = origpoints[i + 1];
prevp = p;
if (y < below)
p = threspoints;
else
p = newpoints;
if (addCrossingPoints && prevp != p && x != null
&& i > 0 && origpoints[i - ps] != null) {
var interx = (x - origpoints[i - ps]) / (y - origpoints[i - ps + 1]) * (below - y) + x;
prevp.push(interx);
prevp.push(below);
for (m = 2; m < ps; ++m)
prevp.push(origpoints[i + m]);
p.push(null); // start new segment
p.push(null);
for (m = 2; m < ps; ++m)
p.push(origpoints[i + m]);
p.push(interx);
p.push(below);
for (m = 2; m < ps; ++m)
p.push(origpoints[i + m]);
}
p.push(x);
p.push(y);
}
datapoints.points = newpoints;
thresholded.datapoints.points = threspoints;
if (thresholded.datapoints.points.length > 0)
plot.getData().push(thresholded);
// FIXME: there are probably some edge cases left in bars
}
plot.hooks.processDatapoints.push(thresholdData);
}
$.plot.plugins.push({
init: init,
options: options,
name: 'threshold',
version: '1.0'
});
})(jQuery);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment