Skip to content
Browse files

Support for customizing the point type through a callback when plotti…

…ng 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
  • Loading branch information...
1 parent f192ea9 commit 8031f5fdf3c12fcd691c6d91dd003e21b4df1c1a olau@iola.dk committed Jul 12, 2010
Showing with 174 additions and 14 deletions.
  1. +21 −0 API.txt
  2. +3 −0 NEWS.txt
  3. +2 −1 examples/index.html
  4. +49 −0 examples/symbols.html
  5. +29 −13 jquery.flot.js
  6. +70 −0 jquery.flot.symbol.js
View
21 API.txt
@@ -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.
View
3 NEWS.txt
@@ -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
View
3 examples/index.html
@@ -32,14 +32,15 @@
<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>
<li><a href="stacking.html">Stacked charts</a> (with stacking plugin)</li>
<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>
View
49 examples/symbols.html
@@ -0,0 +1,49 @@
+<!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>
View
42 jquery.flot.js
@@ -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();
}
View
70 jquery.flot.symbol.js
@@ -0,0 +1,70 @@
+/*
+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);

0 comments on commit 8031f5f

Please sign in to comment.
Something went wrong with that request. Please try again.