一:要實現的效果
二:代碼展示
1.需求分析
(1)數據以列表形式展示
var data=[[176.71,77.28,312.23,58.60,
119.62,179.52,458.55,359.68,
114.46,188.93,178.30 ,254.05],
[437.77,153.76,347.83,190.85,
369.70,21.06,219.18,320.39,
481.47,106.88,298.88,482.32]];
(2)折線光滑
需要在直線生成器中設置插值函數。默認點與點之間是直線,折線圖並不光滑。
var linePath=d3.svg.line()
.x(function(d,i){
return xScale(i+1);
})
.y(function(d,i){
return yScale(d);
})
.interpolate("basis");
(3)座標軸樣式設置
<style>
.axis path,
.axis line{
shape-rendering: crispedges;
stroke: black;
fill: none;
}
.axis text{
font-family:sans-serif;
font-size: 14px;
}
</style>
2.整體代碼展示如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="d3.js"></script>
<style>
.axis path,
.axis line{
shape-rendering: crispedges;
stroke: black;
fill: none;
}
.axis text{
font-family:sans-serif;
font-size: 14px;
}
</style>
</head>
<body>
<h3 style="margin-left: 100px;">2018年2019年公司產品銷量變化趨勢</h3>
<script>
//2018年和2019年度各月份產品銷售額數據
var data=[[176.71,77.28,312.23,58.60,
119.62,179.52,458.55,359.68,
114.46,188.93,178.30 ,254.05],
[437.77,153.76,347.83,190.85,
369.70,21.06,219.18,320.39,
481.47,106.88,298.88,482.32]];
//畫布大小
var width=600;
var height=600;
var padding={top:10,bottom:100,left:100,right:100};
svg=d3.select("body").append("svg")
.attr("width",width)
.attr("height",height);
//總體產品銷售額最大值
var max=d3.max([d3.max(data[0]),d3.max(data[1])]);
console.log(max);
//定義X軸和Y軸的比例尺
var xScale=d3.scale.linear()
.domain([1,12])
.range([0,width-padding.left-padding.right]);
var yScale=d3.scale.linear()
.domain([0,max+30])
.range([height-padding.top-padding.bottom,0]);
//創建直線生成器
var linePath=d3.svg.line()
.x(function(d,i){
return xScale(i+1);
})
.y(function(d,i){
return yScale(d);
})
.interpolate("basis");
//添加路徑
svg.selectAll("path")
.data(data)
.enter()
.append("path")
.attr("transform","translate("+padding.left+","+padding.top+")")
.attr("d",function(d,i){return linePath(d);})
.attr("fill","none")
.attr("stroke-width",2)
.attr("stroke",function(d,i){
if(i==0){
return "blue";
}else{
return "yellow";
}
});
//x軸
var xAxis=d3.svg.axis()
.scale(xScale)
.tickValues(d3.range(1,13))
.orient("bottom");
//添加x軸
svg.append("g")
.attr("transform","translate("+padding.left+","+(height-padding.bottom)+")")
.attr("class","axis")
.call(xAxis);
//y軸
var yAxis=d3.svg.axis()
.scale(yScale)
.orient("left");
//添加y軸
svg.append("g")
.attr("transform","translate("+padding.left+","+padding.top+")")
.attr("class","axis")
.call(yAxis);
//添加標識
svg.append("rect")
.attr("x",150)
.attr("y",550)
.attr("width",20)
.attr("height",20)
.attr("fill","blue");
svg.append("text")
.attr("x",180)
.attr("y",568)
.attr("fill","black")
.text("2018年度");
svg.append("rect")
.attr("x",350)
.attr("y",550)
.attr("width",20)
.attr("height",20)
.attr("fill","yellow");
svg.append("text")
.attr("x",380)
.attr("y",568)
.attr("fill","black")
.text("2019年度");
</script>
</body>
</html>
三:總結
1.直線生成器傳遞的參數是一個列表形式,而不能是單純的一個點,即數據至少是二維結構。如果只需要畫一條折線即可,可採用二維列表結構。
2.如果需要在底部加一定的標識,則在繪製時應適當地在底部預留出一部分位置。
3.d3.range(1,13)是指從1到12。不確定的情況下可以事先測試。