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
| // 原始代码 // 绘制图形数据 drawChart() { const canvasBox = document.getElementById('canvas-box1') if (!canvasBox) { return } const ctx = canvasBox.getContext('2d') const ctxWidth = parseInt( window.getComputedStyle(canvasBox, null).width, 10 ) const ctxHeight = parseInt( window.getComputedStyle(canvasBox, null).height, 10 ) let step = ctxWidth / 24 // 除以24小时 let textAlign const labelHeight = 20 const barRadius = (ctxHeight - labelHeight) / 2 canvasBox.width = ctxWidth canvasBox.height = ctxHeight ctx.clearRect(0, 0, ctxWidth, ctxHeight) // 绘制x轴文字 ctx.save() ctx.font = '12px serif' ctx.textBaseline = 'bottom' for (let index = 0; index <= 24; index += 4) { if (index === 0) { textAlign = 'left' } else if (index === 24) { textAlign = 'right' } else { textAlign = 'center' } ctx.textAlign = textAlign ctx.fillText(`${index}:00`, index * step, ctxHeight) } ctx.restore() // 绘制背景 ctx.save() ctx.fillStyle = '#f5f5f5' ctx.beginPath() ctx.moveTo(barRadius, 0) ctx.lineTo(ctxWidth - barRadius, 0) ctx.arc( ctxWidth - barRadius, barRadius, barRadius, -Math.PI / 2, Math.PI / 2 ) ctx.lineTo(barRadius, barRadius * 2) ctx.arc(barRadius, barRadius, barRadius, Math.PI / 2, (3 * Math.PI) / 2) ctx.closePath() ctx.fill() ctx.restore()
step = ctxWidth / (24 * 60) // 按分钟分区 if ( this.workData.length === 0 || this.workData.length <= this.currentPeriod ) { return } // 绘制所有数据 ctx.save() ctx.beginPath() ctx.fillStyle = '#ebebeb' this.workData.forEach(item => { const { startTime, endTime } = item const startDate = new Date(startTime) const stopDate = new Date(endTime) const px1 = step * (60 * startDate.getHours() + startDate.getMinutes() + startDate.getSeconds() / 60) const px2 = step * (60 * stopDate.getHours() + stopDate.getMinutes() + stopDate.getSeconds() / 60) if (px2 > px1) { ctx.rect(px1, 0, px2 - px1, barRadius * 2) } }) ctx.fill() ctx.restore() // 绘制高亮数据 ctx.save() ctx.beginPath() ctx.fillStyle = '#70b913' const currentItem = this.workData[this.currentPeriod] { const { startTime, endTime } = currentItem const startDate = new Date(startTime) const stopDate = new Date(endTime) const px1 = step * (60 * startDate.getHours() + startDate.getMinutes() + startDate.getSeconds() / 60) const px2 = step * (60 * stopDate.getHours() + stopDate.getMinutes() + stopDate.getSeconds() / 60) if (px2 > px1) { ctx.rect(px1, 0, px2 - px1, barRadius * 2) } } ctx.fill() ctx.restore() // 给高亮数据加描边,不然工作时间太短看不出来 ctx.save() ctx.beginPath() ctx.strokeStyle = '#70b913' ctx.lineWidth = 5 { const { startTime, endTime } = currentItem const startDate = new Date(startTime) const stopDate = new Date(endTime) const px1 = step * (60 * startDate.getHours() + startDate.getMinutes() + startDate.getSeconds() / 60) const px2 = step * (60 * stopDate.getHours() + stopDate.getMinutes() + stopDate.getSeconds() / 60) if (px2 > px1) { ctx.rect(px1, 0, px2 - px1, barRadius * 2 - 2.5) } } ctx.stroke() ctx.restore() // 绘制x轴刻度 step = ctxWidth / 24 // 除以24小时 ctx.save() ctx.strokeStyle = '#d5d5d5' ctx.beginPath() for (let index = 4; index < 24; index += 4) { const px = index * step ctx.moveTo(px, barRadius * 2) ctx.lineTo(px, ctxHeight - labelHeight - 10) } ctx.stroke() ctx.restore() },
|