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

Zooming in CircosJS #62

Open
jorgenunezsiri opened this issue Mar 19, 2018 · 7 comments
Open

Zooming in CircosJS #62

jorgenunezsiri opened this issue Mar 19, 2018 · 7 comments

Comments

@jorgenunezsiri
Copy link

Hello @nicgirault,

Is there a way to implement normal D3 zooming abilities within Circos layouts?

I'm using the Chords track similar to this example: https://github.com/nicgirault/circosJS/blob/master/doc/chords.png. I want to implement normal pan and zoom by scrolling with the mouse (https://bl.ocks.org/sgruhier/50990c01fe5b6993e82b8994951e23d0), and this is what I'm trying to do:

var width = 1000;
var height = 850;

var svg = d3.select("body")
  .append("div")
  .attr('id', 'chart')
  .attr("width", width)
  .attr("height", height);

svg.select(".all")
  .call(d3.zoom().on("zoom", function() {
    svg.select(".all").attr("transform", d3.event.transform)
  }))
  .append("g");

var myCircos = new Circos({
  container: '#chart',
  width: width,
  height: height
});

// ...
// Adding the configuration data for the layout and chords, and rendering

The zooming is not working as expected. As you can see, I have to do svg.select(".all") to actually select the svg element within the div tag.

Thank you!

@nicgirault
Copy link
Owner

Hi @jnunez17 sorry for the late answer. I don't know at all how zoom is working so I won't be able to help you without digging into the subject. I let the issue open so that I will work on it next time I maintain this project. If you found a solution, I would be really glad if you can share it so that I could add it to the documentation of this project.

@jorgenunezsiri
Copy link
Author

Hello @nicgirault, sorry for the late reply. The issue is that having the structure svg > div > svg or div > div > svg is not valid for adding zooming to the main container. So, I was able to add zooming by removing the div container, and changing the main container to svg. Solving it is as easy as going to these lines and changing them to:

const container = select(this.conf.container)

This small change will allow users to have SVG containers in their applications, by giving an id to an svg element instead of a div. Then, you should get the expected zooming by adding the following to the SVG:

svg.call(d3.zoom().on("zoom", function() {
  svg.attr("transform", d3.event.transform)
}));

There is more information about having an SVG container in the other discussion here.

@mtwichan
Copy link

mtwichan commented Dec 2, 2018

@jnunez17 Do you mind posting a code snippet on how you implemented this? I've been trying to make it work with react but I keep getting this error:

Uncaught TypeError: Cannot read property 'button' of null

Thank you!

@jorgenunezsiri
Copy link
Author

jorgenunezsiri commented Dec 2, 2018

@matthewchan15 That does not seem to be an issue with the zoom itself, but with something you are missing for getting it to work, possibly how you are importing the d3 modules. One thing you can try is importing the whole d3 library at the top of your script (import * as d3 from 'd3';), and if that fixes your issue then perhaps you are missing a specific d3 module (in case you were importing them separately).

For the zoom, it should work just by removing the extra div container from the library and then calling the zoom event transform on the outer svg. I'm explaining the issue and the steps with more detail in my previous comment.

@mtwichan
Copy link

mtwichan commented Dec 2, 2018

@jnunez17 Ah yes I tried import * as d3 from 'd3';, as well as this method import {select} from 'd3-selection' (example). I am using the d3 package provided in this library with package.json -> https://github.com/nicgirault/circosJS/blob/master/package.json.

I think there may be a misunderstanding on my part. Did you specify this block of code in circos.js (this is what I'm trying to do) or when you were creating your instance such as in the first comment you posted?

svg.call(d3.zoom().on("zoom", function() {
  svg.attr("transform", d3.event.transform)
}));

@jorgenunezsiri
Copy link
Author

@matthewchan15 Sorry, I did not understand you before. You should be specifying the zoom call in your application, after creating the svg parent container (the same container that you use to create the Circos instance). Make sure you attach the zoom call to that parent container. Then, that svg is going to include an inner svg (coming from circos.js). The zoom should be working because the structure will be svg > svg, instead of svg > div > svg.

@mtwichan
Copy link

@jnunez17 The issue was that I wrongly assumed that d3-zoom was included in the package,json. Once I installed it, everything worked wonderfully 👍

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

No branches or pull requests

3 participants