气象相关图表制作-字体图标、图片、折线的堆叠

开发工作中有个需要展示气温(折线)、天气(图片)、风羽(字体图标)的图表展示需求,之前用过highcharts的关于类似的chart,里面的风雨用的是自带的图片,但是现在要求风羽需要用字体图标渲染,于是我选择了比较熟悉的Echarts制作这个图表。

难点

  1. 风羽(字体图标)不仅需要显示,还需要旋转,但是旋转的时,风羽会偏移
  2. 各类元素之间需要分层显示

代码

/**
* SouthAsiaViewHighImpactWeatherSingleAirportChart.vue 逐3小时天气预报图
* @Author ZhangJun
* @Date  2024/6/19 10:18
**/
<template>
  <div class="w-full h-full"></div>
</template>
<script>
import * as echarts from 'echarts';
import CanvasGridUtils from "@/utils/leaflet/CanvasGridUtils";
import moment from "moment/moment";

export default {
  name: 'SouthAsiaViewHighImpactWeatherSingleAirportChart',
  data() {
    return {
      chartOption: {
        grid: {
          left: '5%',
          right: '5%',
          bottom: '3%',
          top: '5px',
          containLabel: true
        },
        tooltip: {
          trigger: 'axis',
          backgroundColor: 'rgba(0, 38, 72, 0.9)',
          borderColor: 'rgba(141, 180, 255, 0.31)',
          borderWidth: 2,
          formatter: (params) => {
            let [temperatureParams, weatherParams, windParams, levelParams] = params;
            let date = moment(temperatureParams?.name, 'YYYYMMDDHHmm').format('YYYY-MM-DD HH:mm');

            //温度值
            let temperatureValue = `${temperatureParams?.value}`;
            let temperatureMarker = temperatureParams?.marker;

            //天气
            let weatherValue = weatherParams?.value?.[2];
            let weatherMarker = weatherParams?.data.symbol;

            //风向/风力
            let windMarker = CanvasGridUtils.GetWindChar(windParams?.value?.[1]);
            let rotate = windParams?.data.label.rotate;
            let levelValue = `${levelParams?.value?.[1]}`;
            return [
              `<div style="font-size: 14px; color: #FFFFFF;font-weight: bold;">
                 ${date}
                </div>`,
              `<div style="display: flex; justify-content: space-between; align-items: center;">
                 <div style="padding: 0 10px;">${temperatureMarker}</div><div style="font-size: 12px; color: #FFFFFF;">${temperatureValue}</div>
                </div>`,
              `<div style="display: flex; justify-content: space-between; align-items: center;">
                  <img src="${weatherMarker.replace('image://', '')}" alt="${weatherValue}" style="width: 30px; height: 30px;"><div  style="font-size: 12px; color: #FFFFFF;">${weatherValue}</div>
                </div>`,
              `<div style="display: flex; justify-content: space-between; align-items: center;">
                  <div style="transform: rotate(${rotate}deg);font-size: 30px;font-weight: bold;color: #FFFFFF;">${windMarker}</div><div style="font-size: 12px; color: #FFFFFF;">${levelValue}</div>
                </div>`
            ].join('');
          }
        },
        xAxis: {
          type: 'category',
          boundaryGap: false,
          axisLine: {
            show: false
          },
          axisTick: {
            show: false
          },
          splitLine: {
            show: false
          },
          axisLabel: {
            fontFamily: 'D-DIN,SAN-SERIF',
            fontSize: '12px',
            fontWeight: 'normal',
            color: '#FFFFFF',
            formatter: (value) => {
              return value ? moment(value, 'YYYYMMDDHHmm').format('HH:mm') : '';
            },
          },
          //日期数据
          data: ['202406280000', '202406280300', '202406280600', '202406280900', '202406281200', '202406281500', '202406281800', '202406282100']
        },
        yAxis: [
          {
            type: 'value',
            axisLine: {show: false},
            axisTick: {show: false},
            axisLabel: {show: false},
            splitLine: {show: false},
            min: -120,
            max: 60,
          },
          {
            type: 'value',
            axisLine: {show: false},
            axisTick: {show: false},
            axisLabel: {show: false},
            splitLine: {show: false},
            min: 0,
            max: 100,
          }
        ],
        series: [
          {
            name: '温度',
            type: 'line',
            yAxisIndex: 0,
            label: {
              show: true,
              color: '#fff',
              align: 'center',
              formatter: '{c}℃'
            },
            lineStyle: {
              color: '#FFBC1E'
            },
            labelLayout(params) {
              return {
                x: params.rect.x - params.rect.width,
                y: params.rect.y < params.rect.height * 2 ? params.rect.y + params.rect.height * 3 : params.rect.y - params.rect.height,
                verticalAlign: 'middle',
                align: 'left'
              }
            },
            data: [-10, -12, 11, 13, 60, 23, 21, 11]
          },
          //天气
          {
            name: 'weather',
            type: 'pictorialBar',
            yAxisIndex: 1,
            symbolSize: 30,
            symbolOffset: [0, -65],
            label: {
              show: true,
              fontSize: 12,
              color: '#fff',
              offset: [0, -10],
              formatter: ({value}) => {
                return value?.[2];
              },
            },
            data: [
              {
                value: ['202406280000', 0, '晴'],
                symbol: `image://${require('@/assets/images/weather/晴.png')}`,
              },
              {
                value: ['202406280300', 0, '晴'],
                symbol: `image://${require('@/assets/images/weather/晴.png')}`,
              },
              {
                value: ['202406280600', 0, '多云'],
                symbol: `image://${require('@/assets/images/weather/多云.png')}`,
              },
              {
                value: ['202406280900', 0, '晴'],
                symbol: `image://${require('@/assets/images/weather/晴.png')}`,
              },
              {
                value: ['202406281200', 0, '晴'],
                symbol: `image://${require('@/assets/images/weather/晴.png')}`,
              },
              {
                value: ['202406281500', 0, '阵雨'],
                symbol: `image://${require('@/assets/images/weather/阵雨.png')}`,
              },
              {
                value: ['202406281800', 0, '阴'],
                symbol: `image://${require('@/assets/images/weather/阴.png')}`,
              },
              {
                value: ['202406282100', 0, '晴'],
                symbol: `image://${require('@/assets/images/weather/晴.png')}`,
              },
            ]
          },
          //绘制风羽
          {
            name: 'winBarb',
            type: 'pictorialBar',
            yAxisIndex: 1,
            symbolSize: [0, 65],
            label: {
              show: true,
              fontFamily: 'iconfont',
              fontSize: 30,
              fontWeight: 'bold',
              color: '#fff',
              formatter: ({value}) => {
                return CanvasGridUtils.GetWindChar(value?.[1]);
              },
            },
            data: [{
              value: ['202406280000', 10],
              label: {
                rotate: 180,
              },
            }, {
              value: ['202406280300', 10],
              label: {
                rotate: 0,
              },
            }, {
              value: ['202406280600', 10],
              label: {
                rotate: 90,
              },
            }, {
              value: ['202406280900', 10],
              label: {
                rotate: 200,
              },
            }, {
              value: ['202406281200', 10],
              label: {
                rotate: 180,
              },
            }, {
              value: ['202406281500', 10],
              label: {
                rotate: 180,
              },
            }, {
              value: ['202406281800', 10],
              label: {
                rotate: 180,
              },
            }, {
              value: ['202406282100', 10],
              label: {
                rotate: 180,
              },
            }]
          },
          // 绘制风力等级图标
          {
            name: 'winLevel',
            type: 'pictorialBar',
            yAxisIndex: 1,
            symbolSize: [0, 20],
            label: {
              show: true,
              fontSize: 12,
              fontFamily: 'MiSans, sans-serif',
              color: '#fff',
              align: 'center',
              formatter: ({value}) => {
                let level = value?.[1];
                return `${level}`;
              },
            },
            data: [
              ['202406280000', 3],
              ['202406280300', 3],
              ['202406280600', 4],
              ['202406280900', 5],
              ['202406281200', 4],
              ['202406281500', 3],
              ['202406281800', 4],
              ['202406282100', 3],
            ]
          }
        ]
      }
    }
  },
  methods: {
    /**
     * 初始化图表
     */
    initChart() {
      echarts.init(this.$el).setOption(this.chartOption);
    },
  },
  mounted() {
    this.$nextTick(() => {
      this.initChart();
    });
  }
}
</script>

效果

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/750148.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一站式自动化测试工具——AI-TestOps

文章目录 软件测试的重要性龙测科技是什么&#xff1f;核心优势平台使用 软件测试的重要性 软件测试在整个软件生命周期里&#xff0c;具有十分关键的地位&#xff0c;学校只可以在运行与后期维护时期以前&#xff0c;软件调试瀑布模型&#xff0c;是一类常规的运行方式&#…

超好用的思维导图—万兴亿图脑图 v10解锁版安装教程 (思维导图软件和头脑风暴工具)

前言 万兴亿图脑图 (Wondershare EdrawMind) 是一款多平台协作思维导图软件和头脑风暴工具,亿图思维导图提供丰富的布局,样式,主题及配色方案,集成拥有数万幅原创思维导图作品的思维导图社区,涵盖教育,职场,自我提升等各大领域精华知识.支持会议演示,多端创作,云端存储,导图分…

KubeCon 香港:移动云与云猿生联合议题《在没有专用 Operator 的情况下管理数据库集群》

KubeCon CloudNativeCon 开源峰会 AI_dev 中国大会将于 2024 年 8 月 21 日至 23 日在香港举行。来自全球的云原生技术专家与爱好者在这里相会&#xff0c;探讨云原生领域的技术创新与最佳实践。此外&#xff0c;本次 KubeCon CloudNativeCon 和开源峰会将与 AI_dev&#x…

如何获得更高质量的回答-chatgpt

在与技术助手如ChatGPT进行交互时&#xff0c;提问的方式直接影响到你获得的答案质量。以下是几个关键的提问技巧&#xff0c;可以帮助你在与ChatGPT的互动中获得更有效的回答&#xff1a; 1. 清晰明了的问题 技巧&#xff1a;确保问题清晰明了&#xff0c;避免含糊不清或模糊的…

Postgresql从小白到高手 九 : psql高级查询及内部视图使用

Postgresql从小白到高手 九:pgsql 复杂查询及内部表高级查询 文章目录 Postgresql从小白到高手 九:pgsql 复杂查询及内部表高级查询一、多表查询二、pgsql内部表1.内部表2.内部表查询应用 一、多表查询 内联 &#xff1a;inner join on 简写 join on 结果集只有符合 筛选条件…

视觉震撼背后:带宽对渲染农场的重要性

在这个注重视觉体验的时代&#xff0c;无论是电影、电子游戏还是虚拟现实&#xff08;VR&#xff09;&#xff0c;令人印象深刻的视觉效果都依赖于渲染农场的强大能力。而带宽&#xff0c;则是确保这些画面能够迅速且以高清晰度传递给我们的核心要素。 一、核心概念&#xff1a…

HexPlane代码复现(十几分钟就复现成功的一篇论文代码!!!!!)

https://caoang327.github.io/HexPlane/ 一、 python setup.py develop命令用不了了 running develop /home/uriky/anaconda3/envs/hexplane/lib/python3.8/site-packages/setuptools/command/easy_install.py:144: EasyInstallDeprecationWarning: easy_install command is d…

监控员工电脑的软件有哪些?6款企业必备的电脑监控软件

监控员工电脑的软件在企业管理和网络安全领域扮演着重要角色&#xff0c;它们可以帮助企业提高工作效率&#xff0c;确保数据安全&#xff0c;以及合规性。以下是六款知名的员工电脑监控软件&#xff1a; 1.安企神 - 一个全面的企业级电脑监控和管理解决方案。 2.Work Examine…

智能猫砂盆到底是不是智商税?解救上班族双手的测评合集来了

不得不说&#xff0c;像我这样的上班族真的是很需要一个智能猫砂盆了。普通的猫砂盆一天就要打扫3次&#xff0c;遇到很能拉的猫咪的时候&#xff0c;就不止是三次那么简单了。如果有个产品能帮我解决这个问题&#xff0c;让我能放心外出&#xff0c;那又何乐而不为呢&#xff…

Win32消息机制原理及消息运转

一.消息机制原理 1.消息类型&#xff1a; WIndows定义的一系列WM_XXX开头的&#xff0c;用来表示键盘按键&#xff0c;鼠标点击&#xff0c;窗口变化&#xff0c;用户自定义等各种消息; 2.消息队列&#xff1a; Windows为每一个正在运行的程序维护一个消息队列应用程序的消…

【光伏开发】工商业光伏的优势

随着全球对可再生能源的日益重视和环保意识的增强&#xff0c;工商业光伏作为一种清洁、高效的能源利用方式&#xff0c;正在得到广泛的推广和应用。工商业光伏系统通过安装在工厂、仓库、办公楼等工商业场所的太阳能电池板&#xff0c;将太阳能转化为电能&#xff0c;以满足工…

【Java Web】Element-plus组件库

目录 一、Element-plus组件库概述 二、Element-plus组件库基本用法 一、Element-plus组件库概述 Element-plus组件库是由饿了么团队基于Vue3框架编写的前端UI设计组件库。通俗点讲就是将用户页面设计所需的按钮、表格、导航栏等前端代码编写生成的组件元素都封装好了、用户在进…

java中的Collections工具类

Collections类是java中提供的一个工具类&#xff0c;它和接口Collection乍一看非常相像&#xff0c;但是二者的区别是非常大的&#xff0c;最明显的就是它们一个是类&#xff0c;而另一个是接口了。Collections工具类的作用是对Set 、Map、 List这些容器提供辅助方法来对容器中…

AI时代的风口,中小企业也不能错过

文&#xff5c;白 鸽 编&#xff5c;周效敬 这些场景&#xff0c;对你来说或许并不陌生&#xff1a; 在医院的大屏上&#xff0c;一个医生模样的数字人在做医疗知识科普&#xff1b;在抖音的直播间里&#xff0c;一个真人模样的数字人在线上直播带货&#xff0c;24小时无休无…

SQLite、MySQL、PostgreSQL 3个关系数据库之间优缺点对比

引言 关系数据模型以行和列的表格形式组织数据&#xff0c;在数据库管理工具中占主导地位。今天还有其他数据模型&#xff0c;包括NoSQL和NewSQL&#xff0c;但是关系数据库管理系统&#xff08;RDBMS&#xff09;仍然占主导地位用于存储和管理全球数据。 本文比较了三种实现最…

【金融研究】6月,对冲基金狂卖美国科技股 短期乐观,长期悲观?“油价最大空头”花旗:明年跌到60

科技股新高的背后&#xff0c;是对冲基金与散户投资者的分歧&#xff0c;对冲基金正在向散户投资者出售创纪录数量的科技/半导体/美股“七姐妹”股票。 对冲基金狂卖美国科技股 在五大明星科技股&#xff08;苹果、亚马逊、微软、英伟达、谷歌&#xff09;轮番创下历史新高的…

CSS基础学习记录(6)

目录 1、从最基本的页面开始 2、添加图像/浮层部分 3、位置调整 4、添加动效 4.1、添加浮层动效 4.2、添加背景动画 根据前面css的学习&#xff0c;本篇来实践下前面学习的知识&#xff0c;主要实现如下这样的效果。 下面我们一步步实现上面的效果。 1、从最基本的页面开…

uniapp开发H5、手机APP、微信小程序 可拖动菜单按钮

ml-fab 插件地址&#xff1a;https://ext.dcloud.net.cn/plugin?id18909 1、可拖拽悬浮按钮 ml-fab&#xff0c;支持自定义插槽&#xff0c;点击可展开一个图标按钮菜单&#xff0c;可随意拖拽。 2、支持自定义插槽&#xff0c;可实现自定义配置。 3、操作简单易上手。 ml-f…

锐捷AP从其它项目拆下,怎么也加入不了到现在这个网络里来

环境: AP 产品型号:RG-RAP2260G 问题描述: 锐捷AP从其它项目拆下,怎么也加入不了到现在这个网络里来,现网是WIFI5的,想把2260G用来升级,恢复出厂设置后,插上网线,现网找不到这个AP 解决方案: 1.通电重置AP后,连接AP WiFi进入管理页面,要求先快速配置 2.开始配置…

【计算机网络篇】数据链路层(12)交换机式以太网___以太网交换机

文章目录 &#x1f354;交换式以太网&#x1f6f8;以太网交换机 &#x1f354;交换式以太网 仅使用交换机&#xff08;不使用集线器&#xff09;的以太网就是交换式以太网 &#x1f6f8;以太网交换机 以太网交换机本质上就是一个多接口的网桥&#xff1a; 交换机的每个接口…