user1718064
user1718064

Reputation: 475

d3 interaction between xAxis and text

I have a problem that it is cause by the interaction of a g' axis element and a series oftext` elements. I am trying to build a graph with only a date x axis where squares are positioned along the correspondent date x coordinate but at the same y.

The code I am working on is the following:

var dataset = [

            {'startYear' : '2004-01-12',
            'label' : 'green'},
            {'startYear' : '2005-06-07',
            'label' : 'red'},
            {'startYear' : '2010-03-04',
            'label' : 'red'},
            {'startYear' : '2010-07-28',
            'label' : 'yellow'}

          ];

          var w = 750;
          var h = 500;
          var padding = 30;


          var svg = d3.select(element[0])
                      .append('svg')
                      .attr('width',w)
                      .attr('height',h);

          var xScale = d3.time.scale()
                        .domain([new Date('2004-01-01'),new Date('2014-12-31')])
                        .range([padding,w-padding*2]);

          var xAxis = d3.svg.axis()
                        .scale(xScale)
                        .orient('bottom')
                        .ticks(d3.time.years)
                        .tickFormat(d3.time.format('%Y'));


          var axisStyle = {'fill': 'none', 'stroke': 'black','shape-rendering': 'crispEdges','font-family':'sans-serif','font-size': '11px'};

          svg.append('g')
                .style(axisStyle)
                .attr('transform', 'translate(0,' + (h - padding) + ')')
                .attr('text-anchor', 'end')
                .call(xAxis);

          svg.selectAll('rect')
             .data(dataset)
             .enter()
             .append('rect')
             .attr('x',function(d){return xScale(new Date(d.startYear));})
             .attr('y',h-padding*2.5)
             .attr('height',20)
             .attr('width',20)
             .attr('fill',function(d){return d.label;});

          svg.selectAll('text')
            .data(dataset)
            .enter()
            .append('text')
            .attr('x',0)
            .attr('y',30)
            .text('monkeys');

For some reasons the text elements are not rendered on the screen. When investigating the causes of the problem, I found out that commenting out the g element for the x axis is a solution but obviously I need to keep to xaxis. Why is this happening? And is there a solution around it?

Upvotes: 0

Views: 145

Answers (1)

Lars Kotthoff
Lars Kotthoff

Reputation: 109232

The problem is that you're adding the axes first. That means that by the time you run the code to add the labels, there are already text elements in the DOM. Therefore, svg.selectAll('text') selects them. Then D3 matches the data you pass to .data() to them and finds a match for each data item. Hence, the .enter() selection is empty.

To fix, assign a special class to these labels that allows you to distinguish them from the other text elements:

svg.selectAll('text.label')
        .data(dataset)
        .enter()
        .append('text')
        .attr("class", "label")
        .attr('x',0)
        .attr('y',30)
        .text('monkeys');

Upvotes: 1

Related Questions