Hejazzman
Hejazzman

Reputation: 2152

Remove end-ticks from D3.js axis

I'm using (the excellent) D3.js to generate some plots, and I can't find a way to remove the end ticks from the x and y axis.

Take the y-axis for example.

When the end tick value coincides with a label, I'm ok with having it.

But when the last round label is below the end of the plot, I get two ticks, one for the last rounded label and one above it at the end of the y-axis.

I don't want this end-tick visible, because I find the fact that it appears in less than the regular interval between labels distracting.

See here for an example of what I'm describing, the ticks at 0 and 15 are the end ticks:

15 ─┐ 
    | 
10 _| 
    |
5  _|
    |
0  ─┤──────

Any tips?

P.S As a response suggested, I could set the ticks explicitly. But I like the convenience of the implicit generated ticks, just don't want unlabelled ticks to pollute the axis. So an ideal solution (if exists) would also take than into account.

Upvotes: 47

Views: 47536

Answers (10)

Herii
Herii

Reputation: 510

Solution for d3.js 7.9.0

The solutions I found here did not solve my problem for my version but lead me to the right direction.

 svg
    .append('g')
    .call(d3.axisLeft(yScale).tickSize(0)) // Set tick size to zero
    .selectAll("path").remove();

after we call or axis (in my caseAxisLeft) we can set the tick size to zero.

Upvotes: 0

Kebby
Kebby

Reputation: 329

This will remove the whole axis. This does not answer the question posted.

Upvotes: -1

Jeremy Chone
Jeremy Chone

Reputation: 3157

In d3.js v4.x use .tickSizeOuter(0), like:

self._leftAxis = d3.axisLeft(self._y)
      .tickSizeInner(3) // the inner ticks will be of size 3
      .tickSizeOuter(0); // the outer ones of 0 size

Note that the zero tick below is considered a inner on

enter image description here

This d3.js v4 doc: https://github.com/d3/d3-axis

Upvotes: 12

KiriSakow
KiriSakow

Reputation: 1207

Working solution for D3 v5.9.2:

  1. After you declared yAxis and set the attributes, wrap it in a g and call it:

     svg.append("g").attr("id", "yAxisG").call(yAxis);
    
  2. Remove the first <path> element from the axis group:

     d3.select("g#yAxisG").select("path").remove();
    

Upvotes: 1

Just remove both axis:

d3.selectAll('.axis').remove();

Upvotes: -5

BairDev
BairDev

Reputation: 3211

I'not sure, what the outer tick size has to do with the first or last tick of an axis.


tickSize actually controls the length of the <line> element inside of the tick group. Therefore it deals with the distance between the <text> element of the tick and the axis or the length of helper lines starting at the tick positions, which depends on the orientation of the axis and where it has been moved to (via css translate()).

This is how a tick group looks like:

<g transform="translate(10,0)" style="opacity: 1;" class="tick">
   <line x2="0" y2="-15"></line>
   <text x="0" y="-18" style="text-anchor: middle;" dy="0em">0.0</text>
</g>

Now you can control the x2 and the y2 attribute of the <line> element with the tickSize method. Here I'm using tickSize(15, 0) and orientation('top') for the x axis, which has been moved to the bottom of the chart. So the lables of the ticks project into the chart in a quite messy way.

Upvotes: 1

Sisi
Sisi

Reputation: 1524

For anyone who got to this question because all you want to do is remove the two end ticks from an axis, this will do the trick:

.outerTickSize(0)

Add that to any axis call you make, such as:

d3.svg.axis().outerTickSize(0)

Upvotes: 121

Supra
Supra

Reputation: 1652

Remove end ticks using something like this: note tickSize(inner, outer)

var xAxis = d3.svg.axis().scale(x).
                tickSize(3, 0).orient("bottom").tickFormat( ... );

If you put outer param to 0 in tickSize(inner, outer) you will not get the outer ticks.

Upvotes: 3

Angie
Angie

Reputation: 1535

If you want to just hide the bounding values and keep the implicit behavior in the middle, you can modify the axis SVG object just after you draw it

Say, here you draw/update your axis:

g.selectAll(".x.axis").call(xAxis);

Now g will contain .tick classed objects. each of them will refer to one tick value. You can select them and set visibility attribute:

d3.select(g.selectAll(".tick")[0][0]).attr("visibility","hidden");

Alternatively, you can address any specific tick by its value d or index i

g.selectAll(".tick")
    .each(function (d, i) {
        if ( d == 0 ) {
            this.remove();
        }
    });

Be careful with .remove() though. Sometimes the first value is removed already and it removes the second value on update. Visibility hidden is more reliable.

credit to Ian & Denis at d3-js google group https://groups.google.com/forum/#!topic/d3-js/LBxR_finiME

Upvotes: 8

Lars Kotthoff
Lars Kotthoff

Reputation: 109232

The axis.tick* functions can help you there. You have a number of possibilities to prevent the behaviour you're describing. You could set the ticks explicitly using the tickValues() function. Or you could set the size of the end ticks to 0 using tickSize(). You can also control the underlying scale using the ticks() function.

Depending on your particular scenario, one of these options may make more sense than the others.

Upvotes: 21

Related Questions