feat(图表): 优化图表组件并添加动态数据支持
- 修改Line.vue组件,修复默认值格式和优化数据反转逻辑 - 更新newsInfo.ts API,修改热门标签/行业/来源的请求参数拼接方式 - 重构LineHol.vue组件,移除硬编码数据,支持动态数据绑定和样式优化 - 在realtimeInfo页面添加7天热度统计功能,支持不同标签切换 - 改进LineHolYellow.vue组件,支持动态数据并优化图表样式
This commit is contained in:
parent
2e68592cf1
commit
3a29305df7
|
|
@ -42,15 +42,14 @@ export const getNews_cnt_d = (data: any) => {
|
|||
|
||||
// 热门标签某时间段内topN列表
|
||||
export const getTopConceptPeriod = (data: any) => {
|
||||
return request.get("/top_concept_period", data);
|
||||
return request.get("/top_concept_period?start_date=" + data.start_time + "&end_date=" + data.end_time + "&limit_num=" + data.limit_num, data);
|
||||
};
|
||||
|
||||
// 热门标签某时间段内topN列表
|
||||
// 热门行业某时间段内topN列表
|
||||
export const getTopIndustryPeriod = (data: any) => {
|
||||
return request.get("/top_industry_period", data);
|
||||
return request.get("/top_industry_period?start_date=" + data.start_time + "&end_date=" + data.end_time + "&limit_num=" + data.limit_num, data);
|
||||
};
|
||||
|
||||
// 热门标签某时间段内topN列表
|
||||
export const getTopSourcePeriod = (data: any) => {
|
||||
return request.get("/top_source_period", data);
|
||||
return request.get("/top_source_period?start_date=" + data.start_date + "&end_date=" + data.end_time + "&limit_num=" + data.limit_num, data);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ watch(
|
|||
keys.value.push(item.key);
|
||||
values.value.push(item.doc_count);
|
||||
});
|
||||
keys.value.reverse()
|
||||
values.value.reverse()
|
||||
keys.value.reverse();
|
||||
values.value.reverse();
|
||||
initChart();
|
||||
}
|
||||
);
|
||||
|
|
|
|||
|
|
@ -23,30 +23,22 @@ const props = defineProps({
|
|||
},
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.data,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
initChart();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 初始化图表
|
||||
const initChart = () => {
|
||||
myChart = echarts.init(chartDom.value);
|
||||
|
||||
const builderJson = {
|
||||
all: 10887,
|
||||
charts: {
|
||||
map: 3237,
|
||||
lines: 2164,
|
||||
bar: 7561,
|
||||
line: 7778,
|
||||
pie: 7355,
|
||||
scatter: 2405,
|
||||
candlestick: 1842,
|
||||
radar: 2090,
|
||||
heatmap: 1762,
|
||||
treemap: 1593,
|
||||
graph: 2060,
|
||||
boxplot: 1537,
|
||||
parallel: 1908,
|
||||
gauge: 2107,
|
||||
funnel: 1692,
|
||||
sankey: 1568,
|
||||
},
|
||||
charts: {},
|
||||
components: {
|
||||
geo: 2788,
|
||||
title: 9575,
|
||||
|
|
@ -63,6 +55,16 @@ const initChart = () => {
|
|||
},
|
||||
ie: 9743,
|
||||
};
|
||||
// 查找value最大的项
|
||||
const maxItem = props.data.reduce((prev, current) => {
|
||||
// 比较当前项和上一项的value,返回较大的那个
|
||||
return current.value > prev.value ? current : prev;
|
||||
}, props.data[0]); // 初始值设为数组的第一个元素
|
||||
|
||||
props.data.forEach((item) => {
|
||||
builderJson.charts[item.content] = item.value;
|
||||
});
|
||||
builderJson.all = maxItem.value;
|
||||
|
||||
const waterMarkText = "ECHARTS";
|
||||
const canvas = document.createElement("canvas");
|
||||
|
|
@ -76,19 +78,20 @@ const initChart = () => {
|
|||
ctx.rotate(-Math.PI / 4);
|
||||
ctx.fillText(waterMarkText, 0, 0);
|
||||
let option = {
|
||||
backgroundColor: {
|
||||
type: "pattern",
|
||||
image: canvas,
|
||||
repeat: "repeat",
|
||||
},
|
||||
// backgroundColor: {
|
||||
// type: "pattern",
|
||||
// image: canvas,
|
||||
// repeat: "repeat",
|
||||
// },
|
||||
tooltip: {},
|
||||
title: [],
|
||||
grid: [
|
||||
{
|
||||
top: 0,
|
||||
width: "90%",
|
||||
bottom: "0%",
|
||||
left: 0,
|
||||
top: "5%",
|
||||
bottom: "10%",
|
||||
left: 10,
|
||||
containLabel: true,
|
||||
},
|
||||
],
|
||||
|
|
@ -123,6 +126,12 @@ const initChart = () => {
|
|||
position: "right",
|
||||
show: true,
|
||||
},
|
||||
itemStyle: {
|
||||
color: "#52A8FF",
|
||||
normal: {
|
||||
borderRadius: [0, 4, 4, 0],
|
||||
},
|
||||
},
|
||||
data: Object.keys(builderJson.charts).map(function (key) {
|
||||
return builderJson.charts[key];
|
||||
}),
|
||||
|
|
@ -141,8 +150,6 @@ onMounted(async () => {
|
|||
// await getData();
|
||||
// initChart();
|
||||
// }, 5000);
|
||||
|
||||
initChart();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -26,40 +26,77 @@ const props = defineProps({
|
|||
// 初始化图表
|
||||
const initChart = () => {
|
||||
myChart = echarts.init(chartDom.value);
|
||||
let source = [];
|
||||
source.push(["score", "amount", "product"]);
|
||||
props.data.forEach((item) => {
|
||||
source.push([item.value, item.value, item.content]);
|
||||
});
|
||||
|
||||
let option = {
|
||||
dataset: {
|
||||
source: [
|
||||
["score", "amount", "product"],
|
||||
[89.3, 58212, "Matcha Latte"],
|
||||
[57.1, 78254, "Milk Tea"],
|
||||
[74.4, 41032, "Cheese Cocoa"],
|
||||
[50.1, 12755, "Cheese Brownie"],
|
||||
[89.7, 20145, "Matcha Cocoa"],
|
||||
[68.1, 79146, "Tea"],
|
||||
[19.6, 91852, "Orange Juice"],
|
||||
[10.6, 101852, "Lemon Juice"],
|
||||
[32.7, 20112, "Walnut Brownie"],
|
||||
],
|
||||
source: source,
|
||||
// [
|
||||
// ["score", "amount", "product"],
|
||||
// [89.3, 58212, "Matcha Latte"],
|
||||
// [57.1, 78254, "Milk Tea"],
|
||||
// [74.4, 41032, "Cheese Cocoa"],
|
||||
// [50.1, 12755, "Cheese Brownie"],
|
||||
// [89.7, 20145, "Matcha Cocoa"],
|
||||
// [68.1, 79146, "Tea"],
|
||||
// [19.6, 91852, "Orange Juice"],
|
||||
// [10.6, 101852, "Lemon Juice"],
|
||||
// [32.7, 20112, "Walnut Brownie"],
|
||||
// ],
|
||||
},
|
||||
grid: { containLabel: true },
|
||||
xAxis: { name: "amount" },
|
||||
yAxis: { type: "category" },
|
||||
visualMap: {
|
||||
orient: "horizontal",
|
||||
left: "center",
|
||||
min: 10,
|
||||
max: 100,
|
||||
text: ["High Score", "Low Score"],
|
||||
// Map the score column to color
|
||||
dimension: 0,
|
||||
inRange: {
|
||||
color: ["#65B581", "#FFCE34", "#FD665F"],
|
||||
grid: {
|
||||
top: 0,
|
||||
width: "90%",
|
||||
top: "5%",
|
||||
bottom: "10%",
|
||||
left: 10,
|
||||
containLabel: true,
|
||||
},
|
||||
xAxis: {
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
type: "category",
|
||||
axisLabel: {
|
||||
interval: 0,
|
||||
rotate: 30,
|
||||
},
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
// visualMap: {
|
||||
// show: false,
|
||||
// orient: "horizontal",
|
||||
// left: "center",
|
||||
// min: 1,
|
||||
// max: 100,
|
||||
// text: ["High Score", "Low Score"],
|
||||
// // Map the score column to color
|
||||
// dimension: 0,
|
||||
// inRange: {
|
||||
// color: ["#65B581", "#FFCE34", "#FD665F"],
|
||||
// },
|
||||
// },
|
||||
series: [
|
||||
{
|
||||
type: "bar",
|
||||
label: {
|
||||
position: "right",
|
||||
show: true,
|
||||
},
|
||||
itemStyle: {
|
||||
color: "#FFCE34",
|
||||
normal: {
|
||||
borderRadius: [0, 4, 4, 0],
|
||||
},
|
||||
},
|
||||
encode: {
|
||||
// Map the "amount" column to X axis.
|
||||
x: "amount",
|
||||
|
|
|
|||
|
|
@ -64,10 +64,10 @@
|
|||
</view>
|
||||
|
||||
<view style="background-color: white; margin-top: 40rpx">
|
||||
<indexMenuTitle title="周热度统计"></indexMenuTitle>
|
||||
<LineHol v-if="lineTabIndex === 0"></LineHol>
|
||||
<LineHol v-else-if="lineTabIndex === 1"></LineHol>
|
||||
<LineHolYellow v-else-if="lineTabIndex === 2"></LineHolYellow>
|
||||
<indexMenuTitle title="近7天热度统计"></indexMenuTitle>
|
||||
<LineHol v-if="lineTabIndex === 0" :data="lineTopData"></LineHol>
|
||||
<LineHol v-else-if="lineTabIndex === 1" :data="lineTopData"></LineHol>
|
||||
<LineHolYellow v-else-if="lineTabIndex === 2" :data="lineTopData"></LineHolYellow>
|
||||
|
||||
<div style="display: flex; justify-content: center; margin-bottom: 20px; margin-top: 20px">
|
||||
<div class="tabs">
|
||||
|
|
@ -143,7 +143,18 @@ import tagicon_2 from "@/assets/zixun/tagicon_2.png";
|
|||
import LoginPopup from "@/components/loginPopup/index.vue";
|
||||
import { Session } from "@/utils/storage";
|
||||
|
||||
import { getindustryCount, getConceptCount, getTopNews, getTopIndustry_d, getTopConcept_d, getNews_cnt_d, newsInfoScore } from "@/api/newsInfo";
|
||||
import {
|
||||
getindustryCount,
|
||||
getConceptCount,
|
||||
getTopNews,
|
||||
getTopIndustry_d,
|
||||
getTopConcept_d,
|
||||
getNews_cnt_d,
|
||||
newsInfoScore,
|
||||
getTopConceptPeriod,
|
||||
getTopIndustryPeriod,
|
||||
getTopSourcePeriod,
|
||||
} from "@/api/newsInfo";
|
||||
import countTo from "@/components/count-to/vue-countTo.vue";
|
||||
import RankList from "@/components/RankList.vue"; // 路径根据实际调整
|
||||
import InfoSummary from "@/components/InfoSummary.vue"; // 路径根据实际调整
|
||||
|
|
@ -268,6 +279,36 @@ function loginOut() {
|
|||
const lineTabIndex = ref(0);
|
||||
function handleTabClick(index) {
|
||||
lineTabIndex.value = index;
|
||||
getLineDataFn();
|
||||
}
|
||||
|
||||
const lineTopData = ref({});
|
||||
async function getLineDataFn() {
|
||||
if (lineTabIndex.value == 0) {
|
||||
getTopConceptPeriod({
|
||||
start_time: "2025-09-06",
|
||||
end_time: "2025-09-13",
|
||||
limit_num: 10,
|
||||
}).then((res) => {
|
||||
lineTopData.value = res;
|
||||
});
|
||||
} else if (lineTabIndex.value == 1) {
|
||||
getTopIndustryPeriod({
|
||||
start_time: "2025-09-06",
|
||||
end_time: "2025-09-13",
|
||||
limit_num: 10,
|
||||
}).then((res) => {
|
||||
lineTopData.value = res;
|
||||
});
|
||||
} else if (lineTabIndex.value == 2) {
|
||||
getTopSourcePeriod({
|
||||
start_time: "2025-09-06",
|
||||
end_time: "2025-09-13",
|
||||
limit_num: 10,
|
||||
}).then((res) => {
|
||||
lineTopData.value = res;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function goSreach() {
|
||||
|
|
@ -290,6 +331,8 @@ onMounted(async () => {
|
|||
if (!Session.get("token")) {
|
||||
LoginShow.value = true;
|
||||
}
|
||||
|
||||
getLineDataFn();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue