a rectangle for simple interval selection

308 views
Skip to first unread message

Tommaso Bianco

unread,
Feb 4, 2013, 7:09:04 AM2/4/13
to dygraph...@googlegroups.com
Hi,
I am trying to implement a selection/highlight/interval functionality.

It should behave as for the zoom selection, that is the mouse click event starts drawing a grey rectangle over the plot.
But once the mouse is released, no zoom is performed, and the rectangle remains on the plot.

At the moment I have the following problems:
- once the mouse is released, the automatic painting of the dots in the nearby "eats" the borders of the grey rectangle
- once the rectangle is drawn, hovering over it, or going out from the canvas with the mouse, or resizing the window, cause the grey rectangle to disappear

Do you have any suggestion about how to proceed to correct these problems?

Many thanks!

Robert Konigsberg

unread,
Feb 4, 2013, 9:59:23 AM2/4/13
to tommaso...@gmail.com, dygraphs-users
Not particularly. The information you've provided isn't enough for me to advise you. My guess is those things are most likely details with the code, and not generic things. But if it helps, it sounds like you're working on http://code.google.com/p/dygraphs/issues/detail?id=188, which even points to http://dygraphs.com/mocks/base/demo7.html

 
Many thanks!

--
You received this message because you are subscribed to the Google Groups "dygraphs-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dygraphs-user...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Robert Konigsberg
Google Project Hosting Team

Tommaso Bianco

unread,
Feb 4, 2013, 10:05:55 AM2/4/13
to dygraph...@googlegroups.com
Well, I think I've found a way to overcome my problem. I'll pass the mouse positions back to underlayCallback in order to create a new "region highlight" (http://dygraphs.com/tests/highlighted-region.html).

Tommaso Bianco

unread,
Feb 4, 2013, 10:55:31 AM2/4/13
to dygraph...@googlegroups.com, tommaso...@gmail.com
Hi,
to explain it differently, I am trying to add the possibility to define a highlighted region as in http://dygraphs.com/tests/highlighted-region.html.
However, this region is not defined at the Dygraph instantiation, but it is defined by selecting a region with the mouse once the plot is displayed.
To do that I wrote methods similar to Dygraph.Interaction.startZoom / endZoom, which I call startSelect and endSelect, which are linked to my custom mousedown, mousemove, mouseup associated callbacks.
endSelect does not call doZoomX_, of course, because there must be no zoom involved.
As I pointed out in my later reply, I plan to look at how to use underlayCallback in endSelect for that.
Does this information add clearness to my previous post ?

Tommaso Bianco

unread,
Feb 4, 2013, 11:55:13 AM2/4/13
to dygraph...@googlegroups.com, tommaso...@gmail.com
Dear Robert,
an update of dygraph options with a new underlayCallback did the trick.
Here's the endSelect method, which drew from endZoom
(it works with numerical x-axis by now, I haven't yet experiences with timestamps)


Dygraph.Interaction.endSelect = function(event, g, context) {
  context.isSelecting = false;
  context.isSelected = true;
  context.dragEndX = g.dragGetX_(event, context);
  context.dragEndY = g.dragGetY_(event, context);
  var regionWidth = Math.abs(context.dragEndX - context.dragStartX);
  var regionHeight = Math.abs(context.dragEndY - context.dragStartY);
 
  if (regionWidth < 2 && regionHeight < 2 &&
      g.lastx_ !== undefined && g.lastx_ != -1) {
    Dygraph.Interaction.treatMouseOpAsClick(g, event, context);
  }
 
  if (regionWidth >= 10 && context.dragDirection == Dygraph.HORIZONTAL) {
    context.cancelNextDblclick = true;
  } else if (regionHeight >= 10 && context.dragDirection == Dygraph.VERTICAL) {
    context.cancelNextDblclick = true;
  } else {
    if (context.zoomMoved) g.clearZoomRect_();
  }
 
  var minDate = Math.round(g.toDataXCoord(Math.min(context.dragStartX, context.dragEndX)));
  var maxDate = Math.round(g.toDataXCoord(Math.max(context.dragStartX, context.dragEndX)));
 
  g.updateOptions({
    underlayCallback: function(canvas, area, g) {
      var highlight_start = minDate;
      var highlight_end = maxDate;
      var bottom_left = g.toDomCoords(highlight_start, -20);
      var top_right = g.toDomCoords(highlight_end, +20);

      var left  = bottom_left[0];
      var right = top_right[0];

      canvas.fillStyle = "rgba(128,128,128,0.33)";
      canvas.fillRect(left, area.y, right - left, area.h);
    }
  });
 
  context.dragStartX = null;
  context.dragStartY = null;
 
};

Robert Konigsberg

unread,
Feb 4, 2013, 1:43:45 PM2/4/13
to Tommaso Bianco, dygraphs-users
I wouldn't call updateOptions to replace the underlay callback. Instead I'd just store the highlight start and end coordinates, and let drawCallback always remain unchanged. That's a minor thing though. Glad you've got it working.

Tommaso Bianco

unread,
Feb 5, 2013, 6:01:43 AM2/5/13
to dygraph...@googlegroups.com, Tommaso Bianco
I'll try what you say and let you know. Thanks!

John Schwegler

unread,
Oct 7, 2015, 12:00:12 PM10/7/15
to dygraphs-users, tommaso...@gmail.com
I know this is a quite old topic, but how did it work out for you?  I'm currently looking at the same issue - allowing the user to highlight a sub-region of the chart without zooming, for use in other elements of the page (not the chart itself).

Tommaso Bianco

unread,
Oct 8, 2015, 3:40:41 AM10/8/15
to dygraphs-users, tommaso...@gmail.com
Hi John,
I defined for the click down even a function like this

Dygraph.Interaction.startSelect = function(event, g, context) {
 g
.clearZoomRect_(); // remove previous selection
 context
.isSelecting = true;
};


And in the Dygraph.Interaction.endSelect this
g.updateOptions({ 
      underlayCallback: function(canvas, area, g) {
        var highlight_start = g.xSelectionStart;
        var highlight_end = g.xSelectionEnd;
      
        var bottom_left = g.toDomCoords(highlight_start, -20);
        var top_right = g.toDomCoords(highlight_end, +20);

        var left  = bottom_left[0];
        var right = top_right[0];

        canvas.fillStyle = "rgba(128,128,128,0.33)";
        canvas.fillRect(left, area.y, right - left, area.h);
      }
    });

John Schwegler

unread,
Oct 9, 2015, 10:09:25 AM10/9/15
to dygraphs-users, tommaso...@gmail.com
Tommaso,

Thanks very much for the quick reply!  I'm going to be doing something very similar, so that I don't need a separate selector for time ranges.
Reply all
Reply to author
Forward
0 new messages