gencay
gencay

Reputation: 609

d3js ticks positioning

I am trying to develop a timeline chart on d3.js. As you will see on the image below, I cannot position the triangles on the same orientation with the y-axis values. The milestones are positioned in the middle of the related y-axis component.

yaxis initiation code fragment:

    var x = d3.time.scale().rangeRound([0, self.config.width]);
    var y = d3.scale.ordinal().rangeRoundBands([self.config.height, 0]);

    var xAxis = d3.svg.axis().scale(x).orient("bottom").tickSubdivide(4).tickSize(6, 3, 0);//.ticks(d3.time.months,4)
    var yAxis = d3.svg.axis().scale(y).orient("left").tickSize(4);

appending y axis to svg:

svg.append("g")
          .attr("class", "y axis")
          .call(yAxis);

the code fragment for milestones:

var abs = svg.selectAll(".milestone")
          .data(data)
        .enter().append("g");

        abs.selectAll("symbol")
          .data(function(d) { 
            return d.milestoneList; 
          })
        .enter().append("svg:path")
          .attr("transform", function(d) { 
            return "translate(" + x(d.deadline) + "," + y(d.name) + ")"; 
          })
          .attr("d", d3.svg.symbol().type("triangle-down"));

For instance FG55 y-axis is set: translate(0,423) although the milestones from FG55 are set translate(<xValue for each>,376) so there are 47px difference on y

How can I position the yaxis labels and ticks properly?

chart

Upvotes: 4

Views: 2401

Answers (2)

Tom
Tom

Reputation: 2944

When using bands in D3 the scale will give you the location of the top of the band, rather than the centre. The scale also provides you with the width of the bands which you can use to calculate the y position where your point should be placed.

Therefore in the code above, you would change your transform to this:

.attr("transform", function(d) { 
  var yPosition = y(d.name) + y.bandwidth() / 2;
  return "translate(" + x(d.deadline) + "," + yPosition + ")"; 
})

Upvotes: 1

gencay
gencay

Reputation: 609

I modified my code as it follows:

Old code

var y = d3.scale.ordinal().rangeRoundBands([self.config.height, 0]); 

New Code

var y = d3.scale.ordinal().rangePoints([self.config.height, 0], 1.5);

Upvotes: 1

Related Questions