这是博主用d3.js第一次绘制的图形,可以实现数据的添加和排序的功能,里面用到了线性比例尺和颜色比例尺等知识,后面都打了备注,因为时间的原因就不一个一个展开说了,源码放在下面,方便我管理也供大家参考!!!
<!DOCTYPE html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="d3.min.js"></script>
<title>d3实践</title>
</head>
<style>
.axis path,
.axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
}
</style>
<body>
<svg width="600" height="600"></svg>
<script>
let dataset = [5, 10, 15, 40, 22, 80, 76, 20, 25];
let marge = {
top: 60,
bottom: 60,
left: 60,
right: 60
};
let svg = d3.select("body").select("svg"),
width = svg.attr("width"),
height = svg.attr("height");
//设置画布位置
let g = svg.append("g").attr("transform", "translate(" + marge.left + "," + marge.top + ")");
function draw(x) {
//定义x轴序数比例尺
let xScale = d3.scale.ordinal().domain(d3.range(dataset.length))
.rangeBands([0, width - marge.left], 0.1);
//定义y轴线性比例尺
let yScale = d3.scale.linear().domain([0, d3.max(dataset)]).range([0, height - marge.top - marge.bottom]);
//定义表示颜色的序数比例尺
let color = d3.scale.category10();
//模板
//获取矩形的update部分
let updateRect = g.selectAll("rect").data(dataset);
//获取矩形的enter部分
let enterRect = updateRect.enter();
//获取矩形的exit部分
let exitRect = updateRect.exit();
//1. 矩形的update部分的处理方法
updateRect
.attr("x", function (d, i) {
return xScale(i);
})
.attr("y", function (d) {
return height - marge.top - marge.bottom - yScale(d);
})
.attr("width", xScale.rangeBand())
.attr("height", function (d) {
return yScale(d);
})
.attr("fill", function (d, i) {
return color(i);
});
//2. 矩形的enter部分的处理方法
enterRect
.append("rect")
.attr("x", function (d, i) {
return xScale(i);
})
.attr("y", function (d) {
return height - marge.top - marge.bottom - yScale(d);
})
.attr("width", xScale.rangeBand())
.attr("height", function (d) {
return yScale(d);
})
.attr("fill", function (d, i) {
return color(i);
});
//3. 矩形的exit部分的处理方法
exitRect.remove();
//获取文字的update部分
let updateText = g.selectAll("text")
.data(dataset);
//获取文字的enter部分
let enterText = updateText.enter();
//获取文字的exit部分
let exitText = updateText.exit();
//1. 文字的update部分的处理方法
updateText
.text(function (d) {
return d;
})
.attr("text-anchor", "middle")
.attr("x", function (d, i) {
return xScale(i);
})
.attr("y", function (d) {
return height - marge.top - marge.bottom - yScale(d)
})
.attr("dx", xScale.rangeBand() / 2)
.attr("dy", "1em")
//2. 文字的enter部分的处理方法
enterText
.append("text")
.text(function (d) {
return d;
})
.attr("text-anchor", "middle")
.attr("x", function (d, i) {
return xScale(i);
})
.attr("y", function (d) {
return height - marge.top - marge.bottom - yScale(d)
})
.attr("dx", xScale.rangeBand() / 2)
.attr("dy", "1em")
//3. 文字的exit部分的处理方法
exitText.remove();
if(x==true) d3.select("body").select("svg").select(".axis").remove();
//绘制x坐标轴
let xAxis = d3.svg.axis().scale(xScale).orient("bottom");
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + marge.left + "," + (height - marge.bottom) + ")")
.call(xAxis);
//重新设置y轴比例尺的值域,与原来的相反
yScale.range([height - marge.top - marge.bottom, 0]);
let yAxis = d3.svg.axis().scale(yScale).orient("left");
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + marge.left + "," + marge.top + ")")
.call(yAxis);
// d3.select(".axis").remove();
}
draw(false);
function mysort() {
dataset.sort(d3.ascending);
draw(false);
}
function myadd() {
dataset.push(Math.floor(Math.random() * 80));
d3.select("body").select(".axis").remove();
draw(true);
}
</script>
<br>
<button type="button" onclick="mysort()" style="margin-left: 60px;">排序</button>
<button type="button" onclick="myadd()" style="margin-left: 60px;">添加数据</button>
</body>
</html>