D3 折线图出现错误且未绘制
D3 line graph getting error and not getting plotted
我正在为一组关于字母与频率的数据制作折线图。我已经为 x 和 y 轴编写了正确的代码,但是在绘制线条时出现错误并且无法绘制折线图。有人可以帮助解决这个问题吗?
片段:
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.12/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.3.0/d3.min.js"></script>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<svg></svg>
<script>
//module declaration
var app = angular.module('myApp',[]);
//Controller declaration
app.controller('myCtrl',function($scope){
$scope.svgWidth = 800;//svg Width
$scope.svgHeight = 500;//svg Height
//Data in proper format
var data = [
{"letter": "A","frequency": "5.01"},
{"letter": "B","frequency": "7.80"},
{"letter": "C","frequency": "15.35"},
{"letter": "D","frequency": "22.70"},
{"letter": "E","frequency": "34.25"},
{"letter": "F","frequency": "10.21"},
{"letter": "G","frequency": "7.68"},
];
//removing prior svg elements ie clean up svg
d3.select('svg').selectAll("*").remove();
//resetting svg height and width in current svg
d3.select("svg").attr("width", $scope.svgWidth).attr("height", $scope.svgHeight);
//Setting up of our svg with proper calculations
var svg = d3.select("svg");
var margin = {top: 20, right: 20, bottom: 30, left: 40};
var width = svg.attr("width") - margin.left - margin.right;
var height = svg.attr("height") - margin.top - margin.bottom;
//Plotting our base area in svg in which chart will be shown
var g = svg.append("g");
//shifting the canvas area from left and top
g.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
//X and Y scaling
var x = d3.scaleLinear().rangeRound([0, width]);
var y = d3.scaleBand().rangeRound([height, 0]).padding(0.4);
//Feeding data points on x and y axis
x.domain([0, d3.max(data, function(d) { return +d.frequency; })]);
y.domain(data.map(function(d) { return d.letter; }));
//Final Plotting
//for x axis
g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
//for y axis
g.append("g")
.call(d3.axisLeft(y))
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.attr("text-anchor", "end");
//the line function for path
var lineFunction = d3.line()
.x(function(d) {return xScale(d.x); })
.y(function(d) { return yScale(d.y); })
.curve(d3.curveLinear);
//defining the lines
var path = g.append("path");
//plotting lines
path
.attr("d", lineFunction(data))
.attr("stroke", "blue")
.attr("stroke-width", 2)
.attr("fill", "none");
});
</script>
</body>
</html>
错误:
新错误:
查看控制台:您没有 xScale
或 yScale
。
所以,线生成器应该是:
var lineFunction = d3.line()
.x(function(d) {return x(d.frequency); })
.y(function(d) { return y(d.letter); })
.curve(d3.curveLinear);
除此之外,frequency
是一个字符串,不是一个数字。所以,把它变成一个数字是个好主意。在你的 data
变量之后写下这个:
data.forEach(function(d){
d.frequency = +d.frequency;
});
注意:使用描述性名称正确定义变量名是一个很好的做法,例如 xScale
、yAxis
、chartLegend
或 formatNumber
... 看看你的线生成器:你在一行中有两个不同的 x
。一不留神就混了
如果你想使用 xScale 和 yScale ,你需要定义这些函数。语法如下(忽略值):
以下代码适用于 d3 版本 3
me.xscale = d3.scale.linear() // for horizontal distances if using for 2D
.domain([0, 500])
.range([0, 700]);
me.yscale = d3.scale.linear() // for vertical distances if using for 2D
.domain([0, 600])
.range([0, 200]);
这些函数用于定义一个范围内的值到另一范围内的值的映射。
例如 - 假设您想在浏览器屏幕上绘制图形。你想假设你的浏览器屏幕上的宽度 500px 在你的图表上应该算作 500。
你需要像上面那样定义 xScale 。在这种情况下,此函数会将域 (0-500) 中的每个值映射到范围 (0-700) 中的唯一值,反之亦然。
我正在为一组关于字母与频率的数据制作折线图。我已经为 x 和 y 轴编写了正确的代码,但是在绘制线条时出现错误并且无法绘制折线图。有人可以帮助解决这个问题吗?
片段:
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.12/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.3.0/d3.min.js"></script>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<svg></svg>
<script>
//module declaration
var app = angular.module('myApp',[]);
//Controller declaration
app.controller('myCtrl',function($scope){
$scope.svgWidth = 800;//svg Width
$scope.svgHeight = 500;//svg Height
//Data in proper format
var data = [
{"letter": "A","frequency": "5.01"},
{"letter": "B","frequency": "7.80"},
{"letter": "C","frequency": "15.35"},
{"letter": "D","frequency": "22.70"},
{"letter": "E","frequency": "34.25"},
{"letter": "F","frequency": "10.21"},
{"letter": "G","frequency": "7.68"},
];
//removing prior svg elements ie clean up svg
d3.select('svg').selectAll("*").remove();
//resetting svg height and width in current svg
d3.select("svg").attr("width", $scope.svgWidth).attr("height", $scope.svgHeight);
//Setting up of our svg with proper calculations
var svg = d3.select("svg");
var margin = {top: 20, right: 20, bottom: 30, left: 40};
var width = svg.attr("width") - margin.left - margin.right;
var height = svg.attr("height") - margin.top - margin.bottom;
//Plotting our base area in svg in which chart will be shown
var g = svg.append("g");
//shifting the canvas area from left and top
g.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
//X and Y scaling
var x = d3.scaleLinear().rangeRound([0, width]);
var y = d3.scaleBand().rangeRound([height, 0]).padding(0.4);
//Feeding data points on x and y axis
x.domain([0, d3.max(data, function(d) { return +d.frequency; })]);
y.domain(data.map(function(d) { return d.letter; }));
//Final Plotting
//for x axis
g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
//for y axis
g.append("g")
.call(d3.axisLeft(y))
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.attr("text-anchor", "end");
//the line function for path
var lineFunction = d3.line()
.x(function(d) {return xScale(d.x); })
.y(function(d) { return yScale(d.y); })
.curve(d3.curveLinear);
//defining the lines
var path = g.append("path");
//plotting lines
path
.attr("d", lineFunction(data))
.attr("stroke", "blue")
.attr("stroke-width", 2)
.attr("fill", "none");
});
</script>
</body>
</html>
错误:
新错误:
查看控制台:您没有 xScale
或 yScale
。
所以,线生成器应该是:
var lineFunction = d3.line()
.x(function(d) {return x(d.frequency); })
.y(function(d) { return y(d.letter); })
.curve(d3.curveLinear);
除此之外,frequency
是一个字符串,不是一个数字。所以,把它变成一个数字是个好主意。在你的 data
变量之后写下这个:
data.forEach(function(d){
d.frequency = +d.frequency;
});
注意:使用描述性名称正确定义变量名是一个很好的做法,例如 xScale
、yAxis
、chartLegend
或 formatNumber
... 看看你的线生成器:你在一行中有两个不同的 x
。一不留神就混了
如果你想使用 xScale 和 yScale ,你需要定义这些函数。语法如下(忽略值):
以下代码适用于 d3 版本 3
me.xscale = d3.scale.linear() // for horizontal distances if using for 2D
.domain([0, 500])
.range([0, 700]);
me.yscale = d3.scale.linear() // for vertical distances if using for 2D
.domain([0, 600])
.range([0, 200]);
这些函数用于定义一个范围内的值到另一范围内的值的映射。
例如 - 假设您想在浏览器屏幕上绘制图形。你想假设你的浏览器屏幕上的宽度 500px 在你的图表上应该算作 500。 你需要像上面那样定义 xScale 。在这种情况下,此函数会将域 (0-500) 中的每个值映射到范围 (0-700) 中的唯一值,反之亦然。