d3js mysql_D3.js 基于数据的绘图

这里涉及了 HTML & CSS 的知识,比如说元素的样式和元素块,以后我会把相关知识补上。

绘制直线图

条形图实际上是矩形,而 HTML 的 div 元素是绘制矩形的最简单手段。(对于浏览器来说,HTML 中的一切元素都可以用来表示矩形)。

所以我们可以定义一个叫 bar 的 div 类,用于存放图表的公共属性。(除了高度,其他的属性应该是共享的)

div.bar {

display: inline-block;  width: 20px;  height: 75px; /*最后这里会被覆写*/margin-right: 2px;  background-color: green;

关于类

元素的类作为 HTML 属性存在于标记代码中,同时 CSS 规则也可以引用它。除了为元素设定类以外,直接给元素应用样式也可以。(这里不太懂,下次遇到案例再写上)

D3 有一种方法用于快速添加或者删除元素的类:

.classed("bar",true) //给选中的元素添加类 bar.classed("bar",false) //从元素总删除类 bar

关于样式

.style 方法用于直接为 HTML 元素应用 CSS 属性和值。这方法执行的结果等价于在 HTML 的 style 属性中直接写入 CSS 规则

如果要生成条形图,每个条形图的高度必须是对应数据值得函数,D3 代码中可以对这个高度之进行重写:

.style("height", function(d) {var barHeight = d * 5; //这里是因为原始生成高度太矮了

return barHeight + "px";

});

关于属性设定

attr() 用于设定HTML 元素的属性和值。我们要给我们生成的 div 中添加 bar 类,需要这样写:

.attr("class","bar")

21f55ac3a0ff927bc0bfb04f852b00dd.png

代码如下:

D3: Our first bar chart with data

display: inline-block;

width: 20px;

height: 75px;/*Gets overridden by D3-assigned height below*/margin-right: 2px;

background-color: green;

}

var dataset = [ 25, 7, 5, 26, 11];

d3.select("body").selectAll("div")

.data(dataset)

.enter()

.append("div")

.attr("class", "bar")

.style("height", function(d) {var barHeight = d * 5;return barHeight + "px";

});

随机数据

教材上面用了一个可以生成随机数值得方法,在这里记录一下:

这里是创建了一个名为 dataset 得空数组;

初始化一个循环25次的 for 循环,执行25次

每次生成一个介于0到30之间的随机数

把新数值追加到数组中(push() 是数组的方法,每次执行都会把一个新值推进数组末尾)。

var dataset =[];for( var i = 0; i < 25 ;i ++){var newNumber= Math.random() * 30;

dataset.push( newNumber);}

注意:

此时 push 进去的都是浮点数,可以用 Math.round() 或者Math.floor () 方法取整。前者是将数值想上取整,后者是向下取整。

var newNumber = Math.floor(Math.random() * 30);

dataset.push( newNumber();)

绘制 SVG

SVG 元素是通过标签中的属性 / 值对来指定SVG元素的个各方面特征,如:

因为 SVG 元素存在于 DOM 中,与其他 HTML 元素一样,因此生成 SVG 图形依然要使用 append() 和 attr() 方法。

创建 SGV

首先要创建一个元素,以便在其中保存所有图形。这行代码先找到文档的 body 元素,然后再结束的 标签前添加一个新的 svg 元素。

d3.select("body").append("svg");

也可以使用一种更好的方式,把append() 返回的新元素保存在了变量 svg 中。有了这个引用,将来可以少些很多代码,从而不用总是写 da.select("svg") ,而是只要写 svg 即可:

var svg = d3.select("body").append("svg");

完整代码如下,DOM 中将创建一个新的空的 SVG元素。其中高度和宽度保存于变量中,可以方便引用。

var w =500;var h = 50;var svg = d3.select("body") .append("svg")  .attr("width",w)  .attr("height",h);

然使用data() 迭代每个数据节点,创建一个圆形。同时创建一个新的变量保存引用

var circles = svg.selectAll("circle")  .data(dataset)  .enter  .append("circle");

创建位置和大小信息:

circle.attr( "cx", function(d, i)){return (i*50) +25;  // 这里是通过引用所有的圆形的变量来设置每一个圆形的属性。(在SVG中,cx 是圆形圆心的 x 坐标,由于数据已经绑定到了圆形,所以对于每个圆形来说,都有其对应于原始数据的值。

// 并且其中的i值是自动生成的),同时,索引 i 是从function(d,i)中传入的,使其与 d 元素一致。

}) .attr("cry", h/2) .attr("r", function(d) {returnd; });

// cy 是圆形圆心的 Y 的坐标,这里把 cy 设置成了 h 的一半。由于 h 保存着整个SVG元素的高度,所以这里是将所有圆形垂直居中

// 每个圆形的半径被设为 d,从而反映数据的大小

最后生成如图示:

ec6a7abdcb1a924aa042ed12562c2b12.png

也可以在上面添加色彩:

色彩填充( fill )和描边( stroke )同样也是属性,所以也可以通过attr()方法来设定。

.attr("fill", "yellow")

.attr("stroke", "orange")

.attr("stroke-width", function(d) {return d/2;}

最后图像如下:

53fd4fef1126fdbee63d64d3e04a38fb.png

源代码为:

D3: Using color in SVG

/*No style rules here yet*/

//Width and height

var w = 500;var h = 100;//Data

var dataset = [ 5, 10, 15, 20, 25];//Create SVG element

var svg = d3.select("body")

.append("svg")

.attr("width", w)

.attr("height", h);var circles = svg.selectAll("circle")

.data(dataset)

.enter()

.append("circle");

circles.attr("cx", function(d, i) {return (i * 50) + 25;

})

.attr("cy", h/2)

.attr("r", function(d) {returnd;

})

.attr("fill", "yellow")

.attr("stroke", "orange")

.attr("stroke-width", function(d) {return d/2;

});

关于绘制条形图的改进:

我们也可以通过 SVG 的方式来绘制条形图:

首先确定 SVG 的大小:

var w = 500;var h = 500;

然后让 D3 创建一个空元素,将其添加到 DOM 中.复习一下,这些代码会在结束的标签前面插入新的 svg 元素,并将结果保存在了变量 svg 中,因此以后可以方便引用这个 sv g元素,而不用每次再使用 select() 之类的代码重新选择。

var svg = d3.select("body")

.append("svg")

.attr("width",w)

.attr("height",h);

然后不创建 div,而是生成矩形元素 rect 并将其添加到 svg 中。

这段代码选择了 svg 中所有的矩形。但是,现在什么也没有,所以会返回一个空的元素集。

接下来 data(dataset) 看到了数据集中有20个值,就把这些值交给了 enter() 处理。每个rect  必须有 x, y width 和 height 属性。这里就是用 attr() 为每个新创建的 rect 设置了这些属性。但是这样会出现一个问题,就是所有的条形生成以后就重叠在了一起,而且此时并没有反映数据。

svg.selectAll("rect")

.data(dataset)

.enter()

.append("rect")

.attr("x",0)

.attr("y",0)

.attr("width",20)

.attr("height",100);

为了解决重叠问题们同样需要使用 function() 函数:

.attr("x",function(d,i)) {return i*21; //由于矩形宽20像素,所以外加一个像素作为间距。

};

动态缩放:

当数据比较多的时候,最右边的矩形很有可能跑到 SVG 外面去,这时候就需要使用灵活、动态的坐标方案了。

首先,从改进设置每条矩阵 x 坐标的那行代码进行修改,这样的话,每个矩形就会进行缩放生成。当数据密的时候就会密集,当数据稀疏的时候间距就会拉大。

.attr("x",function(d,i) {return i * (w /dataset.length);

})

以图为例:

当数据密集的时候:

9e8c1280a7c13c90d55f7206ec492a15.png

当数据稀疏的时候:

ab220191f50e547a97b12b023d82cc3a.png

这种解决方式并不好看。为了更加的美观,可以将矩形的宽度也成比例的缩放。

var w = 500;var h = 100;var barPadding = 1; //这里的变量是减去的间距的值

.attr("width",w / dataset.length - Padding)

然后再让数据值决定条形高度:

.attr("height",function(d)){return d*4; //放大四倍

});

结果如图所示:

由于 SVG 在绘制时,x 和 y 值指定的是它们左上角的坐标,所以 SVG 支持的只有左上角坐标系。如果我们需要改成一般的矩形图,就需要将每个图形的“下沿”与 SVG 的下沿对齐,每个 rect 的 height可以就设置为数据值的本身。

7578b6cdc5d3b34aa364fbd2be788a91.png

.attr("y", function(d){return h -d;

})

.attr("height",function(d){returnd;

});

结果如图示:

d39fad06c320bf5771a87d7e371b7b31.png

上色

使用 fill 属性可以对其添加颜色:

.attr(" fill", "teal");

我们也可以让颜色反映数据的某些特性,对着条形图而言,这样做叫做双重编码,即同样的数据值可以被编码成俩种可以见的特性:条形高度和颜色。

.attr( "fill", function(d){return "rgb( 0, 0, "+(d * 10) +" )";

附录:关于多值映射

D3 拥有多值映射机制,从而可以一次性设置多个值。而且依然是用 attr( ) 方法。假设要把一个圆形平移到 SVG 左上角,再设置成红色,可以每次单独调用 attr( ) :

svg.select("circlr")

.attr("cx",0)

.attr("cy",0)

.attr("fill", "red")

也可以把这三个属性的值都封装在一个对象中,然后统一交给 attr( ) :

svg.select("circlr")

.attr({

cx:0;

cy:0;

fill:"red"});

源代码为:

D3: Adding dynamic color, based on data

/*No style rules here yet*/

//Width and height

var w = 500;var h = 100;var barPadding = 1;var dataset = [ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13,11, 12, 15, 20, 18, 17, 16, 18, 23, 25];//Create SVG element

var svg = d3.select("body")

.append("svg")

.attr("width", w)

.attr("height", h);

svg.selectAll("rect")

.data(dataset)

.enter()

.append("rect")

.attr("x", function(d, i) {return i * (w /dataset.length);

})

.attr("y", function(d) {return h - (d * 4);

})

.attr("width", w / dataset.length -barPadding)

.attr("height", function(d) {return d * 4;

})

.attr("fill", function(d) {return "rgb(0, 0, " + Math.round(d * 10) + ")";

});

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值