123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- <script setup lang="ts">
- /**
- * @Name: NegativeLabelChart.vue
- * @Description:
- * @Author: Cheney
- */
- import * as echarts from 'echarts';
- import * as api from '/@/views/product-manage/comment-detail/api';
- const props = defineProps({
- asin: String
- });
- const { asin } = props;
- const loading = ref(false);
- let responseData: any = null;
- const chartRef: any = useTemplateRef('chartRef');
- let chart: echarts.ECharts | null = null;
- let resizeObserver: ResizeObserver | null = null;
- const hasData = ref(true);
- onBeforeMount(() => {
- fetchWordCloudData();
- });
- onBeforeUnmount(() => {
- // 清理 ResizeObserver
- if (resizeObserver) {
- resizeObserver.disconnect();
- }
- if (chart) {
- chart.dispose();
- chart = null;
- }
- });
- async function fetchWordCloudData() {
- loading.value = true;
- const query = {
- asin,
- agg_field: 'raw_label'
- };
- try {
- responseData = await api.getWordCloudData(query);
- if (!responseData.data || responseData.data.length === 0) {
- // 处理空数据的情况
- hasData.value = false;
- if (chart) {
- chart.clear();
- }
- return;
- }
- hasData.value = true;
- setOption();
- } catch (error) {
- console.error('==Error==', error);
- } finally {
- loading.value = false;
- }
- }
- function setOption() {
- const option = {
- title: {
- text: '负面标签'
- },
- tooltip: {
- show: true
- },
- series: [
- {
- type: 'wordCloud',
- width: '90%',
- height: '85%',
- // 词云图的形状
- shape: 'star', // 可以是 'circle', 'cardioid', 'diamond', 'triangle-forward', 'triangle', 'pentagon', 'star'
- // 控制字体大小
- sizeRange: [ 12, 60 ],
- // 文本旋转角度
- rotationRange: [ 0, 0 ],
- rotationStep: 45,
- gridSize: 8,
- drawOutOfBound: false,
- shrinkToFit: false,
- layoutAnimation: true,
- // 全局的文字样式
- textStyle: {
- fontFamily: 'PingFang',
- fontWeight: 'bold',
- // Color can be a callback function or a color string
- color: function() {
- // Random color
- return 'rgb(' + [
- Math.round(Math.random() * 160),
- Math.round(Math.random() * 160),
- Math.round(Math.random() * 160)
- ].join(',') + ')';
- }
- },
- // 鼠标hover时的样式
- emphasis: {
- focus: 'self',
- textStyle: {
- textShadowBlur: 10,
- textShadowColor: '#333'
- }
- },
- // left: '10%',
- // top: '10%',
- // right: '10%',
- // bottom: '10%',
- data: responseData.data
- }
- ],
- backgroundColor: '#fff'
- };
- if (!chart) {
- chart = echarts.init(chartRef.value);
- }
- chart.setOption(option);
- // 添加 ResizeObserver 以处理图表大小变化
- if (!resizeObserver) {
- resizeObserver = new ResizeObserver(() => {
- chart?.resize();
- });
- resizeObserver.observe(chartRef.value);
- }
- }
- </script>
- <template>
- <el-card v-loading="loading" class="border-none" shadow="never">
- <!-- 空状态 和 词云图 -->
- <div class="w-full" style="min-height: 400px">
- <div v-show="!loading && !hasData" style="min-height: 400px">
- <el-empty :image-size="200" />
- </div>
- <div v-show="hasData" ref="chartRef" style="width: 100%; height: 400px"></div>
- </div>
- </el-card>
- </template>
- <style scoped>
- </style>
|