circosJS
circosJS copied to clipboard
Zooming in CircosJS
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!
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.
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.
@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!
@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.
@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)
}));
@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
.
@jnunez17 The issue was that I wrongly assumed that d3-zoom
was included in the package,json
. Once I installed it, everything worked wonderfully 👍