转载请注明出处!
概述:
与比例尺类似,D3的数轴实际上也使用来定义参数的函数。但与比例尺不同的是,调用数轴函数并不会返回值,而是会生成数轴相关的可见元素。包括:轴线,标签和刻度。
但是要注意数轴函数只适应于SVG图形,因为他们生成的都是SVG元素,同样,数轴是设计与定量比例尺(与序数比例尺相对)配合使用的。
定义和创建X轴:
1 //定义x轴 2 3 var xAxis = d3.svg.axis() 4 .scale(xScale) 5 .orient("bottom"); 6 7 8 //创建x轴 9 10 svg.append("g") 11 .call(xAxis);
上面的代码首先引用了svg,然后append()在这个元素的末尾追加了一个新的g元素。在SVG标签中,g元素是一个分组元素。分组元素是不可见的,跟line,rect和circle不一样,但是他有两大用途:
一是可以用来包含(或组织)其他元素,好让代码看起来整齐;
二是可以对整个分组应用变换,从而影响到该分组中所有元素(line,rect和circle)的视觉表现。
创建了新的g元素后,我们直接在这个元素上调用了call()方法,call()的作用如下:
D3的call()方法回去的传递过来的元素,然后把它交给其他函数,对我们这而言,传递过来的元素是新的分组元素g(虽然这个元素不是必须的,但是鉴于数轴函数需要生成很多线条和数值,有了它可以把所有的元素都封装到一个分组对象中)。而call()接着把g元素交给xAxis函数,也就是要在g元素中生成数轴。
效果图:
修整数轴:
首先给新创建的g元素添加一个axis类,然后为他添加CSS样式:
1 svg.append("g") 2 3 .attr(“class”, “axis”) 4 5 .call(xAxis);
1 .axis path, 2 3 .axis line { 4 5 fill: none; 6 7 stroke: black; 8 9 shape-rendering: crispEdges; 10 11 } 12 13 14 15 .axis text { 16 17 font-family: sans-serif; 18 19 font-size: 11px; 20 21 }
现在就体现出把所有数轴元素组织到一个分组g中的好处了,只要使用简单的CSS选择符.axis就能为其中的任何元素添加样式。数周本身是由path,line和text元素组成的,因此上面的css样式瞄准这三个元素。注意,上面通过css对SVG元素使用样式的时候,只能使用SVG认识的属性名。(SVG的属性可以参照MDN网站)。
调整坐标位置到图表下面:
1 svg.append("g") 2 .attr("class", "axis") 3 .attr("transform", "translate(0," + (h - padding) + ")") 4 .call(xAxis);
通过设置g元素的属性transform。SVG的变换功能非常强大这儿先介绍平移(transform)变换。他可以把整个g分组向下平移一段距离。
平移变换的语法很简单,就是translate(x, y),x,y就是把元素移动到新位置的x和y坐标。可以在浏览器中查看DOM元素g。
效果图:
优化刻度:
数轴上的刻度线(ticks)使用来传达信息的,也不是越多越好。可以用ticks()方法粗略的指定刻度线的数量。注意,D3只是把ticks的值当做一个参考,如果发现有更清晰方便理解的值,那么他就会舍弃ticks的值。
1 var xAxis = d3.svg.axis() 2 .scale(xScale) 3 .orient("bottom") 4 .ticks(5); //粗略的设置刻度线的数量
垂直数轴:
1 var yAxis = d3.svg.axis() 2 .scale(yScale) 3 .orient("left") 4 .ticks(5);
同样设置起始坐标:
1 //Create Y axis 2 svg.append("g") 3 .attr("class", "axis") 4 .attr("transform", "translate(" + padding + ",0)") 5 .call(yAxis);
效果图:
最终代码:
1 <!DOCTYPE html> 2 3 <html lang="en"> 4 5 <head> 6 7 <title>D3: Test of formatted axis values</title> 8 9 <script type="text/javascript" src="../d3/d3.js"></script> 10 11 <style type="text/css"> 12 .axis path, 16 17 .axis line { 18 19 fill: none; 20 21 stroke: black; 22 23 shape-rendering: crispEdges; 24 25 } 26 .axis text { 30 31 font-family: sans-serif; 32 33 font-size: 11px; 34 35 } 39 </style> 40 41 </head> 42 43 <body> 44 45 <script type="text/javascript"> 49 //Width and height 50 51 var w = 500; 52 53 var h = 300; 54 55 var padding = 30; 56 59 /* 60 61 //Static dataset 62 63 var dataset = [ 64 65 [5, 20], [480, 90], [250, 50], [100, 33], [330, 95], 66 67 [410, 12], [475, 44], [25, 67], [85, 21], [220, 88], 68 69 [600, 150] 70 71 ]; 72 73 */ 74 77 //动态随机生成数据集 78 79 var dataset = []; //Initialize empty array 80 81 var numDataPoints = 50; //Number of dummy data points to create 82 83 var xRange = Math.random() * 1000; //Max range of new x values 84 85 var yRange = Math.random() * 1000; //Max range of new y values 86 87 for (var i = 0; i < numDataPoints; i++) { //Loop numDataPoints times 88 89 var newNumber1 = Math.floor(Math.random() * xRange); //New random integer 90 91 var newNumber2 = Math.floor(Math.random() * yRange); //New random integer 92 93 dataset.push([newNumber1, newNumber2]); //Add new number to array 94 95 } 96 99 //Create scale functions 100 101 var xScale = d3.scale.linear() 102 103 .domain([0, d3.max(dataset, function(d) { return d[0]; })]) 104 105 .range([padding, w - padding * 2]); 106 107 108 109 var yScale = d3.scale.linear() 110 111 .domain([0, d3.max(dataset, function(d) { return d[1]; })]) 112 113 .range([h - padding, padding]); 114 115 116 117 var rScale = d3.scale.linear() 118 119 .domain([0, d3.max(dataset, function(d) { return d[1]; })]) 120 121 .range([2, 5]); 122 123 //为刻度标签定义样式(这个例子只是做说明并无太大实际意义) 124 125 var formatAsPercentage = d3.format(".1%"); 126 127 128 129 //Define X axis 130 131 var xAxis = d3.svg.axis() 132 133 .scale(xScale) 134 135 .orient("bottom") 136 137 .ticks(5) 138 139 .tickFormat(formatAsPercentage); 140 143 //Define Y axis 144 145 var yAxis = d3.svg.axis() 146 147 .scale(yScale) 148 149 .orient("left") 150 151 .ticks(5) 152 153 //对数轴刻度应用定义的格式化函数(观察坐标轴) 154 155 .tickFormat(formatAsPercentage); 156 157 158 159 //Create SVG element 160 161 var svg = d3.select("body") 162 163 .append("svg") 164 165 .attr("width", w) 166 167 .attr("height", h); 168 169 170 171 //Create circles 172 173 svg.selectAll("circle") 174 175 .data(dataset) 176 177 .enter() 178 179 .append("circle") 180 181 .attr("cx", function(d) { 182 183 return xScale(d[0]); 184 185 }) 186 187 .attr("cy", function(d) { 188 189 return yScale(d[1]); 190 191 }) 192 193 .attr("r", function(d) { 194 195 return rScale(d[1]); 196 197 }); 198 199 200 201 /*注释掉各点旁边的标签 202 203 //Create labels 204 205 svg.selectAll("text") 206 207 .data(dataset) 208 209 .enter() 210 211 .append("text") 212 213 .text(function(d) { 214 215 return d[0] + "," + d[1]; 216 217 }) 218 219 .attr("x", function(d) { 220 221 return xScale(d[0]); 222 223 }) 224 225 .attr("y", function(d) { 226 227 return yScale(d[1]); 228 229 }) 230 231 .attr("font-family", "sans-serif") 232 233 .attr("font-size", "11px") 234 235 .attr("fill", "red"); 236 237 */ 238 241 //Create X axis 242 243 svg.append("g") 244 245 .attr("class", "axis") 246 247 .attr("transform", "translate(0," + (h - padding) + ")") 248 249 .call(xAxis); 250 251 252 253 //Create Y axis 254 255 svg.append("g") 256 257 .attr("class", "axis") 258 259 .attr("transform", "translate(" + padding + ",0)") 260 261 .call(yAxis); 262 265 </script> 266 267 </body> 268 269 </html>
效果图:
For my lover, cc!
参考书籍:《数据可视化实战》
D3基础--数轴