]>
Commit | Line | Data |
---|---|---|
31f18b77 FG |
1 | /* Flot plugin for showing crosshairs when the mouse hovers over the plot. |
2 | ||
3 | Copyright (c) 2007-2013 IOLA and Ole Laursen. | |
4 | Licensed under the MIT license. | |
5 | ||
6 | The plugin supports these options: | |
7 | ||
8 | crosshair: { | |
9 | mode: null or "x" or "y" or "xy" | |
10 | color: color | |
11 | lineWidth: number | |
12 | } | |
13 | ||
14 | Set the mode to one of "x", "y" or "xy". The "x" mode enables a vertical | |
15 | crosshair that lets you trace the values on the x axis, "y" enables a | |
16 | horizontal crosshair and "xy" enables them both. "color" is the color of the | |
17 | crosshair (default is "rgba(170, 0, 0, 0.80)"), "lineWidth" is the width of | |
18 | the drawn lines (default is 1). | |
19 | ||
20 | The plugin also adds four public methods: | |
21 | ||
22 | - setCrosshair( pos ) | |
23 | ||
24 | Set the position of the crosshair. Note that this is cleared if the user | |
25 | moves the mouse. "pos" is in coordinates of the plot and should be on the | |
26 | form { x: xpos, y: ypos } (you can use x2/x3/... if you're using multiple | |
27 | axes), which is coincidentally the same format as what you get from a | |
28 | "plothover" event. If "pos" is null, the crosshair is cleared. | |
29 | ||
30 | - clearCrosshair() | |
31 | ||
32 | Clear the crosshair. | |
33 | ||
34 | - lockCrosshair(pos) | |
35 | ||
36 | Cause the crosshair to lock to the current location, no longer updating if | |
37 | the user moves the mouse. Optionally supply a position (passed on to | |
38 | setCrosshair()) to move it to. | |
39 | ||
40 | Example usage: | |
41 | ||
42 | var myFlot = $.plot( $("#graph"), ..., { crosshair: { mode: "x" } } }; | |
43 | $("#graph").bind( "plothover", function ( evt, position, item ) { | |
44 | if ( item ) { | |
45 | // Lock the crosshair to the data point being hovered | |
46 | myFlot.lockCrosshair({ | |
47 | x: item.datapoint[ 0 ], | |
48 | y: item.datapoint[ 1 ] | |
49 | }); | |
50 | } else { | |
51 | // Return normal crosshair operation | |
52 | myFlot.unlockCrosshair(); | |
53 | } | |
54 | }); | |
55 | ||
56 | - unlockCrosshair() | |
57 | ||
58 | Free the crosshair to move again after locking it. | |
59 | */ | |
60 | ||
61 | (function ($) { | |
62 | var options = { | |
63 | crosshair: { | |
64 | mode: null, // one of null, "x", "y" or "xy", | |
65 | color: "rgba(170, 0, 0, 0.80)", | |
66 | lineWidth: 1 | |
67 | } | |
68 | }; | |
69 | ||
70 | function init(plot) { | |
71 | // position of crosshair in pixels | |
72 | var crosshair = { x: -1, y: -1, locked: false }; | |
73 | ||
74 | plot.setCrosshair = function setCrosshair(pos) { | |
75 | if (!pos) | |
76 | crosshair.x = -1; | |
77 | else { | |
78 | var o = plot.p2c(pos); | |
79 | crosshair.x = Math.max(0, Math.min(o.left, plot.width())); | |
80 | crosshair.y = Math.max(0, Math.min(o.top, plot.height())); | |
81 | } | |
82 | ||
83 | plot.triggerRedrawOverlay(); | |
84 | }; | |
85 | ||
86 | plot.clearCrosshair = plot.setCrosshair; // passes null for pos | |
87 | ||
88 | plot.lockCrosshair = function lockCrosshair(pos) { | |
89 | if (pos) | |
90 | plot.setCrosshair(pos); | |
91 | crosshair.locked = true; | |
92 | }; | |
93 | ||
94 | plot.unlockCrosshair = function unlockCrosshair() { | |
95 | crosshair.locked = false; | |
96 | }; | |
97 | ||
98 | function onMouseOut(e) { | |
99 | if (crosshair.locked) | |
100 | return; | |
101 | ||
102 | if (crosshair.x != -1) { | |
103 | crosshair.x = -1; | |
104 | plot.triggerRedrawOverlay(); | |
105 | } | |
106 | } | |
107 | ||
108 | function onMouseMove(e) { | |
109 | if (crosshair.locked) | |
110 | return; | |
111 | ||
112 | if (plot.getSelection && plot.getSelection()) { | |
113 | crosshair.x = -1; // hide the crosshair while selecting | |
114 | return; | |
115 | } | |
116 | ||
117 | var offset = plot.offset(); | |
118 | crosshair.x = Math.max(0, Math.min(e.pageX - offset.left, plot.width())); | |
119 | crosshair.y = Math.max(0, Math.min(e.pageY - offset.top, plot.height())); | |
120 | plot.triggerRedrawOverlay(); | |
121 | } | |
122 | ||
123 | plot.hooks.bindEvents.push(function (plot, eventHolder) { | |
124 | if (!plot.getOptions().crosshair.mode) | |
125 | return; | |
126 | ||
127 | eventHolder.mouseout(onMouseOut); | |
128 | eventHolder.mousemove(onMouseMove); | |
129 | }); | |
130 | ||
131 | plot.hooks.drawOverlay.push(function (plot, ctx) { | |
132 | var c = plot.getOptions().crosshair; | |
133 | if (!c.mode) | |
134 | return; | |
135 | ||
136 | var plotOffset = plot.getPlotOffset(); | |
137 | ||
138 | ctx.save(); | |
139 | ctx.translate(plotOffset.left, plotOffset.top); | |
140 | ||
141 | if (crosshair.x != -1) { | |
142 | var adj = plot.getOptions().crosshair.lineWidth % 2 === 0 ? 0 : 0.5; | |
143 | ||
144 | ctx.strokeStyle = c.color; | |
145 | ctx.lineWidth = c.lineWidth; | |
146 | ctx.lineJoin = "round"; | |
147 | ||
148 | ctx.beginPath(); | |
149 | if (c.mode.indexOf("x") != -1) { | |
150 | var drawX = Math.round(crosshair.x) + adj; | |
151 | ctx.moveTo(drawX, 0); | |
152 | ctx.lineTo(drawX, plot.height()); | |
153 | } | |
154 | if (c.mode.indexOf("y") != -1) { | |
155 | var drawY = Math.round(crosshair.y) + adj; | |
156 | ctx.moveTo(0, drawY); | |
157 | ctx.lineTo(plot.width(), drawY); | |
158 | } | |
159 | ctx.stroke(); | |
160 | } | |
161 | ctx.restore(); | |
162 | }); | |
163 | ||
164 | plot.hooks.shutdown.push(function (plot, eventHolder) { | |
165 | eventHolder.unbind("mouseout", onMouseOut); | |
166 | eventHolder.unbind("mousemove", onMouseMove); | |
167 | }); | |
168 | } | |
169 | ||
170 | $.plot.plugins.push({ | |
171 | init: init, | |
172 | options: options, | |
173 | name: 'crosshair', | |
174 | version: '1.0' | |
175 | }); | |
176 | })(jQuery); |