2021-11-09

在这里插入图片描述
代码

<template>
  <div style="width: calc(100vw - 300px); height: calc(80vh - 10px)">
    <el-scrollbar always>
      <canvas ref="canvas" id="cavsElem" :width="width" :height="height">
        您的浏览器不支持canvas, 请升级更换或升级浏览器
      </canvas>
    </el-scrollbar>
  </div>
</template>

<script lang="ts">
import { computed, defineComponent, onMounted, ref, watch } from "vue";
import { useStore } from "vuex";
import tranListToTreeData from "@/utils/tree";
import { Item } from "ant-design-vue/lib/menu";
// 字符串分割
function splitArr(arr: string | any[], num: number) {
  var resultArr = [];
  for (var i = 0, len = arr.length; i < len; i += num) {
    resultArr.push(arr.slice(i, i + num));
  }
  return resultArr;
}

export default defineComponent({
  setup() {
    const store = useStore();
    store.dispatch("financialPlan/getProductionListAndAxis", 0);

    // 获取canvas实例
    const canvas: any = ref(null);
    const timeaxis: any = computed(() => store.state.financialPlan.axisList);
    const dataList: any = computed(() => store.state.financialPlan.childlist);
    const parentlist: any = computed(() => store.state.financialPlan.parentlist);
    console.log(parentlist.value, 123);
    const width: any = ref(0);
    const height: any = ref(0);
    console.log(width, height);

    watch(
      () => timeaxis.value,
      (val) => {
        console.log(123);

        width.value = computed(() => timeaxis.value.length * 300 + 600).value;
        height.value = computed(() => dataList.value.length * 100 + 200).value;
      }
    );

    onMounted(() => {
      const cavesSave = () => {
        var ctx = canvas.value.getContext("2d");
        // 获取鼠标位置
        // let bgID = -1;
        // 	canvas.addEventListener("mousemove", function(e) {
        // 		var x = e.clientX;
        // 		var y = e.clientY;
        // 		var rect = canvas.getBoundingClientRect();
        // 		x -= rect.left;
        // 		y -= rect.top;
        // 		console.log(x, y); // (x, y) 就是鼠标在 canvas 单击时的坐标
        // 		console.log(parseInt(y / 100))

        // 		ctx.clearRect(250,75,2000, 50);
        // 		if(bgID != 0 ){
        // 			console.log(1123123)
        // 			ctx.beginPath()
        // 			ctx.clearRect(250,75,2000, 50);
        // 			ctx.clearRect(250,75,2000, 50);
        // 			ctx.fillStyle = "rgba(0, 0, 0, 0)"
        // 			ctx.fillRect(250,75,2000, 50);
        // 			ctx.fill()
        // 		}

        // 		bgID = 2
        // 	})

        // 渲染表格
        var rectH = 100;
        var rectW = 300;
        ctx.lineWidth = 1;
        console.log(ctx);

        //绘制表格
        ctx.lineWidth = 1;
        // 第一步: 绘制y线 和 x的值
        let starty = 400; // y轴起始位置的基数
        timeaxis.value.forEach((item: any, i: any) => {
          ctx.setLineDash([5, 1]);
          starty = item.interval * (rectW / 10) + starty;
          ctx.beginPath();
          ctx.strokeStyle = "rgba(0, 0, 0, 0.5)";
          ctx.moveTo(starty, 0);
          //如果不设置moveTo,当前画笔没有位置
          ctx.lineTo(starty, canvas.value.height - 100);
          ctx.stroke();
          ctx.font = "16px 微软雅黑";
          ctx.fillText(item.day, starty - 50, canvas.value.height - 80);
        });
        ctx.setLineDash([0, 0]);
        //第二步:绘制横线
        let startx = 400; // x轴起始位置的基数
        for (var i = 0; i < 19; i++) {
          ctx.beginPath();
          ctx.strokeStyle = "rgba(0, 0, 0, 0.5)";
          ctx.moveTo(startx, rectH * i);
          ctx.lineTo(canvas.value.width - 380, rectH * i);
          ctx.stroke();
        }

        // 数据清洗
        let dataID = 0;
        dataID = 0;
        let dataArr2: any = [];
        dataList.value.map((itemFa: any, i: any) => {
          itemFa.data.map((item: any) => {
            const x = dataArr2.findIndex((res: any) => res.dwID === itemFa.id);
            const endTime = new Date(new Date(item.ENDTIME).getTime() + 86400000).toISOString();
            if (x == -1) {
              dataArr2.push({
                dwID: itemFa.id,
                id: dataID,
                type: item.NAME,
                childer: [
                  {
                    values: [
                      item.STARTTIME.split("T")[0].split("-").join("/"),
                      endTime.split("T")[0].split("-").join("/")
                    ],
                    text: item.NAME,
                    name: item.NAME,
                    dwname: item.DWNAME,
                    planeclass: item.PLANECLASS,
                    drawrowno: item.DRAWROWNO,
                    isoverdraw: item.ISOVERDRAW,
                    daysprogressed: item.DAYSPROGRESSED
                  }
                ],
                text: item.NAME + item.DWNAME
              });
              dataID++;
            } else {
              dataArr2[x].childer.push({
                values: [item.STARTTIME.split("T")[0].split("-").join("/"), endTime.split("T")[0].split("-").join("/")],
                text: item.NAME,
                name: item.NAME,
                dwname: item.DWNAME,
                planeclass: item.PLANECLASS,
                drawrowno: item.DRAWROWNO,
                isoverdraw: item.ISOVERDRAW,
                daysprogressed: item.DAYSPROGRESSED
              });
            }
          });
        });

        // 数据条数绘制
        dataArr2.forEach((res: any) => {
          res.childer.forEach((resChi: any) => {
            let dataStarsx =
              (new Date(resChi.values[0]).getTime() - new Date(timeaxis.value[0].day).getTime()) / 86400000;
            let dateTime = (new Date(resChi.values[1]).getTime() - new Date(resChi.values[0]).getTime()) / 86400000;
            // 绘制 单条数据的填充
            ctx.beginPath();
            //
            // 数据长度
            let datax = dateTime * (rectW / 10);
            //(x起始位置, y起始位置, 长度, 高度 )
            // 填充
            if (resChi.isoverdraw) {
              if (resChi.drawrowno == 1) {
                ctx.rect(startx + dataStarsx * (rectW / 10), res.id * 100 + 75, datax, 22);
              } else {
                ctx.rect(startx + dataStarsx * (rectW / 10), res.id * 100 + 75 + 29, datax, 21);
              }
              // 填充色
              if (resChi.planeclass === 11) {
                ctx.fillStyle = "#FFF2CC";
              } else if (resChi.planeclass === 12) {
                ctx.fillStyle = "#F2DCDA";
              } else if (resChi.planeclass === 13) {
                ctx.fillStyle = "#99FFCC";
              } else {
                ctx.fillStyle = "#00ffff";
              }
              ctx.strokeStyle = "rgba(0, 0, 0,1)";
              ctx.stroke();
              ctx.fill();
              // 绘制进度方框
              // 需要一个进度参数

              if (resChi.drawrowno == 1) {
                for (var i = 0; i < datax / (rectW / 10); i++) {
                  ctx.beginPath();
                  if (i < resChi.daysprogressed) {
                    ctx.lineWidth = 1;
                    ctx.fillStyle = "rgba(170, 0, 0, 0.5)";
                    ctx.fillRect(
                      startx + dataStarsx * (rectW / 10) + i * (rectW / 10),
                      res.id * 100 + 98,
                      rectW / 10,
                      5
                    );
                  }
                  ctx.rect(startx + dataStarsx * (rectW / 10) + i * (rectW / 10), res.id * 100 + 98, rectW / 10, 5);
                  ctx.strokeStyle = "rgba(0, 0, 0, 0.5 )";
                  ctx.stroke();
                }
              } else {
                for (var index = 0; index < datax / (rectW / 10); index++) {
                  ctx.beginPath();
                  if (index < resChi.daysprogressed) {
                    ctx.lineWidth = 1;
                    ctx.fillStyle = "rgba(170, 0, 0, 0.5)";
                    ctx.fillRect(
                      startx + dataStarsx * (rectW / 10) + index * (rectW / 10),
                      res.id * 100 + 125,
                      rectW / 10,
                      5
                    );
                  }
                  ctx.rect(
                    startx + dataStarsx * (rectW / 10) + index * (rectW / 10),
                    res.id * 100 + 125,
                    rectW / 10,
                    5
                  );
                  ctx.strokeStyle = "rgba(0, 0, 0, 0.5 )";
                  ctx.stroke();
                }
              }

              // 绘制单条数据的文本内容
              ctx.beginPath();
              ctx.fillStyle = "#000000";
              ctx.font = "12px Arial";
              let rerChiText = resChi.text;
              if (resChi.dwname) rerChiText = rerChiText + `- ${resChi.dwname}`;
              let textWidth = ctx.measureText(rerChiText).width;

              if (textWidth < datax) {
                if (resChi.drawrowno == 1) {
                  ctx.fillText(
                    rerChiText,
                    startx + dataStarsx * (rectW / 10) + datax / 2 - textWidth / 2,
                    res.id * 100 + 91
                  );
                } else {
                  ctx.fillText(
                    rerChiText,
                    startx + dataStarsx * (rectW / 10) + datax / 2 - textWidth / 2,
                    res.id * 100 + 93 + 25
                  );
                }
              } else {
                let resChiTextArr = rerChiText.split("");

                let textArr = splitArr(resChiTextArr, Math.floor(rerChiText.length / 2) + 1);

                textArr.forEach((resText: any, i: any) => {
                  ctx.fillText(
                    resText.join(""),
                    startx + dataStarsx * (rectW / 10) + datax / 2 - textWidth / 3,
                    res.id * 100 + (93 + i * 20)
                  );
                });
              }
            } else {
              let datax = dateTime * (rectW / 10);
              ctx.rect(startx + dataStarsx * (rectW / 10), res.id * 100 + 75, datax, 45);
              if (resChi.planeclass === 11) {
                ctx.fillStyle = "#FFF2CC";
              } else if (resChi.planeclass === 12) {
                ctx.fillStyle = "#F2DCDA";
              } else if (resChi.planeclass === 13) {
                ctx.fillStyle = "#99FFCC";
              } else {
                ctx.fillStyle = "#00ffff";
              }
              ctx.strokeStyle = "rgba(0, 0, 0,1)";
              ctx.stroke();
              ctx.fill();
              // 绘制进度方框
              // 需要一个进度参数
              for (var index2 = 0; index2 < datax / (rectW / 10); index2++) {
                ctx.beginPath();
                if (index2 < resChi.daysprogressed) {
                  ctx.lineWidth = 1;
                  ctx.fillStyle = "rgba(170, 0, 0, 0.5)";
                  ctx.fillRect(
                    startx + dataStarsx * (rectW / 10) + index2 * (rectW / 10),
                    res.id * 100 + 120,
                    rectW / 10,
                    10
                  );
                }
                ctx.rect(
                  startx + dataStarsx * (rectW / 10) + index2 * (rectW / 10),
                  res.id * 100 + 120,
                  rectW / 10,
                  10
                );
                ctx.strokeStyle = "rgba(0, 0, 0, 0.5 )";
                ctx.stroke();
              }
              // 绘制单条数据的文本内容
              ctx.beginPath();
              ctx.fillStyle = "#000000";
              ctx.font = "12px Arial";
              let rerChiText = resChi.text;
              if (resChi.dwname) rerChiText = rerChiText + `- ${resChi.dwname}`;
              let textWidth = ctx.measureText(rerChiText).width;

              if (textWidth < datax) {
                ctx.fillText(
                  rerChiText,
                  startx + dataStarsx * (rectW / 10) + datax / 2 - textWidth / 2,
                  res.id * 100 + 105
                );
              } else {
                let resChiTextArr = rerChiText.split("");

                let textArr = splitArr(resChiTextArr, Math.floor(rerChiText.length / 2) + 1);

                textArr.forEach((resText: any, i: any) => {
                  ctx.fillText(
                    resText.join(""),
                    startx + dataStarsx * (rectW / 10) + datax / 2 - textWidth / 3,
                    res.id * 100 + (93 + i * 20)
                  );
                });
              }
            }
          });

          const paData = tranListToTreeData(parentlist.value, -1);
          // 基数
          let index = 1;
          const x = (item: any, height: any, startDot: any = 0, endDot: any = 0) => {
            item.map((item: any, i: any) => {
              // console.log(item);
              // 第一步绘制方框
              ctx.beginPath();
              ctx.rect(15 + (item.PLANECLASS - 1) * 200, height, 170, 25);
              // 第二步绘制填充
              if (item.PLANECLASS == 1) {
                ctx.fillStyle = "#B7DDE8";
              } else if (item.PLANECLASS == 2) {
                ctx.fillStyle = "#D7E3BF";
              } else if (item.PLANECLASS == 3) {
                ctx.fillStyle = "#99FFCC";
              }
              // 第三部绘制文字
              ctx.stroke();
              ctx.fill();
              ctx.fillStyle = "#000";
              let textWidth = ctx.measureText(item.NAME).width;
              ctx.fillText(item.NAME, 100 - textWidth / 2 + (item.PLANECLASS - 1) * 200, height + 15);
              // 绘制连接线
              if (item.PLANECLASS !== 1) {
                ctx.lineWidth = 0.9;
                ctx.beginPath();
                ctx.moveTo(startDot, endDot + 12.5);
                ctx.lineTo(startDot + 15, endDot + 12.5);
                ctx.lineTo(startDot + 15, height + 12.5);
                ctx.lineTo(startDot + 30, height + 12.5);
                ctx.stroke();
              }

              if (item.PLANECLASS == 2 || item.PLANECLASS == 3) {
                if (!item.children) height += 100;
              }
              if (item.children) {
                x(item.children, height, 15 + (item.PLANECLASS - 1) * 200 + 170, height);
                index++;
                if (item.PLANECLASS == 1) height += index * 100;
                if (item.PLANECLASS == 2) height += item.children.length * 100;
              }
              // height += item?.children?.length * 100 ?? 100;
            });
          };
          x(paData, 87.5, -2);

          ctx.stroke();
        });
      };

      watch(
        () => timeaxis.value,
        (val) => {
          cavesSave();
        }
      );
      watch(
        () => width.value,
        (val) => {
          console.log(val);
          console.log(313123);
          setTimeout(() => {
            cavesSave();
          }, 1);
        }
      );
    });
    return { canvas, width, height };
  }
});
</script>

<style lang="scss" scoped>
:deep() .el-scrollbar__bar {
  // height: 10px;
  // width: 10px;
}
</style>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值