提交 97c21cbd authored 作者: coderBryanFu's avatar coderBryanFu

feat: 新增词云图组件

上级 cdc914d0
export const TAGTYPE = ["primary", "success", "warning", "danger", "info"]; export const TAGTYPE = ["primary", "success", "warning", "danger", "info"];
// 双色图表
export const DOUBLECHARTCOLORS = [
'#055FC2',
'#CE4F51'
]
// 多色图表预设颜色列表 20种
export const MUTICHARTCOLORS = [
"#69B1FF",
"#FF7875",
"#B37FEB",
"#FFC069",
"#1677FF",
"#87E8DE",
"#ADC6FF",
"#FFBB96",
"#BAE0FF",
"#FFD591",
"#6691FF",
"#FFB2AF",
"#81D0FF",
"#D8E5FB",
"#7981F1",
"#FF9696",
"#6678A1",
"#273C57",
"#E8B8FF",
"#DF812E"
];
<template>
<div class="wordcloud-wrapper" :style="{ width: width ? width : '520px', height: height ? height : '400px' }">
<div class="chart-box" id="wordcloud-chart">
</div>
</div>
</template>
<script setup>
import { onMounted } from 'vue';
import setChart from '@/utils/setChart';
import getWordCloudChart from './wordCloudChart';
const props = defineProps(({
width: {
type: String,
default: ''
},
height: {
type: String,
default: ''
},
data: {
type: Array,
default: [
// { name: "与马斯克公开冲突", value: 100 },
// { name: "传统能源", value: 5 },
// { name: "共和党财政鹰派", value: 77 },
// { name: "未实现赤字控制目标", value: 35 },
// { name: "得克萨斯州", value: 88 },
// { name: "选举压力", value: 57 },
// { name: "主张财政紧缩", value: 72 },
// { name: "财政保守", value: 18 },
]
}
}))
onMounted(() => {
let chart = getWordCloudChart(props.data);
setChart(chart, "wordcloud-chart");
})
</script>
<style lang="scss">
.chart-box {
width: 100%;
height: 100%;
}
</style>
\ No newline at end of file
import 'echarts-wordcloud';
const getWordCloudChart = (data) => {
const option = {
grid: {
left: 5,
top: 5,
right: 5,
bottom: 5,
},
series: [
{
type: "wordCloud",
shape: 'circle',
width: '100%',
height: '100%',
// 其他形状你可以使用形状路径
// shape: 'circle', // 示例
// 或者自定义路径
gridSize: 35, // 网格大小,影响词间距。
sizeRange: [16, 36], // 定义词云中文字大小的范围
rotationRange: [0, 0],
rotationStep: 0,
drawOutOfBound: false, // 是否超出画布
shrinkToFit: true, // 是否自动缩小以适应容器
// 字体
textStyle: {
// normal: {
// color: function () {
// return 'rgb(' + [
// Math.round(Math.random() * 160),
// Math.round(Math.random() * 160),
// Math.round(Math.random() * 160)
// ].join(',') + ')';
// }
// },
color: function () {
let colors = [
"rgba(189, 33, 33, 1)",
"rgba(232, 151, 21, 1)",
"rgba(220, 190, 68, 1)",
"rgba(96, 58, 186, 1)",
"rgba(32, 121, 69, 1)",
"rgba(22, 119, 255, 1)",
];
return colors[parseInt(Math.random() * colors.length)];
},
emphasis: {
shadowBlur: 5,
shadowColor: "#333",
},
},
// 设置词云数据
data: data,
},
],
};
return option
}
export default getWordCloudChart
\ No newline at end of file
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
.left-btn-wrapper { .left-btn-wrapper {
width: 24px; width: 24px;
height: 48px; height: 48px;
cursor: pointer
img { img {
width: 100%; width: 100%;
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
.right-btn-wrapper { .right-btn-wrapper {
width: 24px; width: 24px;
height: 48px; height: 48px;
cursor: pointer
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
<ActionButton name="选项A" type="normal" /> <ActionButton name="选项A" type="normal" />
<ActionButton name="选项B" type="normal" /> <ActionButton name="选项B" type="normal" />
<ActionButton name="选项C" type="normal" /> <ActionButton name="选项C" type="normal" />
选项按钮
` `
}} }}
</pre> </pre>
...@@ -20,19 +22,49 @@ ...@@ -20,19 +22,49 @@
</div> </div>
</el-col> </el-col>
<el-col :span="span">
<pre>
{{
`
import LeftBtn from '@/components/base/PageBtn/LeftBtn.vue'
import RightBtn from '@/components/base/PageBtn/RightBtn.vue'
<LeftBtn />
<RightBtn />
左右按钮
`
}}
</pre>
<div class="button-box1">
<LeftBtn />
<RightBtn />
</div>
</el-col>
</el-row> </el-row>
</template> </template>
<script setup> <script setup>
import '@/styles/common.scss' import '@/styles/common.scss'
import ActionButton from '@/components/base/ActionButton/index.vue' import LeftBtn from '@/components/base/PageBtn/LeftBtn.vue'
import RightBtn from '@/components/base/PageBtn/RightBtn.vue'
const span = 12 const span = 12
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.button-box { .button-box {
margin-left: 40px;;
display: flex;
gap: 8px
}
.button-box1 {
width: 200px;
display: flex; display: flex;
margin-left: 20px; justify-content: space-between;
margin-left: 40px;
margin-bottom: 10px; margin-bottom: 10px;
gap: 8px gap: 8px
} }
......
<template>
<el-row class="wrapper layout-grid-line">
<el-col :span="span">
<pre>
{{
`
import WordCloudChart from "@/components/base/WordCloundChart/index.vue"
<div class="chart-box">
<WordCloudChart :data="data" />
</div>
`
}}
</pre>
<div class="chart-box">
<WordCloudChart :data="data" />
</div>
</el-col>
</el-row>
</template>
<script setup>
import {ref} from 'vue'
import '@/styles/common.scss'
import WordCloudChart from "@/components/base/WordCloundChart/index.vue"
const span = 12
const data = ref([
{ name: "与马斯克公开冲突", value: 100 },
{ name: "传统能源", value: 5 },
{ name: "共和党财政鹰派", value: 77 },
{ name: "未实现赤字控制目标", value: 35 },
{ name: "得克萨斯州", value: 88 },
{ name: "选举压力", value: 57 },
{ name: "主张财政紧缩", value: 72 },
{ name: "财政保守", value: 18 },
])
</script>
<style lang="scss" scoped>
.chart-box {
width: 520px;
height: 400px;
border: 1px solid var(--bg-black-5);
}
</style>
\ No newline at end of file
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
<el-tab-pane label="领域标签" lazy> <el-tab-pane label="领域标签" lazy>
<AreaTag /> <AreaTag />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="选项按钮" lazy> <el-tab-pane label="按钮" lazy>
<ActionButton /> <ActionButton />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="层级关系图" lazy> <el-tab-pane label="层级关系图" lazy>
...@@ -43,6 +43,9 @@ ...@@ -43,6 +43,9 @@
<el-tab-pane label="引力关系图" lazy> <el-tab-pane label="引力关系图" lazy>
<GraphTreeChart /> <GraphTreeChart />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="词云图" lazy>
<WordCloudChart />
</el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
</el-space> </el-space>
...@@ -67,6 +70,7 @@ import GraphChart from './GraphChart/index.vue' ...@@ -67,6 +70,7 @@ import GraphChart from './GraphChart/index.vue'
import GraphTreeChart from './GraphTreeChart/index.vue' import GraphTreeChart from './GraphTreeChart/index.vue'
import AreaTag from './AreaTag/index.vue' import AreaTag from './AreaTag/index.vue'
import ActionButton from './ActionButton/index.vue' import ActionButton from './ActionButton/index.vue'
import WordCloudChart from './WordCloudChart/index.vue'
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
......
...@@ -64,8 +64,7 @@ ...@@ -64,8 +64,7 @@
</div> </div>
</div> --> </div> -->
<div class="home-main-header-item-box"> <div class="home-main-header-item-box">
<div class="item" v-for="(item, index) in govInsList" :key="index" <div class="item" v-for="(item, index) in govInsList" :key="index" @click="handleToInstitution(item)">
@click="handleToInstitution(item)">
<div class="item-left"> <div class="item-left">
<img :src="item.img ? item.img : DefaultIcon2" alt="" /> <img :src="item.img ? item.img : DefaultIcon2" alt="" />
</div> </div>
...@@ -123,8 +122,7 @@ ...@@ -123,8 +122,7 @@
}" v-for="(tag, index) in item.industryList" :key="index"> }" v-for="(tag, index) in item.industryList" :key="index">
{{ tag.industryName }} {{ tag.industryName }}
</div> --> </div> -->
<AreaTag v-for="(tag, index) in item.industryList" :key="index" <AreaTag v-for="(tag, index) in item.industryList" :key="index" :tagName="tag.industryName">
:tagName="tag.industryName">
</AreaTag> </AreaTag>
</div> </div>
<div class="box1-main-right-center"> <div class="box1-main-right-center">
...@@ -187,17 +185,16 @@ ...@@ -187,17 +185,16 @@
<div class="text">{{ "查看更多" }}</div> <div class="text">{{ "查看更多" }}</div>
</div> </div>
</div> --> </div> -->
<RiskSignal :list="warningList" @item-click="handleClickToDetail" <RiskSignal :list="warningList" @item-click="handleClickToDetail" @more-click="handleToMoreRiskSignal"
@more-click="handleToMoreRiskSignal" riskLevel="signalLevel" postDate="signalTime" riskLevel="signalLevel" postDate="signalTime" name="signalTitle">
name="signalTitle">
</RiskSignal> </RiskSignal>
</div> </div>
<DivideHeader id="position2" class="divide2" :titleText="'资讯要闻'"></DivideHeader> <DivideHeader id="position2" class="divide2" :titleText="'资讯要闻'"></DivideHeader>
<div class="center-center"> <div class="center-center">
<NewsList :newsList="newsList" @item-click="handleToNewsAnalysis" @more-click="handleToMoreNews" /> <NewsList :newsList="newsList" @item-click="handleToNewsAnalysis" @more-click="handleToMoreNews" />
<!-- <NewsList :newsList="newsList" /> --> <!-- <NewsList :newsList="newsList" /> -->
<MessageBubble :messageList="messageList" @person-click="handleClickPerson" <MessageBubble :messageList="messageList" @person-click="handleClickPerson" @info-click="handleGetMessage"
@info-click="handleGetMessage" imageUrl="img" @more-click="handleToSocialDetail" /> imageUrl="img" @more-click="handleToSocialDetail" />
</div> </div>
<DivideHeader id="position3" class="divide3" :titleText="'数据总览'"></DivideHeader> <DivideHeader id="position3" class="divide3" :titleText="'数据总览'"></DivideHeader>
<div class="center-footer"> <div class="center-footer">
...@@ -212,8 +209,7 @@ ...@@ -212,8 +209,7 @@
<div class="box5-selectbox"> <div class="box5-selectbox">
<el-select @change="handleBox5YearChange" v-model="box5SelectedYear" placeholder="选择时间" <el-select @change="handleBox5YearChange" v-model="box5SelectedYear" placeholder="选择时间"
style="width: 120px"> style="width: 120px">
<el-option v-for="item in box5YearList" :key="item.value" :label="item.label" <el-option v-for="item in box5YearList" :key="item.value" :label="item.label" :value="item.value" />
:value="item.value" />
</el-select> </el-select>
</div> </div>
</div> </div>
...@@ -231,8 +227,7 @@ ...@@ -231,8 +227,7 @@
<div class="box6-selectbox"> <div class="box6-selectbox">
<el-select @change="handleBox6YearChange" v-model="box6SelectedYear" placeholder="选择时间" <el-select @change="handleBox6YearChange" v-model="box6SelectedYear" placeholder="选择时间"
style="width: 120px"> style="width: 120px">
<el-option v-for="item in box6YearList" :key="item.value" :label="item.label" <el-option v-for="item in box6YearList" :key="item.value" :label="item.label" :value="item.value" />
:value="item.value" />
</el-select> </el-select>
</div> </div>
</div> </div>
...@@ -248,8 +243,7 @@ ...@@ -248,8 +243,7 @@
<div class="header-title">{{ "关键行政令" }}</div> <div class="header-title">{{ "关键行政令" }}</div>
</div> </div>
<div class="box7-main"> <div class="box7-main">
<div class="box7-item" v-for="(item, index) in keyDecreeList" :key="index" <div class="box7-item" v-for="(item, index) in keyDecreeList" :key="index" @click="handleKeyDecree(item)">
@click="handleKeyDecree(item)">
<div class="icon"> <div class="icon">
<img src="./assets/images/warning.png" alt="" /> <img src="./assets/images/warning.png" alt="" />
</div> </div>
...@@ -263,7 +257,7 @@ ...@@ -263,7 +257,7 @@
<template #reference> <template #reference>
<div class="info-content">{{ item.content ? item.content : "暂无数据" }}</div> <div class="info-content">{{ item.content ? item.content : "暂无数据" }}</div>
</template> </template>
</el-popover> --> </el-popover> -->
</div> </div>
</div> </div>
</div> </div>
...@@ -312,9 +306,9 @@ ...@@ -312,9 +306,9 @@
</div> </div>
<div class="select-main"> <div class="select-main">
<div class="checkbox-group"> <div class="checkbox-group">
<el-checkbox v-for="type in decreeTypeList" :key="type.id" <el-checkbox v-for="type in decreeTypeList" :key="type.id" v-model="checkedDecreeType"
v-model="checkedDecreeType" :label="type.typeId" style="width: 180px" :label="type.typeId" style="width: 180px" class="filter-checkbox"
class="filter-checkbox" @change="handleChangeCheckedDecreeType"> @change="handleChangeCheckedDecreeType">
{{ type.typeName }} {{ type.typeName }}
</el-checkbox> </el-checkbox>
</div> </div>
...@@ -356,8 +350,8 @@ ...@@ -356,8 +350,8 @@
</div> </div>
<div class="select-main"> <div class="select-main">
<div class="checkbox-group"> <div class="checkbox-group">
<el-checkbox v-for="time in pubTime" :key="time.id" v-model="activePubTime" <el-checkbox v-for="time in pubTime" :key="time.id" v-model="activePubTime" :label="time.id"
:label="time.id" style="width: 100px" class="filter-checkbox" style="width: 100px" class="filter-checkbox"
@change="checked => handlePubTimeChange(time.id, checked)"> @change="checked => handlePubTimeChange(time.id, checked)">
{{ time.name }} {{ time.name }}
</el-checkbox> </el-checkbox>
...@@ -388,8 +382,7 @@ ...@@ -388,8 +382,7 @@
<div class="title">{{ "政令库" }}</div> <div class="title">{{ "政令库" }}</div>
</div> </div>
<div class="content-box" v-show="decreeList"> <div class="content-box" v-show="decreeList">
<div class="main-item" v-for="(item, index) in decreeList" :key="index" <div class="main-item" v-for="(item, index) in decreeList" :key="index" @click="handleClickDecree(item)">
@click="handleClickDecree(item)">
<div class="main-item-left"> <div class="main-item-left">
<div class="left-left"> <div class="left-left">
{{ item.time?.split("-")[0] }}<br />{{ item.time?.split("-")[1] }}月{{ {{ item.time?.split("-")[0] }}<br />{{ item.time?.split("-")[1] }}月{{
...@@ -422,9 +415,8 @@ ...@@ -422,9 +415,8 @@
{{ `共 ${totalDecreesNum} 项` }} {{ `共 ${totalDecreesNum} 项` }}
</div> </div>
<div class="footer-right"> <div class="footer-right">
<el-pagination @current-change="handleCurrentChange" :pageSize="10" <el-pagination @current-change="handleCurrentChange" :pageSize="10" :current-page="currentPage"
:current-page="currentPage" background layout="prev, pager, next" background layout="prev, pager, next" :total="totalDecreesNum" />
:total="totalDecreesNum" />
</div> </div>
</div> </div>
</div> </div>
...@@ -435,7 +427,7 @@ ...@@ -435,7 +427,7 @@
</template> </template>
<script setup> <script setup>
import NewsList from "@/components/base/newsList/index.vue"; import NewsList from "@/components/base/NewsList/index.vue";
import { onMounted, ref, watch, nextTick } from "vue"; import { onMounted, ref, watch, nextTick } from "vue";
import router from "@/router"; import router from "@/router";
import { import {
...@@ -633,7 +625,7 @@ const handlegetDecreeRiskSignal = async () => { ...@@ -633,7 +625,7 @@ const handlegetDecreeRiskSignal = async () => {
const res = await getDecreeRiskSignal(params); const res = await getDecreeRiskSignal(params);
console.log("风险信号", res); console.log("风险信号", res);
if (res.code === 200 && res.data) { if (res.code === 200 && res.data) {
warningList.value = res.data.map(item => ({...item, id:item.orderId})); warningList.value = res.data.map(item => ({ ...item, id: item.orderId }));
} }
} catch (error) { } catch (error) {
console.error("风险信号error", error); console.error("风险信号error", error);
...@@ -3324,10 +3316,12 @@ onMounted(async () => { ...@@ -3324,10 +3316,12 @@ onMounted(async () => {
letter-spacing: 0px; letter-spacing: 0px;
border-radius: 4px; border-radius: 4px;
} }
.type1 { .type1 {
color: rgba(232, 189, 11, 1); color: rgba(232, 189, 11, 1);
background: rgba(232, 189, 11, 0.1); background: rgba(232, 189, 11, 0.1);
} }
.type2 { .type2 {
color: rgba(255, 149, 77, 1); color: rgba(255, 149, 77, 1);
background: rgba(255, 149, 77, 0.1); background: rgba(255, 149, 77, 0.1);
......
...@@ -17,8 +17,8 @@ const getWordCloudChart = (data) => { ...@@ -17,8 +17,8 @@ const getWordCloudChart = (data) => {
// 其他形状你可以使用形状路径 // 其他形状你可以使用形状路径
// shape: 'circle', // 示例 // shape: 'circle', // 示例
// 或者自定义路径 // 或者自定义路径
gridSize: 30, // 网格大小,影响词间距。 gridSize: 35, // 网格大小,影响词间距。
sizeRange: [15, 40], // 定义词云中文字大小的范围 sizeRange: [16, 36], // 定义词云中文字大小的范围
rotationRange: [0, 0], rotationRange: [0, 0],
rotationStep: 0, rotationStep: 0,
drawOutOfBound: false, // 是否超出画布 drawOutOfBound: false, // 是否超出画布
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论