balazs
balazs

Reputation: 520

position tick to overlap axis in d3

How do I achieve the following effect for an axis in d3.js, wherein the tick mark actually intersects the axis, and the tick mark and axis are different colors.

  |
 ---
  |
 ---     |      |      |      |      |
  |======|======|======|======|======|
         |      |      |      |      |

I can set the the stroke width of the tick, but I can't figure out how to position/offset it.

UPDATE: Lars's answer below is helpful for positioning the tick, but it doesn't allow me to have the tick overlap the axis because the path element comes after the tick marks, so it has a higher "z-index". So, the second part of the answer will require being able to shift the path element to the beginning of the containing g in the following listing:

<g class="x axis" transform="translate(0,55)">
    <g style="opacity: 1;" transform="translate(50,0)">
        <line class="tick" y2="-55" x2="0" transform="translate(0,5)"></line>
        <text y="3" x="0" dy="1.5em" text-anchor="middle" style="font-size: 10px;">1955</text>
    </g>
    <g style="opacity: 1;" transform="translate(112.5,0)">
        <line class="tick" y2="-55" x2="0" transform="translate(0,5)"></line>
        <text y="3" x="0" dy="1.5em" text-anchor="middle" style="font-size: 10px;">1960</text>
    </g>
    <g style="opacity: 1;" transform="translate(175,0)">
        <line class="tick" y2="-55" x2="0" transform="translate(0,5)"></line>
        <text y="3" x="0" dy="1.5em" text-anchor="middle" style="font-size: 10px;">1965</text>
    </g>
    <path class="domain" d="M0,-55V0H800V-55"></path>
</g>

Upvotes: 1

Views: 3066

Answers (1)

Lars Kotthoff
Lars Kotthoff

Reputation: 109232

The tick marks are assigned to the tick class. You can use this to differentiate between axis and ticks for setting the color if you set a class for the axis itself:

.axis { stroke: black; }
.tick { stroke: red; }

Similarly you can use this to translate the ticks. For example

xAxisElement.selectAll(".tick").attr("transform", "translate(0,-5)");

You can then use .sort() and .order() to select the g element containing the axis, sort them such that the axis line comes last and reorder the elements in the document accordingly. The code would look something like

d3.selectAll("axis *").sort(function(a,b) {
    if(a.nodeName == "path") { return -1; }
    else if(b.nodeName == "path") { return 1; }
    return 0;
}).order();

Upvotes: 2

Related Questions