Commit e7a909a6 authored by olau@iola.dk's avatar olau@iola.dk

Added axis transformation support


git-svn-id: https://flot.googlecode.com/svn/trunk@202 1e0a6537-2640-0410-bfb7-f154510ff394
parent d9ba5235
......@@ -166,8 +166,6 @@ If you want the legend to appear somewhere else in the DOM, you can
specify "container" as a jQuery object/expression to put the legend
table into. The "position" and "margin" etc. options will then be
ignored. Note that Flot will overwrite the contents of the container.
Most of the above settings do not apply
Customizing the axes
......@@ -178,9 +176,13 @@ Customizing the axes
min: null or number
max: null or number
autoscaleMargin: null or number
labelWidth: null or number
labelHeight: null or number
transform: null or fn: number -> number
inverseTransform: null or fn: number -> number
ticks: null or number or ticks array or (fn: range -> ticks array)
tickSize: number or array
minTickSize: number or array
......@@ -208,6 +210,29 @@ nearest whole tick. The default value is "null" for the x axis and
labels in pixels. They're useful in case you need to align several
plots.
"transform" and "inverseTransform" are callbacks you can put in to
change the way the data is drawn. You can design a function to
compress or expand certain parts of the axis non-linearly, e.g.
suppress weekends or compress far away points with a logarithm or some
other means. When Flot draws the plot, each value is first put through
the transform function. Here's an example, the x axis can be turned
into a natural logarithm axis with the following code:
xaxis: {
transform: function (v) { return Math.log(v); },
inverseTransform: function (v) { return Math.exp(v); }
}
Note that for finding extrema, Flot assumes that the transform
function does not reorder values (monotonicity is assumed).
The inverseTransform is simply the inverse of the transform function
(so v == inverseTransform(transform(v)) for all relevant v). It is
required for converting from canvas coordinates to data coordinates,
e.g. for a mouse interaction where a certain pixel is clicked. If you
don't use any interactive features of Flot, you may not need it.
The rest of the options deal with the ticks.
If you don't specify any ticks, a tick generator algorithm will make
......
......@@ -111,6 +111,8 @@ Changes:
- More configurable grid.
- Axis transformation support, useful for non-linear plots, e.g. log
axes and compressed time axes (like omitting weekends).
Bug fixes:
......
......@@ -28,6 +28,8 @@
},
xaxis: {
mode: null, // null or "time"
transform: null, // null or f: number -> number to transform axis
inverseTransform: null, // if transform is set, this should be the inverse function
min: null, // min. value to show, null means set automatically
max: null, // max. value to show, null means set automatically
autoscaleMargin: null, // margin in % to add if auto-setting min/max
......@@ -561,27 +563,42 @@
}
function setupGrid() {
function setTransformationHelpers(axis) {
var s, m;
function setTransformationHelpers(axis, o) {
function identity(x) { return x; }
var s, m, t = o.transform || identity,
it = o.inverseTransform;
// add transformation helpers
if (axis == axes.xaxis || axis == axes.x2axis) {
// precompute how much the axis is scaling a point
// in canvas space
s = axis.scale = plotWidth / (axis.max - axis.min);
m = axis.min;
s = axis.scale = plotWidth / (t(axis.max) - t(axis.min));
m = t(axis.min);
// data point to canvas coordinate
axis.p2c = function (p) { return (p - m) * s; };
// canvas coordinate to data point
axis.c2p = function (c) { return m + c / s; };
if (t === identity) // slight optimization
axis.p2c = function (p) { return (p - m) * s; };
else
axis.p2c = function (p) { return (t(p) - m) * s; };
// canvas coordinate to data point
if (!it)
axis.c2p = function (c) { return m + c / s; };
else
axis.c2p = function (c) { return it(m + c / s); };
}
else {
s = axis.scale = plotHeight / (axis.max - axis.min)
m = axis.max;
s = axis.scale = plotHeight / (t(axis.max) - t(axis.min));
m = t(axis.max);
axis.p2c = function (p) { return (m - p) * s; };
axis.c2p = function (p) { return m - p / s; };
if (t === identity)
axis.p2c = function (p) { return (m - p) * s; };
else
axis.p2c = function (p) { return (m - t(p)) * s; };
if (!it)
axis.c2p = function (c) { return m - c / s; };
else
axis.c2p = function (c) { return it(m - c / s); };
}
}
......@@ -686,7 +703,7 @@
}
for (axis in axes)
setTransformationHelpers(axes[axis]);
setTransformationHelpers(axes[axis], options[axis]);
if (options.grid.show)
insertLabels();
......
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