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列表
|
// 热门标签某时间段内topN列表
|
||||||
export const getTopConceptPeriod = (data: any) => {
|
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) => {
|
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列表
|
// 热门标签某时间段内topN列表
|
||||||
export const getTopSourcePeriod = (data: any) => {
|
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);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ const colorList = ["#F05040", "#696BBE", "#93CFED", "#FE9F19", "#3C74F1"];
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: {
|
data: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => { },
|
default: () => {},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -42,8 +42,8 @@ watch(
|
||||||
keys.value.push(item.key);
|
keys.value.push(item.key);
|
||||||
values.value.push(item.doc_count);
|
values.value.push(item.doc_count);
|
||||||
});
|
});
|
||||||
keys.value.reverse()
|
keys.value.reverse();
|
||||||
values.value.reverse()
|
values.value.reverse();
|
||||||
initChart();
|
initChart();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -23,30 +23,22 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.data,
|
||||||
|
(newVal) => {
|
||||||
|
if (newVal) {
|
||||||
|
initChart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// 初始化图表
|
// 初始化图表
|
||||||
const initChart = () => {
|
const initChart = () => {
|
||||||
myChart = echarts.init(chartDom.value);
|
myChart = echarts.init(chartDom.value);
|
||||||
|
|
||||||
const builderJson = {
|
const builderJson = {
|
||||||
all: 10887,
|
all: 10887,
|
||||||
charts: {
|
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,
|
|
||||||
},
|
|
||||||
components: {
|
components: {
|
||||||
geo: 2788,
|
geo: 2788,
|
||||||
title: 9575,
|
title: 9575,
|
||||||
|
|
@ -63,6 +55,16 @@ const initChart = () => {
|
||||||
},
|
},
|
||||||
ie: 9743,
|
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 waterMarkText = "ECHARTS";
|
||||||
const canvas = document.createElement("canvas");
|
const canvas = document.createElement("canvas");
|
||||||
|
|
@ -76,19 +78,20 @@ const initChart = () => {
|
||||||
ctx.rotate(-Math.PI / 4);
|
ctx.rotate(-Math.PI / 4);
|
||||||
ctx.fillText(waterMarkText, 0, 0);
|
ctx.fillText(waterMarkText, 0, 0);
|
||||||
let option = {
|
let option = {
|
||||||
backgroundColor: {
|
// backgroundColor: {
|
||||||
type: "pattern",
|
// type: "pattern",
|
||||||
image: canvas,
|
// image: canvas,
|
||||||
repeat: "repeat",
|
// repeat: "repeat",
|
||||||
},
|
// },
|
||||||
tooltip: {},
|
tooltip: {},
|
||||||
title: [],
|
title: [],
|
||||||
grid: [
|
grid: [
|
||||||
{
|
{
|
||||||
top: 0,
|
top: 0,
|
||||||
width: "90%",
|
width: "90%",
|
||||||
bottom: "0%",
|
top: "5%",
|
||||||
left: 0,
|
bottom: "10%",
|
||||||
|
left: 10,
|
||||||
containLabel: true,
|
containLabel: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
@ -123,6 +126,12 @@ const initChart = () => {
|
||||||
position: "right",
|
position: "right",
|
||||||
show: true,
|
show: true,
|
||||||
},
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: "#52A8FF",
|
||||||
|
normal: {
|
||||||
|
borderRadius: [0, 4, 4, 0],
|
||||||
|
},
|
||||||
|
},
|
||||||
data: Object.keys(builderJson.charts).map(function (key) {
|
data: Object.keys(builderJson.charts).map(function (key) {
|
||||||
return builderJson.charts[key];
|
return builderJson.charts[key];
|
||||||
}),
|
}),
|
||||||
|
|
@ -141,8 +150,6 @@ onMounted(async () => {
|
||||||
// await getData();
|
// await getData();
|
||||||
// initChart();
|
// initChart();
|
||||||
// }, 5000);
|
// }, 5000);
|
||||||
|
|
||||||
initChart();
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,40 +26,77 @@ const props = defineProps({
|
||||||
// 初始化图表
|
// 初始化图表
|
||||||
const initChart = () => {
|
const initChart = () => {
|
||||||
myChart = echarts.init(chartDom.value);
|
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 = {
|
let option = {
|
||||||
dataset: {
|
dataset: {
|
||||||
source: [
|
source: source,
|
||||||
["score", "amount", "product"],
|
// [
|
||||||
[89.3, 58212, "Matcha Latte"],
|
// ["score", "amount", "product"],
|
||||||
[57.1, 78254, "Milk Tea"],
|
// [89.3, 58212, "Matcha Latte"],
|
||||||
[74.4, 41032, "Cheese Cocoa"],
|
// [57.1, 78254, "Milk Tea"],
|
||||||
[50.1, 12755, "Cheese Brownie"],
|
// [74.4, 41032, "Cheese Cocoa"],
|
||||||
[89.7, 20145, "Matcha Cocoa"],
|
// [50.1, 12755, "Cheese Brownie"],
|
||||||
[68.1, 79146, "Tea"],
|
// [89.7, 20145, "Matcha Cocoa"],
|
||||||
[19.6, 91852, "Orange Juice"],
|
// [68.1, 79146, "Tea"],
|
||||||
[10.6, 101852, "Lemon Juice"],
|
// [19.6, 91852, "Orange Juice"],
|
||||||
[32.7, 20112, "Walnut Brownie"],
|
// [10.6, 101852, "Lemon Juice"],
|
||||||
],
|
// [32.7, 20112, "Walnut Brownie"],
|
||||||
|
// ],
|
||||||
},
|
},
|
||||||
grid: { containLabel: true },
|
grid: {
|
||||||
xAxis: { name: "amount" },
|
top: 0,
|
||||||
yAxis: { type: "category" },
|
width: "90%",
|
||||||
visualMap: {
|
top: "5%",
|
||||||
orient: "horizontal",
|
bottom: "10%",
|
||||||
left: "center",
|
left: 10,
|
||||||
min: 10,
|
containLabel: true,
|
||||||
max: 100,
|
},
|
||||||
text: ["High Score", "Low Score"],
|
xAxis: {
|
||||||
// Map the score column to color
|
splitLine: {
|
||||||
dimension: 0,
|
show: false,
|
||||||
inRange: {
|
|
||||||
color: ["#65B581", "#FFCE34", "#FD665F"],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
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: [
|
series: [
|
||||||
{
|
{
|
||||||
type: "bar",
|
type: "bar",
|
||||||
|
label: {
|
||||||
|
position: "right",
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: "#FFCE34",
|
||||||
|
normal: {
|
||||||
|
borderRadius: [0, 4, 4, 0],
|
||||||
|
},
|
||||||
|
},
|
||||||
encode: {
|
encode: {
|
||||||
// Map the "amount" column to X axis.
|
// Map the "amount" column to X axis.
|
||||||
x: "amount",
|
x: "amount",
|
||||||
|
|
|
||||||
|
|
@ -64,10 +64,10 @@
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view style="background-color: white; margin-top: 40rpx">
|
<view style="background-color: white; margin-top: 40rpx">
|
||||||
<indexMenuTitle title="周热度统计"></indexMenuTitle>
|
<indexMenuTitle title="近7天热度统计"></indexMenuTitle>
|
||||||
<LineHol v-if="lineTabIndex === 0"></LineHol>
|
<LineHol v-if="lineTabIndex === 0" :data="lineTopData"></LineHol>
|
||||||
<LineHol v-else-if="lineTabIndex === 1"></LineHol>
|
<LineHol v-else-if="lineTabIndex === 1" :data="lineTopData"></LineHol>
|
||||||
<LineHolYellow v-else-if="lineTabIndex === 2"></LineHolYellow>
|
<LineHolYellow v-else-if="lineTabIndex === 2" :data="lineTopData"></LineHolYellow>
|
||||||
|
|
||||||
<div style="display: flex; justify-content: center; margin-bottom: 20px; margin-top: 20px">
|
<div style="display: flex; justify-content: center; margin-bottom: 20px; margin-top: 20px">
|
||||||
<div class="tabs">
|
<div class="tabs">
|
||||||
|
|
@ -143,7 +143,18 @@ import tagicon_2 from "@/assets/zixun/tagicon_2.png";
|
||||||
import LoginPopup from "@/components/loginPopup/index.vue";
|
import LoginPopup from "@/components/loginPopup/index.vue";
|
||||||
import { Session } from "@/utils/storage";
|
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 countTo from "@/components/count-to/vue-countTo.vue";
|
||||||
import RankList from "@/components/RankList.vue"; // 路径根据实际调整
|
import RankList from "@/components/RankList.vue"; // 路径根据实际调整
|
||||||
import InfoSummary from "@/components/InfoSummary.vue"; // 路径根据实际调整
|
import InfoSummary from "@/components/InfoSummary.vue"; // 路径根据实际调整
|
||||||
|
|
@ -268,6 +279,36 @@ function loginOut() {
|
||||||
const lineTabIndex = ref(0);
|
const lineTabIndex = ref(0);
|
||||||
function handleTabClick(index) {
|
function handleTabClick(index) {
|
||||||
lineTabIndex.value = 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() {
|
function goSreach() {
|
||||||
|
|
@ -290,6 +331,8 @@ onMounted(async () => {
|
||||||
if (!Session.get("token")) {
|
if (!Session.get("token")) {
|
||||||
LoginShow.value = true;
|
LoginShow.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getLineDataFn();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue