2014-12-11 4 views
0

Я разрабатываю гистограмму d3.js, интегрирующую с угловыми Js. Код приведен ниже.Ошибка рендеринга в графе d3.js

mainApp.directive('ngTest', function() { 
return { 
    restrict: 'AE', 
    scope: { 
     data: '=' 
      }, 
    link: function (scope, element) { 

     var margin = {top: 20, right: 30, bottom: 30, left: 60}, 
     width = 410 - margin.left - margin.right, 
     height = 230 - margin.top - margin.bottom; 

     var chart = d3.select(element[0]) 
        .append("svg") 
        .attr("width", width + margin.left + margin.right) 
        .attr("height", height + margin.top + margin.bottom) 
        .append("g") 
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

     var x = d3.scale.ordinal().rangeRoundBands([0, width], .1); 

     var tip = d3.tip() 
        .attr('class', 'd3-tip') 
        .offset([-10, 0]) 
        .html(function(d) { 
         return "<strong>Frequency:</strong> <span style='color:red'>" + d.value + "</span>"; 
         }); 

     chart.call(tip); 

     //Render graph based on 'data' 
     scope.render = function(data) { 

      var y = d3.scale.linear() 
        .range([height, 0]) 
        .domain(d3.extent(data, function(d) { return d.value; })) 
        .nice(); 

      var xAxis = d3.svg.axis().scale(x).orient("bottom"); 

      var yAxis = d3.svg.axis().scale(y).orient("left"); 

      x.domain(data.map(function(d) { return d.name; })); 

      //Redraw the axes 
      chart.selectAll('g.axis').remove(); 

      chart.append("g") 
       .attr("class", "x axis") 
       .attr("transform", "translate(0," + (height) + ")") 
       .call(xAxis) 
       .selectAll("text") 
       .style("text-anchor", "end") 
       .attr("dx", "-.8em") 
       .attr("dy", ".15em") 
       .attr("transform", function(d) { 
        return "rotate(-20)"; 
        }); 

      chart.append("g") 
       .attr("class", "y axis") 
       .call(yAxis) 
       .append("text") 
       .attr("transform", "rotate(-90)") 
       .attr("y", 0-margin.left) 
       .attr("x",0-(height/2)) 
       .attr("dy", "1em") 
       .style("text-anchor", "middle") 
       .text("Value"); 

      chart.selectAll(".bar") 
        .data(data) 
        .enter().append("rect") 
        .attr("class", function(d) { return d.value < 0 ? "bar negative" : "bar positive"; })  
        .attr("x", function(d) { return x(d.name); })     
        .attr("y", height) 
        .attr("height", 0) 
        .on('mouseover', tip.show) 
        .on('mouseout', tip.hide) 
        .transition().duration(2000) 
        .attr("y", function(d) {return y(Math.max(0, d.value)); }) 
        .attr("height", function(d) {return Math.abs(y(d.value) - y(0)); })  
        // .attr("width", x.rangeBand()); 
        .attr("width", Math.min.apply(null, [x.rangeBand()-2, 100])); 
      }; 

     scope.$watch('data', function() { 
      scope.render(scope.data); 
      }, true); 

    } 
    }; 
}); 

Полное приложение загружается в скрипку в следующем адрес

http://jsfiddle.net/HB7LU/9060/

У меня есть 3 наборов данных, которые приведены ниже.

$scope.myData = [ 
     {name: "01-12-2014", value: 4984.6}, 
     {name: "02-12-2014", value: -109.45}, 
     {name: "03-12-2014", value: 474}, 
     {name: "04-12-2014", value: 391.07}, 
     {name: "05-12-2014", value: 106.82}, 
     {name: "06-12-2014",  value: -5}, 
     {name: "07-12-2014", value: 30}, 
     {name: "08-12-2014", value: 9} 
           ]; 

$scope.myData = [ 
    {name: "01-12-2014", value: 474}, 
    {name: "02-12-2014", value: 391.07}, 
    {name: "03-12-2014", value: 106.82}, 
    {name: "08-12-2014", value: 9} 
          ] 

График ведет себя нормально при применении над наборами данных.

Но граф себя ubnormally для следующего набора данных, которые включают в себя дополнительным один сырой менее 2 последнего наборе данных

$scope.myData2 = [ 
    {name: "01-12-2014", value: 474}, 
    {name: "02-12-2014", value: 391.07}, 
    {name: "03-12-2014", value: 106.82} 
          ]; 

Поскольку я новичок в d3.js я не могу определить точную проблему. Если какой-либо один знаю, пожалуйста, помогите мне

ответ

0

Ваш вопрос проистекает из того, как вы определяете высоту баров:

.attr("height", function(d) {return Math.abs(y(d.value) - y(0)); })  

Здесь вы устанавливаете высоту как разность между г-значение точки данных и у-значение в 0. Однако, ваш у-шкала начинается с минимального значения в наборе данных:

var y = d3.scale.linear() 
     .range([height, 0]) 
     .domain(d3.extent(data, function(d) { return d.value; })) 
     .nice(); 

в результате y(0) иногда может быть отрицательным. Вы просто не заметили это с двумя другими наборами данных, потому что их минимальные значения близки к 0. Вот как бы я установить высоту:

.attr("height", function(d) {return Math.abs(y(d.value) - y(d3.min(y.domain()))) })  

См updated fiddle и сюжет ниже.

enter image description here

+0

Это не верно для других наборов данных – Pramil

+0

Мне очень жаль, что это не верно и для других наборов данных? – mdml

+0

Есть некоторые несоответствия данных на графике. Если вы проверяете с помощью первых наборов данных, вы можете это понять – Pramil

Смежные вопросы