philogb / jit

The JavaScript InfoVis Toolkit provides tools for creating Interactive Data Visualizations for the Web
http://thejit.org
Other
1.51k stars 297 forks source link

"canvas is not defined" #34

Closed gossi closed 13 years ago

gossi commented 14 years ago

I was playing around with ST and Canvas nodes. Though created Events with the Events property. Dependend on the value of Label.type and Evens.enabled I get errors in firebug.

My events property: Events: { enabled: true/false, onMouseEnter: function () onMouseLeave: function () onClick: function (node) }

Events.enabled = false Label.type = "Native" => none Events.enabled = true Label.type = "Native" => a lot, through mousemove Events.enabled = true Label.type = "HTML" => when clicking Events.enabled = false Label.type = "HTML" => none

I use version 2.0.0a

philogb commented 14 years ago

Hi, at line 6883 of jit.js (uncompressed file) could you try replacing the code with this and tell me if your problem persists? ... plot: function(opt, animating) { var viz = this.viz, aGraph = viz.graph, canvas = viz.canvas, id = viz.root, that = this, ctx = canvas.getCtx(), min = Math.min, opt = opt || this.viz.controller; opt.clearCanvas && canvas.clear();

  var root = aGraph.getNode(id);
  if(!root) return;

  var T = !!root.visited;
  ...

Actually the lines to replace are the ones that take the root node:

  var root = aGraph.getNode(id);
  if(!root) return;

  var T = !!root.visited;
gossi commented 14 years ago

I changed the lines. Here is btw my setup:

    Events: {
        enable: true,
        onMouseEnter: function () {
            console.log("Mouse Enter");
            graph.canvas.getElement().style.cursor = "pointer";
        },
        onMouseLeave: function () {
            console.log("Mouse Leave");
            graph.canvas.getElement().style.cursor = "";
        },
        onClick: function (node) {
            console.log("Click: " + node);
            if (!node) return;
            graph.onClick(node.id);
            displayInformation(node);
        }
    },
    /* Visualisation for DOM Labels */
    onCreateLabel: function (label, node) {
        label.id = node.id;
        label.innerHTML = node.name;
        label.onclick = function() {
            graph.onClick(node.id);
            displayInformation(node);
        };
        if (node.data.isRoot) {
            displayInformation(node);
        }
    },  

so, what happens, when I was adding your fix: The errors disappeared, but the behaviour, too.

I expected both to be fired with node parameter set.

philogb commented 14 years ago

Hi, Thanks for the feedback.

Actually MouseEnter/Leave should be triggered only if the pointer enters/leaves a node when the events config is:

Events: {
    enable: true,
    type: 'Native',
    ...
 }

Or is fired when there's a MouseEnter/Leave on the labels and the configuration is something like:

Events: {
    enable: true,
    type: 'HTML',
    ...
 }
gossi commented 14 years ago

i'm confused right now :) There are too much conditions on what happens when and what based on such many different options that interfere each other. So, I added the type 'Native' on my Events object, but nothing changed. I wanna go for Native Nodes, but was starting with HTML-Nodes back in time. This is why both are present in my config at the moment, so I am able to swap back and forth, but I hope I can get rid of the HTML-Nodes in the future. So here is my complete graph-js:

graph = new $jit.ST({  

    injectInto: 'graphviz',  
    transition: $jit.Trans.Quart.easeInOut,  

    constrained: false,
    levelsToShow : 1,
    levelDistance: 40,
    siblingOffset: 20,
    duration: 450,
    fps: 25,

    Navigation: {  
        enable: true,  
        panning: true,
        zooming: -50,
    }, 

    //set node and edge colors
    Node: {
        overridable: true,
        width: 120,
        autoHeight: true,
        autoWidth: false,
        type: "adv-rect",
        CanvasStyles: {
            fillStyle: "#F1F4F7",
            strokeStyle: "#CCC",
            lineWidth: 0.5,
            radius: 4
        }
    },

    Label: {
        type: "Native",
        size: 10,
        //style: "bold",
        family: "Sans-serif", //'Lucida Grande' 'DejaVu Sans' Verdana Arial FreeSans Helvetica 'Bitstream Vera Sans'  
        color: "#333",
        textBaseline: "middle",
    },

    Edge: {
        type: "bezier",
        color: "#999",
        overridable: true
    },

    Events: {
        enable: true,
        type: "Native",
        onMouseEnter: function () {
            console.log("Mouse Enter");
            graph.canvas.getElement().style.cursor = "pointer";
        },
        onMouseLeave: function () {
            console.log("Mouse Leave");
            graph.canvas.getElement().style.cursor = "";
        },
        onClick: function (node) {
            console.log("Click: " + node);
            if (!node) return;
            graph.onClick(node.id);
            displayInformation(node);
        }
    },

    /* Visualisation for DOM Labels */
    onCreateLabel: function (label, node) {
        label.id = node.id;
        label.innerHTML = node.name;
        label.onclick = function() {
            graph.onClick(node.id);
            displayInformation(node);
        };
        if (node.data.isRoot) {
            displayInformation(node);
        }
    },  

    /* Highlight selected path */
    onBeforePlotLine: function(adj) {
        if (adj.nodeFrom.selected && adj.nodeTo.selected) {
            adj.data.$color = "#888";
            adj.data.$lineWidth = 2;
        }
        else {
            delete adj.data.$color;
            delete adj.data.$lineWidth;
        }
    }
});

graph.loadJSON(json);
graph.compute();
graph.geom.translate(new $jit.Complex(-200, 0), "current");  
graph.onClick(graph.root);

Actually, I copied most of it's functionality from this example here http://thejit.org/static/v20/Jit/Examples/ForceDirected/example1.html and tied it down to my use-case.

gossi commented 13 years ago

Ok, found the error. In the class: $jit.ST.Plot.NodeTypes each 'contains' method is lacking the return statement. That must be added in front of each nodeHelper call. Then two method-calls have the wrong parameters, in ellipse's and rectangle's contains method, change from:

this.nodeHelper.rectangle.contains({x:npos.x+width/2, y:npos.y+height/2}, width, height, canvas);

to:

return this.nodeHelper.rectangle.contains({x:npos.x+width/2, y:npos.y+height/2}, pos, width, height);

this will resolve the "canvas" not defined error and brings back the expected behavior.

philogb commented 13 years ago

That's great! ill write your fix as soon as I get some time. Thanks again for finding and posting the fix here :)

philogb commented 13 years ago

Hi. This is the same issue than : https://github.com/philogb/jit/issues#issue/52 . I will just keep the newest one. Already found a solution for this and will close that ticket when I push.