Not Known
Not Known

Reputation: 55

Change x scale of path dynamically d3.js

I am trying to change the x-scale of already plotted path in d3.js

Also, i am able to change the x-scale of circles using following code.

var s = d3.event.selection || xTimeScale.range();

                    xTimeScale.domain(s.map(xDateScale.invert, xDateScale));

                d3.selectAll(".dot").transition().duration(10).attr("cx",function(d){ return xTimeScale(d.date); })

As you can see i have changed the domain of xTimeScale with new values. and then select all the circles with class(.dot) and replot the x and y with changed xTimeScale.

Now i also want to change the path with this new scale.

Here is the code when my path first plotted.

var lineFunction = d3.line().x(function(d) { return x(d.date); }).y(function(d) { return y(d.value); })

                    var lineGraph = svg.append("path").attr("d",lineFunction(data)).attr("stroke", "blue")
                        .attr("stroke-width", 2).attr("fill", "none").attr("class","dotsLine");

Upvotes: 1

Views: 1582

Answers (1)

Gerardo Furtado
Gerardo Furtado

Reputation: 102174

Since you're just changing the scale used by the line generator you don't need to rebind the data (by the way, I see that you are not binding any data), you just need to pass the new scale to the line generator and, then, update the d attribute of the path.

Look at this demo. There is a x scale, named xScale1, used by the line generator:

var line = d3.line()
    .x(function(d) {
        return xScale1(d)
    })

When you click the button, the line generator uses another scale...

line.x(function(d) {
    return xScale2(d)
})

... and the path d attribute is updated:

path.transition()
    .duration(1000)
    .attr("d", line(data));

Here is the demo:

var svg = d3.select("svg");

var data = [12, 130, 45, 60, 110, 21];

var yScale = d3.scaleLinear()
  .domain(d3.extent(data))
  .range([140, 10]);

var xScale1 = d3.scalePoint()
  .domain(data)
  .range([10, 290]);

var xScale2 = d3.scalePoint()
  .domain(data.concat(d3.range(6)))
  .range([10, 290]);

var line = d3.line()
  .x(function(d) {
    return xScale1(d)
  })
  .y(function(d) {
    return yScale(d)
  })
  .curve(d3.curveBasis);

var path = svg.append("path")
  .attr("d", line(data))
  .attr("fill", "none")
  .attr("stroke", "black");

d3.select("button").on("click", function() {

  line.x(function(d) {
    return xScale2(d)
  })

  path.transition()
    .duration(1000)
    .attr("d", line(data));
})
<script src="https://d3js.org/d3.v4.min.js"></script>
<button>Click me</button>
<br>
<svg></svg>

Upvotes: 3

Related Questions