• uniapp实现大气质量指标图(app端小程序端均支持,app-nvue不支持画布)


    效果图如下:

    思路:

    1.首先我想到的就是使用图标库echarts或ucharts,可是找了找没有找到类似的。

    2.其次我就想用画布来实现这个效果,直接上手。(app-vue和小程序均可以实现,但是在app-nvue页面不支持画布,尝试了一下再nvue页面直接导致程序闪退)

    3.后来,使用手动创建一个竖向的类似效果。

    注意:

    1.app-nvue页面不支持画布效果,官方说引入插件支持,但直接导致闪退。

    2.map很多参数app端仅支持app-nvue页面。

    方法一 使用画布进行绘制(不支持app-nvue)

    1. <script>
    2. export default {
    3. data() {
    4. return {
    5. canvasId: "canvas",
    6. pollutionLevels: [{
    7. level: "优",
    8. color: "#00FF00",
    9. percent: 0.133,
    10. mark: "35"
    11. },
    12. {
    13. level: "良",
    14. color: "#FFFF00",
    15. percent: 0.133,
    16. mark: "75"
    17. },
    18. {
    19. level: "轻度",
    20. color: "#ff5500",
    21. percent: 0.133,
    22. mark: "115"
    23. },
    24. {
    25. level: "中度",
    26. color: "#FF0000",
    27. percent: 0.133,
    28. mark: "150"
    29. },
    30. {
    31. level: "重度",
    32. color: "#860000",
    33. percent: 0.133,
    34. mark: "250"
    35. },
    36. {
    37. level: "严重",
    38. color: "#510000",
    39. percent: 0.133,
    40. mark: "500"
    41. }
    42. ]
    43. };
    44. },
    45. mounted() {
    46. this.drawChart();
    47. },
    48. methods: {
    49. drawChart() {
    50. const ctx = uni.createCanvasContext(this.canvasId, this);
    51. const startX = 0; // 图表起始位置X坐标
    52. const startY = 20; // 图表起始位置Y坐标
    53. const chartWidth = 260; // 图表宽度
    54. const chartHeight = 10; // 图表高度
    55. const textHeight = 20; // 标题高度
    56. const markfontSize = 10; //标点信息字体大小
    57. const fideWeight = 10 //减去范围坐标点的宽度
    58. const fideHeight = 44 //加上范围坐标点的高度
    59. const tdPaddingHeight = 4 //垂直距离高度
    60. let x = startX;
    61. const y = startY;
    62. let nextX = 0; // 下一个起始位置的x坐标
    63. function drawColorBlock(color, width, height) {
    64. ctx.setFillStyle(color);
    65. ctx.fillRect(x, y, width, height);
    66. }
    67. function drawText(text, width) {
    68. ctx.setFontSize(markfontSize);
    69. ctx.setFillStyle("#000000");
    70. const textWidth = ctx.measureText(text).width; // 计算文字宽度
    71. const textX = x + (width - textWidth) / 2; // 水平居中对齐
    72. ctx.fillText(text, textX, y - chartHeight + tdPaddingHeight); //在图表的上方
    73. }
    74. function drawMarkText(text) {
    75. ctx.setFontSize(markfontSize);
    76. ctx.setFillStyle("#000000");
    77. const textWidth = ctx.measureText(text).width; // 计算文字宽度
    78. const textX = startX + nextX - fideWeight - textWidth / 2; // 水平居中对齐
    79. if (text === "0") {
    80. ctx.fillText("0", startX, y - textHeight + fideHeight);
    81. } else {
    82. ctx.fillText(text, textX + 10, y - textHeight + fideHeight);
    83. }
    84. }
    85. this.pollutionLevels.forEach(level => {
    86. const width = chartWidth * level.percent;
    87. nextX = x + width; // 记录下一个起始位置的x坐标
    88. // 绘制颜色区块
    89. drawColorBlock(level.color, width, chartHeight);
    90. // 绘制标题
    91. drawText(level.level, width);
    92. drawMarkText(level.mark);
    93. if (level.level==='优') {
    94. drawMarkText("0");
    95. drawMarkText(level.mark);
    96. }
    97. x = nextX; // 更新起始位置的x坐标
    98. });
    99. ctx.draw();
    100. }
    101. }
    102. }
    103. script>

    实现效果图如下

    方法二 使用盒子创建竖向对应(比较笨拙,但是app-nvue页面只能这样来实现了)

    这里我封装了一个方法

    组件代码

    1. <script>
    2. export default {
    3. props: {
    4. legendList: {
    5. type: [Array],
    6. default: () => []
    7. },
    8. },
    9. data() {
    10. return {
    11. list: []
    12. }
    13. },
    14. watch: {
    15. legendList: {
    16. handler: function(newVal) {
    17. const datas = JSON.parse(newVal)
    18. datas.forEach((ele) => {
    19. if (ele.mark === '优') {
    20. ele.bgColor = "#00FF00"
    21. } else if (ele.mark === '良') {
    22. ele.bgColor = "#FFFF00"
    23. } else if (ele.mark === '轻度') {
    24. ele.bgColor = "#ff5500"
    25. } else if (ele.mark === '中度') {
    26. ele.bgColor = "#FF0000"
    27. } else if (ele.mark === '重度') {
    28. ele.bgColor = "#860000"
    29. } else if (ele.mark === '严重') {
    30. ele.bgColor = "#510000"
    31. } else if (ele.mark === '离线') {
    32. ele.bgColor = "#818181"
    33. }
    34. })
    35. this.list = datas
    36. },
    37. deep: true, // 深度监听
    38. immediate: true // 立即执行
    39. }
    40. },
    41. }
    42. script>
    43. <style lang="scss" scoped>
    44. .legend-section {
    45. border-radius: 2rpx;
    46. padding: 10rpx;
    47. }
    48. .rowlist {
    49. display: flex;
    50. flex-flow: row nowrap;
    51. align-items: center;
    52. justify-content: flex-start;
    53. margin: 10rpx 12rpx;
    54. }
    55. .mark {
    56. padding-left: 10rpx;
    57. }
    58. style>

    调用组件

    1. class="maplegend-list" v-if="legendFlag">
    2. <legend :legend-list="legendList">legend>
    3. //数据初始化
    4. legendList: [], //图例信息
    5. //传入数据
    6. this.legendList = JSON.stringify(legendList.data) //图例信息

    实现效果如下

    总而言之,app-nvue页面有很大的性能提升,但总会牺牲一些东西来弥补。app-nvue页面css很多有局限性,仔细阅读文档。

  • 相关阅读:
    Xshell + lrzsz 实现Linux与Windos文件互传
    2023前端面试整理
    web前端-JQuery
    智工教育:注册计量师职业资格条件已改革!
    dubbo 2.5.3 环境搭建
    Java_多态
    MySQL 啥时候用表锁,啥时候用行锁?
    振动传感器在电机监测中的应用
    COVID疫苗加强针来袭,是否该接种?
    python学习笔记1-SortedList的使用
  • 原文地址:https://blog.csdn.net/weixin_53339757/article/details/132940808