mini-trend.vue 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. <template>
  2. <view class="mini-trend">
  3. <canvas :canvas-id="canvasId" class="trend-canvas"></canvas>
  4. </view>
  5. </template>
  6. <script>
  7. export default {
  8. props: {
  9. data: {
  10. type: Array,
  11. default: function() { return [] }
  12. }
  13. },
  14. data: function() {
  15. return {
  16. canvasId: 'trend-' + Math.random().toString(36).substr(2, 9),
  17. drawn: false
  18. }
  19. },
  20. mounted: function() {
  21. this.$nextTick(this.drawChart)
  22. },
  23. watch: {
  24. data: function() {
  25. this.$nextTick(this.drawChart)
  26. }
  27. },
  28. methods: {
  29. drawChart: function() {
  30. var ctx = uni.createCanvasContext(this.canvasId, this)
  31. var width = 600 // rpx
  32. var height = 60
  33. var data = this.data
  34. if (!data.length) return
  35. var min = Math.min.apply(null, data)
  36. var max = Math.max.apply(null, data)
  37. var range = max - min || 1
  38. var stepX = width / (data.length - 1 || 1)
  39. ctx.setStrokeStyle('#EF4444')
  40. ctx.setLineWidth(3)
  41. ctx.beginPath()
  42. for (var i = 0; i < data.length; i++) {
  43. var x = i * stepX
  44. var y = height - (data[i] - min) / range * (height - 10) - 5
  45. if (i === 0) ctx.moveTo(x, y)
  46. else ctx.lineTo(x, y)
  47. }
  48. ctx.stroke()
  49. // 末端圆点
  50. var lastX = (data.length - 1) * stepX
  51. var lastY = height - (data[data.length - 1] - min) / range * (height - 10) - 5
  52. ctx.setFillStyle('#EF4444')
  53. ctx.beginPath()
  54. ctx.arc(lastX, lastY, 4, 0, 2 * Math.PI)
  55. ctx.fill()
  56. ctx.draw()
  57. this.drawn = true
  58. }
  59. }
  60. }
  61. </script>
  62. <style scoped>
  63. .mini-trend {
  64. margin: 12rpx 0;
  65. width: 100%;
  66. }
  67. .trend-canvas {
  68. width: 100%;
  69. height: 60rpx;
  70. }
  71. </style>