79 lines
6.7 KiB
JavaScript
79 lines
6.7 KiB
JavaScript
|
/* Flot plugin for selecting regions of a plot.
|
||
|
|
||
|
Copyright (c) 2007-2013 IOLA and Ole Laursen.
|
||
|
Licensed under the MIT license.
|
||
|
|
||
|
The plugin supports these options:
|
||
|
|
||
|
selection: {
|
||
|
mode: null or "x" or "y" or "xy",
|
||
|
color: color,
|
||
|
shape: "round" or "miter" or "bevel",
|
||
|
minSize: number of pixels
|
||
|
}
|
||
|
|
||
|
Selection support is enabled by setting the mode to one of "x", "y" or "xy".
|
||
|
In "x" mode, the user will only be able to specify the x range, similarly for
|
||
|
"y" mode. For "xy", the selection becomes a rectangle where both ranges can be
|
||
|
specified. "color" is color of the selection (if you need to change the color
|
||
|
later on, you can get to it with plot.getOptions().selection.color). "shape"
|
||
|
is the shape of the corners of the selection.
|
||
|
|
||
|
"minSize" is the minimum size a selection can be in pixels. This value can
|
||
|
be customized to determine the smallest size a selection can be and still
|
||
|
have the selection rectangle be displayed. When customizing this value, the
|
||
|
fact that it refers to pixels, not axis units must be taken into account.
|
||
|
Thus, for example, if there is a bar graph in time mode with BarWidth set to 1
|
||
|
minute, setting "minSize" to 1 will not make the minimum selection size 1
|
||
|
minute, but rather 1 pixel. Note also that setting "minSize" to 0 will prevent
|
||
|
"plotunselected" events from being fired when the user clicks the mouse without
|
||
|
dragging.
|
||
|
|
||
|
When selection support is enabled, a "plotselected" event will be emitted on
|
||
|
the DOM element you passed into the plot function. The event handler gets a
|
||
|
parameter with the ranges selected on the axes, like this:
|
||
|
|
||
|
placeholder.bind( "plotselected", function( event, ranges ) {
|
||
|
alert("You selected " + ranges.xaxis.from + " to " + ranges.xaxis.to)
|
||
|
// similar for yaxis - with multiple axes, the extra ones are in
|
||
|
// x2axis, x3axis, ...
|
||
|
});
|
||
|
|
||
|
The "plotselected" event is only fired when the user has finished making the
|
||
|
selection. A "plotselecting" event is fired during the process with the same
|
||
|
parameters as the "plotselected" event, in case you want to know what's
|
||
|
happening while it's happening,
|
||
|
|
||
|
A "plotunselected" event with no arguments is emitted when the user clicks the
|
||
|
mouse to remove the selection. As stated above, setting "minSize" to 0 will
|
||
|
destroy this behavior.
|
||
|
|
||
|
The plugin allso adds the following methods to the plot object:
|
||
|
|
||
|
- setSelection( ranges, preventEvent )
|
||
|
|
||
|
Set the selection rectangle. The passed in ranges is on the same form as
|
||
|
returned in the "plotselected" event. If the selection mode is "x", you
|
||
|
should put in either an xaxis range, if the mode is "y" you need to put in
|
||
|
an yaxis range and both xaxis and yaxis if the selection mode is "xy", like
|
||
|
this:
|
||
|
|
||
|
setSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } });
|
||
|
|
||
|
setSelection will trigger the "plotselected" event when called. If you don't
|
||
|
want that to happen, e.g. if you're inside a "plotselected" handler, pass
|
||
|
true as the second parameter. If you are using multiple axes, you can
|
||
|
specify the ranges on any of those, e.g. as x2axis/x3axis/... instead of
|
||
|
xaxis, the plugin picks the first one it sees.
|
||
|
|
||
|
- clearSelection( preventEvent )
|
||
|
|
||
|
Clear the selection rectangle. Pass in true to avoid getting a
|
||
|
"plotunselected" event.
|
||
|
|
||
|
- getSelection()
|
||
|
|
||
|
Returns the current selection in the same format as the "plotselected"
|
||
|
event. If there's currently no selection, the function returns null.
|
||
|
|
||
|
*/(function(e){function t(t){function s(e){n.active&&(h(e),t.getPlaceholder().trigger("plotselecting",[a()]))}function o(t){if(t.which!=1)return;document.body.focus(),document.onselectstart!==undefined&&r.onselectstart==null&&(r.onselectstart=document.onselectstart,document.onselectstart=function(){return!1}),document.ondrag!==undefined&&r.ondrag==null&&(r.ondrag=document.ondrag,document.ondrag=function(){return!1}),c(n.first,t),n.active=!0,i=function(e){u(e)},e(document).one("mouseup",i)}function u(e){return i=null,document.onselectstart!==undefined&&(document.onselectstart=r.onselectstart),document.ondrag!==undefined&&(document.ondrag=r.ondrag),n.active=!1,h(e),m()?f():(t.getPlaceholder().trigger("plotunselected",[]),t.getPlaceholder().trigger("plotselecting",[null])),!1}function a(){if(!m())return null;if(!n.show)return null;var r={},i=n.first,s=n.second;return e.each(t.getAxes(),function(e,t){if(t.used){var n=t.c2p(i[t.direction]),o=t.c2p(s[t.direction]);r[e]={from:Math.min(n,o),to:Math.max(n,o)}}}),r}function f(){var e=a();t.getPlaceholder().trigger("plotselected",[e]),e.xaxis&&e.yaxis&&t.getPlaceholder().trigger("selected",[{x1:e.xaxis.from,y1:e.yaxis.from,x2:e.xaxis.to,y2:e.yaxis.to}])}function l(e,t,n){return t<e?e:t>n?n:t}function c(e,r){var i=t.getOptions(),s=t.getPlaceholder().offset(),o=t.getPlotOffset();e.x=l(0,r.pageX-s.left-o.left,t.width()),e.y=l(0,r.pageY-s.top-o.top,t.height()),i.selection.mode=="y"&&(e.x=e==n.first?0:t.width()),i.selection.mode=="x"&&(e.y=e==n.first?0:t.height())}function h(e){if(e.pageX==null)return;c(n.second,e),m()?(n.show=!0,t.triggerRedrawOverlay()):p(!0)}function p(e){n.show&&(n.show=!1,t.triggerRedrawOverlay(),e||t.getPlaceholder().trigger("plotunselected",[]))}function d(e,n){var r,i,s,o,u=t.getAxes();for(var a in u){r=u[a];if(r.direction==n){o=n+r.n+"axis",!e[o]&&r.n==1&&(o=n+"axis");if(e[o]){i=e[o].from,s=e[o].to;break}}}e[o]||(r=n=="x"?t.getXAxes()[0]:t.getYAxes()[0],i=e[n+"1"],s=e[n+"2"]);if(i!=null&&s!=null&&i>s){var f=i;i=s,s=f}return{from:i,to:s,axis:r}}function v(e,r){var i,s,o=t.getOptions();o.selection.mode=="y"?(n.first.x=0,n.second.x=t.width()):(s=d(e,"x"),n.first.x=s.axis.p2c(s.from),n.second.x=s.axis.p2c(s.to)),o.selection.mode=="x"?(n.first.y=0,n.second.y=t.height()):(s=d(e,"y"),n.first.y=s.axis.p2c(s.from),n.second.y=s.axis.p2c(s.to)),n.show=!0,t.triggerRedrawOverlay(),!r&&m()&&f()}function m(){var e=t.getOptions().selection.minSize;return Math.abs(n.second.x-n.first.x)>=e&&Math.abs(n.second.y-n.first.y)>=e}var n={first:{x:-1,y:-1},second:{x:-1,y:-1},show:!1,active:!1},r={},i=null;t.clearSelection=p,t.setSelection=v,t.getSelection=a,t.hooks.bindEvents.push(function(e,t){var n=e.getOptions();n.selection.mode!=null&&(t.mousemove(s),t.mousedown(o))}),t.hooks.drawOverlay.push(function(t,r){if(n.show&&m()){var i=t.getPlotOffset(),s=t.getOptions();r.save(),r.translate(i.left,i.top);var o=e.color.parse(s.selection.color);r.strokeStyle=o.scale("a",.8).toString(),r.lineWidth=1,r.lineJoin=s.selection.shape,r.fillStyle=o.scale("a",.4).toString();var u=Math.min(n.first.x,n.second.x)+.5,a=Math.min(n.first.y,n.second.y)+.5,f=Math.abs(n.second.x-n.first.x)-1,l=Math.abs(n.second.y-n.first.y)-1;r.fillRect(u,a,f,l),r.strokeRect(u,a,f,l),r.restore()}}),t.hooks.shutdown.push(function(t,n){n.unbind("mousemove",s),n.unbind("mousedown",o),i&&e(document).unbind("mouseup",i)})}e.plot.plugins.push({init:t,options:{selection:{mode:null,color:"#e8cfac",shape:"round",minSize:5}},name:"selection",version:"1.1"})})(jQuery);
|