本文以及后面几篇文章会通过几个例子来熟悉d3.js的使用。
先上代码,后面细说
<script type="text/javascript"> var height = 600; var width = 600; var dataset= [30,20,45,12,21,28,46,64,73,78,54]; var num = 15; for(var i = 0; i < 4; i++){ var tempnum = Math.floor(Math.random() * 50); dataset.push(tempnum); } console.log(dataset); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height); var xAxisScale = d3.scale.ordinal() .domain(d3.range(dataset.length)) .rangeRoundBands([0, 500]); var yAxisScale = d3.scale.linear() .domain([0, d3.max(dataset)]) .range([500, 0]); var xAxis = d3.svg.axis().scale(xAxisScale).orient("bottom"); var yAxis = d3.svg.axis().scale(yAxisScale).orient("left"); var xScale = d3.scale.ordinal() .domain(d3.range(dataset.length)) .rangeRoundBands([0,500],0.05); var yScale = d3.scale.linear() .domain([0,d3.max(dataset)]) .range([0,500]); svg.selectAll("rect") .data(dataset) .enter() .append("rect") .on("click", function(){ d3.select(this).attr("fill","black"); }) .attr("x", function(d,i){ return 100 + xScale(i); } ) .attr("y",function(d,i){ return 50 + 500 - yScale(d) ; }) .attr("width", function(d,i){ return xScale.rangeBand(); }) .attr("height",yScale) .attr("fill", "steelblue") .transition() .duration(2000) .ease("bounce") .delay(1000) .attr("fill","red"); svg.selectAll("text") .data(dataset) .enter().append("text") .attr("x", function(d,i){ return 100 + xScale(i); } ) .attr("y",function(d,i){ return 50 + 500 - yScale(d) ; }) .attr("dx", function(d,i){ return xScale.rangeBand()/3; }) .attr("dy", 15) .attr("text-anchor", "begin") .attr("font-size", 14) .attr("fill","white") .text(function(d,i){ return d; }); svg.append("g") .attr("class","axis") .attr("transform","translate(100,550)") .call(xAxis); svg.append("g") .attr("class","axis") .attr("transform","translate(100,50)") .call(yAxis); </script>
d3.js中所有的函数的定义都在命名空间d3下面
var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height);
d3.select()选中某个结点,如果多个结点符合要求,则返回第一个
d3.selectAll()选中所有的结点,返回一个数组
var xAxisScale = d3.scale.ordinal() .domain(d3.range(dataset.length)) .rangeRoundBands([0, 500]); var yAxisScale = d3.scale.linear() .domain([0, d3.max(dataset)]) .range([500, 0]); var xAxis = d3.svg.axis().scale(xAxisScale).orient("bottom"); var yAxis = d3.svg.axis().scale(yAxisScale).orient("left")
上面的代码定义了坐标轴x和坐标轴y
我们先来了解一下d3.js中的比例尺的概念,给定一个domain(定义域),和一个range(值域)就可以进行数值之间的换算。
以d3.scale.liner()为例,liner()表示使用线性函数的比例尺,给定的定义域是0到数据集dataset中最大的值,而值域范围是[500, 0]
这里dataset = [30,20,45,12,21,28,46,64,73,78,54],即定义域为[0-78],如果实际值为78,则换算成图形的高度就是0,如果实际值为39,换算成图形的高度就是250。
其中还有sqrt, pow, log, quantize, ordinal等各种类型的比例尺。具体的算法和使用方式可以参照官方的api
d3.svg.axis()定义坐标尺的函数
scale指定坐标尺的比例
orient指定坐标轴的分割点和数字的朝向
svg.selectAll("rect") .data(dataset) .enter() .append("rect") .on("click", function(){ d3.select(this).attr("fill","black"); }) .attr("x", function(d,i){ return 100 + xScale(i); } ) .attr("y",function(d,i){ return 50 + 500 - yScale(d) ; }) .attr("width", function(d,i){ return xScale.rangeBand(); }) .attr("height",yScale) .attr("fill", "steelblue") .transition() .duration(2000) .ease("bounce") .delay(1000) .attr("fill","red");这一段代码是绘制矩形
我们可能会疑惑svg.selectAll("recct"),这里我们并没有给svg元素添加rect子元素啊?后面会说
data(dataset)将选中的元素集合数据集绑定起来
enter()这个函数是干嘛用的?
当将元素集合数据集进行绑定的时候,如果数据集内数据的个数大于元素集内元素的个数的时候,函数enter返回与多余的数据集对应的元素的占位符,这里占时是还没有rect元素的,append("rect")会将缺少的元素补齐。
通常的使用方式是svg.selectAll(node).data(dataset).enter().append(node)
on()给元素添加点击事件,这里点中矩形的时候,给矩形填充黑色
attr("key","value")给结点rect添加属性,x,y分别表示矩形的x坐标与y左边,width,height表示矩形的宽度与高度,
svg.selectAll("text") .data(dataset) .enter().append("text") .attr("x", function(d,i){ return 100 + xScale(i); } ) .attr("y",function(d,i){ return 50 + 500 - yScale(d) ; }) .attr("dx", function(d,i){ return xScale.rangeBand()/3; }) .attr("dy", 15) .attr("text-anchor", "begin") .attr("font-size", 14) .attr("fill","white") .text(function(d,i){ return d; });这段代码绘制矩形的文字标签
svg.append("g") .attr("class","axis") .attr("transform","translate(100,550)") .call(xAxis);在<svg>中添加元素<g>,g是svg标准中定义的元素,是分组的意思,用于把相关的元素进行组合的容器元素,将包含坐标轴的元素组合在一个group里
call(xAxis),调用函数xAxis并设置执行上下文为元素<g>。
attr("transform","translate(100, 550)")表示将x轴右移100px,并下移550px