【问题标题】:D3.js Error: Invalid value for <path> attribute for a line chartD3.js 错误:折线图的 <path> 属性值无效
【发布时间】:2015-10-05 12:19:06
【问题描述】:

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

并使用 d3.time.format 将月份编号“0”转换为月份“Jan”和 解析它。

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

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

下面附上代码sn-p。

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");
         });

       }
   };
});

【问题讨论】:

    标签: javascript angularjs d3.js


    【解决方案1】:

    您使用的是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]; 
        });
    

    【讨论】:

    • 感谢马克的回复。我只想让一个整数代表一个月的数据。所以我更喜欢使用线性。 jsfiddle : [link] jsfiddle.net/AnilRahul16/r2x7ebkv 我尝试了上述解决方案。我仍然遇到同样的错误。错误: 属性 的值无效
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-07
    • 1970-01-01
    • 2016-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多