Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom tick size on axis (d3js)

I am creating a svg x-y-chart in d3.js. Is it possible to create ticks of different lengths depending on tickValue?

I have made my own tickFormat function myTickFormat and use that in .tickFormat([format]) and that works fine because [format] is expected to be a function. But it is not possible to do the same with .innerTickSize([size]), which expects a number.

E.g. if I want the tick at value 70 to be longer I want to do something like this:

var myTickSize = function(d) {
    if (d === 70) { return 20;}
    return 6;
};

But when I use myTickSize as argument to .innerTickSize():

var yScale = d3.scale.linear();
var yAxis = d3.svg.axis()
               .scale(yScale).orient("left")
               .innerTickSize(myTickSize);

I get an Error: Invalid value for attribute x2="NaN" error for each tick.

like image 414
swenedo Avatar asked Feb 05 '14 16:02

swenedo


People also ask

What is tick size in D3?

tickSize() function in D3. js is used to set the inner and outer tick size to the specified value and returns the axis. If size is not specified, returns the current inner tick size, which defaults to 6.

What is D3 js axis component?

Advertisements. D3 provides functions to draw axes. An axis is made of Lines, Ticks and Labels. An axis uses a Scale, so each axis will need to be given a scale to work with.

What is D3 range?

D3 creates a function myScale which accepts input between 0 and 10 (the domain) and maps it to output between 0 and 600 (the range).

What is D3 extent?

extent() function in D3. js is used to returns the minimum and maximum value in an array from the given array using natural order. If an array is empty then it returns undefined, undefined as output.


1 Answers

The tickSize function can only accept a number as argument, not a function, but there are other solutions.

The easiest approach? After the axis is drawn, select all the tick lines and resize them according to their data value. Just remember that you'll have to do this after every axis redraw, as well.

Example:
https://jsfiddle.net/zUj3E/1/

Key code:

d3.selectAll("g.y.axis g.tick line")
    .attr("x2", function(d){
    //d for the tick line is the value
    //of that tick 
    //(a number between 0 and 1, in this case)
       if ( (10*d)%2 ) //if it's an even multiple of 10%
           return 10;
       else
           return 4;
    });

Note that the tick marks at the max and min values are also drawn as part of the same <path> as the axis line, so shortening them doesn't have much effect. If you don't like that lack of control, declare the "outer" ticks to have zero length when you set up the axis. That turns off the corners of the path, but the outer ticks will still have lines that you can control the same as the other tick lines:

var axis = d3.svg.axis()
    .tickSize(10,0)

Example: https://jsfiddle.net/zUj3E/2/

If that doesn't work, google for examples of major/minor tick patterns. Just make sure the example you're looking at uses d3 version 3: there were a few extra tick-related methods added in version 2 that are no longer supported. See this SO Q&A.

like image 84
AmeliaBR Avatar answered Sep 30 '22 06:09

AmeliaBR