前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >树状图js的实现方法

树状图js的实现方法

原创
作者头像
用户5317830
修改2021-01-19 23:14:24
3.9K0
修改2021-01-19 23:14:24
举报

本文是基于决策树的需求做的前期demo实现,所以以二叉树为实现目标。基本术语如下:

二叉树

  • 1、二叉树中的节点最多只能有两个子节点,一左一右。因此不怒在度大于2的节点
  • 2、左右子节点的顺序不能颠倒
代码语言:txt
复制
<body>
  <canvas id="canvas"></canvas>
  <button class="btn" onClick="draw()">画树</button>

  <script>
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    var startX = window.innerWidth * 0.5;
    var startY = window.innerHeight;

    function init() {
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
      ctx.fillStyle = 'rgb(255,255,255)';
      ctx.beginPath();
      ctx.moveTo(startX, startY * 0.9);
      ctx.lineTo(startX, startY * 0.7);
      ctx.closePath();
      ctx.strokeStyle = 'black';
      ctx.lineWidth = 10;
      ctx.stroke();
    }

    function nextStep(parentLength, lineWidth, color, parentEndX, parentEndY, k, baseAngle, angle) {
      if (parentLength <= 1) {
        return 0;
      }
      var leftAngle = angle + baseAngle;
      var rightAngle = baseAngle - angle;
      //根据传来的角度,算出左枝和右枝需要偏移的量
      var LdisX = k * parentLength * Math.round(Math.cos(leftAngle / 180 * Math.PI) * 10) / 10;
      var LdisY = k * parentLength * Math.round(Math.sin(leftAngle / 180 * Math.PI) * 10) / 10;
      var RdisX = k * parentLength * Math.round(Math.cos(rightAngle / 180 * Math.PI) * 10) / 10;
      var RdisY = k * parentLength * Math.round(Math.sin(rightAngle / 180 * Math.PI) * 10) / 10;
      //算出左枝和右枝终点坐标的值
      var LXbough = parentEndX + LdisX;
      var LYbough = parentEndY - LdisY;
      var RXbough = parentEndX + RdisX;
      var RYbough = parentEndY - RdisY;
      //开始绘画
      ctx.beginPath();
      ctx.moveTo(parentEndX, parentEndY);
      ctx.lineTo(LXbough, LYbough);
      ctx.moveTo(parentEndX, parentEndY);
      ctx.lineTo(RXbough, RYbough);
      ctx.closePath();
      //当树枝长度到一定值时,树枝的颜色逐渐变浅
      var rgb = '#f' + color + "" + color;
      if (parentLength < 20) {
        ctx.strokeStyle = rgb;
        switch (color) {
          case 1: color = 4; break;
          case 4: color = 7; break;
          case 7: color = 'a'; break;
          case 'a': color = 'c'; break;
          case 'c': color = 'e'; break;
          default: color = 'e'; break;
        }
      } else {
        ctx.strokeStyle = 'black';
      }
      ctx.lineWidth = lineWidth;
      ctx.stroke();

      //树枝下个分支点的角度 值越大,伞盖越大,常数为了防止树枝分叉角度太小重叠
      var newAngle = Math.random() * 30 + 10;
      //画左枝和右枝
      nextStep(parentLength * k, lineWidth * 0.6, color, LXbough, LYbough, k, leftAngle, newAngle);
      nextStep(parentLength * k, lineWidth * 0.6, color, RXbough, RYbough, k, rightAngle, newAngle);
    }

    function draw() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      init();
      nextStep(startY * 0.3, 6, 4, startX, startY * 0.7, 0.7, 90, Math.random() * 30 + 10);
    }

    init();

  </script>
</body>

效果图如下:

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 二叉树
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档