Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added plug-in for custom node shapes and images #106

Closed
wants to merge 10 commits into from

Conversation

rpeleg1970
Copy link
Contributor

Hi,

I added a plug-in called sigma.nodeShapes - demo / intro code sample here: https://dl.dropboxusercontent.com/u/45136256/sigma.js/nodeshapes.html

screen shot 2013-06-05 at 11 36 17 am

the plug-in itself adds more node drawing functions for:

  • square
  • triangle
  • diamond
  • star (configurable number of points and inner radius)

In addition, the plug-in exposes an API to add additional custom shapes - also shown in demo with a 'Pacman' node.

All node drawing functions keep the shape bounded in the node size radius. This is important for keeping the rest working - mouse click and hover, force atlas, arrow edges, etc.

Last - the plug-in adds the ability to draw images on nodes, demonstrated as well. This addresses issue #83

This plugin is based on minimal changes to plotter - needed to expose the functionality that currently draws circle for regular, active, and hover nodes (as well as borders). no changes to node attribute were made - the attributes for shape and image drawing are piggybacked on the node.attr bag.

_NOTE_: post-mortem I noticed the file changes for plotter.js shows a lot of false diffs, due to auto-indent in my vi editor. I believe these are good indentations but can provide a non-indented version if you prefer. To help you review the code - I added a note next to each REAL code change (see under Files Changed tab)

rpeleg1970 and others added 8 commits June 1, 2013 17:55
drawNodeShape (used by drawNode)
drawHoverNodeBorder/Shape (used by drawHoverNode)
drawActiveNodeBorder/Shape (use by drawActiveNode)

The drawing functions gets color, x, y and size as parameters, and draw to a ctx parameter. Optionally the drawing functions can use the node.attr data to do additional stuff (may be used by plug-ins later on).
The drawing functions adhere to keeping the drawn shape in the radius of 'size' - so that other graph calculations work well.

In the default case - all functions draw a filled circle according to the passed parameters. This is identical to the current behavior.
- skeleton
- on init store original plotter methods and replace with plug-in drawShapedNode function
- on finalize restore original plotter functions
- currently drawShapedNode focuses on adding images on top of the regular circle shapes. Image attributes taken from node.attr.image. Function not yet complete
… (instance override instead of class override)

- image on nodes work well in nodeShapes plugin
currently the circle drawing from the original Plotter class are plugged as shape 'circle'
- extending sigma.tools with shape drawing functions
- 'shape' attribute is now a hash, with shape name in 'name' inside it. Allows adding more options - see impl. of star allows configuring number of points and inner radius
… reached

also addede custom node shape to public API
@@ -215,10 +215,10 @@ function Plotter(nodesCtx, edgesCtx, labelsCtx, hoverCtx, graph, w, h) {
s['hidden'] ||
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the diff reflects a lot of indentation corrections, likely caused by my vim's auto-indent
I added a comment below ONLY FOR real (non-indent) code changes to make the review easier

@hansifer
Copy link

hansifer commented Jun 6, 2013

That's really awesome. I can definitely use that. Thanks!

@rpeleg1970
Copy link
Contributor Author

Thanks! I'll start writing the classic-video-games-node-shape-expansion pack ;)

@rpeleg1970
Copy link
Contributor Author

screen shot 2013-06-06 at 6 07 25 pm

@rpeleg1970 rpeleg1970 closed this Jun 6, 2013
@rpeleg1970 rpeleg1970 reopened this Jun 6, 2013
@rpeleg1970
Copy link
Contributor Author

oops.. closed by mistake, reopened.

ronp@winter added 2 commits June 10, 2013 15:09
- set number of pointes
- set rotation (degrees) clockwise
- 'iso-poly' with numPoint=3 equals 'triangle'. add 'rotate': 60 to turn it on its head
- 'iso-poly' with numPoint=4 equals 'diamond'. add 'rotate': 45 to make it a 'square'
@sheymann
Copy link
Contributor

awesome work!

@ParkHanbum
Copy link

awesome work!! 👍
is it work with parseGexf library?

I put node-shape like this [viz:node-shape value="image" uri="/img/switch.png" /] = ( ] to > )
but doesn't load image.

@rpeleg1970
Copy link
Contributor Author

Thanks. Currently it does not work with parseGexf - the problem is that since the node shapes/images are plug-in functionality, it would not be the best behavior to put dependent code in another plug-in. However, this would be easy to add to a custom version of the GEXF plug-in:

  1. In the parseGexf.js code (https://github.com/jacomyal/sigma.js/blob/master/plugins/sigma.parseGexf.js), add a vis:node-shape section (similar to the viz:size, vis:color, and viz:position), and extract image url if node-shape is image.
  2. When the node is created (lines 109-121) add image: {url: } to the attributes as demonstrated in https://dl.dropboxusercontent.com/u/45136256/sigma.js/nodeshapes.html

Let me know if you need help with this

@ParkHanbum
Copy link

nice~ I make very very rough code . anyway it seems work.

  //add node shape
  nodeShape = "";
  imgUri = "";
  var shapeNodes = nodeNode.getElementsByTagName('node-shape');
  shapeNodes = shapeNodes.length || poorBrowserXmlNsSupport ?
               shapeNodes :
               nodeNode.getElementsByTagNameNS('*','node-shape');
  if(shapeNodes.length>0){
    var shapeNode = shapeNodes[0];
    nodeShape = shapeNode.getAttribute('value');
    imgUri  = shapeNode.getAttribute('uri');
  }

  // Create Node
  var node = {label:label, size:size, x:x, y:y, attributes:[], color:color, shape:{name: nodeShape}, image:{url:imgUri, scale:1}};  // The graph node

don't blame me :)
just test code

@Nibbels
Copy link

Nibbels commented Nov 19, 2013

Thanks :)

I love it!!

@blt909
Copy link

blt909 commented Dec 5, 2013

Great plug-in there ! 👍

@Bhb2011 @rpeleg1970
I tried to implement it with parseGexf.js.
My nodes attr Object seems to be well populated with shapes and images but the shapes and images won't show on the graph...

In graph loading script :

    sigInst.parseGexf('{{ asset("assets/json/linternaute.gexf")}}');
    sigInst.startNodeShapes();

In parseGexf.js :

//add node shape

    var shapeNodes = nodeNode.getElementsByTagName('nodeshape');
    shapeNodes = shapeNodes.length ?
                 shapeNodes :
                 nodeNode.getElementsByTagName('viz:nodeshape');
    if(shapeNodes.length>0){
      shapeNode = shapeNodes[0];
      nodeShape = shapeNode.getAttribute('value');
      imgUri  = shapeNode.getAttribute('uri');
    }

      // Create Node
      var node = {label:label, size:size, x:x, y:y, attributes:[], color:color,  shape:{name: nodeShape}, image:{url:imgUri, scale:1}};  // The graph node

In my gexf file :

<viz:nodeshape value="square" uri="/assets/img_wd/Post.png"></viz:nodeshape>

Thanx for your advice

@rpeleg1970
Copy link
Contributor Author

Hello @blt909

I understand you took the code that worked for @Bhb2011 . One thing that comes to mind - I see you call sigInst.startNodeShapes() AFTER you call sigInst.parseGexf('...'). This means that when you run the parse- the node-shape plug-in is not yet initialized. Can you try reverse the order and try again?

Thanks
R

@blt909
Copy link

blt909 commented Dec 11, 2013

Hello @rpeleg1970

I reversed the instructions sequence and tried again with no improval .
In console, I have the excepted output for my attributes, but no image on the concerned node :

image: Object
    scale: 1
    url: "/assets/img_wd/Post.png"

Thanks

@rpeleg1970
Copy link
Contributor Author

Hmm... Is the asset URI correct? I see when you load the GEXF file you load it from 'assets/...' (relative path) while for the image you use an absolute path ('/assets/...')
If this does not help - can you post me the simplest GEXF file I can try with your code?

Also - before you try the GEXF - can try to use an example similar to https://dl.dropboxusercontent.com/u/45136256/sigma.js/nodeshapes.html - just to see the plug-in is working well as is?

@blt909
Copy link

blt909 commented Dec 11, 2013

I verified my assets URIs, they are both ok (relative one comes from a templating engine, absolute one is a copy/paste from the output of the templating engine for testing the plugin).

Here's the simpliest example possible for a gexf file (2 nodes , 1 edge) :

<?xml version='1.0' encoding='UTF-8'?>
<gexf xmlns="http://www.gexf.net/1.2draft" version="1.2" xmlns:viz="http://www.gexf.net/1.2draft/viz" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.gexf.net/1.2draft http://www.gexf.net/1.2draft/gexf.xsd">
  <meta lastmodifieddate="2013-12-11">
    <creator>Gephi 0.8.1</creator>
    <description></description>
  </meta>
  <graph defaultedgetype="undirected" mode="static">
    <attributes class="node" mode="static">
      <attribute id="onto_class" title="onto_class" type="string"/>
      <attribute id="note" title="note" type="integer"/>
    </attributes>
    <nodes>
      <node id="Agent35" label="Agent35">
        <attvalues>
          <attvalue for="onto_class" value="Agent"/>
          <attvalue for="note" value="0"/>
        </attvalues>
        <viz:size value="1.0"/>
        <viz:nodeshape value="square" uri="/assets/img_wd/Agent.png"></viz:nodeshape>
        <viz:position x="40.94513" y="-36.955757" z="0.0"/>
        <viz:color r="153" g="153" b="153"/>
      </node>
      <node id="Post36" label="Post36">
        <attvalues>
          <attvalue for="onto_class" value="Post"/>
          <attvalue for="note" value="0"/>
        </attvalues>
        <viz:size value="1.0"/>
        <viz:nodeshape value="diamond" uri="/assets/img_wd/Post.png"></viz:nodeshape>
        <viz:position x="-40.94513" y="36.955757" z="0.0"/>
        <viz:color r="153" g="153" b="153"/>
      </node>
    </nodes>
    <edges>
      <edge source="Agent35" target="Post36" label="webdrone:postedBy">
        <attvalues/>
      </edge>
    </edges>
  </graph>
</gexf>

I'm looking forward to test that the plugin is working well without the GEXF loader

Thanks

@rpeleg1970
Copy link
Contributor Author

Hi

I used your exact code with the obvious modification of images and locations, to fit my setup. It worked well, sorry..
A few points for you to check:

  1. Does the plug-in work for you without the Gexf parsing?
  2. What browser are you using? Does this browser display the https://dl.dropboxusercontent.com/u/45136256/sigma.js/nodeshapes.html example well?
  3. After I loaded the GEXF file, I inspected the sigInst (see below screen grab from chrome developer console). Note that the image and shapes fall under node.attr

Hope any of this helps
Ron

screen shot 2013-12-12 at 8 29 00 am

@blt909
Copy link

blt909 commented Dec 12, 2013

Hi

I checked the few points :

  1. No, I've implemented your exact example on my setup and it doesn't worked.
    I discovered that the plug-in send a log but it doesn't appear on my setup
redraw on image load 

So I think there's something disturbing the access to the methods.

  1. I use Chrome or Firefox when I do tests, both worked well on your webpage
  2. I did the same check and had the same result, sigma.parseGexf.js seems to perfectly handle the datas.

@rpeleg1970
Copy link
Contributor Author

Hmmm... kind of ran out of ideas, wish I could recreate it here. I would try to break inside the draw.*NodeShape, in the sigma.nodeShapes.js, and see where its going, and where it's blocked.

one last idea as I write:
Did you take the entire sigmajs branch from my repo - or did you take from jacomyal and just copied my plugin file?
If you just took my file - it will not work. The plug-in relies on small changes that I did to src/core/plotter.js - these changes were not integrated into the main sigmajs branch.

Cheers
R

@blt909
Copy link

blt909 commented Dec 12, 2013

Hi,

that awkward you realize it was so simple after all ^^.
I missed that you've mentionned you have a custom sigma.min.js... and all work perfectly well now.

Sorry for the waste of your time Ron and thanks for your attention.

@rpeleg1970
Copy link
Contributor Author

Great, glad I helped

@jacomyal
Copy link
Owner

Here is how custom node renderers work in the new version of sigma:

Everyone wants different ways to render nodes, but I cannot merge everything in the core. So, from now, it is easy for you to develop custom node renderers on the fly or as plugins for your specific needs. I just added an example with a renderer that draws images instead of discs, to show how it works.

Anyway, the plugin still sounds relevant, to make it easier to display nodes as images + shapes. It might be interested to port it to the new sigma.

@jacomyal jacomyal closed this Jan 12, 2014
@rpeleg1970
Copy link
Contributor Author

Hi Alexis,

I will take the porting on me, thanks for the feedback !

Cheers
R

‫ב-12 בינו 2014, בשעה 18:13, ‏"Alexis Jacomy" notifications@github.com כתב/ה:‬

Here is how custom node renderers work in the new version of sigma:

Everyone wants different ways to render nodes, but I cannot merge everything in the core. So, from now, it is easy for you to develop custom node renderers on the fly or as plugins for your specific needs. I just added an example with a renderer that draws images instead of discs, to show how it works.

Anyway, the plugin still sounds relevant, to make it easier to display nodes as images + shapes. It might be interested to port it to the new sigma.


Reply to this email directly or view it on GitHub.

@jacomyal
Copy link
Owner

That's good news, thanks for this :)

A---- pushed a commit to A----/sigma.js that referenced this pull request Sep 16, 2015
Dragging an unselected node while another node is selected drags both
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants