# d3.line d3折线图曲线图实现
- d3.line()实现的其实依赖于svg:path而不是svg中line元素
var line =d3.line()
.x(function(d){return x(d.x)})
.y(function(d){return y(d.y)})
- 绘制线条的data是个二维数组!可同时画多条线
var data = [ // <-C
[
{x: 0, y: 5},{x: 1, y: 9},{x: 2, y: 7},
{x: 3, y: 5},{x: 4, y: 3},{x: 6, y: 4},
{x: 7, y: 2},{x: 8, y: 3},{x: 9, y: 2}
],
d3.range(10).map(function(i){
return {x: i, y: Math.sin(i) + 5};
})
];
- d3.line函数返回一个D3线条生成器函数,结合svg:path中的d属性生成路径
svg.selectAll("path")
.data(data)
.enter()
.append("path") // <-E
.attr("class", "line")
.attr("d", function(d){
console.log(d)
return line(d)
;}); // <-F
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Lines</title>
<link rel="stylesheet" type="text/css" href="../../css/styles.css"/>
<script type = "text/javascript" src = "https://d3js.org/d3.v6.min.js"></script>
</head>
<body>
<script type="text/javascript">
var width = 500,
height = 500,
margin = 50,
x = d3.scaleLinear() // <-A
.domain([0, 10])
.range([margin, width - margin]),
y = d3.scaleLinear() // <-B
.domain([0, 10])
.range([height - margin, margin]);
var data = [ // <-C
[
{x: 0, y: 5},{x: 1, y: 9},{x: 2, y: 7},
{x: 3, y: 5},{x: 4, y: 3},{x: 6, y: 4},
{x: 7, y: 2},{x: 8, y: 3},{x: 9, y: 2}
],
d3.range(10).map(function(i){
return {x: i, y: Math.sin(i) + 5};
})
];
var line = d3.line() // <-D
.x(function(d){return x(d.x);})
.y(function(d){return y(d.y);});
var svg = d3.select("body").append("svg");
svg.attr("height", height)
.attr("width", width);
svg.selectAll("path")
.data(data)
.enter()
.append("path") // <-E
.attr("class", "line")
.attr("d", function(d){
console.log(d)
return line(d)
;}); // <-F
renderAxes(svg);
function renderAxes(svg){ // <-G
var xAxis = d3.axisBottom()
.scale(x.range([0, quadrantWidth()]));
var yAxis = d3.axisLeft()
.scale(y.range([quadrantHeight(), 0]));
svg.append("g")
.attr("class", "axis")
.attr("transform", function(){
return "translate(" + xStart()
+ "," + yStart() + ")";
})
.call(xAxis);
svg.append("g")
.attr("class", "axis")
.attr("transform", function(){
return "translate(" + xStart()
+ "," + yEnd() + ")";
})
.call(yAxis);
}
function xStart(){
return margin;
}
function yStart(){
return height - margin;
}
function xEnd(){
return width - margin;
}
function yEnd(){
return margin;
}
function quadrantWidth(){
return width - 2 * margin;
}
function quadrantHeight(){
return height - 2 * margin;
}
</script>
</body>
</html>
# d3.line优化线条curve
var line =d3.line()
.x(function(d){return x(d.x)})
.y(function(d){return y(d.y)})
.curve(mode)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Line Curve</title>
<link rel="stylesheet" type="text/css" href="../../css/styles.css"/>
<script type = "text/javascript" src = "https://d3js.org/d3.v6.min.js"></script>
</head>
<body>
<script type="text/javascript">
var width = 500,
height = 500,
margin = 30,
x = d3.scaleLinear()
.domain([0, 10])
.range([margin, width - margin]),
y = d3.scaleLinear()
.domain([0, 10])
.range([height - margin, margin]);
var data = [
[
{x: 0, y: 5},{x: 1, y: 9},{x: 2, y: 7},
{x: 3, y: 5},{x: 4, y: 3},{x: 6, y: 4},
{x: 7, y: 2},{x: 8, y: 3},{x: 9, y: 2}
],
d3.range(10).map(function(i){
return {x: i, y: Math.sin(i) + 5};
})
];
var svg = d3.select("body").append("svg");
svg.attr("height", height)
.attr("width", width);
renderAxes(svg);
render(d3.curveLinear);
renderDots(svg);
function render(mode){
var line = d3.line()
.x(function(d){return x(d.x);})
.y(function(d){return y(d.y);})
.curve(mode); // <-A
svg.selectAll("path.line")
.data(data)
.enter()
.append("path")
.attr("class", "line");
svg.selectAll("path.line")
.data(data)
.attr("d", function(d){return line(d);});
}
function renderDots(svg){ // <-B
data.forEach(function(list){
svg.append("g").selectAll("circle")
.data(list)
.enter().append("circle") // <-C
.attr("class", "dot")
.attr("cx", function(d) { return x(d.x); })
.attr("cy", function(d) { return y(d.y); })
.attr("r", 4.5);
});
}
function renderAxes(svg){
var xAxis = d3.axisBottom()
.scale(d3.scaleLinear().range([0, quadrantWidth()]));
var yAxis = d3.axisLeft()
.scale(d3.scaleLinear().range([quadrantHeight(), 0]));
svg.append("g")
.attr("class", "axis")
.attr("transform", function(){
return "translate(" + xStart() + "," + yStart() + ")";
})
.call(xAxis);
svg.append("g")
.attr("class", "axis")
.attr("transform", function(){
return "translate(" + xStart() + "," + yEnd() + ")";
})
.call(yAxis);
}
function xStart(){
return margin;
}
function yStart(){
return height - margin;
}
function xEnd(){
return width - margin;
}
function yEnd(){
return margin;
}
function quadrantWidth(){
return width - 2 * margin;
}
function quadrantHeight(){
return height - 2 * margin;
}
</script>
<h4>Curve Mode:</h4>
<div class="control-group">
<button onclick="render(d3.curveLinear)">linear</button>
<button onclick="render(d3.curveLinearClosed)">linear closed</button>
<button onclick="render(d3.curveStepBefore)">step before</button>
<button onclick="render(d3.curveStepAfter)">step after</button>
<button onclick="render(d3.curveBasis)">basis</button>
<button onclick="render(d3.curveBasisOpen)">basis open</button>
<button onclick="render(d3.curveBasisClosed)">basis closed</button>
</div>
<div class="control-group">
<button onclick="render(d3.curveBundle)">bundle</button>
<button onclick="render(d3.curveCardinal)">cardinal</button>
<button onclick="render(d3.curveCardinalOpen)">cardinal open</button>
<button onclick="render(d3.curveCardinalClosed)">cardinal closed</button>
<button onclick="render(d3.curveMonotoneY)">monotone</button>
<button onclick="render(d3.curveCatmullRom)">CatmullRom</button>
</div>
</body>
</html>
# d3tension线条张力
tension:[0,1](大于1线条也会变动)(1是无张力的直线,大于1可能是曲线且奇怪)
var line = d3.line()
.curve(d3.curveCardinal.tension(tension)) // <-A
.x(function(d){return x(d.x);})
.y(function(d){return y(d.y);});