NewToJS
NewToJS

Reputation: 2101

D3.JS trying to format the text in first tick of axis

I'm trying to write a function to select the text within the last tick of this axis and prepend a "$" to it (so that the text is $100 in this case)

enter image description here

So far I've used this prototype to select that last tick:

d3.selection.prototype.last = function() {
  var last = this.size() - 1;
  return d3.select(this[0][last]);
};

//first I select all of the ticks:
var tickLabels =  d3.selectAll("g.cardbasegroup g.yaxis g.tick");

//and then use that prototype to select the last one:
var lastTick = tickLabels.last();

...But now how to I grab that text within that tick and prepend a "$"?

Upvotes: 2

Views: 2189

Answers (2)

Damien Fayol
Damien Fayol

Reputation: 958

You can do :

 var textNode = lastTick.select('text');
 textNode.text('$' + textNode.text());

Another way to proceed would be to use the .tickFormat method.

var nbTicks = 5;
var axis = d3.svg.axis()
    .ticks(nbTicks)
    .tickFormat(function(d, i) {
        if(i == nbTicks) {
            return '$' + d;
        }
        return d;
    });

The problem with this method is that the doc for linear.ticks (used to generate the correct number of ticks) tells us :

The specified count is only a hint; the scale may return more or fewer values depending on the input domain.

References:

Upvotes: 3

Sascha
Sascha

Reputation: 1158

Starting from the example you could do

svg.selectAll(".tick text").each(function (data) {
  var tick = d3.select(this);
  tick.text("$"+tick.text());
});

All together:

<!DOCTYPE html>
<html>
<meta charset="utf-8">
<style>
  .axis text {
    font: 10px sans-serif;
  }

  .axis line,
  .axis path {
    fill: none;
    stroke: #000;
    shape-rendering: crispEdges;
  }
</style>

<body>
  <script src="d3.min.js"></script>
  <script>
    var margin = {
        top: 250,
        right: 40,
        bottom: 250,
        left: 40
      },
      width = 960 - margin.left - margin.right,
      height = 500 - margin.top - margin.bottom;

    var x = d3.time.scale()
      .domain([new Date(2012, 0, 1), new Date(2013, 0, 1)])
      .range([0, width]);

    var xAxis = d3.svg.axis()
      .scale(x);

    var svg = d3.select("body").append("svg")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
      .append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis)
      .selectAll("text")
      .attr("y", 0)
      .attr("x", 9)
      .attr("dy", ".35em")
      .attr("transform", "rotate(90)")
      .style("text-anchor", "start");

    svg.selectAll(".tick text").each(function (data) {
      var tick = d3.select(this);
      tick.text("$"+tick.text());
    });
  </script>
</body>

</html>

Just add your prototype to get the last element.

Upvotes: 1

Related Questions