| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400 |
- <template>
- <div ref="chartDom" class="chart"></div>
- </template>
- <script setup>
- import { onMounted, ref, watch } from "vue";
- import * as echarts from "echarts";
- const props = defineProps({
- weatherData: {
- type: Object,
- default: null,
- },
- });
- // 将接口数据转换为图表需要的格式
- function formatWeatherData(weatherData) {
- if (!weatherData || !weatherData.daily || !Array.isArray(weatherData.daily)) {
- return [];
- }
-
- const weekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
-
- return weatherData.daily.map((item) => {
- // 格式化日期:从 "2025-11-14" 转换为 "11/14"
- const date = new Date(item.fxDate);
- const month = String(date.getMonth() + 1).padStart(2, '0');
- const day = String(date.getDate()).padStart(2, '0');
- const rq = `${month}/${day}`;
-
- // 获取星期几
- const weekDay = weekDays[date.getDay()];
-
- // 根据 iconDay 和 iconNight 生成图片URL(这里需要根据实际API返回的icon值来映射)
- // 暂时使用默认图片,后续可以根据icon值映射到具体图片
- const getWeatherImg = (icon) => {
- // 可以根据icon值返回对应的图片URL
- // 例如:icon "100" -> 晴, "101" -> 多云, "104" -> 阴等
- // return `https://d.scggqx.com/forecast/img/${icon}.png`;
- return `https://birdseye-img.sysuimars.com/weather/${icon}.svg`;
- };
-
- return {
- rq: rq,
- weatherZgwd: item.tempMax,
- weatherZdwd: item.tempMin,
- weatherTqDay: item.textDay,
- weatherTqNight: item.textNight,
- weatherImgDay: getWeatherImg(item.iconDay),
- weatherImgNight: getWeatherImg(item.iconNight),
- windDirectDay: item.windDirDay,
- windDirectNight: item.windDirNight,
- windPowerDay: item.windScaleDay,
- windPowerNight: item.windScaleNight,
- week: weekDay,
- };
- });
- }
- // 处理天气数据
- function processWeatherData(data) {
- let weekday = [];
- let datelist = [];
- let weatherDaylist = [];
- let weatherNightlist = [];
- let weatherImgDaylist = [];
- let weatherImgNightlist = [];
- let windDirectlist = [];
- let windPowerlist = [];
- let weatherZgwdlist = [];
- let weatherZdwdlist = [];
- data.forEach((item) => {
- weekday.push(item.week);
- datelist.push(item.rq);
- weatherDaylist.push(item.weatherTqDay);
- weatherNightlist.push(item.weatherTqNight);
- weatherImgDaylist.push(item.weatherImgDay);
- weatherImgNightlist.push(item.weatherImgNight);
- windDirectlist.push(item.windDirectDay);
- windPowerlist.push(item.windPowerDay);
- weatherZgwdlist.push(item.weatherZgwd);
- weatherZdwdlist.push(item.weatherZdwd);
- });
-
- const maxWD = weatherZgwdlist.length > 0 ? Math.max(...weatherZgwdlist) + 30 : 60;
- const minWD = weatherZdwdlist.length > 0 ? Math.min(...weatherZdwdlist) - 30 : 0;
-
- return {
- weekday,
- datelist,
- weatherDaylist,
- weatherNightlist,
- weatherImgDaylist,
- weatherImgNightlist,
- windDirectlist,
- windPowerlist,
- weatherZgwdlist,
- weatherZdwdlist,
- maxWD,
- minWD
- };
- }
- // 生成天气图片样式
- function generateWeatherImgRich(weatherImgList) {
- const weatherImgListStyle = weatherImgList.map((item) => {
- return {
- backgroundColor: {
- image: item,
- },
- height: 20,
- width: 20,
- };
- });
-
- const rich = {};
- weatherImgListStyle.forEach((i, index) => {
- rich[index] = i;
- });
- return rich;
- }
- const myChart = ref(null);
- const chartDom = ref(null);
- // 初始化默认数据(用于首次渲染)
- const defaultData = formatWeatherData(null);
- const defaultProcessed = processWeatherData(defaultData.length > 0 ? defaultData : []);
- const defaultWeatherImgDaylistRich = generateWeatherImgRich(defaultProcessed.weatherImgDaylist);
- const defaultWeatherImgNightlistRich = generateWeatherImgRich(defaultProcessed.weatherImgNightlist);
- // 生成图表配置
- function generateOptions(processedData, weatherImgDaylistRich, weatherImgNightlistRich) {
- return {
- grid: {
- top: "-100px",
- right: "20px",
- bottom: '-55px',
- left: "-20px",
- containLabel: true,
- },
- xAxis: [
- {
- type: "category",
- boundaryGap: false,
- position: "top",
- offset: 0,
- zlevel: 100,
- axisLine: {
- show: false,
- },
- axisTick: {
- show: false,
- },
- splitLine: {
- show: false,
- },
- axisLabel: {
- interval: 0,
- formatter: ["{a|{value}}"].join("\n"),
- rich: {
- a: {
- color: "#000",
- },
- },
- },
- data: processedData.weekday,
- },
- {
- type: "category",
- position: "top",
- offset: -15,
- boundaryGap: false,
- zlevel: 100,
- axisLine: {
- show: false,
- },
- axisTick: {
- show: false,
- },
- axisLabel: {
- interval: 0,
- formatter: ["{a|{value}}"].join("\n"),
- rich: {
- a: {
- color: "#999999",
- fontSize: 10,
- },
- },
- },
- data: processedData.datelist,
- axisPointer: {
- show: false,
- },
- },
- {
- type: "category",
- position: "top",
- offset: -35,
- boundaryGap: false,
- zlevel: 100,
- axisLine: {
- show: false,
- },
- axisTick: {
- show: false,
- },
- axisLabel: {
- interval: 0,
- formatter: ["{a|{value}}"].join("\n"),
- rich: {
- a: {
- color: "#000",
- },
- },
- },
- data: processedData.weatherDaylist,
- axisPointer: {
- show: false,
- },
- },
- {
- type: "category",
- boundaryGap: false,
- position: "top",
- offset: -60,
- zlevel: 100,
- axisLine: {
- show: false,
- },
- axisTick: {
- show: false,
- },
- axisLabel: {
- interval: 0,
- formatter: ["{{value}|}"].join("\n"),
- rich: weatherImgDaylistRich,
- },
- data: processedData.weatherImgDaylist.map((_, index) => String(index)),
- axisPointer: {
- show: false,
- },
- },
- {
- type: "category",
- position: "top",
- offset: -80,
- boundaryGap: false,
- zlevel: 100,
- axisLine: {
- show: false,
- },
- axisTick: {
- show: false,
- },
- axisLabel: {
- interval: 0,
- formatter: ["{a|{value}°}"].join("\n"),
- rich: {
- a: {
- color: "#000",
- },
- },
- },
- data: processedData.weatherZgwdlist,
- axisPointer: {
- show: false,
- },
- },
- {
- type: "category",
- position: "top",
- offset: -160,
- boundaryGap: false,
- zlevel: 100,
- axisLine: {
- show: false,
- },
- axisTick: {
- show: false,
- },
- axisLabel: {
- interval: 0,
- formatter: ["{a|{value}°}"].join("\n"),
- rich: {
- a: {
- color: "#000",
- },
- },
- },
- data: processedData.weatherZdwdlist,
- axisPointer: {
- show: false,
- },
- },
- ],
- yAxis: {
- show: false,
- interval: 15,
- type: "value",
- axisLabel: {
- formatter: "{value}" + "℃",
- },
- max: processedData.maxWD,
- min: processedData.minWD,
- },
- series: [
- {
- name: "最高温度",
- type: "line",
- data: processedData.weatherZgwdlist,
- symbol: "circle",
- symbolSize: 3,
- showSymbol: true,
- smooth: true,
- itemStyle: {
- color: "#FA8258", // 设置圆形的填充色
- borderColor: "#FA8258", // 设置边框颜色
- borderWidth: 3, // 设置边框宽度
- },
- lineStyle: {
- width: 2, // 设置折线的宽度
- color: "#FA8258", // 设置折线的颜色
- shadowColor: "#FA8258", // 线的阴影颜色
- shadowBlur: 5, // 线的阴影模糊级数
- shadowOffsetX: 0, // 线的阴影水平偏移
- shadowOffsetY: 5, // 线的阴影垂直偏移
- },
- silent: false,
- },
- {
- name: "最低温度",
- type: "line",
- data: processedData.weatherZdwdlist,
- symbol: "circle",
- symbolSize: 3,
- showSymbol: true,
- smooth: true,
- itemStyle: {
- color: "#2E9AFE", // 设置圆形的填充色
- borderColor: "#2E9AFE", // 设置边框颜色
- borderWidth: 3, // 设置边框宽度
- },
- lineStyle: {
- width: 2, // 设置折线的宽度
- color: "#2E9AFE", // 设置折线的颜色
- shadowColor: "#2E9AFE", // 线的阴影颜色
- shadowBlur: 5, // 线的阴影模糊级数
- shadowOffsetX: 0, // 线的阴影水平偏移
- shadowOffsetY: 5, // 线的阴影垂直偏移
- },
- silent: false,
- },
- ],
- };
- }
- const options = ref(generateOptions(defaultProcessed, defaultWeatherImgDaylistRich, defaultWeatherImgNightlistRich));
- onMounted(() => {
- setTimeout(() => {
- initChart();
- }, 200);
- });
- // 监听 weatherData 变化,更新图表
- watch(
- () => props.weatherData,
- (newValue) => {
- if (newValue && newValue.daily) {
- const formattedData = formatWeatherData(newValue);
- const processedData = processWeatherData(formattedData);
- const weatherImgDaylistRich = generateWeatherImgRich(processedData.weatherImgDaylist);
- const weatherImgNightlistRich = generateWeatherImgRich(processedData.weatherImgNightlist);
-
- options.value = generateOptions(processedData, weatherImgDaylistRich, weatherImgNightlistRich);
-
- if (myChart.value) {
- myChart.value.setOption(options.value);
- }
- }
- },
- { deep: true }
- );
- const initChart = () => {
- myChart.value = echarts.init(chartDom.value);
- myChart.value.setOption(options.value);
- };
- </script>
- <style lang="scss" scoped>
- .chart {
- width: 100%;
- height: 100%;
- }
- </style>
|