墙上的堆积物

被稿子虐,被代码搞

D3.js:绘制SVG

今天学习的是SVG的绘制,也是D3的核心内容之一,虽然这章并没有学完,但稍微的浏览了下后面的内容,我觉得D3果然是个神器没跑了~那就好好学着吧。


<!DOCTYPE html>

<html lang="en">
<head>
<meta charset="utf-8">
<title>D3 Page Template</title>
<script src="d3/d3.js"></script>
<style>
div.bar {
display: inline-block;
width: 20px;
height: 75px;/*后面会根据数值定义*/
background-color: teal;
}
</style>
</head>
<body>
<script>
var dataset = [5, 10, 15, 20, 25 ]
<div class="bar"></div>
//attr()用于设定 HTML 元素的属性和值。
/*包含以下5个属性及值
class caption
id country
src logo.png
width 100px
alt Logo
*/
//.attr("class","bar")等同<div class="bar"></div>
//利用class()快速添加或删除元素的类
.classed("bar",true)
.classed("bar",false)

//案例
var dataset = [5, 10, 15, 20, 25 ];
d3.select("body").selectAll("div")
.data(dataset)
.enter()
.append("div")
.attr("class","bar")
//添加高度,并以5倍乘,添加间隙
.style("height",function(d){
return d*5 +"px";
});



//excise

var dataset = [ 25, 7, 5, 26, 11, 8, 25, 14, 23, 19, 14, 11, 22, 29, 11, 13, 12, 17, 18, 10, 24, 18, 25, 9, 3 ];
d3.select("body").selectAll("div")
.data(dataset)
.enter()
.append("div")
.attr("class","bar")
.style("height",function(d){
return d*5 + "px";
})



//随机柱状图
var dataset = [];//空数组
//for 循环
for (var i = 0; i<25; i++){
var newNumber = Math.floor(Math.random()*30); //生成介于0到30的随机数
dataset.push(newNumber)//将数值追加到数组中。
}
//math.round()向上舍入最接近的整数
//math.floor()向下舍入最接近的整数
var newNumber = Math.round(Math.random()*30)

//完整
var dataset = [];
for (var i = 0; i<25; i++){
var newNumber = Math.floor(Math.random()*30);
dataset.push(newNumber);
}
d3.select("body").selectAll("div")
.data(dataset)
.enter()
.append("div")
.attr("class","bar")
.style("height",function(d){
return d*5 +"px";
})
/*出错点:
d3.select <- da.select
for(var i = 0; i<25; i++) <- (var i = 0, i<25, i++)
.data(dataset) <- .data = dataset
return d*5 +"px" <-return d*5 +px
*/




//绘制SVG

//create cirle
//set width and height
var w = 500;
var h =50;
d3.select("body").append("svg")//create a svg
var svg = d3.select("body")
.append("svg")//create a new variable
.attr("width",w)
.attr("height",h);
var = dataset = [5, 10, 15, 20, 25 ];
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle");
/*set cx cy and r
cx:圆心x坐标
cy:圆心y坐标
r :半径,此处直接使用数据值。
*/
circle.attr("cx", function(d, i){
return (i * 50 ) + 25;
})
.attr("cy",h/2)
.attr("r",function(d) {
return d;
});



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



      //create rect
      var dataset = [ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13,11, 12, 15, 20, 18, 17, 16, 18, 23, 25 ];
      var w = 500
      var h = 100
      var svg = d3.select("body")
                 .append("svg")
                 .attr("width",w)
                 .attr("height",h);

     svg.selectAll("rect")
     .data(dataset)
      .enter()
      .append("rect")
      .attr("x",0)
      .attr("y",0)
      .attr("weight",20)
      .attr("height",100);
      //解决重叠问题
      .attr("x", function(d, i) {
          return i * 21;
         })//width:20,gap:1




      //宽度的动态缩放
      var ws = w / dataset.length - barpadding//自己给加的一个函数,我作者也只是忘了放上去吧。
         .attr("x", function(d, i) {
          return i * (ws + 1);
         })//width:20,gap:1
         .attr("width", ws)





      //坐标轴变换
         .attr("y", function(d) {
          return h - d * 4;
         .attr("height", function(d) {
          return d * 4;
         })
        //fill color
        .attr("fill", "teal")




         //自己尝试定义了一个条件,终于有次能不看书敲出if的代码了!
         .attr("fill", function(d) {
          if (d > 15){
            return "red"
          }else{return "black"};
         })


      //多值映射的写法
      svg.select("rect")
         .data(dataset)
         .enter()
         .append("rect")
         .attr({
          x:function(d, i) {
            return i * (ws + 1);},
          y:function(d) { return h - d * 4;},
          width: w / dataset.length - barpadding,
          height: function(d) { return d *4 ;}
          fill: function(d) { return "rgb(255, 0, " + (d * 10) + ")";}
         })

 

      //添加数值标签
      svg.selectAll("text")
         .data(dataset)
         .enter()
         .append("text")
         .text(function(d) {
          return d;
         })
         .attr("x",function(d, i ) {
          return i * ( ws + 1);
         })
         .attr("y",function(d) {
          return h - (d * 4) + 14;
         })
         .attr("fill","white")


作者吐槽:
假如你没有排版强迫症,现在就可以收手了。不过,假如你跟我一样吹毛求疵,会发现值标签与各自的条形没有完美对齐。(比如,第一个条形中的 5。)改这个太容易啦,可以使用 SVG 的 text-anchor 属性来水平居中文本,就像指定 x 值一样:
         .attr("text-anchor", "middle")
太懂我好嘛!!!
加上去了以后。
         .attr("text-anchor","middle")

  
 

但是居然是这样的@_@

发现问题后,才知道x的轴点没算对。果然数学太差,智商捉急。
         .attr("x",function(d, i ) {
          return i * ( ws + 1) + ws / 2;
         })

      //添加数值标签全部代码
      svg.selectAll("text")
         .data(dataset)
         .enter()
         .append("text")
         .text(function(d) {
          return d;
         })
         .attr("x",function(d, i ) {
          return i * ( ws + 1) + ws / 2;
         })
         .attr("y",function(d) {
          return h - (d * 4) + 14;
         })
         .attr("fill","white")
         .attr("text-anchor","middle")



      //绘制散点图
      //散点图需要用到数组。(x,y)轴点
      var w = 500
      var h = 100
      var dataset = [
        [  5,  20 ],
        [480,  90 ],
        [250,  50 ],
        [100,  33 ],
        [330,  95 ],
        [410,  12 ],
        [475,  44 ],
        [ 25,  67 ],
        [ 85,  21 ],
        [220,  88 ]
      ];

      //绘制svg
      var svg = d3.select("body")
                  .append("svg")
                  .attr("width", w)
                  .attr("height", h);

      svg.selectAll("circle")
          .data(dataset)
          .enter()
          .append("circle")
          .attr("cx",function(d) {
            return d[0];
          })
          .attr("cy",function(d) {
            return d[1];
          })
          .attr("r", 5);

  
 

      /*数组中的元素调用
      d[0]返回小数组的第一个元素-> 5
      d[1]返回小数组的第二个元素-> 20
      访问大数组的值
      dataset[5] -> [410,12]
      */


      /*设置散点大小
      几乎所有的绘图都是无法直接指定圆形面积的,都需要依靠自己计算半径,也就是对面积开平方*/
          .attr("r", function(d) {
            return Math.sqrt(h - d[1])
          });



      //添加标签
      svg.selectAll("text")
          .data(dataset)
          .enter()
          .append("text")
          .text(function(d){
            return d[0] + "," + d[1];
          })
          .attr({
          x: function(d) {return d[0];},
          y: function(d) {return d[1];},
          fill: "red",
          })
          .attr("font-size","11px")
          .attr("font-family","sans-serif");


 
    </script> 
 
  </body> 
</html> 
 
This would be a good time to take a break and stretch your legs. Maybe go for a walk, or grab a coffee or a sandwich. I’ll hang out here (if you don’t mind), and when you get back, we’ll jump into D3 scales! 
 
好的呢~看完吃了顿饭回来写这个~ 



评论

© 墙上的堆积物 | Powered by LOFTER