vue canvas绘制信令图,动态显示标题、宽度、高度,前端中高级面试题

49 阅读6分钟

js基础

1)对js的理解? 2)请说出以下代码输出的值? 3)把以下代码,改写成依次输出0-9 4)如何区分数组对象,普通对象,函数对象 5)面向对象、面向过程 6)面向对象的三大基本特性 7)XML和JSON的区别? 8)Web Worker 和webSocket? 9)Javascript垃圾回收方法? 10)new操作符具体干了什么呢? 11)js延迟加载的方式有哪些? 12)WEB应用从服务器主动推送Data到客户端有那些方式?

js基础.PNG

前16.PNG

开源分享:docs.qq.com/doc/DSmRnRG… this.gapX * (k < j ? k : j) + this.paddingLeft, height - 10, maxWidth, this.lineHeight );

    if (i < this.xlArr.length - 1) {
      let nextWords = this.xlArr[i + 1].showInfo.split("\r\n");
      height += (this.lineHeight * (words.length + nextWords.length)) / 2 + 30;
    } else {
      height += this.lineHeight * words.length + 30;
    }
    // console.log(height, "height")
  })
  // 画虚线以及标题
  this.typeArr.map((v, i) => {
    this.paintText(context, v, i);
    setTimeout(() => {
      this.drawDashed(context, i);
    }, 300)
  })

  // document.getElementById('container').onscroll = (e) => {
  //   // console.log('e:', e.target)
  //   this.left = e.target.scrollLeft
  // }
  // 屏蔽所有页面 右键菜单
  // document.oncontextmenu = (event) => {
  //   event.returnValue = false
  // }
  // 屏蔽当前页面 右键菜单
  // document.getElementById('container').oncontextmenu = (event) => {
  //   event.returnValue = false
  // }
}

### 三、绘制箭头



// 箭头
paintArr(item, s, t, direction, ctx) {
  ctx.beginPath()
  ctx.lineWidth = 1
  if (item.dataStatus == 1) {
    ctx.strokeStyle = 'red'
  } else {
    ctx.strokeStyle = '#000' // 箭头线的颜色
  }

  if (item.lineType === 1) {
    ctx.setLineDash([5, 2]); // 虚线
  }
  ctx.moveTo(s[0], s[1])
  ctx.lineTo(t[0], t[1])
  ctx.stroke()
  ctx.closePath()

  ctx.beginPath()
  if (direction === 'right') {
    ctx.moveTo(t[0] - 10, t[1] + 3)
    ctx.lineTo(t[0], t[1])
    ctx.lineTo(t[0] - 10, t[1] - 3)
  } else {
    ctx.moveTo(t[0] + 10, t[1] - 3)
    ctx.lineTo(t[0], t[1])
    ctx.lineTo(t[0] + 10, t[1] + 3)
  }
  // ctx.closePath()
  ctx.stroke()
  // ctx.fill()
},

### 四、绘制 标题列的虚线



// 标题列的虚线
drawDashed(ctx, i) {
  ctx.beginPath()
  ctx.lineWidth = 1
  ctx.strokeStyle = '#696969' // '#FF8080'//虚线的颜色
  ctx.setLineDash([5, 2])
  ctx.moveTo(320 * i + this.paddingLeft, this.paddingTop + 40);
  ctx.lineTo(320 * i + this.paddingLeft, 400 * this.typeArr.length);
  ctx.fill()
  ctx.stroke()
  ctx.closePath()
},

### 五、文字自动换行 遇到换行符换行



// 文字自动换行 遇到换行符换行,并且超出最大宽度换行,只计算了最多显示7行的情况,超出7行得再计算
wrapText(item, context, words, x, y, maxWidth, lineHeight) {
  // console.log(words, "words")
  let originY = y;
  let len = words.length;
  let rectWidth = 0;

  for (var n = 0; n < len; n++) {
    // 不超出一行
    var testWidth = context.measureText(words[n]).width;
    if (testWidth < maxWidth) {
      if (rectWidth < testWidth) {
        rectWidth = testWidth;
      }
    }
  }
  // 在上面循环计算出文字实际最宽的位置,画出背景色遮挡箭头
  // 画背景色遮盖箭头, 背景色自己调,跟画布统一就行
  context.fillStyle = "#fff"; // 背景颜色
  context.fillRect(
    x + this.gapX / 2 - rectWidth / 2 - 4,
    originY,
    rectWidth + 6,
    lineHeight
  ); // 填充黄色背景

  for (var n = 0; n < len; n++) {
    // 不超出一行
    var testWidth = context.measureText(words[n]).width;
    if (testWidth < maxWidth) {
      // console.log(words[n], 1);
      let currentY = y;
      if (len === 1) {
        currentY = y + 14;
      } else if (len === 2) {
        currentY = y + 2;
      } else if (len === 3) {
        currentY = y - 6;
      } else if (len === 4) {
        currentY = y - 18;
      } else if (len === 5) {
        currentY = y - 28;
      } else if (len === 6) {
        currentY = y - 38;
      } else if (len === 7) {
        currentY = y - 48;
      }

      if (item.dataStatus == 1) {
        context.fillStyle = 'red'
      } else {
        context.fillStyle = '#000' // 字体颜色
      }
      // context.fillStyle = "#000"; // 字体颜色
      context.fillText(words[n], x + this.gapX / 2 - testWidth / 2, currentY);
      if (len > 1) {
        y += lineHeight;
      }
    } else {
      console.log(words[n], 2);
      // 文字超出一行,需要换行展示
      // 实际大于页面width font-size: 12, 计算出显示多少行
      let singleWordwith = 13;
      // 计算一行显示的最大字数,以及显示多少行
      let len = Math.floor(maxWidth / singleWordwith);
      let lineCount = Math.ceil(words[n].length / len);
      for (let j = 0; j <= lineCount; j++) {
        // 截取出每行显示的字
        let word = words[n].substr(j * len, len);
        let wordWidth = context.measureText(word).width;
        // 写入画布
        // 画背景色遮盖箭头, 背景色自己调,跟画布统一就行
        context.fillStyle = "#fff";
        context.fillRect(
          x + this.gapX / 2 - wordWidth / 2,
          y - 4,
          wordWidth,
          lineHeight
        ); // 填充黄色背景
        let currentY = y;
        if (lineCount === 2) {
          currentY = y + 2;
        } else if (lineCount === 3) {
          currentY = y - 6;
        } else if (lineCount === 4) {
          currentY = y - 18;
        } else if (lineCount === 5) {
          currentY = y - 28;
        } else if (lineCount === 6) {
          currentY = y - 38;
        } else if (lineCount === 7) {
          currentY = y - 48;
        }
        if (item.dataStatus == 1) {
          context.fillStyle = 'red'
        } else {
          context.fillStyle = '#000' // 字体颜色
        }
        // context.fillStyle = "#000";
        context.fillText(word, x + this.gapX / 2 - wordWidth / 2, currentY);
        y += lineHeight; // 换行
      }
    }
  }
},

### 六、模拟后端返回的数据



// signalTimeData: [ // { // startDataDir: "ATP", // endDataDir: "MT", // recTime: '2023-09-10 09:12:48', // showInfo: "M136\r\nT_Train=9340940ms\r\nDT:16", // dataDir: 0, // dataDirStr: "上行", // lineType: 0, // dataStatus: 0 // }, // { // startDataDir: "MT", // endDataDir: "ATP", // recTime: '2023-09-10 09:12:49', // showInfo: "M24\r\nT_Train=9341070ms", // dataDir: 1, // dataDirStr: "下行", // lineType: 0, // dataStatus: 0 // }, // { // startDataDir: "ATP", // endDataDir: "MT", // recTime: '2023-09-10 09:13:06', // showInfo: "M136\r\nT_Train=9358940ms\r\nDT:19\r\n此时,M24之后ATP发送3条APDU", // dataDir: 0, // dataDirStr: "上行", // lineType: 0, // dataStatus: 1 // }, // { // startDataDir: "MT", // endDataDir: "ATP", // recTime: '2023-09-10 09:13:07', // showInfo: "AK:20\r\n此时,M24之后RBC发送3条AK,无APDU", // dataDir: 1, // dataDirStr: "下行", // lineType: 0, // dataStatus: 1 // }, // { // startDataDir: "ATP", // endDataDir: "MT", // recTime: '2023-09-10 09:13:08', // showInfo: "TPDU_DR/SaPDU_D", // dataDir: 0, // dataDirStr: "上行", // lineType: 0, // dataStatus: 1 // }, // { // startDataDir: "MT", // endDataDir: "ATP", // recTime: '2023-09-10 09:13:09', // showInfo: "TPDU_DC", // dataDir: 1, // dataDirStr: "下行", // lineType: 0, // dataStatus: 0 // }, // { // startDataDir: "ATP", // endDataDir: "MT", // recTime: "2023-09-10 09:13:09", // showInfo: "DISC", // dataDir: 0, // dataDirStr: "上行", // lineType: 0, // dataStatus: 0 // }, // { // startDataDir: "MT", // endDataDir: "ATP", // recTime: "2023-09-10 09:13:09", // showInfo: "NO CARRIER", // dataDir: 1, // dataDirStr: "下行", // lineType: 0, // dataStatus: 0 // } // ],


**全部代码如下:**