D3.js(v3版本)

D3.js

<script src="https://d3js.org/d3.v6.min.js"></script>
import * as d3 from "d3";//将内容导入到命名空间
const d3 = require("d3");//在节点中
1.svg

一种文本格式

给svg元素指定width和height值

<svg width="500" height="50"></svg>

rect用于绘制矩形

(x和y用于指定矩形左上角的坐标)

circle用于绘制圆形

ellipse每个轴要分别指定半径

line用于绘制直线

text用于绘制文本(x用于指定文本左上角的位置,y用于指定字体的基线位置)

Easy-peasy

svg属性

fill颜色 stroke颜色值 stroke-width带单位的数值 opacity设置透明度

文本font-family font-size

分层与绘制顺序–代码中元素出现的顺序决定了它们的深度次序

<!DOCTYPE html>
<html lang="en">
 <head>
 <meta charset="utf-8">
 <title>D3 Page Template</title>
 <script type="text/javascript" src="d3/d3.v3.js"></script>
 </head>
 <body>
 <script type="text/javascript">
 // 创建新的元素
//  d3.select("body").append("p").text("New paragraph!");
 //绑定数据selection.data()

 //1.加载csv数据
//  d3.csv("1.csv",function(data){
//      console.log(data);
//  });
// var dataset; // 全局变量
// d3.csv("1.csv", function(data) {
//  dataset = data; // 加载完毕,就将其复制到 dataset.
//  generateVis(); // 再调用其他依赖数据
//  hideLoadingMsg(); // 显示图形的函数
// });
// d3.json("1.json",function(json){
//     console.log(json);
// });
var dataset=[5,10,15,20,25];
d3.select("body").selectAll("p")
    .data(dataset)//解析并数出数据值,因为数组中有5个值,因而此后的所有方法都将执行五遍,每次针对一个值
    .enter()//创建新的绑定元素
    .append("p")
    // .text("New paragraph!");
    //使用绑定到了DOM中新创建的元素
    .text(function(d){return d;})
    //D3绑定的数据没有出现在DOM中,而是作为元素的__data__属性保存在内存中
    //添加样式
    // .style("color","red");
    .style("color",function(d){
        if(d>15){
            return "red";
        }else{
            return "black";
        }
    });

 </script>
 </body>
</html>
2.设定样式style(),设定属性attr()
 <style>
     div.bar{
         display:inline-block;
         width:20px;
         height:75px;
         background-color: teal;
         margin-right: 2px;
     }
 </style>
 </head>
 <body>
     <div></div>
 <script type="text/javascript">
   var dataset=[];
   for(var i=0;i<25;i++){
       var newNumber=Math.random()*30;
       dataset.push(newNumber);//把新数值添加到数组中
   }
   d3.select("body").selectAll("div")
      .data(dataset)
      .enter()
      .append("div")
      //attr()设定属性,class,id,src,width,alt
      .attr("class","bar")
      .style("height",function(d){
          var barHeight=d*5;
          return barHeight+"px";
      });
 </script>
 </body>
3.绘制svg元素
<body>
     
 <script type="text/javascript">
    var svg=d3.select("body")
              .append("svg")
              .attr("width",500)
              .attr("height",50);
    var dataset=[5,10,15,20,25];
    var circles=svg.selectAll("circle")
       .data(dataset)//把数据绑定到即将创建的元素
       .enter()//返回对这个新元素的占位引用
       .append("circle");
    circles.attr("cx",function(d,i){//i当前元素的索引值
        return (i*50)+25;
        })
        .attr("cy",h/2)
        .attr("r",function(d){
            return d;
        })
        .attr("fill","yellow")
        .attr("stroke","orange")
        .attr("stroke-width",function(d){
            return d/2;
        });
    
 </script>
 </body>
4.绘制条形图
<!DOCTYPE html>
<html lang="en">
 <head>
 <meta charset="utf-8">
 <title>D3 Page Template</title>
 <script type="text/javascript" src="d3/d3.v3.js"></script>
 <style>
 </style>
 </head>
 <body>
     <p>Click on this text to update the chart with new data values (once).</p>
 </body>
</html>
<script type="text/javascript">
    var dataset=[ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13,11, 12, 15, 20, 18, 17, 16, 18, 23, 25 ];
    var w=600;
    var h=300;

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

    //设置序数比例尺
    var xScale = d3.scale.ordinal()
                         .domain(d3.range(dataset.length))//设置了输入值的值域
                         //.rangeBands()根据输入值域的长度自动将其切成相等的块或档,第二个参数设置档间距
                         //.rangeRoundBands()输出的值会舍入为最接近的整数
                         .rangeRoundBands([0, w], 0.05);
    var yScale = d3.scale.ordinal()
                         .domain(d3.range(30))//设置了输入值的值域
                         //.rangeBands()根据输入值域的长度自动将其切成相等的块或档,第二个参数设置档间距
                         //.rangeRoundBands()输出的值会舍入为最接近的整数
                         .rangeRoundBands([0, h],0.05);
    //添加矩形,条形图
    svg.selectAll("rect")
        .data(dataset)
        .enter()
        .append("rect")
        .attr("x",function(d,i){return xScale(i);})
        .attr("y", function(d){return h-yScale(d);})//让条形从下向上
        .attr("width",xScale.rangeBand())
        .attr("height", function(d){return yScale(d);})
        .attr("fill",function(d){return "rgb(0,0,"+(d*10)+")";});

    //加标签
    svg.selectAll("text")
       .data(dataset)
       .enter()
       .append("text")
       .text(function(d){return d;})
       .attr("x",function(d,i){return xScale(i) + xScale.rangeBand() / 2;})
       .attr("y",function(d){ return h-yScale(d)+14;})
       .attr("font-family","sans-serif")
       .attr("font-size","11px")
       .attr("fill","white")
       .attr("text-anchor","middle")//text-anchor水平居中文本


    d3.select("p")
      .on("click",function(){
      //从数据集中删除第一个元素
    //   dataset.shift();

      //新数据集
      var numValues = dataset.length; // 取得原数据集的长度
      dataset = []; // 初始化空数组
      for (var i = 0; i < numValues; i++) { 
        var newNumber = Math.floor(Math.random() * 25); // 生成新随机数(0~24)
        dataset.push(newNumber); // 把新数值添加到数组
      }

      yScale.domain(d3.range(30));//更新比例尺的值域
      //更新所有矩形
      var bars=svg.selectAll("rect")
         .data(dataset)
         .transition()//动态动画
         .duration(1000)//参数的单位是持续1毫秒
         .attr("y", function(d) {return h - yScale(d);})
         .attr("height", function(d) {return yScale(d);});
         
      svg.selectAll("text")
         .data(dataset)
         .transition()
         //设置静态延迟时间
         //  .delay(1000)//延迟时间
         //设置动态延迟时间
         .delay(function(d,i){
             return i/dataset.length*1000;//确保数据在很多时总的过渡时间是可以接收的
         })
         .duration(500)
         //默认缓动效果是cublic-in-out逐渐加速然后逐渐减速
        //  .ease("linear")//线性缓动,没有逐渐加速和减速的变化
        //  .ease("circle")//逐渐加速进入并加速,然后突然停止
        //  .ease("elastic")//有弹性
         .ease("bounce")//像皮球落地一样反复弹跳,慢慢停下来
         .text(function(d) {
            return d;
            })
         .attr("x", function(d, i) {
            return xScale(i) + xScale.rangeBand() / 2;
            })
         .attr("y", function(d) {
            return h - yScale(d) + 14;
           });
        //退出
        // bars.exit()
        //     .transition(1000)
        //     .attr("x",w)
        //     .remove();
        // svg.selectAll("text")
        // .data(dataset,key)
        // .exit()
        // .transition()
        // .duration(500)
        // .attr("x",w)
    });
 </script>
5.绘制散点图
<script type="text/javascript">
 var dataset = [[5, 20], [480, 90], [250, 50], [100, 33], [330, 95],[410, 12], [475, 44], [25, 67], [85, 21], [220, 88]];
 //创建svg元素
 var w=1000;
 var h=1000;
 var svg = d3.select("body")
             .append("svg")
             .attr("width", w)
             .attr("height", h);
 var circles=svg.selectAll("circle") // <-- 不是 "rect" 了
                .data(dataset)
                .enter()
                .append("circle") // <-- 不是 "rect" 了
 circles.attr("cx",function(d){
            return d[0];
        })
        .attr("cy",function(d){
            return d[1];
        })
        .attr("r",function(d){
            return Math.sqrt(d[1]);//下方的圆形大
            // return Math.sqrt(h-d[1]);//上方的圆形大
        });
 var texts=svg.selectAll("text") // <-- 注意是 "text",而非 "circle" 或 "rect"
    .data(dataset)
    .enter()
    .append("text")
    //text()方法设定了每个元素的内容
    .text(function(d) {
         return d[0] + "," + d[1];
     })
     //为文本设置样式
    .attr("x", function(d) {
         return d[0];
     })
     .attr("y", function(d) {
        return d[1];
     })
     .attr("font-family", "sans-serif")
     .attr("font-size", "11px")
     .attr("fill", "red");
 </script>
<!DOCTYPE html>
<html lang="en">
 <head>
 <meta charset="utf-8">
 <title>D3 Page Template</title>
 <script type="text/javascript" src="d3/d3.v3.js"></script>
 <style>
     /* 数轴本身由path,line和text组成 */
    /* css给svg元素应用样式时,只能使用svg的属性名,不能使用常规的CSS属性 */
    .axis path,
    .axis line{
        fill:none;
        stroke:black;
        shape-rendering:crispEdges;
        /* shape-rendering保证数轴和刻度线精确到像素级 */
    }
    .axis text{
        font-family: sans-serif;
        font-size: 11px;
    }
 </style>
 </head>
 <body>
     <P>点击我试试更换数据吧</P>
     <!-- 剪切路径,本身不可见,但可以包含可见的元素 -->
     <!-- 在clipPath中放一个可见的元素 -->
     <clipPath id="chart-area">
        <rect x="30" y="30" width="410" height="240"></rect>
       </clipPath>
 </body>
</html>
<script type="text/javascript">
var h=500;
var w=500;
var dataset = [];
var numDataPoints = 50;
var xRange = Math.random() * 1000;
var yRange = Math.random() * 1000;
for (var i = 0; i < numDataPoints; i++) {
 var newNumber1 = Math.floor(Math.random() * xRange);
 var newNumber2 = Math.floor(Math.random() * yRange);
 dataset.push([newNumber1, newNumber2]);
}
var padding=30;//边距向量
var svg=d3.select("body")
          .append("svg")
          .attr("width",h)
          .attr("height",w);

//创建比例尺
var xScale=d3.scale.linear()
                   .domain([0,d3.max(dataset,function(d){return d[0];})])//设置比例尺的值域 
                   .range([padding,w-padding*2]);//设置输出范围
                   //边距可以把圆形向里推,使它们远离svg的四边,从而避免被切掉
var yScale=d3.scale.linear()
                   .domain([0,d3.max(dataset,function(d){return d[1];})])//设置比例尺的值域 
                //    .range([0,h]);//设置输出范围,较小的y值在图表上方
                   .range([h-padding,padding]);

var rScale=d3.scale.linear()
                   .domain([0,d3.max(dataset,function(d){return d[1];})])
                   .range([2,5]);
 //d3.max()会循环数组中的每一个x值,返回其中最大的那个
//设定数轴
var xAxis=d3.svg.axis()
                .scale(xScale)
                .orient("bottom")//设定标签相对于数轴显示在什么地方
                .ticks(5);//粗略设置刻度线的数量
// 定义 y 轴
var yAxis = d3.svg.axis()
                  .scale(yScale)
                  .orient("left")
                  .ticks(5);

//定义剪切路径,添加蒙版
svg.append("clipPath")//创建新的clipPath元素
   .attr("id","chart-area")//指定ID  
   .append("rect")//在clipPath中创建并添加新的rect
   .attr("x",padding)//设置rect的位置和大小
   .attr("y",padding)
   .attr("width",w-padding*3)
   .attr("height",h-padding*2)

var circles=svg.append("g") // 创建新的 g 元素
                   .attr("id", "circles") // 指定它的 ID 为 circles
                   .attr("clip-path", "url(#chart-area)") // 添加对 clipPath 的引用
                   .selectAll("circle") // 剩下的代码跟以前一样……
                   .data(dataset)
                   .enter()
                   .append("circle")
                   //所有的圆形都被组织到一个g元素中,这个g元素的clip-path属性指向了新创建的剪切路径
circles.attr("cx",function(d){
            return xScale(d[0]);
        })
        .attr("cy",function(d){
            return yScale(d[1]);
        })
        // .attr("r",function(d){
        //     return Math.sqrt(d[1]);//下方的圆形大
        //     // return Math.sqrt(h-d[1]);//上方的圆形大
        // });
        .attr("r",function(d){
            return rScale(d[1]);
        });
var texts=svg.selectAll("text") // <-- 注意是 "text",而非 "circle" 或 "rect"
    .data(dataset)
    .enter()
    .append("text")
    //text()方法设定了每个元素的内容
    .text(function(d) {
         return d[0] + "," + d[1];
     })
     //为文本设置样式
    .attr("x", function(d) {
         return xScale(d[0]);//缩放后的值
     })
     .attr("y", function(d) {
        return yScale(d[1]);
     })
     .attr("font-family", "sans-serif")
     .attr("font-size", "11px")
     .attr("fill", "red");
 //添加x轴数轴
 //调用数轴函数
svg.append("g")//g是一个分组元素,是不可见的,1.可以用来包含其他元素 2.可以对整个分组应用变换
   .attr("class","x axis")
   .attr("transform","translate(0,"+(h-padding)+")")//将整个数轴分组平移到图表下方;translate(x,y)平移函数
   .call(xAxis);//call()函数会取得传递过来的元素;把g交给了xAxis函数,在g里面生成数轴
//将剪切路径应用到圆形
 //添加y轴数轴      
svg.append("g")
    .attr("class", "y axis")
    .attr("transform", "translate(" + padding + ",0)")
    .call(yAxis);


d3.select("p")
  .on("click",function(){
  //更新x上的比例尺
  var xScale=d3.scale.linear()
                .domain([0,d3.max(dataset,function(d) {return d[0]; })])
                .range([padding,w-padding*2]);
                
  //更新y上的比例尺               
  var yScale=d3.scale.linear()
                     .domain([0,d3.max(dataset,function(d) {return d[1]; })])
                     .range([h-padding,padding])           
  //更新r的比例尺
  var rScale=d3.scale.linear()
                .domain([0,d3.max(dataset,function(d){ return d[1]; })])
                .range([2,5]);

 //定义x轴数轴  一定要重新定义一次在更新,否则数轴更新无效
  var xaxis=d3.svg.axis()
                .scale(xScale)
                .orient("bottom")//设定标签相对于数轴显示在什么地方
                .ticks(5);//粗略设置刻度线的数量
  var yaxis = d3.svg.axis()
                  .scale(yScale)
                  .orient("left")
                  .ticks(5);    
  
  //更换x轴数据
  svg.select(".x.axis")
     .transition()
     .duration(1000)
     .call(xaxis);
  // 更新 y 轴
  svg.select(".y.axis")
     .transition()
     .duration(1000)
     .call(yaxis);
  //方法一   
//   svg.selectAll("circle")
//     .data(dataset)
//     .transition()
//     .duration(1000)
//     .each("start", function() { // <-- 在过渡开始时执行
//         d3.select(this)
//             .attr("fill", "magenta")
//             .attr("r", 3);
//             })
//     //each(start)里面执行立即变换,而不能再添加任何过渡效果
//     .attr("cx", function(d) {
//     return xScale(d[0]);
//     })
//     .attr("cy", function(d) {
//     return yScale(d[1]);
//     })
//     .each("end", function() { // <-- 在过渡结束时执行
//         d3.select(this)
//             .transition()
//             .duration(1000)
//             .attr("fill", "black")
//             .attr("r", 2);
//             })
//     //each(end)支持过渡
//     });
    //方法二
   svg.selectAll("circle")
    .data(dataset)
    .transition() // <-- #1 过渡
    .duration(1000)
    .each("start", function() {
        d3.select(this)
        .attr("fill", "magenta")
        .attr("r", 7);
        })
    .attr("cx", function(d) {
         return xScale(d[0]);
        })
    .attr("cy", function(d) {
         return yScale(d[1]);
        })
    .transition() // <-- #2 过渡
    .duration(1000)
    .attr("fill", "black")
    .attr("r", 2);
    })
</script>
6.比例尺d3.scale.linear()
<!DOCTYPE html>
<html lang="en">
 <head>
 <meta charset="utf-8">
 <title>D3 Page Template</title>
 <script type="text/javascript" src="d3/d3.v3.js"></script>
 <style>
     /* 数轴本身由path,line和text组成 */
    /* css给svg元素应用样式时,只能使用svg的属性名,不能使用常规的CSS属性 */
    .axis path,
    .axis line{
        fill:none;
        stroke:black;
        shape-rendering:crispEdges;
        /* shape-rendering保证数轴和刻度线精确到像素级 */
    }
    .axis text{
        font-family: sans-serif;
        font-size: 11px;
    }
 </style>
 </head>
 <body>
 </body>
</html>
<script type="text/javascript">
var h=500;
var w=500;
var dataset = [];
var numDataPoints = 50;
var xRange = Math.random() * 1000;
var yRange = Math.random() * 1000;
for (var i = 0; i < numDataPoints; i++) {
 var newNumber1 = Math.floor(Math.random() * xRange);
 var newNumber2 = Math.floor(Math.random() * yRange);
 dataset.push([newNumber1, newNumber2]);
}
var padding=30;//边距向量
var svg=d3.select("body")
          .append("svg")
          .attr("width",w)
          .attr("height",h);

//创建比例尺
var xScale=d3.scale.linear()
                   .domain([0,d3.max(dataset,function(d){return d[0];})])//设置比例尺的值域 
                   .range([padding,w-padding*2]);//设置输出范围
                   //边距可以把圆形向里推,使它们远离svg的四边,从而避免被切掉
var yScale=d3.scale.linear()
                   .domain([0,d3.max(dataset,function(d){return d[1];})])//设置比例尺的值域 
                //    .range([0,h]);//设置输出范围,较小的y值在图表上方
                   .range([h-padding,padding]);

var rScale=d3.scale.linear()
                   .domain([0,d3.max(dataset,function(d){return d[1];})])
                   .range([2,5]);
 //d3.max()会循环数组中的每一个x值,返回其中最大的那个
//设定数轴
var xAxis=d3.svg.axis()
                .scale(xScale)
                .orient("bottom")//设定标签相对于数轴显示在什么地方
                .ticks(5);//粗略设置刻度线的数量
// 定义 y 轴
var yAxis = d3.svg.axis()
                  .scale(yScale)
                  .orient("left")
                  .ticks(5);
svg.append("g")
    .attr("class", "axis")
    .attr("transform", "translate(" + padding + ",0)")
    .call(yAxis);
    
//调用数轴函数
svg.append("g")//g是一个分组元素,是不可见的,1.可以用来包含其他元素 2.可以对整个分组应用变换
   .attr("class","axis")
   .attr("transform","translate(0,"+(h-padding)+")")//将整个数轴分组平移到图表下方;translate(x,y)平移函数
   .call(xAxis);//call()函数会取得传递过来的元素;把g交给了xAxis函数,在g里面生成数轴
var circles=svg.selectAll("circle") // <-- 不是 "rect" 了
                .data(dataset)
                .enter()
                .append("circle") // <-- 不是 "rect" 了
circles.attr("cx",function(d){
            return xScale(d[0]);
        })
        .attr("cy",function(d){
            return yScale(d[1]);
        })
        // .attr("r",function(d){
        //     return Math.sqrt(d[1]);//下方的圆形大
        //     // return Math.sqrt(h-d[1]);//上方的圆形大
        // });
        .attr("r",function(d){
            return rScale(d[1]);
        });
var texts=svg.selectAll("text") // <-- 注意是 "text",而非 "circle" 或 "rect"
    .data(dataset)
    .enter()
    .append("text")
    //text()方法设定了每个元素的内容
    .text(function(d) {
         return d[0] + "," + d[1];
     })
     //为文本设置样式
    .attr("x", function(d) {
         return xScale(d[0]);//缩放后的值
     })
     .attr("y", function(d) {
        return yScale(d[1]);
     })
     .attr("font-family", "sans-serif")
     .attr("font-size", "11px")
     .attr("fill", "red");
 </script>

nice()告诉比例尺取得为range()设置的任何值域

rangeRound()则比例尺输出的所有值都会舍入到最接近的整数值。

clamp()线性比例尺可以返回指定范围之外的值

7.添加值
<!DOCTYPE html>
<html lang="en">
 <head>
 <meta charset="utf-8">
 <title>D3 Page Template</title>
 <script type="text/javascript" src="d3/d3.v3.js"></script>
 <style>
 </style>
 </head>
 <body>
     <p>Click on this text to update the chart with new data values (once).</p>
 </body>
</html>
<script type="text/javascript">
    var dataset=[ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13,11, 12, 15, 20, 18, 17, 16, 18, 23, 25 ];
    var w=600;
    var h=300;

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

    //设置序数比例尺
    var xScale = d3.scale.ordinal()
                         .domain(d3.range(dataset.length))//设置了输入值的值域
                         //.rangeBands()根据输入值域的长度自动将其切成相等的块或档,第二个参数设置档间距
                         //.rangeRoundBands()输出的值会舍入为最接近的整数
                         .rangeRoundBands([0, w], 0.05);
    var yScale = d3.scale.ordinal()
                         .domain(d3.range(30))//设置了输入值的值域
                         //.rangeBands()根据输入值域的长度自动将其切成相等的块或档,第二个参数设置档间距
                         //.rangeRoundBands()输出的值会舍入为最接近的整数
                         .rangeRoundBands([0, h],0.05);
    //添加矩形,条形图
    svg.selectAll("rect")
        .data(dataset)
        .enter()
        .append("rect")
        .attr("x",function(d,i){return xScale(i);})
        .attr("y", function(d){return h-yScale(d);})//让条形从下向上
        .attr("width",xScale.rangeBand())
        .attr("height", function(d){return yScale(d);})
        .attr("fill",function(d){return "rgb(0,0,"+(d*10)+")";});

    //加标签
    svg.selectAll("text")
       .data(dataset)
       .enter()
       .append("text")
       .text(function(d){return d;})
       .attr("x",function(d,i){return xScale(i) + xScale.rangeBand() / 2;})
       .attr("y",function(d){ return h-yScale(d)+14;})
       .attr("font-family","sans-serif")
       .attr("font-size","11px")
       .attr("fill","white")
       .attr("text-anchor","middle")//text-anchor水平居中文本


    d3.select("p")
      .on("click",function(){
      //向数据集中添加一个新值
      var maxValue=25;
      var newNumber = Math.floor(Math.random()*maxValue); // 生成新随机数(0~24)
      dataset.push(newNumber); // 把新数值添加到数组

      xScale.domain(d3.range(dataset.length));//更新比例尺的值域
      //1.选择,bars就保存了新的数据集
      var bars=svg.selectAll("rect")
                  .data(dataset)

      //2.加入
      bars.enter()
        .append("rect")
        .attr("x", w)
        .attr("y", function(d) {
        return h - yScale(d);
        })
        .attr("width", xScale.rangeBand())
        .attr("height", function(d) {
        return yScale(d);
        })
        .attr("fill", function(d) {
        return "rgb(0, 0, " + (d * 10) + ")";
        });
      //3.更新
      bars.transition()
            .duration(500)
            .attr("x", function(d, i) {
            return xScale(i);
            })
            .attr("y", function(d) {
            return h - yScale(d);
            })
            .attr("width", xScale.rangeBand())
            .attr("height", function(d) {
            return yScale(d);
            });        
    
      texts=svg.selectAll("text")
         .data(dataset)
         .enter()
         .append("text")
         .text(function(d){return d;})
         
      texts.transition()
         //设置静态延迟时间
         //  .delay(1000)//延迟时间
         //设置动态延迟时间
         .delay(function(d,i){
             return i/dataset.length*1000;//确保数据在很多时总的过渡时间是可以接收的
         })
         .duration(500)
         .ease("bounce")//像皮球落地一样反复弹跳,慢慢停下来
         .text(function(d) {
            return d;
            })
         .attr("x", function(d, i) {
            return xScale(i) + xScale.rangeBand() / 2;
            })
         .attr("y", function(d) {
            return h - yScale(d) + 14;
           })
         .attr("font-family","sans-serif")
         .attr("font-size","11px")
         .attr("fill","white")
         .attr("text-anchor","middle");//text-anchor水平居中文本

        //退出
        // bars.exit()
        //     .transition(1000)
        //     .attr("x",w)
        //     .remove();
        // svg.selectAll("text")
        // .data(dataset,key)
        // .exit()
        // .transition()
        // .duration(500)
        // .attr("x",w)
    });
 </script>
8.删除值
<!DOCTYPE html>
<html lang="en">
 <head>
 <meta charset="utf-8">
 <title>D3 Page Template</title>
 <script type="text/javascript" src="d3/d3.v3.js"></script>
 <style>
 </style>
 </head>
 <body>
     <p>Click on this text</p>
 </body>
</html>
<script type="text/javascript">
    var dataset = [ { key: 0, value: 5 },
                    { key: 1, value: 10 },
                    { key: 2, value: 13 },
                    { key: 3, value: 19 },
                    { key: 4, value: 21 },
                    { key: 5, value: 25 },
                    { key: 6, value: 22 },
                    { key: 7, value: 18 },
                    { key: 8, value: 15 },
                    { key: 9, value: 13 },
                    { key: 10, value: 11 },
                    { key: 11, value: 12 },
                    { key: 12, value: 15 },
                    { key: 13, value: 20 },
                    { key: 14, value: 18 },
                    { key: 15, value: 17 },
                    { key: 16, value: 16 },
                    { key: 17, value: 18 },
                    { key: 18, value: 23 },
                    { key: 19, value: 25 } ];
                    //键名可以自己定义
    var w=600;
    var h=300;

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

    //设置序数比例尺
    var xScale = d3.scale.ordinal()
                         .domain(d3.range(dataset.length))//设置了输入值的值域
                         //.rangeBands()根据输入值域的长度自动将其切成相等的块或档,第二个参数设置档间距
                         //.rangeRoundBands()输出的值会舍入为最接近的整数
                         .rangeRoundBands([0, w], 0.05);
    var yScale = d3.scale.linear()
                         .domain([0, d3.max(dataset, function(d) { return d.value; })])
                         .range([0, h]);
    //定义键函数,以备把数据绑定到元素时使用
    var key=function(d){
        return d.key
    }

    //添加矩形,条形图
    svg.selectAll("rect")
        .data(dataset,key)
        .enter()
        .append("rect")
        .attr("x",function(d,i){return xScale(i);})
        .attr("y", function(d){return h-yScale(d.value);})//让条形从下向上
        .attr("width",xScale.rangeBand())
        .attr("height", function(d){return yScale(d.value);})
        .attr("fill",function(d){return "rgb(0,0,"+(d.value*10)+")";});

    //加标签
    svg.selectAll("text")
       .data(dataset,key)
       .enter()
       .append("text")
       .text(function(d){return d.value;})
       .attr("x",function(d,i){return xScale(i) + xScale.rangeBand() / 2;})
       .attr("y",function(d){ return h-yScale(d.value)+14;})
       .attr("font-family","sans-serif")
       .attr("font-size","11px")
       .attr("fill","white")
       .attr("text-anchor","middle")//text-anchor水平居中文本


    d3.select("p")
      .on("click",function(){
      //从数据集中删除第一个元素
      dataset.shift();
      //更新所有矩形
      var bars=svg.selectAll("rect")
                  .data(dataset,key)
      //退出
            bars.exit()
                .transition(1000)
                .attr("x",w)
                .remove();
            svg.selectAll("text")
            .data(dataset,key)
            .exit()
            .transition()
            .duration(500)
            .attr("x",w)
    });
 </script>
9.添加和删除
<!DOCTYPE html>
<html lang="en">
 <head>
 <meta charset="utf-8">
 <title>D3 Page Template</title>
 <script type="text/javascript" src="d3/d3.v3.js"></script>
 <style>
 </style>
 </head>
 <body>
     <p id="add">Add a new data a value</p>
     <p id="remove">Remove a data value</p>
 </body>
</html>
<script type="text/javascript">
    var dataset=[ { key: 0, value: 5 },
                    { key: 1, value: 10 },
                    { key: 2, value: 13 },
                    { key: 3, value: 19 },
                    { key: 4, value: 21 },
                    { key: 5, value: 25 },
                    { key: 6, value: 22 },
                    { key: 7, value: 18 },
                    { key: 8, value: 15 },
                    { key: 9, value: 13 },
                    { key: 10, value: 11 },
                    { key: 11, value: 12 },
                    { key: 12, value: 15 },
                    { key: 13, value: 20 },
                    { key: 14, value: 18 },
                    { key: 15, value: 17 },
                    { key: 16, value: 16 },
                    { key: 17, value: 18 },
                    { key: 18, value: 23 },
                    { key: 19, value: 25 } ];
    var w=600;
    var h=300;
    var key=function(d){return d.key};
    var svg = d3.select("body")
                .append("svg")
                .attr("width", w)
                .attr("height", h);

    //设置序数比例尺
    var xScale = d3.scale.ordinal()
                         .domain(d3.range(dataset.length))//设置了输入值的值域
                         //.rangeBands()根据输入值域的长度自动将其切成相等的块或档,第二个参数设置档间距
                         //.rangeRoundBands()输出的值会舍入为最接近的整数
                         .rangeRoundBands([0, w], 0.05);
    var yScale = d3.scale.ordinal()
                         .domain(d3.range(30))//设置了输入值的值域
                         //.rangeBands()根据输入值域的长度自动将其切成相等的块或档,第二个参数设置档间距
                         //.rangeRoundBands()输出的值会舍入为最接近的整数
                         .rangeRoundBands([0, h],0.05);
    //添加矩形,条形图
    svg.selectAll("rect")
        .data(dataset,key)
        .enter()
        .append("rect")
        .attr("x",function(d,i){return xScale(i);})
        .attr("y", function(d){return h-yScale(d.value);})//让条形从下向上
        .attr("width",xScale.rangeBand())
        .attr("height", function(d){return yScale(d.value);})
        .attr("fill",function(d){return "rgb(0,0,"+(d.value*10)+")";});

    d3.selectAll("p")
      .on("click",function(){
      // 看看单击了哪个段落
        var paragraphID = d3.select(this).attr("id");
        // 确定接下来该干什么
        if (paragraphID == "add") {
        //Add a data value
        var maxValue = 25;
        var newNumber = Math.floor(Math.random() * maxValue);
        var lastKeyValue = dataset[dataset.length - 1].key;
        console.log(lastKeyValue);
        dataset.push({
        key: lastKeyValue + 1,
        value: newNumber
        })
        } else {
        // 删除一个值
        dataset.shift();
        }
        
      xScale.domain(d3.range(dataset.length));//更新比例尺的值域
      //1.选择,bars就保存了新的数据集
      var bars=svg.selectAll("rect")
                  .data(dataset,key)

      //2.加入
      bars.enter()
        .append("rect")
        .attr("x", w)
        .attr("y", function(d) {
        return h - yScale(d.value);
        })
        .attr("width", xScale.rangeBand())
        .attr("height", function(d) {
        return yScale(d.value);
        })
        .attr("fill", function(d) {
        return "rgb(0, 0, " + (d.value * 10) + ")";
        });
      //3.更新
      bars.transition()
            .duration(500)
            .attr("x", function(d, i) {
            return xScale(i);
            })
            .attr("y", function(d) {
            return h - yScale(d.value);
            })
            .attr("width", xScale.rangeBand())
            .attr("height", function(d) {
            return yScale(d.value);
            });       

        //退出
        bars.exit()
            .transition(1000)
            .attr("x",w)
            .remove();
    });
 </script>
10.悬停高亮
<!DOCTYPE html>
<html lang="en">
 <head>
 <meta charset="utf-8">
 <title>D3 Page Template</title>
 <script type="text/javascript" src="d3/d3.v3.js"></script>
 <style>
 </style>
 </head>
 <body>
     <p id="add">Add a new data a value</p>
     <p id="remove">Remove a data value</p>
 </body>
</html>
<script type="text/javascript">
    var dataset=[ { key: 0, value: 5 },
                    { key: 1, value: 10 },
                    { key: 2, value: 13 },
                    { key: 3, value: 19 },
                    { key: 4, value: 21 },
                    { key: 5, value: 25 },
                    { key: 6, value: 22 },
                    { key: 7, value: 18 },
                    { key: 8, value: 15 },
                    { key: 9, value: 13 },
                    { key: 10, value: 11 },
                    { key: 11, value: 12 },
                    { key: 12, value: 15 },
                    { key: 13, value: 20 },
                    { key: 14, value: 18 },
                    { key: 15, value: 17 },
                    { key: 16, value: 16 },
                    { key: 17, value: 18 },
                    { key: 18, value: 23 },
                    { key: 19, value: 25 } ];
    var w=600;
    var h=300;
    var key=function(d){return d.key};
    var svg = d3.select("body")
                .append("svg")
                .attr("width", w)
                .attr("height", h);

    //设置序数比例尺
    var xScale = d3.scale.ordinal()
                         .domain(d3.range(dataset.length))//设置了输入值的值域
                         //.rangeBands()根据输入值域的长度自动将其切成相等的块或档,第二个参数设置档间距
                         //.rangeRoundBands()输出的值会舍入为最接近的整数
                         .rangeRoundBands([0, w], 0.05);
    var yScale = d3.scale.ordinal()
                         .domain(d3.range(30))//设置了输入值的值域
                         //.rangeBands()根据输入值域的长度自动将其切成相等的块或档,第二个参数设置档间距
                         //.rangeRoundBands()输出的值会舍入为最接近的整数
                         .rangeRoundBands([0, h],0.05);
    //添加矩形,条形图
    svg.selectAll("rect")
        .data(dataset,key)
        .enter()
        .append("rect")
        .attr("x",function(d,i){return xScale(i);})
        .attr("y", function(d){return h-yScale(d.value);})//让条形从下向上
        .attr("width",xScale.rangeBand())
        .attr("height", function(d){return yScale(d.value);})
        .attr("fill",function(d){return "rgb(0,0,"+(d.value*10)+")";})
        .on("mouseover",function(){
            d3.select(this)
            .attr("fill","orange");
        })
        .on("mouseout",function(d){
            d3.select(this)
              .transition()
              .duration(250)
            .attr("fill","rgb(0,0,"+(d.value*10)+")");
        });
    //指针事件和重叠元素,在svg中,后加入DOM元素在视觉层次上会被渲染在先加入元素的前面
    //希望在某些元素上忽略鼠标事件,在css中给要忽略的元素添加一行代码即可
    //pointer-events:none;
 </script>
11.分组SVG 元素

g元素自身不会触发任何鼠标事件(g没有像素),被它封装的元素,比如rect,circle和text元素才有像素

可以把事件监听器绑定给g元素,因为要是被包含的元素中有哪个被单击了或被鼠标悬停了,那么绑定到g元素的事件监听器也会被触发

12.点击排序
<!DOCTYPE html>
<html lang="en">
 <head>
 <meta charset="utf-8">
 <title>D3 Page Template</title>
 <script type="text/javascript" src="d3/d3.v3.js"></script>
 <style>
 </style>
 </head>
 <body>
     <p>Click on this text to update the chart with new data values (once).</p>
 </body>
</html>
<script type="text/javascript">
    var dataset=[ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13,11, 12, 15, 20, 18, 17, 16, 18, 23, 25 ];
    var w=600;
    var h=300;

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

    //设置序数比例尺
    var xScale = d3.scale.ordinal()
                         .domain(d3.range(dataset.length))//设置了输入值的值域
                         //.rangeBands()根据输入值域的长度自动将其切成相等的块或档,第二个参数设置档间距
                         //.rangeRoundBands()输出的值会舍入为最接近的整数
                         .rangeRoundBands([0, w], 0.05);
    var yScale = d3.scale.ordinal()
                         .domain(d3.range(30))//设置了输入值的值域
                         //.rangeBands()根据输入值域的长度自动将其切成相等的块或档,第二个参数设置档间距
                         //.rangeRoundBands()输出的值会舍入为最接近的整数
                         .rangeRoundBands([0, h],0.05);
    //添加矩形,条形图
    svg.selectAll("rect")
        .data(dataset)
        .enter()
        .append("rect")
        .attr("x",function(d,i){return xScale(i);})
        .attr("y", function(d){return h-yScale(d);})//让条形从下向上
        .attr("width",xScale.rangeBand())
        .attr("height", function(d){return yScale(d);})
        .attr("fill",function(d){return "rgb(0,0,"+(d*10)+")";})
        .on("click", function() {
             sortBars();
         });

    //加标签
    svg.selectAll("text")
       .data(dataset)
       .enter()
       .append("text")
       .text(function(d){return d;})
       .attr("x",function(d,i){return xScale(i) + xScale.rangeBand() / 2;})
       .attr("y",function(d){ return h-yScale(d)+14;})
       .attr("font-family","sans-serif")
       .attr("font-size","11px")
       .attr("fill","white")
       .attr("text-anchor","middle")//text-anchor水平居中文本

       //点击排序函数
       var sortOrder=false;
       var sortBars = function() {
            // 反转 sortOrder 的值
            sortOrder = !sortOrder;
            svg.selectAll("rect")
            .sort(function(a, b) {
                if (sortOrder) {
                return d3.ascending(a, b);
                } else {
                return d3.descending(a, b);
                }
                })
            .transition()
            .delay(function(d, i) {
                return i * 50;
                })
            .duration(1000)
            .attr("x", function(d, i) {
            return xScale(i);
            });
};
 </script>
13.SVG元素提示条
<!DOCTYPE html>
<html lang="en">
 <head>
 <meta charset="utf-8">
 <title>D3 Page Template</title>
 <script type="text/javascript" src="d3/d3.v3.js"></script>
 <style>
 </style>
 </head>
 <body>
     <p>Click on this text to update the chart with new data values (once).</p>
 </body>
</html>
<script type="text/javascript">
    var dataset=[ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13,11, 12, 15, 20, 18, 17, 16, 18, 23, 25 ];
    var w=600;
    var h=300;

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

    //设置序数比例尺
    var xScale = d3.scale.ordinal()
                         .domain(d3.range(dataset.length))//设置了输入值的值域
                         //.rangeBands()根据输入值域的长度自动将其切成相等的块或档,第二个参数设置档间距
                         //.rangeRoundBands()输出的值会舍入为最接近的整数
                         .rangeRoundBands([0, w], 0.05);
    var yScale = d3.scale.ordinal()
                         .domain(d3.range(30))//设置了输入值的值域
                         //.rangeBands()根据输入值域的长度自动将其切成相等的块或档,第二个参数设置档间距
                         //.rangeRoundBands()输出的值会舍入为最接近的整数
                         .rangeRoundBands([0, h],0.05);
    //添加矩形,条形图
    svg.selectAll("rect")
        .data(dataset)
        .enter()
        .append("rect")
        .attr("x",function(d,i){return xScale(i);})
        .attr("y", function(d){return h-yScale(d);})//让条形从下向上
        .attr("width",xScale.rangeBand())
        .attr("height", function(d){return yScale(d);})
        .attr("fill",function(d){return "rgb(0,0,"+(d*10)+")";})
        // .append("title")
        // .text(function(d){
        //     return d;
        // });
        .on("mouseover",function(d){
            //取得条形的x/y值。增大后作为提示条的坐标
            var xPosition=parseFloat(d3.select(this).attr("x"))+xScale.rangeBand()/2;
            var yPosition=parseFloat(d3.select(this).attr("y"))+14;

            //创建提示条
            svg.append("text")
               .attr("id","tooltip")
               .attr("x",xPosition)
               .attr("y",yPosition)
               .attr("text-anchor","middle")
               .attr("font-family","sans-serif")
               .attr("font-size","11px")
               .attr("font-weight","bold")
               .attr("fill","black")
               .text(d);
        })
        .on("mouseout",function(){
            //删除提示条
            d3.select("#tooltip").remove();HTML
        })
    
 </script>
14.HTML的div提示条
<!DOCTYPE html>
<html lang="en">
 <head>
 <meta charset="utf-8">
 <title>D3 Page Template</title>
 <script type="text/javascript" src="d3/d3.v3.js"></script>
 <style>
     #tooltip {
    position: absolute;
    width: 200px;
    height: auto;
    padding: 10px;
    background-color: white;
    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
    border-radius: 10px;
    -webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
    -moz-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
    box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
    pointer-events: none;
    }
    #tooltip.hidden {
    display: none;
    }
    #tooltip p {
    margin: 0;
    font-family: sans-serif;
    font-size: 16px;
    line-height: 20px;
    }
 </style>
 </head>
 <body>
    <div id="tooltip" class="hidden">
        <p><strong>Important Label Heading</strong></p>
        <p><span id="value">100</span>%</p>
    </div>
 </body>
</html>
<script type="text/javascript">
    var dataset=[ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13,11, 12, 15, 20, 18, 17, 16, 18, 23, 25 ];
    var w=600;
    var h=300;

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

    //设置序数比例尺
    var xScale = d3.scale.ordinal()
                         .domain(d3.range(dataset.length))//设置了输入值的值域
                         //.rangeBands()根据输入值域的长度自动将其切成相等的块或档,第二个参数设置档间距
                         //.rangeRoundBands()输出的值会舍入为最接近的整数
                         .rangeRoundBands([0, w], 0.05);
    var yScale = d3.scale.ordinal()
                         .domain(d3.range(30))//设置了输入值的值域
                         //.rangeBands()根据输入值域的长度自动将其切成相等的块或档,第二个参数设置档间距
                         //.rangeRoundBands()输出的值会舍入为最接近的整数
                         .rangeRoundBands([0, h],0.05);
    //添加矩形,条形图
    svg.selectAll("rect")
        .data(dataset)
        .enter()
        .append("rect")
        .attr("x",function(d,i){return xScale(i);})
        .attr("y", function(d){return h-yScale(d);})//让条形从下向上
        .attr("width",xScale.rangeBand())
        .attr("height", function(d){return yScale(d);})
        .attr("fill",function(d){return "rgb(0,0,"+(d*10)+")";})
        .on("mouseover", function(d) {
        // 取得条形的 x/y 值,增大后作为提示条的坐标
        var xPosition = parseFloat(d3.select(this).attr("x")) + xScale.rangeBand() / 2;
        var yPosition = parseFloat(d3.select(this).attr("y")) / 2 + h / 2;
        // 更新提示条的位置和值
        d3.select("#tooltip")
        .style("left", xPosition + "px")
        .style("top", yPosition + "px")
        .select("#value")
        .text(d);
        // 显示提示条
        d3.select("#tooltip").classed("hidden", false);
        })
        .on("mouseout",function(){
            //隐藏提示条
            d3.select("#tooltip").classed("hidden",true);
        })
    
 </script>
15.力导向图
<!DOCTYPE html>
<html lang="en">
 <head>
 <meta charset="utf-8">
 <title>D3 Page Template</title>
 <script type="text/javascript" src="d3/d3.v3.js"></script>
 <style>
     
 </style>
 </head>
 <body>
    
 </body>
</html>
<script type="text/javascript">
    var w=600;
    var h=300;

    var svg = d3.select("body")
                .append("svg")
                .attr("width", w)
                .attr("height", h);
    var dataset = {
                    nodes: [
                    { name: "Adam" },
                    { name: "Bob" },
                    { name: "Carrie" },
                    { name: "Donovan" },
                    { name: "Edward" },
                    { name: "Felicity" },
                    { name: "George" },
                    { name: "Hannah" },
                    { name: "Iris" },
                    { name: "Jerry" }
                    ],
                    edges: [
                    { source: 0, target: 1 },
                    { source: 0, target: 2 },
                    { source: 0, target: 3 },
                    { source: 0, target: 4 },
                    { source: 1, target: 5 },
                    { source: 2, target: 5 },
                    { source: 2, target: 5 },
                    { source: 3, target: 4 },
                    { source: 5, target: 8 },
                    { source: 5, target: 9 },
                    { source: 6, target: 7 },
                    { source: 7, target: 8 },
                    { source: 8, target: 9 }
                    ]
                };
    //初始化力导向图
    var force=d3.layout.force()
                       .nodes(dataset.nodes)
                       .links(dataset.edges)
                       .size([w,h])
                       .linkDistance(150)//连接节点的连线长度
                       .charge([-400])//节点之间的负电荷
                       .start();
    //创建连线的SVG直线
    var edges=svg.selectAll("line")
                 .data(dataset.edges)
                 .enter()
                 .append("line")
                 .style("stroke","red")//定义颜色
                 .style("stroke-width",2);//粗细
    var color=d3.scale.category20();
    //为每个节点创建SVG圆形
    var nodes=svg.selectAll("circle")
                 .data(dataset.nodes)
                 .enter()
                 .append("circle")
                 .attr("r",10)
                 .style("fill",function(d,i){
                     return color(i);
                 })
                 .call(force.drag);//启用拖动交互作用
    //添加描述节点的文字
     var texts = svg.selectAll("text")
                    .data(dataset.nodes)
                    .enter()
                    .append("text")
                    .style("fill", "black")
                    .attr("dx", 20)
                    .attr("dy", 8)
                    .text(function(d){
                        return d.name;
                    });
    //每打一次点,力导向布局就会根据初始化布局时指定的数据,调整每个结点和连线的位置值(更新与之关联的元素--直线和圆形)
    force.on("tick",function(){
        edges.attr("x1",function(d){return d.source.x;})
             .attr("y1",function(d){return d.source.y;})
             .attr("x2",function(d){return d.source.x;})
             .attr("y2",function(d){return d.source.y;})
        nodes.attr("cx",function(d){return d.x;})
             .attr("cy",function(d){return d.y;});
        texts.attr("x",function(d){return d.x;})
             .attr("y",function(d){return d.y;});
    });

</script>
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值