feat(实时资讯): 新增周热度统计图表组件及交互功能
添加LineHol和LineHolYellow图表组件用于展示周热度统计数据 实现行业、概念标签和媒体来源的tab切换功能 优化页面布局和样式,调整部分标题文字
This commit is contained in:
parent
2204df2614
commit
4f5682c80a
|
|
@ -0,0 +1,149 @@
|
||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<div ref="chartDom" style="width: 100vw; height: 700rpx"></div>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { watch, onMounted, reactive, ref } from "vue";
|
||||||
|
import * as echarts from "echarts";
|
||||||
|
import { newsInfoScore } from "@/api/newsInfo";
|
||||||
|
|
||||||
|
const chartDom = ref(null);
|
||||||
|
let myChart = null;
|
||||||
|
|
||||||
|
const data = reactive({});
|
||||||
|
const keys = ref([]);
|
||||||
|
const values = ref([]);
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 初始化图表
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
geo: 2788,
|
||||||
|
title: 9575,
|
||||||
|
legend: 9400,
|
||||||
|
tooltip: 9466,
|
||||||
|
grid: 9266,
|
||||||
|
markPoint: 3419,
|
||||||
|
markLine: 2984,
|
||||||
|
timeline: 2739,
|
||||||
|
dataZoom: 2744,
|
||||||
|
visualMap: 2466,
|
||||||
|
toolbox: 3034,
|
||||||
|
polar: 1945,
|
||||||
|
},
|
||||||
|
ie: 9743,
|
||||||
|
};
|
||||||
|
|
||||||
|
const waterMarkText = "ECHARTS";
|
||||||
|
const canvas = document.createElement("canvas");
|
||||||
|
const ctx = canvas.getContext("2d");
|
||||||
|
// canvas.width = canvas.height = 100;
|
||||||
|
ctx.textAlign = "center";
|
||||||
|
ctx.textBaseline = "middle";
|
||||||
|
ctx.globalAlpha = 0.08;
|
||||||
|
ctx.font = "20px Microsoft Yahei";
|
||||||
|
ctx.translate(50, 50);
|
||||||
|
ctx.rotate(-Math.PI / 4);
|
||||||
|
ctx.fillText(waterMarkText, 0, 0);
|
||||||
|
let option = {
|
||||||
|
backgroundColor: {
|
||||||
|
type: "pattern",
|
||||||
|
image: canvas,
|
||||||
|
repeat: "repeat",
|
||||||
|
},
|
||||||
|
tooltip: {},
|
||||||
|
title: [],
|
||||||
|
grid: [
|
||||||
|
{
|
||||||
|
top: 0,
|
||||||
|
width: "90%",
|
||||||
|
bottom: "0%",
|
||||||
|
left: 0,
|
||||||
|
containLabel: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
xAxis: [
|
||||||
|
{
|
||||||
|
type: "value",
|
||||||
|
max: builderJson.all,
|
||||||
|
splitLine: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
type: "category",
|
||||||
|
data: Object.keys(builderJson.charts),
|
||||||
|
axisLabel: {
|
||||||
|
interval: 0,
|
||||||
|
rotate: 30,
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
type: "bar",
|
||||||
|
stack: "chart",
|
||||||
|
z: 3,
|
||||||
|
label: {
|
||||||
|
position: "right",
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
data: Object.keys(builderJson.charts).map(function (key) {
|
||||||
|
return builderJson.charts[key];
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
//使用配置
|
||||||
|
myChart.setOption(option);
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
// await getData();
|
||||||
|
// initChart();
|
||||||
|
// setInterval(async () => {
|
||||||
|
// await getData();
|
||||||
|
// initChart();
|
||||||
|
// }, 5000);
|
||||||
|
|
||||||
|
initChart();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<div ref="chartDom" style="width: 100vw; height: 700rpx"></div>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { watch, onMounted, reactive, ref } from "vue";
|
||||||
|
import * as echarts from "echarts";
|
||||||
|
import { newsInfoScore } from "@/api/newsInfo";
|
||||||
|
|
||||||
|
const chartDom = ref(null);
|
||||||
|
let myChart = null;
|
||||||
|
|
||||||
|
const data = reactive({});
|
||||||
|
const keys = ref([]);
|
||||||
|
const values = ref([]);
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 初始化图表
|
||||||
|
const initChart = () => {
|
||||||
|
myChart = echarts.init(chartDom.value);
|
||||||
|
|
||||||
|
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"],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
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"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
type: "bar",
|
||||||
|
encode: {
|
||||||
|
// Map the "amount" column to X axis.
|
||||||
|
x: "amount",
|
||||||
|
// Map the "product" column to Y axis
|
||||||
|
y: "product",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
//使用配置
|
||||||
|
myChart.setOption(option);
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
// await getData();
|
||||||
|
// initChart();
|
||||||
|
// setInterval(async () => {
|
||||||
|
// await getData();
|
||||||
|
// initChart();
|
||||||
|
// }, 5000);
|
||||||
|
|
||||||
|
initChart();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
||||||
|
|
@ -6,9 +6,7 @@
|
||||||
<img :src="bannerImg" class="banner_bk" />
|
<img :src="bannerImg" class="banner_bk" />
|
||||||
<view class="r_banner_title">
|
<view class="r_banner_title">
|
||||||
<img :src="bannerTitle" class="banner_title" />
|
<img :src="bannerTitle" class="banner_title" />
|
||||||
<text>数据更新时间:{{
|
<text>数据更新时间:{{ dayjs(new Date().getTime()).format("YYYY-MM-DD") }}</text>
|
||||||
dayjs(new Date().getTime()).format("YYYY-MM-DD")
|
|
||||||
}}</text>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- banner end -->
|
<!-- banner end -->
|
||||||
|
|
@ -60,31 +58,32 @@
|
||||||
<indexMenuTitle title="资讯评分分布区间"></indexMenuTitle>
|
<indexMenuTitle title="资讯评分分布区间"></indexMenuTitle>
|
||||||
<Line style="margin-top: 30rpx" :data="lineData"></Line>
|
<Line style="margin-top: 30rpx" :data="lineData"></Line>
|
||||||
|
|
||||||
<view style="
|
<view style="display: flex; flex-direction: column; text-align: center; justify-content: center; align-items: center; padding-bottom: 30rpx">
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
text-align: center;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
padding-bottom: 30rpx;
|
|
||||||
">
|
|
||||||
<InfoSummary style="width: 85%" :count="newsNum"></InfoSummary>
|
<InfoSummary style="width: 85%" :count="newsNum"></InfoSummary>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view style="background-color: white; margin-top: 40rpx">
|
<view style="background-color: white; margin-top: 40rpx">
|
||||||
<indexMenuTitle title="资讯头条榜 Top20"></indexMenuTitle>
|
<indexMenuTitle title="周热度统计"></indexMenuTitle>
|
||||||
|
<LineHol v-if="lineTabIndex === 0"></LineHol>
|
||||||
|
<LineHolYellow v-else-if="lineTabIndex === 2"></LineHolYellow>
|
||||||
|
|
||||||
|
<div style="display: flex; justify-content: center; margin-bottom: 20px; margin-top: 20px">
|
||||||
|
<div class="tabs">
|
||||||
|
<div :class="['tab', 'tab_left', { active: lineTabIndex === 0 }]" @click="handleTabClick(0)">申万行业</div>
|
||||||
|
<div :class="['tab', { active: lineTabIndex === 1 }]" @click="handleTabClick(1)">概念标签</div>
|
||||||
|
<div :class="['tab', 'tab_right', { active: lineTabIndex === 2 }]" @click="handleTabClick(2)">媒体来源</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view style="background-color: white; margin-top: 40rpx">
|
||||||
|
<indexMenuTitle title="编辑精选 Top20"></indexMenuTitle>
|
||||||
<RankList :newsList="newsList"></RankList>
|
<RankList :newsList="newsList"></RankList>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view style="background-color: white; margin-top: 40rpx">
|
<view style="background-color: white; margin-top: 40rpx">
|
||||||
<view style="
|
<view style="display: flex; justify-content: space-between; align-items: center; padding-right: 30rpx; height: 100rpx">
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding-right: 30rpx;
|
|
||||||
height: 100rpx;
|
|
||||||
">
|
|
||||||
<indexMenuTitle title="热门行业池 Top10"></indexMenuTitle>
|
<indexMenuTitle title="热门行业池 Top10"></indexMenuTitle>
|
||||||
<view style="display: flex; gap: 3rpx">
|
<view style="display: flex; gap: 3rpx">
|
||||||
<text class="view-all" @click="onViewAll(0)">查看全部</text>
|
<text class="view-all" @click="onViewAll(0)">查看全部</text>
|
||||||
|
|
@ -96,13 +95,7 @@
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view style="background-color: white; margin-top: 40rpx">
|
<view style="background-color: white; margin-top: 40rpx">
|
||||||
<view style="
|
<view style="display: flex; justify-content: space-between; align-items: center; padding-right: 30rpx; height: 100rpx">
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding-right: 30rpx;
|
|
||||||
height: 100rpx;
|
|
||||||
">
|
|
||||||
<indexMenuTitle title="风口概念池 Top10"></indexMenuTitle>
|
<indexMenuTitle title="风口概念池 Top10"></indexMenuTitle>
|
||||||
<view style="display: flex; gap: 3rpx">
|
<view style="display: flex; gap: 3rpx">
|
||||||
<text class="view-all" @click="onViewAll(1)">查看全部</text>
|
<text class="view-all" @click="onViewAll(1)">查看全部</text>
|
||||||
|
|
@ -115,8 +108,11 @@
|
||||||
|
|
||||||
<view class="logout" @click="loginOut" v-if="Session.get('token')">退出登录</view>
|
<view class="logout" @click="loginOut" v-if="Session.get('token')">退出登录</view>
|
||||||
|
|
||||||
<LoginPopup :show="LoginShow" @handlePopupClose="handlePopupClose"
|
<LoginPopup
|
||||||
@handlePopupSuccessCallback="handlePopupSuccessCallback" @handlePopupErrorCallback="handlePopupErrorCallback" />
|
:show="LoginShow"
|
||||||
|
@handlePopupClose="handlePopupClose"
|
||||||
|
@handlePopupSuccessCallback="handlePopupSuccessCallback"
|
||||||
|
@handlePopupErrorCallback="handlePopupErrorCallback" />
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -132,21 +128,15 @@ 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 {
|
import { getindustryCount, getConceptCount, getTopNews, getTopIndustry_d, getTopConcept_d, getNews_cnt_d, newsInfoScore } from "@/api/newsInfo";
|
||||||
getindustryCount,
|
|
||||||
getConceptCount,
|
|
||||||
getTopNews,
|
|
||||||
getTopIndustry_d,
|
|
||||||
getTopConcept_d,
|
|
||||||
getNews_cnt_d,
|
|
||||||
newsInfoScore,
|
|
||||||
} 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"; // 路径根据实际调整
|
||||||
import indexMenuTitle from "@/components/indexMenuTitle.vue"; // 路径根据实际调整
|
import indexMenuTitle from "@/components/indexMenuTitle.vue"; // 路径根据实际调整
|
||||||
import dayjs from "dayjs/esm/index";
|
import dayjs from "dayjs/esm/index";
|
||||||
import HotIndustryList from "@/components/HotIndustryList.vue"; // 路径根据实际调整
|
import HotIndustryList from "@/components/HotIndustryList.vue"; // 路径根据实际调整
|
||||||
|
import LineHol from "@/components/charts/LineHol.vue";
|
||||||
|
import LineHolYellow from "@/components/charts/LineHolYellow.vue";
|
||||||
|
|
||||||
const newsList = ref([]);
|
const newsList = ref([]);
|
||||||
|
|
||||||
|
|
@ -218,9 +208,9 @@ function initData() {
|
||||||
getNews_cnt_dFn();
|
getNews_cnt_dFn();
|
||||||
}
|
}
|
||||||
|
|
||||||
const type = ref();
|
const type = ref(null);
|
||||||
function onViewAll(type) {
|
function onViewAll(type1) {
|
||||||
type.value = type;
|
type.value = type1;
|
||||||
if (Session.get("token")) {
|
if (Session.get("token")) {
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: "/pages/realtimeInfo/rankDetail?type=" + type,
|
url: "/pages/realtimeInfo/rankDetail?type=" + type,
|
||||||
|
|
@ -260,6 +250,11 @@ function loginOut() {
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const lineTabIndex = ref(0);
|
||||||
|
function handleTabClick(index) {
|
||||||
|
lineTabIndex.value = index;
|
||||||
|
}
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
clearInterval(timer);
|
clearInterval(timer);
|
||||||
});
|
});
|
||||||
|
|
@ -400,4 +395,41 @@ onMounted(async () => {
|
||||||
margin-right: 20rpx;
|
margin-right: 20rpx;
|
||||||
margin-bottom: 20rpx;
|
margin-bottom: 20rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tabs {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 30px;
|
||||||
|
border-radius: 10px;
|
||||||
|
|
||||||
|
.tab {
|
||||||
|
width: 100px;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
text-align: center;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
border: 1px solid #e7e7e7;
|
||||||
|
color: #000;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab_left {
|
||||||
|
border-start-start-radius: 10px;
|
||||||
|
border-end-start-radius: 10px;
|
||||||
|
border-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab_right {
|
||||||
|
border-start-end-radius: 10px;
|
||||||
|
border-end-end-radius: 10px;
|
||||||
|
border-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active {
|
||||||
|
border: 1px solid #007bff;
|
||||||
|
background-color: #007bff;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue