D3 y轴百分比显示 [英] D3 y-axis percent display

查看:122
本文介绍了D3 y轴百分比显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

D3小提琴

/**
* A bar chart. Required data format:
* [ { name : x-axis-bar-label, value : N }, ...]
*
*  Sample use:
*  var bargraph = d3.select('#bargraph')
*    .append('svg')
*    .chart('BarChart')
*    .yFormat(d3.format("d"))
*    .height(400)
*    .width(800)
*    .max(1.0);
*  bargraph.draw(bardata);
*/
d3.chart('BarChart', {

  initialize: function() {
    var chart = this;

    // chart margins to account for labels.
    // we may want to have setters for this.
    // not sure how necessary that is tbh.
    chart.margins = {
      top : 10,
      bottom : 15,
      left : 50,
      right : 0,
      padding : 10
    };

    // default chart ranges
    chart.x =  d3.scale.linear();
    chart.y = d3.scale.linear();

    chart.base
      .classed('Barchart', true);

    // non data driven areas (as in not to be independatly drawn)
    chart.areas = {};

    // cache for selections that are layer bases.
    chart.layers = {};

    // make sections for labels and main area
    //  _________________
    // |Y|    bars      |
    // | |              |
    // | |              |
    // | |              |
    // | |______________|
    //   |      X       |

    // -- areas
    chart.areas.ylabels = chart.base.append('g')
      .classed('ylabels', true)
      .attr('width', chart.margins.left)
      .attr('transform',
        'translate('+(chart.margins.left-1)+','+(chart.margins.top + 1)+')');

    // -- actual layers
    chart.layers.bars = chart.base.append('g')
      .classed('bars', true)
      .attr('transform',
        'translate(' + chart.margins.left + ',' + (chart.margins.top + 1)+')');

    chart.layers.xlabels = chart.base.append('g')
      .classed('xlabels', true)
      .attr('height', chart.margins.bottom);

    chart.on("change:width", function() {
      chart.x.range([0, chart.w - chart.margins.left]);
      chart.layers.bars.attr('width', chart.w - chart.margins.left);
      chart.layers.xlabels.attr('width', chart.w - chart.margins.left);
    });

    chart.on("change:height", function() {
      chart.y.range([chart.h - chart.margins.bottom - chart.margins.top, 0]);
      chart.areas.ylabels
        .attr('height', chart.h - chart.margins.bottom - chart.margins.top - 1);
      chart.layers.bars
        .attr('height', chart.h - chart.margins.bottom - chart.margins.top);
      chart.layers.xlabels
        .attr('transform', 'translate(' + chart.margins.left + ',' +
        (chart.h - chart.margins.bottom + 1) + ')');
    });

    // make actual layers
    chart.layer('bars', chart.layers.bars, {
      // data format:
      // [ { name : x-axis-bar-label, value : N }, ...]
      dataBind : function(data) {

        chart.data = data;

        // how many bars?
        chart.bars = data.length;

        // compute box size
        chart.bar_width = (chart.w - chart.margins.left - ((chart.bars - 1) *
          chart.margins.padding)) / chart.bars;

        // adjust the x domain - the number of bars.
        chart.x.domain([0, chart.bars]);

        // adjust the y domain - find the max in the data.
        chart.datamax = chart.usermax ||
          d3.extent(data, function(d) { return d.value; })[1];

        chart.y.domain([0, chart.datamax]);

        // draw yaxis
        var yAxis = d3.svg.axis()
          .scale(chart.y)
          .orient('left')
          .ticks(5)
          .tickFormat(chart._yformat || d3.format('.0%'));

        chart.areas.ylabels
          .call(yAxis);

        return this.selectAll('rect')
          .data(data, function(d) { 
            //console.log(d);
            return d.name; 
          });
      },
      insert : function() {
        return this.append('rect')
          .classed('bar', true)
          .classed('highlight', function(d) {
            return d.highlight;
          });
      },

      events: {
        exit: function() {
          this.remove();
        }
      }
    });

    // a layer for the x text labels.
    chart.layer('xlabels', chart.layers.xlabels, {
      dataBind : function(data) {
        // first append a line to the top.
        this.append('line')
          .attr('x1', 0)
          .attr('x2', chart.w - chart.margins.left)
          .attr('y1', 0)
          .attr('y2', 0)
          .style('stroke', '#222')
          .style('stroke-width', '1')
          .style('shape-rendering', 'crispEdges');


        return this.selectAll('text')
          .data(data, function(d) { return d.name; });
      },
      insert : function() {
        return this.append('text')
          .classed('label', true)
          .attr('text-anchor', 'middle')
          .attr('x', function(d, i) {
            return chart.x(i) - 0.5 + chart.bar_width/2;
          })
          .attr('dy', '1em')
          .text(function(d) {
            return d.name;
          });
      },
      events: {
        exit: function() {
          this.remove();
        }
      }
    });

    // on new/update data
    // render the bars.
    var onEnter = function() {
      this.attr('x', function(d, i) {
            return chart.x(i) - 0.5;
          })
          .attr('y', function(d) {
            return chart.h - chart.margins.bottom -
              chart.margins.top - chart.y(chart.datamax - d.value) - 0.5;
          })
          .attr('val', function(d) {
            return d.value;
          })
          .attr('width', chart.bar_width)
          .attr('height', function(d) {
            return chart.y(chart.datamax - d.value);
          });
    };

    chart.layer('bars').on('enter', onEnter);
    chart.layer('bars').on('update', onEnter);
  },

  // return or set the max of the data. otherwise
  // it will use the data max.
  max : function(datamax) {
    if (!arguments.length) {
      return this.usermax;
    }

    this.usermax = datamax;

    if (this.data) this.draw(this.data);

    return this;
  },

  yFormat: function(format) {
    if (!arguments.length) {
      return this._yformat;
    }
    this._yformat = format;
    return this;
  },

  width : function(newWidth) {
    if (!arguments.length) {
      return this.w;
    }
    // save new width
    this.w = newWidth;

    // adjust the x scale range
    this.x.range([this.margins.left, this.w - this.margins.right]);

    // adjust the base width
    this.base.attr('width', this.w);

    this.trigger("change:width");
    if (this.data) this.draw(this.data);

    return this;
  },

  height : function(newHeight) {
    if (!arguments.length) {
      return this.h;
    }

    // save new height
    this.h = newHeight;

    // adjust the y scale
    this.y.range([this.h - this.margins.top, this.margins.bottom]);

    // adjust the base width
    this.base.attr('height', this.h);

    this.trigger("change:height");
    if (this.data) this.draw(this.data);
    return this;
  }
});

var barchart = d3.select('#vis')
  .append('svg')
  .chart('BarChart') //**Moving transform position out of here**
  .yFormat(d3.format("d"))
  .height(400)
  .width(800);

var data = [
  { month : 'January', temperature : 29 },
  { month : 'February', temperature : 32 },
  { month : 'March', temperature : 48 },
  { month : 'April', temperature : 49 },
  { month : 'May', temperature : 58 },
  { month : 'June', temperature : 68 },
  { month : 'July', temperature : 74 },
  { month : 'August', temperature : 73 },
  { month : 'September', temperature : 65 },
  { month : 'October', temperature : 54 },
  { month : 'November', temperature : 45 },
  { month : 'December', temperature : 35 }
];

//**Moving transform function out of barchart definition
//so it is called only once and not everytime 
//the chart is redrawn**

function transform(data) {
    return data.map(function(d) {
        return { name : d.month, value : d.temperature };
    });
}


barchart.draw(transform(data));

在这个小提琴中,我试图以百分比显示y轴值.不完全根据数据计算百分比,而只是将%"符号附加到现有数据上.我正在通过实际代码中的数组获取数据,它是动态的.我尝试使用刻度格式追加,但似乎不起作用.有帮助吗?

In this fiddle, I am trying to display the y-axis values in percentages. Not exactly calculating the percentage from the data, but just appending the "%" sign to the existing data. I am fetching the data through an array in the actual code, it is dynamic. I have tried appending using tick format but somehow it doesn't seem to work. Any help?

推荐答案

执行此操作可将%附加到y勾上:

Do this to append % to the y tick:

var yAxis = d3.svg.axis()
  .scale(chart.y)
  .orient('left')
  .ticks(5)

  .tickFormat(function(d){return d+ "%"});

工作代码此处

这篇关于D3 y轴百分比显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆