dygraphs icon indicating copy to clipboard operation
dygraphs copied to clipboard

Demo broken: Drawing zoom option errors

Open lBowlin opened this issue 9 years ago • 9 comments

The drawing demo is now broken. The change introduced to move the mouseup and mousemove to the document most likely broke this (see https://github.com/danvk/dygraphs/pull/472). Mousemove and mousup are now undefined:

Dygraph.defaultInteractionModel.mousemove(event, g, context); Dygraph.defaultInteractionModel.mouseout(event, g, context); Dygraph.defaultInteractionModel.mouseup(event, g, context);

lBowlin avatar May 21 '15 03:05 lBowlin

I noticed in 1.1.1 this no longer issues an undefined error, the references to mousemove and mouseup were removed in favor of just referencing the default mousedown.

This should work, but when zooming the mouseup event triggers, but context.isZooming is always false which results in never completing the zoom function.

I've been looking into it, but can't figure out where isZooming becomes false.

This doesn't just break the demo, but any other custom interaction model implementation that wishes to make use of the defaults.

lBowlin avatar Jun 28 '15 18:06 lBowlin

I want to define an interaction model as defined here :

interactionModel:
{
mousedown: Dygraph.defaultInteractionModel.mousedown,
mousemove: Dygraph.defaultInteractionModel.mousemove,
mouseup: Dygraph.defaultInteractionModel.mouseup,
touchstart: newDygraphTouchstart,
touchend: Dygraph.defaultInteractionModel.touchend,
touchmove: Dygraph.defaultInteractionModel.touchmove
} 

I m having the same problem mousemove and mousup are undefined. My purpose is to set a different behaviour when the graph is displayed on touchscreen. Is there a different way to do that ?

pmadc avatar Sep 09 '15 14:09 pmadc

Is there a solution available? If I include only the mousedown it doesn't work correctly.

Basically what I want to do is using the defaultmodel and when the user makes a selection ( just like he does when zooming ), it should check the state of the ctrl-key. If not pressed, go on with the default zooming, otherwise do my stuff and finish the event.

HenkV74 avatar Mar 21 '16 07:03 HenkV74

A little late to the convo but @lBowlin a quick workaround is to destroy the graph and recreate it without the custom interactionModels. Not ideal but it does get the job done. I'll try to see if I can address this issue.

wookhuk avatar Jul 11 '16 15:07 wookhuk

The drawing demo somehow works now. But when I try to replicate in my own project, I get the same errors as above:

Uncaught TypeError: _dygraphs2.default.defaultInteractionModel.mousemove is not a function

Was this fixed in a specific version or so?

bbirand avatar Jun 24 '17 00:06 bbirand

Facing the same issue while trying to combine the default behavior with some custom one. I got rid of the error by removing the mousemove and mouseup handlers, which are apparently assigned inside of mousedown (see this). This caused the error to effectively disappear, and I can seem to be able to pan and reset the graph. However, still no zooming; the grey rectangle is drawn but then it just stays there until I move the mouse out of the canvas.

These are my options:

interactionModel: {
  'mousedown': function (event, g, context) {
    Dygraph.defaultInteractionModel.mousedown(event, g, context)
  },
  'dblclick': function (event, g, context) {
    Dygraph.defaultInteractionModel.dblclick(event, g, context)
    console.log('dblclick')
  },
  'mousewheel': function (event, g, context) {
    console.log('mousewheel')
  }
}

Anyone having anything helpful to add to the matter? :)

miccio-dk avatar Nov 16 '17 17:11 miccio-dk

Here is my workaround in TypeScript (JS should be similar). I copy defaultInteractionModel:

  clone(obj) {
    if (obj === null || typeof(obj) !== 'object' || 'isActiveClone' in obj)
      return obj;

    var temp : any;
    if (obj instanceof Date)
      temp = new Date(obj);
    else {
      temp = obj.constructor();

      for (var key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
          obj['isActiveClone'] = null;
          temp[key] = this.clone(obj[key]);
          delete obj['isActiveClone'];
        }
      }
    }

    return temp;
  }
    var newModel = this.clone(Dygraph.defaultInteractionModel);
    newModel.mousedown = this.valueChartMouseDown;
    newModel.mousemove = this.valueChartMouseMove;
    newModel.mouseup = this.valueChartMouseUp;
    var interactionModel = newModel;

clone function from here: https://stackoverflow.com/a/122190

here are custom action functions:


  valueChartMouseUp(event, g, context) {
    if (!context.isSelection) {
      var graphPos = Dygraph.findPos(g.graphDiv);
      var canvasx = Dygraph.pageX(event) - graphPos.x;
      var canvasy = Dygraph.pageY(event) - graphPos.y;
      var xy = g.toDataCoords(canvasx, canvasy);
      var x = xy[0], value = xy[1];
      console.log("x:" + x);
      console.log("value: " + value);
    }
  }
  valueChartMouseMove(event, g, context) {
    context.isSelection = true;
  }
  valueChartMouseDown(event, g, context) {
    context.isSelection = false;
    Dygraph.defaultInteractionModel.mousedown(event, g, context);
  }

No idea why I can't find mousemove on defautlInteractionModel and in case of MouseDown I have to call one - but anyway here it worked for me. I was able to get custom click action with zooming working as originally.

Somebody had a good fun by changing Dygraph code there :D

parvuselephantus avatar Nov 19 '17 11:11 parvuselephantus

I'm using the 2.1.0 release. While trying to implement a custom interaction model I also experienced this issue when trying to use the default model for mousemove, mouseup and mouseout.

The workaround that I used was to redefine the functions as they were defined in previous releases. The code for the functions can be found here .

The code is as follow: ' Dygraph.defaultInteractionModel.mousemove = function(event, g, context) { if (context.isZooming) Dygraph.moveZoom(event, g, context); else if (context.isPanning) Dygraph.movePan(event, g, context); }

Dygraph.defaultInteractionModel.mouseup = function(event, g, context)
{
    if (context.isZooming)
        Dygraph.endZoom(event, g, context);
    else if (context.isPanning)
        Dygraph.endPan(event, g, context);
}

Dygraph.defaultInteractionModel.mouseout = function(event, g, context)
{
    if (!context.isZooming) return;
    context.dragEndX = null;
    context.dragEndY = null;
    g.clearZoomRect_();
}'

Just paste the code before trying to use the functions.

VoxCodice avatar Jan 15 '18 16:01 VoxCodice

Ok, after wrestling with this problem for several hours the solution is simple; you need to set willDestroyContextMyself to true on your custom interaction model, and only propagate mousedown, and dblclick events to the default interaction model. (and possibly touch events if you are using them)

var interactionModel = {
    // ****** THE NEXT LINE IS IMPORTANT *****************
    willDestroyContextMyself: true,
    mousedown: function (event, g, context) {
        Dygraph.defaultInteractionModel.mousedown(event, g, context);
    },
    mousemove: function (event, g, context) {
        // no call to defaultInteractionModel needed as a handler for this event is bound in mousedown.
    },
    mouseup: function(event, g, context) {
        // no call to defaultInteractionModel needed as a handler for this event is bound in mousedown.
    },
    mouseout: function(event, g, context) {
        // no call to defaultInteractionModel needed as this event is not used. (mouseout is detected using the dynamically bound mousemove event)
    },
    dblclick: function(event, g, context) {
        Dygraph.defaultInteractionModel.dblclick(event, g, context);
    },
    mousewheel: function(event, g, context) {
        // no call to defaultInteractionModel needed as this event is not used.
    },
    touchstart: function touchstart(event, g, context) {
        DygraphInteraction.startTouch(event, g, context);
    },
    touchmove: function touchmove(event, g, context) {
        DygraphInteraction.moveTouch(event, g, context);
    },
    touchend: function touchend(event, g, context) {
        DygraphInteraction.endTouch(event, g, context);
    },
};

mp035 avatar Mar 17 '19 04:03 mp035