D3.js错误:折线图的{path>属性值无效

时间:2015-10-05 12:19:06

标签: javascript angularjs d3.js

我正在使用d3.js qith angular JS,在显示x轴标签时遇到错误(例如:jan.feb,mar等...) 我正在读一个json文件: 样本数据 : [     {         "月":0,         " total_cars":65     等......, ]

并转换月份数" 0"进入月份" Jan"使用d3.time.format和 解析它。

但我仍然得到错误:属性的值无效。

我查看了与此错误相关的所有其他堆栈流问题。无法弄清楚我哪里出错了。 谁可以帮我这个事。请让我知道我哪里出错了。

附在代码段下方。

var app = angular.module('chartApp', []);

app.controller('SalesController', ['$scope','$interval', function($scope, $interval){
   $scope.salesData =[];

}]);

app.directive('linearChart', function($parse, $window ,$http){
   return{
      restrict:'EA',
      template:"<svg width='850' height='200'></svg>",
       link: function(scope, elem, attrs){



            $http.get('data.json').
            then(function(response) {
            console.log("line Chart response :"+response);  
                scope.salesData = response.data;

           //var m = moment();    

           var exp = $parse(attrs.chartData);

           var salesDataToPlot=exp(scope);
           var padding = 20;
           var pathClass="path";
           var xScale, yScale, xAxisGen, yAxisGen, lineFun;

           var d3 = $window.d3;
           var rawSvg=elem.find('svg');
           var svg = d3.select(rawSvg[0]);

            var monthNumber = d3.time.format("%-m");
            var monthName = d3.time.format("%B");


            for (i = 0; i < salesDataToPlot.length; i++) {

                var mon = monthNumber.parse((salesDataToPlot[i].month+1).toString());
                salesDataToPlot[i].month = monthName(mon);
            }    

           scope.$watchCollection(exp, function(newVal, oldVal){
               salesDataToPlot=newVal;
               redrawLineChart();
           });

           function setChartParameters(){

               xScale = d3.scale.linear()
                   .domain([salesDataToPlot[0].month, salesDataToPlot[salesDataToPlot.length-1].month])
                   .range([padding + 5, rawSvg.attr("width") - padding]);

               yScale = d3.scale.linear()
                   .domain([0, d3.max(salesDataToPlot, function (d) {
                       return d.total_cars;
                   })])
                   .range([rawSvg.attr("height") - padding, 0]);

               xAxisGen = d3.svg.axis()
                   .scale(xScale)
                   .orient("bottom");
                   /*.ticks(d3.time.months)
                   .tickFormat(d3.time.format("%B"));*/

               yAxisGen = d3.svg.axis()
                   .scale(yScale)
                   .orient("left")
                   .ticks(5);

               lineFun = d3.svg.line()
                   .x(function (d) {
                       return xScale(d.month);
                   })
                   .y(function (d) {
                       return yScale(d.total_cars);
                   })
                   .interpolate("basis");
           }

         function drawLineChart() {

               setChartParameters();

               svg.append("svg:g")
                   .attr("class", "x axis")
                   .attr("transform", "translate(0,180)")
                   .call(xAxisGen);

               svg.append("svg:g")
                   .attr("class", "y axis")
                   .attr("transform", "translate(20,0)")
                   .call(yAxisGen);

               svg.append("svg:path")
                   .attr({
                       d: lineFun(salesDataToPlot),   // This is the line of    code which is giving me the error.
                       "stroke": "blue",
                       "stroke-width": 2,
                       "fill": "none",
                       "class": pathClass
                   });
           }

           function redrawLineChart() {

               setChartParameters();

               svg.selectAll("g.y.axis").call(yAxisGen);

               svg.selectAll("g.x.axis").call(xAxisGen);

               svg.selectAll("."+pathClass)
                   .attr({
                       d: lineFun(salesDataToPlot)
                   });
           }


           drawLineChart();
            }, function(response) {
            console.log("error");
         });

       }
   };
});

1 个答案:

答案 0 :(得分:4)

您正在使用d3.scale.linear(),但是当您设置域时,会传递月份名称,如“Jan”,“Feb”等。这只是行不通,scale.linear期望使用连续数字数据。

因此,您需要决定是否使用x比例的数字或全部使用并使用d3.time.scale()比例的日期。在您的情况下,如果您只有一个整数表示一年多的数据,那么linear可能更容易:

xScale = d3.scale.linear()
    .domain([0,11]) //<-- 12 months
    .range([padding, 500]);

xAxisGen = d3.svg.axis()
    .scale(xScale)
    .orient("bottom")
    .ticks(12) //<-- 12 ticks
    .tickFormat(function(d) {
      // display right month
      return ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][d]; 
    });