如何在d3条形图中制作y尺度动态?

时间:2015-11-16 12:40:41

标签: javascript d3.js

我很难在d3条形图中管理Y-Scale。 我想根据数据使y尺度动态,但不要超过积分[ticks]多于4个正数,4个负数和1个零线[总数9]。现在,在我的小提琴中,滴答声的值随着数据不断变化。有时它的情节2滴答或某个时间4.

Here is my fiddle

var data = [["Since Mar 10, 2015",6], ["1 year",2], ["3 year",-10], ["Since Mar 10, 2010",1]];

d3.select("#example")
  .datum(data)
  .call(columnChart()
    .width(320)
    .height(240)
    .x(function(d, i) { return d[0]; })
    .y(function(d, i) { return d[1]; }));
  function columnChart() {
    var margin = {top: 30, right: 10, bottom: 50, left: 50},
    width = 20,
    height = 20,
    xRoundBands = 0.6,
    xValue = function(d) { return d[0]; },
    yValue = function(d) { return d[1]; },
    xScale = d3.scale.ordinal(),
    yScale = d3.scale.linear(),
    yAxis = d3.svg.axis().scale(yScale).orient("left"),
    xAxis = d3.svg.axis().scale(xScale);
    var isNegative = false;    

  function chart(selection) {
    selection.each(function(data) {

    // Convert data to standard representation greedily;
    // this is needed for nondeterministic accessors.
  for(var i=0; i< data.length; i++){
     if(data[i][1] < 0){
       isNegative = true;
    }
  }  

  data = data.map(function(d, i) {
    return [xValue.call(data, d, i), yValue.call(data, d, i)];
  });

  // Update the x-scale.
  xScale
      .domain(data.map(function(d) { return d[0];} ))
      .rangeRoundBands([0, width - margin.left - margin.right], xRoundBands);

    var min = d3.min(data, function(d) { return d[1]; });
    var max = d3.max(data, function(d) { return d[1]; });
   // alert(min);

    yScale.domain([d3.min(data, function(d) { return d[1]; }), d3.max(data, function(d) { return d[1]; })])
          .range([height - margin.top - margin.bottom, 0])
          .nice();         

    // All Positive
    if(min > 0) { 
        yScale.domain([0, max]);
    } else if(max < 0) {
        yScale.domain([min, 0]);   
    }

    // Select the svg element, if it exists.
  var svg = d3.select(this).selectAll("svg").data([data]);

  // Otherwise, create the skeletal chart.
  var gEnter = svg.enter().append("svg").append("g");

  gEnter.append("g").attr("class", "y axis");
  gEnter.append("g").attr("class", "x axis");
  gEnter.append("g").attr("class", "x axis zero");

  // Update the outer dimensions.
  svg .attr("width", width)
      .attr("height", height);

  // Update the inner dimensions.
  var g = svg.select("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    // Update the y-axis.
     g.select(".y.axis")
        .call(yAxis.tickSize(0).ticks(5))
        .selectAll("g")
        .selectAll("text")
        .text(function(d){
            return d+"%";
        });

    g.append("g")
        .selectAll("line.line")
        .data(yScale.ticks(5))
        .enter()
        .append("line")
         .attr(
            {
                "class":"line grid tick",
                "x1" : 0,
                "x2" : ( width - 60 ),
                "y1" : function(d){ return yScale(d);},
                "y2" : function(d){ return yScale(d);},
            });
  gEnter.append("g").attr("class", "bars");

  // Update the bars.
  var bar = g.select(".bars")
  .selectAll(".bar")
  .data(data);

  bar.enter().append("rect");
  bar.exit().remove();
  bar .attr("class", function(d, i) { return d[1] < 0 ? "bar negative" : "bar positive"; })
      .attr("x", function(d) { return X(d); })
      .attr("y", function(d, i) { return d[1] < 0 ? Y0() : Y(d); })
      .attr("width", xScale.rangeBand())
      .attr("height", function(d, i) { return Math.abs( Y(d) - Y0() ); });

// x axis at the bottom of the chart
if( isNegative === true ){
   var xScaleHeight = height - margin.top - margin.bottom+12;
}else{
    var xScaleHeight = height - margin.top - margin.bottom;
}        
 g.select(".x.axis")
    .attr("transform", "translate(0," + ( xScaleHeight ) + ")")
    .call(xAxis.orient("bottom"))
    .selectAll("text")
    .call(wrap, xScale.rangeBand());

// zero line
 g.select(".x.axis.zero")
    .attr("transform", "translate(0," + Y0() + ")")
    .attr("class", "zero axis")
    .call(xAxis.tickFormat("").tickSize(0));


   // Update the text in bars.
   var bar1 = svg.select(".bars").selectAll("text").data(data);

   bar1 .data(data)
       .enter()
       .append("text")
       .attr("class", "text")
       .text(function(d) { return d[1]+"%"; })
       .attr("x", function(d) { return X(d); })
       .attr("y", function(d, i) { return d[1] < 0 ? Math.abs(Y(d)+10) :         Y(d)-2; });
    });
 }

  // Custom function for text wrap
     function wrap(text, width) {
       text.each(function() {
       var text = d3.select(this),
       words = text.text().split(/\s+/).reverse(),
       word,
       line = [],
       lineNumber = 0,
       lineHeight = 1, // ems
       y = text.attr("y"),
       dy = parseFloat(text.attr("dy")),
       tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
    while (word = words.pop()) {
      line.push(word);
      tspan.text(line.join(" "));
      if (tspan.node().getComputedTextLength() > 55) {
       line.pop();
       tspan.text(line.join(" "));
       line = [word];
    tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
  }
   }
 });
}


 // The x-accessor for the path generator; xScale ∘ xValue.
 function X(d) {
   return xScale(d[0]);
 }

 function Y0() {
  return yScale(0);
 }

 // The x-accessor for the path generator; yScale ∘ yValue.
 function Y(d) {
  return yScale(d[1]);
 }

 chart.margin = function(_) {
  if (!arguments.length) return margin;
  margin = _;
  return chart;
};

 chart.width = function(_) {
  if (!arguments.length) return width;
  width = _;
  return chart;
 };

  chart.height = function(_) {
   if (!arguments.length) return height;
    height = _;
    return chart;
  };

  chart.x = function(_) {
    if (!arguments.length) return xValue;
     xValue = _;
    return chart;
  };

  chart.y = function(_) {
    if (!arguments.length) return yValue;
     yValue = _;
     return chart;
   };

  return chart;
 }

提前致谢:)

0 个答案:

没有答案