admin管理员组

文章数量:1418342

Very slowly I'm learning how to use D3, but already on one of my first charts I can't figure out why the x-axis is located at the top instead of the bottom. I've set orient('bottom') and translated by the left and top margin and it is positioned properly with respect to the translation, but it appears at the top of the bar chart. Can anyone see what the issue is? The code appears to look similar to a bunch of examples, so I'm not sure why it isn't working properly.

   // Ordinal scale to transform data to fit width of the chart
   // -- NOTE: ordinal is equivalent to an ordered list
   xScale = d3.scale.ordinal()
              .domain(d3.range(0, data.length))
              .rangeBands([0, config.width],
                          config.rangeBandPadding,
                          config.rangeBandOuterPadding);

   // Quantitative linear scale to transform data to fit height of the chart
   // -- NOTE: quantitative is equivalent to an unordered list
   yScale = d3.scale.linear()
              .domain([0, d3.max(data)])
              .range([0, config.height]);

   // Create the <svg> canvas with chart group
   svg = D3Service.getSvgCanvas($element[0],
                                config.outerWidth,
                                config.outerHeight,
                                config.margin)

   // Add data bars to the chart and remap to scale to fit chart dimensions
   // -- NOTE: Select all rects (that don't exist yet), bind the data to the selection, append
   // the bound selections within a chart group and apply scaled dimensions, and finally add
   // events to capture user interactions with the chart and transitions to animate the chart
   svg.selectAll('rect')
      .data(data)
      .enter()
      .append('rect')
      .attr('width', xScale.rangeBand())
      .attr('height', 0) // initialized to zero to allow for translation
      .attr('x', function (d, i) {
          return xScale(i);
      })
      .attr('y', config.height) // why???

      // Bind events to the chart
      .on('mouseover', function (d) {

      })
      .on('mouseout', function (d) {

      })
      .on('click', function (d) {

      });

   // Perform transitions on data bars as they are added to the chart
   svg.selectAll('rect')
      .transition()
      .attr('y', function (d) {
          return config.height - yScale(d);
      })
      .attr('height', function (d) {
          return yScale(d);
      })
      .delay(function (d, i) {
          return i * config.transitionDelayFactor;
      })
      .duration(500)
      .ease('bounce');


   // Uses range of xScale domain and filters the data bars to figure who to add a tick to
   // does a number have a zero remainder and get a number every 5th bar

   // From the range of
   xAxis = d3.svg.axis()
             .scale(xScale)
             .orient('bottom')
             .ticks(data.length);

   xGuide = d3.select('svg')
              .append('g')
              .attr('class', 'axes x-axis')
              .call(xAxis)
              .attr('transform',
                    D3Service.getTranslation(config.margin.left, config.margin.top));

   yGuideScale = d3.scale.linear().domain([0, d3.max(data)])
                   .range([config.height, 0]);

   yAxis = d3.svg.axis().scale(yGuideScale)
             .orient('left').ticks(10)

   yGuide = d3.select('svg')
              .append('g')
              .attr('class', 'axes y-axis')
              .call(yAxis)
              .attr('transform',
                    D3Service.getTranslation(config.margin.top, config.margin.left));

Very slowly I'm learning how to use D3, but already on one of my first charts I can't figure out why the x-axis is located at the top instead of the bottom. I've set orient('bottom') and translated by the left and top margin and it is positioned properly with respect to the translation, but it appears at the top of the bar chart. Can anyone see what the issue is? The code appears to look similar to a bunch of examples, so I'm not sure why it isn't working properly.

   // Ordinal scale to transform data to fit width of the chart
   // -- NOTE: ordinal is equivalent to an ordered list
   xScale = d3.scale.ordinal()
              .domain(d3.range(0, data.length))
              .rangeBands([0, config.width],
                          config.rangeBandPadding,
                          config.rangeBandOuterPadding);

   // Quantitative linear scale to transform data to fit height of the chart
   // -- NOTE: quantitative is equivalent to an unordered list
   yScale = d3.scale.linear()
              .domain([0, d3.max(data)])
              .range([0, config.height]);

   // Create the <svg> canvas with chart group
   svg = D3Service.getSvgCanvas($element[0],
                                config.outerWidth,
                                config.outerHeight,
                                config.margin)

   // Add data bars to the chart and remap to scale to fit chart dimensions
   // -- NOTE: Select all rects (that don't exist yet), bind the data to the selection, append
   // the bound selections within a chart group and apply scaled dimensions, and finally add
   // events to capture user interactions with the chart and transitions to animate the chart
   svg.selectAll('rect')
      .data(data)
      .enter()
      .append('rect')
      .attr('width', xScale.rangeBand())
      .attr('height', 0) // initialized to zero to allow for translation
      .attr('x', function (d, i) {
          return xScale(i);
      })
      .attr('y', config.height) // why???

      // Bind events to the chart
      .on('mouseover', function (d) {

      })
      .on('mouseout', function (d) {

      })
      .on('click', function (d) {

      });

   // Perform transitions on data bars as they are added to the chart
   svg.selectAll('rect')
      .transition()
      .attr('y', function (d) {
          return config.height - yScale(d);
      })
      .attr('height', function (d) {
          return yScale(d);
      })
      .delay(function (d, i) {
          return i * config.transitionDelayFactor;
      })
      .duration(500)
      .ease('bounce');


   // Uses range of xScale domain and filters the data bars to figure who to add a tick to
   // does a number have a zero remainder and get a number every 5th bar

   // From the range of
   xAxis = d3.svg.axis()
             .scale(xScale)
             .orient('bottom')
             .ticks(data.length);

   xGuide = d3.select('svg')
              .append('g')
              .attr('class', 'axes x-axis')
              .call(xAxis)
              .attr('transform',
                    D3Service.getTranslation(config.margin.left, config.margin.top));

   yGuideScale = d3.scale.linear().domain([0, d3.max(data)])
                   .range([config.height, 0]);

   yAxis = d3.svg.axis().scale(yGuideScale)
             .orient('left').ticks(10)

   yGuide = d3.select('svg')
              .append('g')
              .attr('class', 'axes y-axis')
              .call(yAxis)
              .attr('transform',
                    D3Service.getTranslation(config.margin.top, config.margin.left));
Share Improve this question asked Dec 2, 2015 at 10:56 mtpultzmtpultz 18.4k24 gold badges127 silver badges210 bronze badges 2
  • 1 Why are you transitioning to config.margin.top instead of config.height - config.margin.bottom while positioning xGuide? – musically_ut Commented Dec 2, 2015 at 11:00
  • Hi @musically_ut thanks nice catch, it turned out to be: config.height + config.margin.top to jump it to the bottom not config.height - config.margin.bottom – mtpultz Commented Dec 2, 2015 at 19:24
Add a ment  | 

1 Answer 1

Reset to default 5

At first glance, when looking at your code, I would say it is because you did not position the "g" element which contains your x-axis. So you select your svg element, then you add a "g" element in your svg but on top of your chart and then you add your axis, and then you perform what looks like a translation on your axis, which is contained by the g element.

You need to translate the g element to the bottom of your chart:

.append("g")
  .attr("transform", "translate(0, height-offset)")
  .(rest of your code)

If I remember correctly, new svg elements overlap previous elements, starting from the svg origin, which is the left upper corner. Since your translate function probably did something to the axis itself (call(xAxis) returns your axis element I think, hence the translate function applies to the axis element), but not to the grouping element, I would assume that is the reason why the "g" element just stays at the upper left corner.

EDIT

the orient function of your axis defines where your text will be placed in relation to your axis line. More information can be found here

I hope that makes sense :-).

本文标签: javascriptD3 XAxis Doesn39t Appear At BottomStack Overflow