helloGoodDay
helloGoodDay

Reputation: 69

D3 - Zooming with D3's SVG Symbols

I want to zoom in my nodes in the following way shown by this fiddle. http://jsfiddle.net/HF57g/2/

Fiddle Source: How to zoom in/out d3.time.scale without scaling other shapes bound to timeline

With the help of the fiddle, I was able to apply the zoom with SVG Circles.

Note: The code below shows that by using SVG Circles you are provided with an x and y axis attribute.

.enter().append("circle")
.attr("cx", function(d) { return xScale(d); })
.attr("cy", function(d) { return yScale(d); })       

What I want, is to have circles and diamonds both using this zoom functionality

So I chose D3's "d3.svg.symbol", to allow both circles and diamonds.

However, the problem I am facing is that by using D3's SVG Symbols I don't have access to manipulating the x axis specifically since it only allows translate.

.enter().append("path")
.attr("transform", function(d) {
      return "translate(" + d.x + "," + d.y + ")"; })
.attr("d", d3.svg.symbol()
             .size(145)
             .type(function(d) {
                          if(d.value <= 10)
                                 return "diamond";
                          else
                             return "circle";
                      })); 

The code below from the fiddle shows the manipulation of the x axis for the zoom taken from the fiddle. I want to do the same with translate if it's possible.

return svg.selectAll("rect.item")
    .attr("x", function(d){return scale(d);}) 

The code below shows the way it works with SVG Circles and it shows the most logical way I thought to make the zoom work. But unfortunately it does not work.

var zoom = d3.behavior.zoom()
           .on("zoom", function(){
           //If I use SVG Circles the following code works.
           //chart.selectAll(".item").attr("cx", function(d){ return xScale(d); });

           //By using SVG Symbols and translate, this does not work
           chart.selectAll(".item").attr("transform", function(d) { return  "translate("+ d.x +", 0)";});

            }).x(xScale);

Here is a fiddle edited with diamonds and circles. https://jsfiddle.net/g67cgt4w/

Upvotes: 3

Views: 869

Answers (1)

Ivan Kovachev
Ivan Kovachev

Reputation: 402

https://jsfiddle.net/62vq9h8p/

In update_events() function you can't use the "circleDiamond.item" as selector because you don't have <circleDiamond> element - there is a <circle> svg element that's why you can use "circle.myCircle" for example. You can set a better class like ".circle.diamond.item." to select them. So I changed this and also added

var cy = d3.transform(d3.select(this).attr("transform")).translate[1];
return "translate(" + scale(d) + "," + cy +")";

This will keep the current Y positioning.

d3.transform(d3.select(this).attr("transform"))

Takes current element's transform and .translate[1] takes the translate object and returns the Y value(which is the second item). You can take current X value if you get the 0 index instead.

Upvotes: 2

Related Questions