D3画完整柱状图(带坐标轴标签)
Posted gti2baby
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了D3画完整柱状图(带坐标轴标签)相关的知识,希望对你有一定的参考价值。
昨天晚上本来打算花一点时间把之前学的柱状图改一下,用CSV文件来替换自定义数据。这一替换可不得了,一晚上就搭进去了,还好今早找到了问题的所在,原因在于我的数据引用出了问题。
现在就来讲解一下如何画一个柱状图吧:
柱状图的画法和折线图其实很类似,只要掌握了比例尺的用法和坐标轴的画法,我们只要在此基础上添加“rect”元素添加矩形就可以了,但这其中也有一些要点,我会在其中标出,希望对你有用。
对于d3不同版本带来的代码不适用的解决办法:1)、下载对应的v3或者v4版本加到代码引用里可以解决。
2)、对于我博客的代码,只要你确保网络畅通,应该不会出错
<!DOCTYPE html> <html> <head>
<meta charset="utf-8"> <title>文档的标题</title> </head>
<body> <script src="https://cdn.bootcss.com/d3/3.5.15/d3.js"></script>//网页引用d3库
</body> </html>
好了,接下来就是完整代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>绘制图形</title> </head> <style> /* 给body添加大小 */ body, html height: 100%; padding: 0; margin: 0; .axis path, .axis line fill: none; stroke: black; shape-rendering: crispEdges; .axis text font-family: sans-serif; font-size: 11px; .MyRect fill: palevioletred; .MyText fill: black; text-anchor: middle; font-size: 10px; </style> <body> <script src="https://cdn.bootcss.com/d3/3.5.15/d3.js"></script> <script> var width = 500; var height = 500; var svg = d3.select("body") .append("svg") .attr("width", width) .attr("height", height); var padding = left: 30, right: 30, top: 20, bottom: 20 ; ////http://blog.sina.com.cn/s/blog_ad72a03a0102v1nx.html 含解释 d3.csv("../bardata.csv", function(error, data, i) if (error) console.log(error); console.log(data); var datavalue = [] for (let i = 0; i < data.length; i++) datavalue.push(data[i].value) // var xp = d3.scale.ordinal() // // .domain(d3.range(dataset.length)) // // 使用map来输入data数组中的字符 // .domain(data.map(function(d,i) // // console.log(d.items) // return d.items // )) // .rangeRoundBands([0,width-padding.left-padding.right]); // var xp = d3.scale.ordinal() // .domain(data.map(function(d) return d.items;)) // .rangeBands([0,width-padding.left-padding.right]);
//以上定义xp(即xscale)横坐标序数比例尺的方法都可以试一下,会有不同的体验 var xp = d3.scale.ordinal() .domain(data.map(function(d) return d.items; )) .rangeRoundBands([0, width - padding.left - padding.right], 0.1); var yp = d3.scale.linear() .domain([0, d3.max(datavalue)]) .range([height - padding.top - padding.bottom, 0]) //反过来?为什么呢(之前似乎讲过哦0w0) var xAxis = d3.svg.axis() .scale(xp) .orient("bottom"); var yAxis = d3.svg.axis() .scale(yp) .orient("left"); var rectPadding = 4; var rects = svg.selectAll(".MyRect") .data(data) .enter() .append("rect") .attr("class", "MyRect") .attr("transform", "translate(" + padding.left + "," + padding.top + ")") .attr("x", function(d, i) return xp(d.items); ) .attr("y", function(d) return yp(d.value); ) .attr("width", xp.rangeBand() - rectPadding) .attr("height", function(d) return height - padding.top - padding.bottom - yp(d.value); ) .on("mouseover", function(d, i) d3.select(this) .style("fill", "aliceblue"); ) .on("mouseout", function(d, i) d3.select(this) .style("fill", "greenyellow"); // 使用style替换attr才会有交互的效果 );
var texts = svg.selectAll(".MyText") .data(data) //害我出错的就是这儿了,我之前写的是.data(datavalue),datavalue又是哪儿来的呢?为什么引用错误,会导致tips的位置错乱呢? .enter() .append("text") .attr("class", "MyText") .attr("transform", "translate(" + padding.left + "," + padding.top + ")") .attr("x", function(d) return xp(d.items);//上面问题的答案都在这儿,d=》data,数据的意思,那data是哪儿来的呢?当然是我们传进来的,那为什么data不会出错,而datavalue会错呢?
//是由于xp()是我们之前定义的序数比例尺,我们如果想要使用就必须传入适合的数据(包含x,y),如果只是传入datavalue就只有y值,而我们并没有将x传入。
) .attr("y", function(d) return yp(d.value); ) .attr("dx", function() return (xp.rangeBand() - rectPadding) / 2; ) .attr("dy", function(d) return 15; ) .text(function(d) return d.value; ); svg.append("g") .attr("class", "axis") .attr("transform", "translate(" + padding.left + "," + (height - padding.bottom) + ")") .call(xAxis); svg.append("g") .attr("class", "axis") .attr("transform", "translate(" + padding.left + "," + padding.top + ")") .call(yAxis); ) </script> </body> </html>
老样子,好货沉底
以上是关于D3画完整柱状图(带坐标轴标签)的主要内容,如果未能解决你的问题,请参考以下文章