我正在使用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");
});
}
};
});
答案 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];
});