可视化D3学习

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <style>
    .axis path,
    .axis line {
    
    
      fill: none;
      stroke: black;
      shape-rendering: crispEdges;
    }

    .axis text {
    
    
      font-family: sans-serif;
      font-size: 11px;
    }
    .node circle {
    
    
      fill: #fff;
      stroke: steelblue;
      stroke-width: 1.5px;
    }

    .node {
    
    
      font: 12px sans-serif;
    }

    .link {
    
    
      fill: none;
      stroke: #ccc;
      stroke-width: 1.5px;
    }
  </style>

  <body></body>
  <script src="lodash.js"></script>

  <!-- <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>  -->

  <script src="https://d3js.org/d3.v5.min.js"></script>
  <!-- <script>
    /** 1、基础d3画出柱状图 */
    // var dataset = [250, 210, 170, 130, 90]; //数据(表示矩形的宽度)

    var width = 1000; //画布的宽度
    var height = 600; //画布的高度

    var svg = d3
      .select("body") //选择文档中的body元素
      .append("svg") //添加一个svg元素
      .attr("width", width) //设定宽度
      .attr("height", height) //设定高度
      /** 专为树状图添加的下面两行 */
      .append("g")
      .attr("transform", "translate(50,0)");

    // var rectHeight = 25; //每个矩形所占的像素高度(包括空白)
    /** 横向的柱状图 */
    /**
              update()
                当对应的元素正好满足时 ( 绑定数据数量 = 对应元素 ),实际上并不存在这样一个函数,只是为了要与之后的 enter 和 exit 一起说明才想象有这样一个函数。但对应元素正好满足时,直接操作即可,后面直接跟 text ,style 等操作即可。
              enter()
                当对应的元素不足时 ( 绑定数据数量 > 对应元素 ),当对应的元素不足时,通常要添加元素,使之与绑定数据的数量相等。后面通常先跟 append 操作。
              exit()
                当对应的元素过多时 ( 绑定数据数量 < 对应元素 ),当对应的元素过多时,通常要删除元素,使之与绑定数据的数量相等。后面通常要跟 remove 操作
            */
    // svg
    //   .selectAll("rect")
    //   .data(dataset)
    //   .enter()
    //   .append("rect")
    //   .attr("x", 20) //每一个距离左侧画布的距离
    //   .attr("y", function (d, i) {//每一个rect距离画布上方的的距离
    //     return i * rectHeight;
    //   })
    //   .attr("width", function (d) {
    
    
    //     return d;
    //   })
    //   .attr("height", rectHeight - 2)
    //   .attr("fill", "steelblue");

    /** 纵向的柱状图 */

    // svg
    //   .selectAll("rect")
    //   .data(dataset)
    //   .enter()
    //   .append("rect")
    //   .attr("y", function (d, i) {
    
    
    //     return height - d;
    //   })
    //   .attr("x", function (d, i) {
    
    
    //     return i * rectHeight;
    //   })
    //   .attr("height", function (d) {
    
    
    //     return d;
    //   })
    //   .attr("width", rectHeight - 2)
    //   .attr("fill", "steelblue");

    /** 2、比例尺使用 */
    // var svg = d3
    //   .select("body")
    //   .append("svg")
    //   .attr("width", 300)
    //   .attr("height", 300);
    // var dataset = [2.5, 2.1, 1.7, 1.3, 0.9];
    // var linear = d3.scale
    //   .linear()
    //   .domain([0, d3.max(dataset)])
    //   .range([0, 300]);
    // var rectHeight = 25;
    // svg
    //   .selectAll("rect")
    //   .data(dataset)
    //   .enter()
    //   .append("rect")
    //   .attr("x", 20)
    //   .attr("y", (ite, idx) => idx * rectHeight)
    //   .attr("width", (ite) => linear(ite))
    //   .attr("height", rectHeight - 2)
    //   .attr("fill", "red");
    /** 3、刻度添加 */
    // var svg = d3
    //   .select("body")
    //   .append("svg")
    //   .attr("width", 300)
    //   .attr("height", 300);
    // var dataset = [2.5, 2.1, 1.7, 1.3, 0.9];
    // var linear = d3.scale
    //   .linear()
    //   .domain([0, d3.max(dataset)])
    //   .range([0, 300]);
    // var rectHeight = 25;
    // var axis = d3.svg
    //   .axis() //坐标轴组件
    //   .scale(linear) //指定比例尺
    //   .orient("bottom") //指定刻度的方向
    //   .ticks(7); //指定刻度的数量
    // svg
    //   .selectAll("rect")
    //   .data(dataset)
    //   .enter()
    //   .append("rect")
    //   .attr("x", 20)
    //   .attr("y", (ite, idx) => idx * rectHeight)
    //   .attr("width", (ite) => linear(ite))
    //   .attr("height", rectHeight - 2)
    //   .attr("fill", "red");
    // svg
    //   .append("g")
    //   .attr("class", "axis")
    //   .attr("transform", "translate(20,130)")
    //   .call(axis);

    /** 4、添加动画 */
    // var circle3 = svg
    //   .append("circle")
    //   .attr("cx", 100) //圆心坐标x
    //   .attr("cy", 100) //圆心坐标y
    //   .attr("r", 45) //半径
    //   .style("fill", "green");

    //在2秒(2000毫秒)内将圆心坐标x由100变为300
    //将颜色从绿色变为红色
    //将半径从45变成25
    //过渡方式采用bounce(在终点处弹跳几次)
    // circle3
    //   .transition() //启动过渡效果
    //   .duration(2000) //指定过渡的持续时间,单位为毫秒
    // 指定过渡的方式,常用的有:
    // linear:普通的线性变化
    // circle:慢慢地到达变换的最终状态
    // elastic:带有弹跳的到达最终状态
    // bounce:在最终状态处弹跳几次
    // .ease("elastic")
    // .attr("r", 25)
    // .attr("cx", 300)
    // .style("fill", "red")

    /** 5、完整的柱形图 */
    //画布大小
    // var width = 400;
    // var height = 400;

    // //在 body 里添加一个 SVG 画布
    // var svg = d3
    //   .select("body")
    //   .append("svg")
    //   .attr("width", width)
    //   .attr("height", height);

    // //画布周边的空白
    // var padding = { left: 30, right: 30, top: 20, bottom: 20 };
    // //定义一个数组
    // var dataset = [10, 20, 30, 40, 33, 24, 12, 5];

    // //x轴的比例尺
    // var xScale = d3.scale
    //   .ordinal()
    //   .domain(d3.range(dataset.length))
    //   .rangeRoundBands([0, width - padding.left - padding.right]);

    // //y轴的比例尺
    // var yScale = d3.scale
    //   .linear()
    //   .domain([0, d3.max(dataset)])
    //   .range([height - padding.top - padding.bottom, 0]);
    // //定义x轴
    // var xAxis = d3.svg.axis().scale(xScale).orient("bottom");

    // //定义y轴
    // var yAxis = d3.svg.axis().scale(yScale).orient("left");
    // //矩形之间的空白
    // var rectPadding = 4;

    // //添加矩形元素
    // var rects = svg
    //   .selectAll(".MyRect")
    //   .data(dataset)
    //   .enter()
    //   .append("rect")
    //   .attr("class", "MyRect")
    //   .attr("transform", "translate(" + padding.left + "," + padding.top + ")")
    //   .attr("x", function (d, i) {
    
    
    //     return xScale(i) + rectPadding / 2;
    //   })
    //   .attr("y", function (d) {
    
    
    //     return yScale(d);
    //   })
    //   .attr("width", xScale.rangeBand() - rectPadding)
    //   .attr("height", function (d) {
    
    
    //     return height - padding.top - padding.bottom - yScale(d);
    //   })
    //   .attr("fill", "steelblue");

    // //添加文字元素
    // var texts = svg
    //   .selectAll(".MyText")
    //   .data(dataset)
    //   .enter()
    //   .append("text")
    //   .attr("class", "MyText")
    //   .attr("transform", "translate(" + padding.left + "," + padding.top + ")")
    //   .attr("x", function (d, i) {
    
    
    //     return xScale(i) + rectPadding / 2;
    //   })
    //   // .attr("y", function (d) {
    
    
    //   //   return yScale(d);
    //   // })
    //   .attr("y", function (d) {
    
    
    //     var min = yScale.domain()[0];
    //     return yScale(min);
    //   })
    //   .transition()
    //   .delay(function (d, i) {
    
    
    //     return i * 200;
    //   })
    //   .duration(2000)
    //   .ease("bounce")
    //   .attr("y", function (d) {
    
    
    //     return yScale(d);
    //   })

    //   .attr("dx", function () {
    
    
    //     return (xScale.rangeBand() - rectPadding) / 2;
    //   })
    //   .attr("dy", function (d) {
    
    
    //     return 20;
    //   })
    //   .text(function (d) {
    
    
    //     return d;
    //   })
    //   .style({
    
    
    //     fill: "#FFF",
    //     "text-anchor": "middle",
    //   });
    // //添加x轴
    // svg
    //   .append("g")
    //   .attr("class", "axis")
    //   .attr(
    //     "transform",
    //     "translate(" + padding.left + "," + (height - padding.bottom) + ")"
    //   )
    //   .call(xAxis);

    // //添加y轴
    // svg
    //   .append("g")
    //   .attr("class", "axis")
    //   .attr("transform", "translate(" + padding.left + "," + padding.top + ")")
    //   .call(yAxis);

    /** 6、力导向图 */
    // var nodes = [
    //   { name: "水果" },
    //   { name: "苹果" },
    //   { name: "梨子" },
    //   { name: "香蕉" },
    //   { name: "动物" },
    //   { name: "法拉利" },
    //   { name: "保时捷大蛤蟆" },
    //   { name: "兰博基尼" },
    // ];

    // var edges = [
    //   { source: 0, target: 1 },
    //   { source: 0, target: 2 },
    //   { source: 0, target: 3 },
    //   { source: 4, target: 5 },
    //   { source: 4, target: 6 },
    //   { source: 4, target: 7 },
    // ];
    // var force = d3.layout
    //   .force()
    //   .nodes(nodes) //指定节点数组
    //   .links(edges) //指定连线数组
    //   .size([width, height]) //指定作用域范围
    //   .linkDistance(80) //指定连线长度
    //   .charge([-400]); //相互之间的作用力
    // force.start(); //开始作用

    // //添加连线
    // var svg_edges = svg
    //   .selectAll("line")
    //   .data(edges)
    //   .enter()
    //   .append("line")
    //   .style("stroke", "#ccc") //连线样式
    //   .style("stroke-width", 1); //连线宽度

    // var color = d3.scale.category20();

    // //添加节点
    // var svg_nodes = svg
    //   .selectAll("circle")
    //   .data(nodes)
    //   .enter()
    //   .append("circle")
    //   .attr("r", 10) //节点半径
    //   .style("fill", function (d, i) {
    
    
    //     return color(i);
    //   })
    //   .call(force.drag); //使得节点能够拖动

    // //添加描述节点的文字
    // var svg_texts = svg
    //   .selectAll("text")
    //   .data(nodes)
    //   .enter()
    //   .append("text")
    //   .style("fill", "black")
    //   .attr("dx", 20)
    //   .attr("dy", 8)
    //   .text(function (d) {
    
    
    //     return d.name;
    //   });

    // //因为拖动需要更新坐标点的位置
    // force.on("tick", function () {
    
    
    //   //对于每一个时间间隔
    //   //更新连线坐标
    //   svg_edges
    //     .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;
    //     });

    //   //更新节点坐标
    //   svg_nodes
    //     .attr("cx", function (d) {
    
    
    //       return d.x;
    //     })
    //     .attr("cy", function (d) {
    
    
    //       return d.y;
    //     });

    //   //更新文字坐标
    //   svg_texts
    //     .attr("x", function (d) {
    
    
    //       return d.x;
    //     })
    //     .attr("y", function (d) {
    
    
    //       return d.y;
    //     });
    // });

    /** 树状图 */
    // var tree = d3.layout.tree().size([360, 320]);
    // // 对角线生成器,并旋转90度。
    // var diagonal = d3.svg.diagonal().projection((d) => [d.y, d.x]); //横纵坐标对调(x,y) => (y,x)

    // // 请求数据:
    // d3.json("data.json", function (error, root) {
    
    
    //   // 获取nodes节点数组和links连线数组
    //   var nodes = tree.nodes(root);
    //   var links = tree.links(nodes);
    //   // 生成连线
    //   var link = svg
    //     .selectAll(".link")
    //     .data(links)
    //     .enter()
    //     .append("path")
    //     .attr("class", "link")
    //     .attr("d", diagonal);
    //   // 生成节点
    //   var node = svg
    //     .selectAll(".node")
    //     .data(nodes)
    //     .enter()
    //     .append("g")
    //     .attr("class", "node")
    //     .attr("transform", function (d) {
    
    
    //       return "translate(" + d.y + "," + d.x + ")";
    //     });

    //   // 给节点添加圆圈,设置半径
    //   node.append("circle").attr("r", 5);
    //   // 给节点添加文本,设置文本的样式位置
    //   node
    //     .append("text")
    //     .text((d) => d.name)
    //     .attr("dx", (d) => (d.children ? -15 : 15))
    //     .attr("dy", 5)
    //     .attr("text-anchor", (d) => (d.children ? "end" : "start"));
    // });

    /** 树状图v5实现 */
    var marge = {
    
     top: 50, bottom: 0, left: 10, right: 0 };
    var g = svg
      .append("g")
      .attr("transform", "translate(" + marge.top + "," + marge.left + ")");

    var dataset = {
    
    
      name: "中国",
      children: [
        {
    
    
          name: "浙江",
          children: [
            {
    
     name: "杭州", value: 100 },
            {
    
     name: "宁波", value: 100 },
            {
    
     name: "温州", value: 100 },
            {
    
     name: "绍兴", value: 100 },
          ],
        },
        {
    
    
          name: "广西",
          children: [
            {
    
    
              name: "桂林",
              children: [
                {
    
     name: "秀峰区", value: 100 },
                {
    
     name: "叠彩区", value: 100 },
                {
    
     name: "象山区", value: 100 },
                {
    
     name: "七星区", value: 100 },
              ],
            },
            {
    
     name: "南宁", value: 100 },
            {
    
     name: "柳州", value: 100 },
            {
    
     name: "防城港", value: 100 },
          ],
        },
        {
    
    
          name: "黑龙江",
          children: [
            {
    
     name: "哈尔滨", value: 100 },
            {
    
     name: "齐齐哈尔", value: 100 },
            {
    
     name: "牡丹江", value: 100 },
            {
    
     name: "大庆", value: 100 },
          ],
        },
        {
    
    
          name: "新疆",
          children: [
            {
    
     name: "乌鲁木齐" },
            {
    
     name: "克拉玛依" },
            {
    
     name: "吐鲁番" },
            {
    
     name: "哈密" },
          ],
        },
      ],
    };

    var hierarchyData = d3.hierarchy(dataset).sum((d) => d.value);

    //创建一个树状图
    var tree = d3
      .tree()
      .size([500, 500])
      .separation(function (a, b) {
    
    
        return (a.parent == b.parent ? 1 : 2) / a.depth;
      });
    var treeData = tree(hierarchyData);
    var nodes = treeData.descendants();
    var links = treeData.links();
    //输出节点和边
    console.log(nodes);
    console.log(links);
    var Bézier_curve_generator = d3
      .linkHorizontal()
      .x(d => d.y)
      .y(d => d.x);
    //生成连线
    g.append("g")
      .selectAll("path")
      .data(links)
      .enter()
      .append("path")
      .attr("class", "link")
      .attr("d", function (d) {
    
    
        var start = {
    
     x: d.source.x, y: d.source.y };
        var end = {
    
     x: d.target.x, y: d.target.y };
        return Bézier_curve_generator({
    
     source: start, target: end });
      });
    //生成节点
    var node = g
      .append("g")
      .selectAll("g")
      .data(nodes)
      .enter()
      .append("g")
      .attr("class", "node") //控制节点文字大小,上面style设置了样式
      .attr("transform", function (d) {
    
    
        return "translate(" + d.y + "," + d.x + ")";
      });

    // 给节点添加圆圈,设置半径
    node.append("circle").attr("r", 4);

    //给节点添加文本,设置文本的样式位置
    node
      .append("text")
      .text((d) => d.data.name)
      .attr("dx", (d) => (d.children ? -15 : 15))
      .attr("dy", 5)
      .attr("text-anchor", (d) => (d.children ? "end" : "start"));
  </script> -->
  <script>
    
  </script>
  </html>

猜你喜欢

转载自blog.csdn.net/weixin_53334387/article/details/126973472