简体   繁体   中英

d3 concise axis update method

I am trying to write a function to handle all of my axis update/enter. What I have right now seems like a hack because it require me to update a global variable to know if it is the first time or not.

var start = true;

function axis(selection, delay) {
    selection.transition().duration(750).select(".x.axis")
        .call(xAxis)
        .selectAll("g")
        .delay(delay);

    if (start) {
        start = false;
        // xaxis
        selection.append("g")
            .attr({
                "class": "x axis",
                "transform": "translate(0," + HEIGHT + ")"
            })
            .call(xAxis);

        // yaxis
        selection.append("g")
            .attr({"class": "y axis"})
            .call(yAxis)
            .append("text")
            .attr({
                "transform": "rotate(-90)",
                "y": 6,
                "dy": ".71em"
            })
            .style("text-anchor", "end")
            .text("Frequency");
     }
}

On the other hand my bar graph follows the pattern of

  • bind the data
  • update old elements
  • append new elements
  • remove old elements

How do I follow the same paradigm with d3.axis?

You could do something like binding some dummy data to your selection. Something like the following?

var xd = [0, 1]; // x domain
var yd = [0, 1]; // y domain
var y1, x1; // your axis' scales

// draw axes first so points can go over the axes
var xaxis = g.selectAll('g.xaxis')
  .data(xd);

// add axis if it doesn't exist  
xaxis.enter()
  .append('g')
    .attr('class', 'xaxis axis')
    .attr('transform', 'translate(0, ' + height + ')')
    .call(d3.svg.axis().orient("bottom").scale(x1));

// update axis if x-bounds changed
xaxis.transition()
  .duration(duration)
  .call(d3.svg.axis().orient("bottom").scale(x1));

var yaxis = g.selectAll('g.yaxis')
  .data(yd);

// add axis if it doesn't exist
yaxis.enter()
  .append('g')
    .attr('class', 'yaxis axis')
    .call(d3.svg.axis().orient("left").scale(y1));

// update axis if y-bounds changed
yaxis.transition()
  .duration(duration)
  .call(d3.svg.axis().orient("left").scale(y1));

If you actually want the ticks to update, you could do something like Mike Bostock does in his qq example . Hope that makes sense!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM