title: Set a minimum height on bars in D3 graph
body: <p>I think this should be fairly simple, but I'm new to D3 and don't know where to start. I'd like to set a minumum height to the bars in my bargraph so that even bars with a value of 0 are still visible. </p>
  
  <p>I'd also like this to be accurately represented by the Y axis (ideally by adding a buffer between the X axis and the start of 0 on the Y axis).</p>
  
  <p>Is there a simple way to do this with a dynamic bar graph? The range on the Y axis could range from having a max of 2 to a max of 50,000, but I still want every bar to have height of some sort. </p>
  
  <p>I apologize for the length of this:</p>
  
  <pre><code>link: function(scope, iElement, iAttrs) {
      var scope = scope;
      var chart = '';
      var margin = {top: 20, right: 100, bottom: 30, left: 40},
          width = 960 - margin.left - margin.right,
          height = 500 - margin.top - margin.bottom;
      scope.postdetails = false;
  
      var x = d3.scale.ordinal()
          .rangeRoundBands([0, width], .1);
  
      var y = d3.scale.linear()
          .range([height, 0]);
  
      var yAxis = d3.svg.axis()
          .scale(y)
          .orient("left")
          .ticks(5, "");
  
      var abbrevNum = function (d) {
          var prefix = d3.formatPrefix(d);
          return d3.round(prefix.scale(d),1) + prefix.symbol;
      };
      var initChart = function(){
          $('.main-report-chart').remove();
          x = null;
          y = null;
          x = d3.scale.ordinal()
              .rangeRoundBands([0, width], .1);
          y = d3.scale.linear()
              .range([height, 0]);
          yAxis = d3.svg.axis()
              .tickFormat(function(d) { return abbrevNum(d); })
              .scale(y)
              .orient("left")
              .ticks(5, "");
          chart = d3.select(iElement[0]).append("svg")
              .attr("width", width + margin.left + margin.right)
              .attr("height", height + margin.top + margin.bottom)
              .attr('class','main-report-chart')
              .append("g")
              .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
      };
      var getMean = function(data){
          var meanData = d3.mean(data,function(d){return eval('d.'+scope.metric)});
          var meanArray = [];
          meanArray.push(meanData);
  
          return meanArray;
      };
      var watchCount = 0;
      var svg='';
      var newData = {}
      scope.$watch('reportData', function(newVals, oldVals) {
  
          if(newVals === oldVals &amp;&amp; newVals !== undefined){
              watchCount++;
              initChart();
              newData = newVals;
              return scope.render(newVals);
          }
          if(watchCount==2){
              if(newVals){
                  initChart();
                  newData = newVals;
                  return scope.render(newVals);
              }
          } else{
              if(newVals){
                  initChart();
                  newData = newVals;
                  return scope.render(newVals);
              }
          }
      }, true);
      var tempValues = {};
  
      scope.$watch('metric', function(newVals, oldVals) {
          if(newVals){
              if(scope.reportData){
                  // where redraw happens:
                  return scope.render(newData);
              }
          }
      }, false);
  
      scope.render = function(data){
          if (scope.metric !== "") {
              x.domain(data.map(function(d) { return d.id; }));
              y.domain([0, d3.max(data, function(d) { return eval('d.' + scope.metric); })]);
              chart.select(".x.axis").remove();
              chart
                  .append("g")
                  .append("line")
                  .attr('x1',0)
                  .attr('x2',width)
                  .attr('y1',height )
                  .attr('y2',height)
                  .attr('stroke-width','2')
                  .attr("class", "domain");
  
              chart.select(".y.axis").remove();
              chart.append("g")
                  .attr("class", "y axis")
                  .call(yAxis)
                  .append("text")
                  .attr("transform", "rotate(-90)")
                  .attr("y", -40)
                  .attr('class','label')
                  .attr("x", -height)
                  .attr("dy", ".71em")
                  .style("text-anchor", "begin")
                  .text(scope.label);
  
              var bar = chart.selectAll(".bar")
                  .data(data, function(d) { return d.id; });
  
              // new data:
              bar.enter()
                  .append("g")
                  .attr("class", "bar-container")
                  .append("rect")
                  .attr("class", "bar")
                  .attr('fill','#4EC7BD')
                  .attr("x", function(d) { return x(d.id); })
                  .attr("y", function(d) { return y(eval('d.'+scope.metric)); })
                  .attr("height", function(d) { return height - y(eval('d.'+scope.metric)); })
                  .attr("width", x.rangeBand())
                  .on('click', function(d){
                      scope.showDetails(d, eval('d.'+scope.metric))
                  });
              bar.exit().remove();
              bar
                  .transition()
                  .duration(750)
                  .attr("y", function(d) { return y(eval('d.'+scope.metric)); })
                  .attr("height", function(d) { return height - y(eval('d.'+scope.metric)); });
  
              var labeltip = chart.selectAll('.tip')
                  .data(data, function(d) { return d.id; });
  
              var meanData = getMean(data);
              var average = chart.selectAll(".average")
                  .data(meanData);
  
              average.enter()
                  .append("line")
                  .attr("class", "average")
                  .attr('stroke-width','2')
                  .attr('stroke','#3D3F49')
                  .attr('x1',0)
                  .attr('x2',width)
                  .attr('y1',y(meanData))
                  .attr('y2',y(meanData));
  
              average.exit().remove();
  
              average.transition()
                  .duration(750)
                  .attr('y1',y(meanData))
                  .attr('y2',y(meanData));
  
              var avgbox = chart.selectAll(".avg-box")
                  .data(meanData);
  
              avgbox.enter().append("rect")
                  .attr('class','avg-box')
                  .attr('width',75)
                  .attr('height',20)
                  .attr('fill','#3D3F49')
                  .attr('x',width )
                  .attr('rx',5)
                  .attr('y',y(meanData)-10);
  
              var avgtext = chart.selectAll(".avg-text")
                  .data(meanData);
  
              avgtext.enter().append('text')
                  .text('AVG '+ abbrevNum(Math.round(meanData)))
                  .attr('x',width +8)
                  .attr('class','avg-text')
                  .attr('y',y(meanData+15))
                  .attr('fill','white');
  
              avgbox.exit().remove();
  
              avgbox.transition()
                  .duration(750)
              .attr('y',y(meanData)-10);
  
              avgtext.exit().remove();
              avgtext.transition()
                  .duration(750)
                  .text('AVG '+ abbrevNum(Math.round(meanData)))
                  .attr('y',y(meanData)+4);
          }
      };
  }
  </code></pre>