当前位置:   article > 正文

D3.js 可视化从入门到精通_d3.js数据可视化

d3.js数据可视化

第一章 Hello world

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>hello</title>
    <script src="https://d3js.org/d3.v5.min.js"></script>
  </head>
  <body>
    <h3></h3>
    <h3></h3>
    <h3></h3>
    <h3></h3>
  </body>
  <script>
    var h3 = d3.select("body").selectAll("h3");
    h3.text("日照香炉生紫烟");
  </script>
</html>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

在这里插入图片描述

第二章 数据绑定

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>datum</title>
    <script src="https://d3js.org/d3.v5.min.js"></script>
  </head>
  <body>
    <h3></h3>
    <h3></h3>
    <h3></h3>
    <h3></h3>
  </body>

  <script>
    var lyrics = [
      "我是一只小小小小鸟",
      "想要飞呀飞却飞也飞不高",
      "我寻寻觅觅寻寻觅觅一个温暖的怀抱",
      "这样的要求算不算太高",
    ];
    var h3 = d3.selectAll("h3");
    h3.data(lyrics).text(function (v, i) {
      return "我是第" + i + "个h3标签,内容是:" + v;
    });

    //    运行结果如下:
    //    我是第0个h3标签,内容是:我是一只小小小小鸟
    //    我是第1个h3标签,内容是:想要飞呀飞却飞也飞不高
    //    我是第2个h3标签,内容是:我寻寻觅觅寻寻觅觅一个温暖的怀抱
    //    我是第3个h3标签,内容是:这样的要求算不算太高
  </script>
</html>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

在这里插入图片描述

第三章 数据更新

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>hello</title>
    <script src="https://d3js.org/d3.v5.min.js"></script>
  </head>
  <body>
    <h2>《执迷不悔》</h2>

    <h3></h3>
    <h3></h3>
    <h3></h3>
  </body>
  <script>
    var lyrics = [
      "我不是你们想的如此完美",
      "我承认有时也会辨不清真伪",
      "并非我不愿意走出迷堆 只是这一次",
      "这次是自己(而)不是谁",
      "要我用谁的心去体会 真真切切地感受周围",
      "就算痛苦 就算是泪 也是属于我的伤悲",
      "我还能用谁的心去体会 真真切切地感受周围",
      "就算疲倦 就算是累 也只能执迷(而)不悔",
    ];

    var h3 = d3.select("body").selectAll("h3");
    //    var h3 = d3.selectAll('h3');

    var updata = h3.data(lyrics);
    var enter = updata.enter();
    console.log(updata);
    console.log(enter);

    updata.text(function (v, i) {
      return v;
    });

    //    代码执行到这里 页面所展示内容如下
    //
    //    执迷不悔
    //    我不是你们想的如此完美
    //    我承认有时也会辨不清真伪
    //    并非我不愿意走出迷堆 只是这一次

    //因为h3标签不够  所以需要先添加h3标签 再给新添加的h3标签绑定后续的数据

    var addH3 = enter.append("h3"); //注意 这里是往enter中插入h3
    console.log(enter);
    addH3.text(function (v, i) {
      //给新添加的h3标签 绑定数据
      return v;
    });

    //    执行到这里 页面展示内容如下
    //
    //    《执迷不悔》
    //    我不是你们想的如此完美
    //    我承认有时也会辨不清真伪
    //    并非我不愿意走出迷堆 只是这一次
    //    这次是自己(而)不是谁
    //    要我用谁的心去体会 真真切切地感受周围
    //    就算痛苦 就算是泪 也是属于我的伤悲
    //    我还能用谁的心去体会 真真切切地感受周围
    //    就算疲倦 就算是累 也只能执迷(而)不悔
  </script>
</html>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68

在这里插入图片描述

第四章 组件选择、更新

选择

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>hello</title>
    <script src="https://d3js.org/d3.v5.min.js"></script>
  </head>
  <body>
    <h3>第一个</h3>
    <h3>第二个</h3>
    <h3>第三个</h3>
    <h3>第四个</h3>
    <h3>第五个</h3>
  </body>
  <script>
    var h3 = d3.select("h3");
    h3.datum("我把内容改了看看").text(function (d, i) {
      return d;
    });
    console.log(h3);
    //输出结果
    //    我把内容改了看看
    //    第二个
    //    第三个
    //    第四个
    //    第五个
  </script>
</html>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

在这里插入图片描述

更新

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>hello</title>
    <script src="https://d3js.org/d3.v5.min.js"></script>
  </head>
  <body>
    <h3>第一个</h3>
    <p title="23℃">第二个</p>
  </body>
  <script>
    var h3 = d3.select("h3");
    var p = d3.select("p");
    h3.attr("title", "我是一个h3标签"); //页面中鼠标滑过 显示 '我是一个h3标签'
    console.log(p.attr("title")); //控制台输出 23℃
  </script>
</html>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

在这里插入图片描述

第五章 柱装图

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Title</title>
    <script src="https://d3js.org/d3.v5.min.js"></script>
  </head>
  <body>
    <svg width="100%" height="300"></svg>
  </body>

  <script>
    var data = [730, 530, 330, 230, 130];
    var g = d3
      .select("svg") // 获取svg
      .append("g") // 创建分组
      .attr("transform", "translate(30,30)"); // 图表距离视口的左、上距离

    var rectHeight = 30; //设定矩形的高+与下一个矩形的边距  共30px

    g.selectAll("rect")
      .data(data)
      .enter()
      .append("rect") //利用enter 创建与数据个数一样的rect矩形
      .attr("x", 0) //这里设定矩形左上顶点的x值
      .attr("y", function (d, i) {
        return rectHeight * i; //这里设定矩形左上顶点的Y值
      })
      .attr("width", function (d, i) {
        return d; //矩形宽度
      })
      .attr("height", rectHeight - 5) //这里矩形实际的高度就是25  与下一个矩形的边距是5
      .style("fill", "pink"); //填充色
  </script>
</html>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

在这里插入图片描述

第六章 坐标轴

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>scaleLinear</title>
    <script src="https://d3js.org/d3.v5.min.js"></script>
  </head>
  <body>
    <svg width="100%" height="300"></svg>
  </body>

  <script>
    var data = [7.3, 5.3, 3.3, 2.3, 1.3];

    //定义比例尺
    var scaleLinear = d3
      .scaleLinear()
      .domain([0, d3.max(data)])
      .range([0, 800]);

    var g = d3.select("svg").append("g").attr("transform", "translate(30,30)");

    var rectHeight = 30;

    g.selectAll("rect")
      .data(data)
      .enter()
      .append("rect")
      .attr("x", 0)
      .attr("y", function (d, i) {
        return rectHeight * i;
      })
      .attr("width", function (d, i) {
        return scaleLinear(d); //在这里的得到 映射的宽度
      })
      .attr("height", rectHeight - 5)
      .attr("fill", "pink");

    //定义一个x坐标轴   坐标轴的比例尺 我们跟图表的用一个
    var axisX = d3.axisBottom(scaleLinear).ticks(20); //ticks 用来设置刻度间隔    其实就是把data数据 根据咱们的参数20  重新调整一下

    g.append("g") //在原有分g矩形分组里 再加一个x轴分组
      .attr("transform", "translate(0," + data.length * rectHeight + ")")
      .call(axisX);
  </script>
</html>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

在这里插入图片描述

第七章 柱装图进阶

静态柱装图

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Title</title>
    <script src="https://d3js.org/d3.v5.min.js"></script>
  </head>
  <body>
    <svg width="500" height="400"></svg>
  </body>

  <script>
    var data = [90, 75, 12, 36, 54, 88, 24, 66];
    var margin = 30; //上下左右边距

    var svg = d3.select("svg");
    var width = svg.attr("width");
    var height = svg.attr("height");
    //创建一个矩形分组
    var g = svg
      .append("g")
      .attr("transform", "translate(" + margin + "," + margin + ")");

    //定义x轴比例尺
    var scaleX = d3
      .scaleBand()
      .domain(d3.range(data.length)) //[0, 1, 2, 3, 4, 5, 6, 7]
      .rangeRound([0, width - margin * 2]); //左右边距30

    //定义Y轴比例尺
    var scaleY = d3
      .scaleLinear()
      .domain([0, d3.max(data)])
      .range([height - margin * 2, 0]); //上边距30   这里还得注意  range后面跟的参数  0放在第二位   因为y轴正方向是反的

    //绘制x y 轴
    var axisX = d3.axisBottom(scaleX);
    var axisY = d3.axisLeft(scaleY);
    g.append("g")
      .attr("transform", "translate(0," + (height - margin * 2) + ")")
      .call(axisX);
    g.append("g").attr("transform", "translate(0,0)").call(axisY);

    var rectP = 30; //柱状图间距
    var gs = g.selectAll("rect").data(data).enter().append("g"); //分组

    //绘制矩形
    gs.append("rect")
      .attr("x", function (d, i) {
        return scaleX(i) + rectP / 2;
      })
      .attr("y", function (d, i) {
        return scaleY(d);
      })
      .attr("width", function () {
        return scaleX.step() - rectP;
      })
      .attr("height", function (d, i) {
        return height - margin * 2 - scaleY(d);
      })
      .attr("fill", "pink");

    //绘制文字
    gs.append("text")
      .attr("x", function (d, i) {
        return scaleX(i) + rectP / 2;
      })
      .attr("y", function (d, i) {
        return scaleY(d);
      })
      .text(function (d, i) {
        return d;
      });
  </script>
</html>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76

在这里插入图片描述

动态柱装图

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Title</title>
    <script src="https://d3js.org/d3.v5.min.js"></script>
  </head>
  <body>
    <svg width="500" height="400"></svg>
  </body>

  <script>
    var data = [90, 75, 12, 36, 54, 88, 24, 66];
    var margin = 30; //svg 上下左右边距

    var svg = d3.select("svg");
    var width = svg.attr("width");
    var height = svg.attr("height");

    //创建分组
    var g = svg
      .append("g")
      .attr("transform", "translate(" + margin + "," + margin + ")");

    //定义 x y 轴比例尺
    var scaleX = d3
      .scaleBand()
      .domain(d3.range(data.length))
      .range([0, width - margin * 2]);
    var scaleY = d3
      .scaleLinear()
      .domain([0, d3.max(data)])
      .range([height - margin * 2, 0]);

    //绘画 x y  轴
    var axisX = d3.axisBottom(scaleX);
    var axisY = d3.axisLeft(scaleY);

    g.append("g")
      .attr("transform", "translate(0," + (height - margin * 2) + ")")
      .call(axisX);
    g.append("g").attr("transform", "translate(0,0)").call(axisY);

    // 创建矩形分组
    var gs = g.selectAll("rect").data(data).enter().append("g");

    //绘 柱状图  +  过度效果
    var rectP = 40; //柱状图间距
    gs.append("rect")
      .attr("x", function (d, i) {
        return scaleX(i) + rectP / 2;
      })
      .attr("y", function (d, i) {
        //            return scaleY(d);
        //            return 0;//动画的初始状态为0  如果是这样的话  就像下雨的效果  柱状图从上往下生长
        //
        var min = scaleY.domain()[0]; //[0,90]
        console.log(min); //  输出 0
        return scaleY(min); // scaleY(0) y轴比例尺 映射出来的是最大值;   这个效果 等同于return height - 2*margin;的效果
      })
      .attr("width", function (d, i) {
        return scaleX.step() - rectP;
      })
      .attr("height", function (d, i) {
        //            return height - margin*2 - scaleY(d);
        return 0; //动画的初始状态为0
      })
      .attr("fill", "pink")
      .transition() //添加过度
      .duration(2000) //动画的持续时间  毫秒
      .delay(function (d, i) {
        //延迟执行
        return i * 300; //每个柱子逐渐开始的效果
      })
      .attr("y", function (d, i) {
        return scaleY(d);
      })
      .attr("height", function (d, i) {
        return height - margin * 2 - scaleY(d);
      });

    //绘 文字  +  过度效果

    gs.append("text")
      .attr("x", function (d, i) {
        return scaleX(i) + rectP / 2;
      })
      .attr("y", function (d, i) {
        //            return scaleY(d);
        return height - 2 * margin; //这里的初始化效果 同上面的矩形初始化效果一样
      })
      .attr("dx", function (d, i) {
        return -2;
      })
      .attr("dy", function (d, i) {
        return 20;
      })
      .text(function (d, i) {
        return d;
      })
      .transition()
      .duration(2000)
      .delay(function (d, i) {
        return i * 300; //300毫秒
      })
      .attr("y", function (d, i) {
        return scaleY(d);
      });
  </script>
</html>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111

在这里插入图片描述

交互柱装图

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Title</title>
    <script src="https://d3js.org/d3.v5.min.js"></script>
  </head>
  <body>
    <svg width="500" height="400"></svg>
  </body>

  <script>
    var data = [90, 75, 12, 36, 54, 88, 24, 66];
    var margin = 30; //svg 上下左右边距

    var svg = d3.select("svg");
    var width = svg.attr("width");
    var height = svg.attr("height");

    //创建分组
    var g = svg
      .append("g")
      .attr("transform", "translate(" + margin + "," + margin + ")");

    //定义 x y 轴比例尺
    var scaleX = d3
      .scaleBand()
      .domain(d3.range(data.length))
      .range([0, width - margin * 2]);
    var scaleY = d3
      .scaleLinear()
      .domain([0, d3.max(data)])
      .range([height - margin * 2, 0]);

    //绘画 x y  轴
    var axisX = d3.axisBottom(scaleX);
    var axisY = d3.axisLeft(scaleY);

    g.append("g")
      .attr("transform", "translate(0," + (height - margin * 2) + ")")
      .call(axisX);
    g.append("g").attr("transform", "translate(0,0)").call(axisY);

    // 创建矩形分组
    var gs = g.selectAll("rect").data(data).enter().append("g");

    //绘 柱状图  +  过度效果
    var rectP = 10; //柱状图间距
    gs.append("rect")
      .attr("x", function (d, i) {
        return scaleX(i) + rectP / 2;
      })
      .attr("y", function (d, i) {
        return scaleY(d);
      })
      .attr("width", function (d, i) {
        return scaleX.step() - rectP;
      })
      .attr("height", function (d, i) {
        return height - margin * 2 - scaleY(d);
      })
      .attr("fill", "pink")

      //添加鼠标划入划出事件
      .on("mouseover", function () {
        //鼠标划入矩形事件
        d3.select(this) //这里的this指向就是当前的矩形

          .transition()
          .duration(1000)
          .delay(200)
          .attr("fill", "#306ade");
      })
      .on("mouseout", function () {
        d3.select(this)

          .transition()
          .duration(1000)
          .delay(200)
          .attr("fill", "pink");
      });

    //绘 文字  +  过度效果

    gs.append("text")
      .attr("x", function (d, i) {
        return scaleX(i) + rectP / 2 + 15;
      })
      .attr("y", function (d, i) {
        //            return scaleY(d);
        return height - 2 * margin; //这里的初始化效果 同上面的矩形初始化效果一样
      })
      .attr("dx", function (d, i) {
        return -2;
      })
      .attr("dy", function (d, i) {
        return 20;
      })
      .text(function (d, i) {
        return d;
      })
      .transition()
      .duration(2000)
      .delay(function (d, i) {
        return i * 300; //300毫秒
      })
      .attr("y", function (d, i) {
        return scaleY(d);
      });
  </script>
</html>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112

在这里插入图片描述

第八章 饼图

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>pie</title>
    <script src="https://d3js.org/d3.v5.min.js"></script>
  </head>
  <body>
    <svg width="500" height="400"></svg>
  </body>

  <script>
    //准备数据
    var margin = 30; //边距
    var data = [56, 21, 11, 85, 42, 66]; //绘制饼图所需数据
    var svg = d3.select("svg");
    var width = svg.attr("width");
    var height = svg.attr("height");

    //创建一个分组 并设置偏移
    var g = svg
      .append("g")
      .attr("transform", "translate(" + margin + "," + margin + ")");

    //为了让饼图不同区域显示不同颜色   我们先创建一个颜色比例尺   用之前我们讲到的序数比例尺
    var scaleColor = d3
      .scaleOrdinal()
      .domain(d3.range(data.length))
      .range(d3.schemeCategory10);

    //创建一个饼图
    var pie = d3.pie();

    //创建一个弧形生成器
    var arc = d3
      .arc()
      .innerRadius(0) //设置环的内半径.
      .outerRadius(100); //设置环的外半径.
    //除了内半径与外半径  还可以设置很多  如下
    //        arc.cornerRadius - 设置拐角半径.
    //        arc.startAngle - 设置起始角度.
    //        arc.endAngle - 设置终止角度.
    //        arc.padAngle - 设置相邻两个环之间的间隙角度.
    //        arc.padRadius - 设置半径间隔.
    //        arc.context - 设置渲染上下文.

    //利用pie 转换数据
    var pieData = pie(data);
    console.log(pieData); //看看转换成了啥

    //创建扇形分组
    var gs = g
      .selectAll(".g")
      .data(pieData)
      .enter()
      .append("g")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

    //绘制扇形
    gs.append("path")
      .attr("d", function (d, i) {
        return arc(d); //给弧形生成器添加数据
      })
      .attr("fill", function (d, i) {
        return scaleColor(i); //给扇形填充颜色
      });

    //绘制文字
    gs.append("text")
      .attr("transform", function (d, i) {
        return "translate(" + arc.centroid(d) + ")"; //位置设置在扇形中心处
      })
      .attr("text-anchor", "middle")
      .text(function (d, i) {
        return d.data;
      });
  </script>
</html>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79

在这里插入图片描述

第九章 力导图(知识图谱)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>force</title>
    <script src="https://d3js.org/d3.v5.min.js"></script>
  </head>
  <body>
    <svg height="600" width="1080"></svg>
  </body>

  <script>
    //数据
    var nodes = [
      //节点集
      { name: "湖南邵阳" },
      { name: "山东莱州" },
      { name: "广东阳江" },
      { name: "山东枣庄" },
      { name: "赵丽泽" },
      { name: "王恒" },
      { name: "张欣鑫" },
      { name: "赵明山" },
      { name: "班长" },
    ];
    var edges = [
      //边集
      { source: 0, target: 4, relation: "籍贯", value: 1.3 },
      { source: 4, target: 5, relation: "舍友", value: 1 },
      { source: 4, target: 6, relation: "舍友", value: 1 },
      { source: 4, target: 7, relation: "舍友", value: 1 },
      { source: 1, target: 6, relation: "籍贯", value: 2 },
      { source: 2, target: 5, relation: "籍贯", value: 0.9 },
      { source: 3, target: 7, relation: "籍贯", value: 1 },
      { source: 5, target: 6, relation: "同学", value: 1.6 },
      { source: 6, target: 7, relation: "朋友", value: 0.7 },
      { source: 6, target: 8, relation: "职责", value: 2 },
    ];

    var margin = 30; //边距
    var svg = d3.select("svg");
    var width = svg.attr("width");
    var height = svg.attr("height");

    //创建一个分组 并设置偏移
    var g = svg
      .append("g")
      .attr("transform", "translate(" + margin + "," + margin + ")");

    //新建一个颜色比例尺
    var scaleColor = d3
      .scaleOrdinal()
      .domain(d3.range(nodes.length))
      .range(d3.schemeCategory10);

    //新建一个力导向图
    var forceSimulation = d3
      .forceSimulation()
      .force("link", d3.forceLink())
      .force("charge", d3.forceManyBody())
      .force("center", d3.forceCenter());

    //生成节点数据
    forceSimulation.nodes(nodes).on("tick", linksTick); //这个函数下面会讲解

    //生成边数据
    forceSimulation
      .force("link")
      .links(edges)
      .distance(function (d, i) {
        return d.value * 100; //设置边长
      });

    //设置图形 中心点
    forceSimulation
      .force("center")
      .x(width / 2) //设置x坐标
      .y(height / 2); //设置y坐标

    //再来看下顶点数据 和 边数据
    console.log(nodes);
    console.log(edges);

    //绘制边  这里注意一下绘制顺序  在d3中  各元素是有层级关系的,先绘制的在下面
    var links = g
      .append("g")
      .selectAll("line")
      .data(edges)
      .enter()
      .append("line")
      .attr("stroke", function (d, i) {
        return scaleColor(i); //设置边线颜色
      })
      .attr("storke-width", "1"); //设置边线宽度

    //绘制边上的文字
    var linksText = g
      .append("g")
      .selectAll("text")
      .data(edges)
      .enter()
      .append("text")
      .text(function (d, i) {
        return d.relation;
      });

    //创建节点分组
    var gs = g
      .selectAll(".circle")
      .data(nodes)
      .enter()
      .append("g")
      .attr("transform", function (d, i) {
        return "translate(" + d.x + "," + d.y + ")";
      })
      .call(
        d3
          .drag() //相当于移动端的拖拽手势  分以下三个阶段
          .on("start", start)
          .on("drag", drag)
          .on("end", end)
      );

    //绘制节点
    gs.append("circle")
      .attr("r", 10)
      .attr("fill", function (d, i) {
        return scaleColor(i);
      });

    //绘制文字
    gs.append("text").text(function (d, i) {
      return d.name;
    });

    function linksTick() {
      links
        .attr("x1", function (d) {
          return d.source.x;
        })
        .attr("y1", function (d) {
          return d.source.y;
        })
        .attr("x2", function (d) {
          return d.target.x;
        })
        .attr("y2", function (d) {
          return d.target.y;
        });

      linksText
        .attr("x", function (d) {
          return (d.source.x + d.target.x) / 2;
        })
        .attr("y", function (d) {
          return (d.source.y + d.target.y) / 2;
        });

      gs &&
        gs.attr("transform", function (d, i) {
          return "translate(" + d.x + "," + d.y + ")";
        });
    }

    function start(d) {
      if (!d3.event.active) {
        //event.active 属性对判断并发的拖拽手势序列中的 start 事件和 end 事件: 在拖拽手势开始时为0,在拖拽结束最后一个手势事件时为0
        //这里就是drag的过程中
        forceSimulation.alphaTarget(0.8).restart(); //设置衰减系数,对节点位置移动过程的模拟,数值越高移动越快,数值范围[0,1]
      }
      d.fx = d.x;
      d.fy = d.y;
    }

    function drag(d) {
      d.fx = d3.event.x;
      d.fy = d3.event.y;
    }

    function end(d) {
      if (!d3.event.active) {
        forceSimulation.alphaTarget(0);
      }
      d.fx = null;
      d.fy = null;
    }
  </script>
</html>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189

在这里插入图片描述

第十章 中国地图

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>中国地图</title>
    <script src="./d3.min.js"></script>
  </head>
  <body>
    <svg width="900" height="700"></svg>
  </body>

  <script>
    //获取svg
    var svg = d3.select("svg");
    var width = svg.attr("width");
    var height = svg.attr("height");

    //创建区域分组
    var g = svg.append("g").attr("transform", "translate(0,0)");

    //创建一个地图投影
    var mercator = d3
      .geoMercator()
      .center([107, 31]) //设置投影的中心点 经纬度
      .scale(550) //设置缩放因子
      .translate([width / 2, height / 2]); //设置平移偏移量

    //创建一个地理路径生成器
    var geoPath = d3.geoPath().projection(mercator); //设置地理路径生成器的投影方式

    //获取中国地图的json文件
    //利用node.js 在本地起一个http-server
    d3.json("map.json").then(function (data) {
      //D3 v5版本d3.json()现在将返回一个你可以在.then()方法中处理的Promise
      console.log(data); //features

      //新建一个颜色比例尺
      var scaleColor = d3
        .scaleOrdinal()
        .domain(d3.range(data.features.length))
        .range(d3.schemeCategory10);

      //绘制区域
      g.append("g")
        .selectAll("path")
        .data(data.features)
        .enter()
        .append("path")
        .attr("stroke", "gray")
        .attr("strok-widht", 1)
        .attr("d", function (d, i) {
          return geoPath(d);
        })
        .attr("fill", function (d, i) {
          return scaleColor(i);
        })
        .on("mouseover", function (d, i) {
          d3.select(this).attr("fill", "yellow");
        })
        .on("mouseout", function (d, i) {
          d3.select(this).attr("fill", scaleColor(i));
        });

      //绘制文字
      g.append("g")
        .selectAll("text")
        .data(data.features)
        .enter()
        .append("text")
        .attr("font-size", 12)
        .attr("text-anchor", "middle")
        .attr("x", function (d, i) {
          var position = mercator(d.properties.centroid || [0, 0]);
          return position[0];
        })
        .attr("y", function (d, i) {
          var position = mercator(d.properties.centroid || [0, 0]);
          return position[1];
        })
        .attr("dy", function (d, i) {
          //这里为什么这么写呢,因为澳门和香港重合了,挤到一起了。
          if (d.properties.name === "澳门特别行政区") {
            return 10;
          }
        })
        .text(function (d, i) {
          return d.properties.name;
        });
    });
  </script>
</html>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/529216
推荐阅读
相关标签
  

闽ICP备14008679号