Commit 8031f5fd authored by olau@iola.dk's avatar olau@iola.dk

Support for customizing the point type through a callback when plotting points...

Support for customizing the point type through a callback when plotting points and new symbol plugin with some predefined point types (sponsored by Utility Data Corporation)


git-svn-id: https://flot.googlecode.com/svn/trunk@263 1e0a6537-2640-0410-bfb7-f154510ff394
parent f192ea9c
......@@ -524,6 +524,7 @@ Customizing the data series
points: {
radius: number
symbol: "circle" or function
}
bars: {
......@@ -590,6 +591,26 @@ connected with a straight (possibly diagonal) line or with first a
horizontal and then a vertical line. Note that this transforms the
data by adding extra points.
For points, you can specify the radius and the symbol. The only
built-in symbol type is circles, for other types you can use a plugin
or define them yourself by specifying a callback:
function cross(ctx, x, y, radius, shadow) {
var size = radius * Math.sqrt(Math.PI) / 2;
ctx.moveTo(x - size, y - size);
ctx.lineTo(x + size, y + size);
ctx.moveTo(x - size, y + size);
ctx.lineTo(x + size, y - size);
}
The parameters are the drawing context, x and y coordinates of the
center of the point, a radius which corresponds to what the circle
would have used and whether the call is to draw a shadow (due to
limited canvas support, shadows are currently faked through extra
draws). It's good practice to ensure that the area covered by the
symbol is the same as for the circle with the given radius, this
ensures that all symbols have approximately the same visual weight.
"shadowSize" is the default size of shadows in pixels. Set it to 0 to
remove shadows.
......
......@@ -64,6 +64,9 @@ Changes:
ensure that they appear next to each other rather than in between,
at the expense of possibly awkward tick steps (sponsored by Flight
Data Services, www.flightdataservices.com).
- Support for customizing the point type through a callback when
plotting points and new symbol plugin with some predefined point
types (sponsored by Utility Data Corporation).
- New hooks: drawSeries
......
......@@ -32,6 +32,7 @@
<p>Various features:</p>
<ul>
<li><a href="symbols.html">Using other symbols than circles for points</a> (with symbol plugin)</li>
<li><a href="time.html">Plotting time series</a> and <a href="visitors.html">visitors per day with zooming and weekends</a> (with selection plugin)</li>
<li><a href="multiple-axes.html">Multiple axes</a> and <a href="interacting-axes.html">interacting with the axes</a></li>
<li><a href="thresholding.html">Thresholding the data</a> (with threshold plugin)</li>
......@@ -39,7 +40,7 @@
<li><a href="percentiles.html">Using filled areas to plot percentiles</a> (with fillbetween plugin)</li>
<li><a href="tracking.html">Tracking curves with crosshair</a> (with crosshair plugin)</li>
<li><a href="image.html">Plotting prerendered images</a> (with image plugin)</li>
<li><a href="pie.html">Pie charts</a> (with pie plugin)</li>
<li><a href="pie.html">Pie charts</a> (with pie plugin)</li>
</ul>
</body>
</html>
<!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.symbol.js"></script>
</head>
<body>
<h1>Flot Examples</h1>
<div id="placeholder" style="width:600px;height:300px"></div>
<p>Various point types. Circles are built-in. For other
point types, you can define a little callback function to draw the
symbol; some common ones are available in the symbol plugin.</p>
<script id="source" language="javascript" type="text/javascript">
$(function () {
function generate(offset, amplitude) {
var res = [];
var start = 0, end = 10;
for (var i = 0; i <= 50; ++i) {
var x = start + i / 50 * (end - start);
res.push([x, amplitude * Math.sin(x + offset)]);
}
return res;
}
var data = [
{ data: generate(2, 1.8), points: { symbol: "circle" } },
{ data: generate(3, 1.5), points: { symbol: "square" } },
{ data: generate(4, 0.9), points: { symbol: "diamond" } },
{ data: generate(6, 1.4), points: { symbol: "triangle" } },
{ data: generate(7, 1.1), points: { symbol: "cross" } }
];
$.plot($("#placeholder"), data, {
series: { points: { show: true, radius: 3 } },
grid: { hoverable: true }
});
});
</script>
</body>
</html>
......@@ -87,7 +87,8 @@
radius: 3,
lineWidth: 2, // in pixels
fill: true,
fillColor: "#ffffff"
fillColor: "#ffffff",
symbol: "circle" // or callback
},
lines: {
// we don't put in show: false so we can see
......@@ -1899,16 +1900,23 @@
}
function drawSeriesPoints(series) {
function plotPoints(datapoints, radius, fillStyle, offset, circumference, axisx, axisy) {
function plotPoints(datapoints, radius, fillStyle, offset, shadow, axisx, axisy, symbol) {
var points = datapoints.points, ps = datapoints.pointsize;
for (var i = 0; i < points.length; i += ps) {
var x = points[i], y = points[i + 1];
if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
continue;
ctx.beginPath();
ctx.arc(axisx.p2c(x), axisy.p2c(y) + offset, radius, 0, circumference, false);
x = axisx.p2c(x);
y = axisy.p2c(y) + offset;
if (symbol == "circle")
ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false);
else
symbol(ctx, x, y, radius, shadow);
ctx.closePath();
if (fillStyle) {
ctx.fillStyle = fillStyle;
ctx.fill();
......@@ -1922,25 +1930,26 @@
var lw = series.points.lineWidth,
sw = series.shadowSize,
radius = series.points.radius;
radius = series.points.radius,
symbol = series.points.symbol;
if (lw > 0 && sw > 0) {
// draw shadow in two steps
var w = sw / 2;
ctx.lineWidth = w;
ctx.strokeStyle = "rgba(0,0,0,0.1)";
plotPoints(series.datapoints, radius, null, w + w/2, Math.PI,
series.xaxis, series.yaxis);
plotPoints(series.datapoints, radius, null, w + w/2, true,
series.xaxis, series.yaxis, symbol);
ctx.strokeStyle = "rgba(0,0,0,0.2)";
plotPoints(series.datapoints, radius, null, w/2, Math.PI,
series.xaxis, series.yaxis);
plotPoints(series.datapoints, radius, null, w/2, true,
series.xaxis, series.yaxis, symbol);
}
ctx.lineWidth = lw;
ctx.strokeStyle = series.color;
plotPoints(series.datapoints, radius,
getFillStyle(series.points, series.color), 0, 2 * Math.PI,
series.xaxis, series.yaxis);
getFillStyle(series.points, series.color), 0, false,
series.xaxis, series.yaxis, symbol);
ctx.restore();
}
......@@ -2382,9 +2391,16 @@
var pointRadius = series.points.radius + series.points.lineWidth / 2;
octx.lineWidth = pointRadius;
octx.strokeStyle = $.color.parse(series.color).scale('a', 0.5).toString();
var radius = 1.5 * pointRadius;
var radius = 1.5 * pointRadius,
x = axisx.p2c(x),
y = axisy.p2c(y);
octx.beginPath();
octx.arc(axisx.p2c(x), axisy.p2c(y), radius, 0, 2 * Math.PI, false);
if (series.points.symbol == "circle")
octx.arc(x, y, radius, 0, 2 * Math.PI, false);
else
series.points.symbol(octx, x, y, radius, false);
octx.closePath();
octx.stroke();
}
......
/*
Flot plugin that adds some extra symbols for plotting points.
The symbols are accessed as strings through the standard symbol
choice:
series: {
points: {
symbol: "square" // or "diamond", "triangle", "cross"
}
}
*/
(function ($) {
function processRawData(plot, series, datapoints) {
// we normalize the area of each symbol so it is approximately the
// same as a circle of the given radius
var handlers = {
square: function (ctx, x, y, radius, shadow) {
// pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2
var size = radius * Math.sqrt(Math.PI) / 2;
ctx.rect(x - size, y - size, size + size, size + size);
},
diamond: function (ctx, x, y, radius, shadow) {
// pi * r^2 = 2s^2 => s = r * sqrt(pi/2)
var size = radius * Math.sqrt(Math.PI / 2);
ctx.moveTo(x - size, y);
ctx.lineTo(x, y - size);
ctx.lineTo(x + size, y);
ctx.lineTo(x, y + size);
ctx.lineTo(x - size, y);
},
triangle: function (ctx, x, y, radius, shadow) {
// pi * r^2 = 1/2 * s^2 * sin (pi / 3) => s = r * sqrt(2 * pi / sin(pi / 3))
var size = radius * Math.sqrt(2 * Math.PI / Math.sin(Math.PI / 3));
var height = size * Math.sin(Math.PI / 3);
ctx.moveTo(x - size/2, y + height/2);
ctx.lineTo(x + size/2, y + height/2);
if (!shadow) {
ctx.lineTo(x, y - height/2);
ctx.lineTo(x - size/2, y + height/2);
}
},
cross: function (ctx, x, y, radius, shadow) {
// pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2
var size = radius * Math.sqrt(Math.PI) / 2;
ctx.moveTo(x - size, y - size);
ctx.lineTo(x + size, y + size);
ctx.moveTo(x - size, y + size);
ctx.lineTo(x + size, y - size);
}
}
var s = series.points.symbol;
if (handlers[s])
series.points.symbol = handlers[s];
}
function init(plot) {
plot.hooks.processDatapoints.push(processRawData);
}
$.plot.plugins.push({
init: init,
name: 'symbols',
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