echarts重叠柱状图相关

echarts重叠柱状图相关,第1张

前言

效果图

主要问题点
1、柱状图重叠stack
2、数据过大显示处理log(对数坐标)
3、对数(极)坐标0数据处理
4、0数据项显示为灰色柱状条
5、窗口变化自适应
6、侧边导航展开收起对echarts图的影响

柱状图重叠stack

// 1.切换x、y轴
 yAxis: {
  type: 'category',
  boundaryGap: true,
  show: true,
  axisLine: {
    lineStyle: {
      opacity: 0,
    },
  },
  axisTick: { show: false }, // 刻度线提示
  data: ['网络风险', '应用风险', '攻击威胁', '数据泄漏', 'APP风险'],
},
xAxis: {
  type: 'value',
  show: true,
  axisLine: {
    show: false,
  },
},
// 2.数据准备
 series: [
  {
    name: '已认证企业',
    data: ['1', '2', '700', '10000', '80'],
    type: 'bar',
    smooth: true,
    stack: 'total',
    emphasis: {
      focus: 'series',
    },
    itemStyle: {
      color: 'rgba(15, 175, 255, 1)', // 柱状图颜色
      borderRadius: [7, 0, 0, 7], // 柱状图圆角
      borderWidth: 0,
    },
    barWidth: 15, // 宽
    barMinHeight: 10, // 高
  },
  {
    name: '三方供应商',
    data: ['100', '200000', '700', '200', '800000'],
    type: 'bar',
    stack: 'total',
    smooth: true,
    emphasis: {
      focus: 'series',
    },
    itemStyle: {
      color:  'rgba(36, 207, 241, 1)',
      borderRadius: [0, 7, 7, 0],
      borderWidth: 0,
    },
    barWidth: 15, // 柱状图的宽度
    barMinHeight: 10, // 柱状图的最小高度
  },
],


以上数据展示效果图:发现超大数据影响柱状图大小

数据过大显示处理log(对数坐标轴)

	xAxis: {
++    type: 'log',
--    //type: 'value',
      show: true,
      axisLine: {
        show: false,
      },
    },
数值坐标系改为:log对数坐标系
啥是对数坐标轴:n=log(a)(b);看下图,这样我们就能理解为什么图可以展示全了


现在效果图

发现:鼠标移上去其他数据被淡出

处理:series->emphasis:disabled: true,

series: [
  {
    name: '已认证企业',
    data: ['1', '2', '700', '10000', '80'],
    // data: data && [data[0]?.risk_network, data[0]?.risk_app, data[0]?.risk_attack, data[0]?.risk_data_leak, data[0]?.risk_mobile_app],
    type: 'bar',
    smooth: true,
    stack: 'total',
    emphasis: {
      focus: 'series',
++    disabled: true,
    },
    startValue: 100,
    lineStyle: {
      color: '#2878FF',
      width: 1,
    },
    itemStyle: {
      color: (params:any) => {
        if (params.value === 105.05) { // undefined的空数据处理 颜色灰色
          return '#ccc'
        }
        return 'rgba(15, 175, 255, 1)'
      },
      borderRadius: [7, 0, 0, 7],
      borderWidth: 0,
    },
    barWidth: 15,
    barMinHeight: 10,
  },

极坐标0数据处理
根据对数坐标系n=log(a)(b) a>0;那么后台返回数据项如果有0的话,会显示如下

0项数据置为undefined

这里的data是获取后台返回的接口数据,然后进行遍历 *** 作
const arr = data.map((item:any) => ({
    risk_network: item.risk_network || undefined,
    risk_app: item.risk_app || undefined,
    risk_attack: item.risk_attack || undefined,
    risk_data_leak: item.risk_data_leak || undefined,
    risk_mobile_app: item.risk_mobile_app || undefined,
  }))
  initContainer(arr)

提示判断是否有undefined

 // 提示判断是否有undefined
 	 tooltip: {
      padding: 0,
      backgroundColor: 'rgba(255,255,255,0)',
      trigger: 'axis',
      axisPointer: {
        type: 'shadow',
        axis: 'y',
      },
      formatter(params:any) {
	        let tipHtml = '';
	        tipHtml = `${''
	            + ''
	            + ''}${params[0]?.axisValue}`
	            + ''
	            + ''
	            + '

' + `${params[0]?.color};margin:0 3px;">` + `${params[0]?.seriesName}` // eslint-disable-next-line no-unsafe-optional-chaining + `${params[0]?.value === undefined ? 0 : params[0]?.value}` + '

'
+ `

${params[1] ? 'block' : 'none'}">` + `${params[1]?.color};margin:0 3px;">` + `${params[1]?.seriesName}` // eslint-disable-next-line no-unsafe-optional-chaining + `${params[1]?.value === undefined ? 0 : params[1]?.value}` + '

'
+ '' return tipHtml; },

0数据项显示为灰色柱状条

如果好几项为空,页面显示就会很空荡

处理:因为数据都是整数,所以当数据返回为0时,我们给他一个小数105.5;在设置颜色的时候,
为其加一个灰色
1、undefined改成105.5
	const arr = data.map((item:any) => ({
		    risk_network: item.risk_network || 105.05,
		    risk_app: item.risk_app || 105.05,
		    risk_attack: item.risk_attack || 105.05,
		    risk_data_leak: item.risk_data_leak || 105.05,
		    risk_mobile_app: item.risk_mobile_app || 105.05,
		  }))
		  initContainer(arr)
2、tooltip->formatter中的undefined改成105.5
	
		${params[0]?.value === undefined ? 0 : params[0]?.value}

3、series->itemStyle->color使用回调函数形式
 series: [
  {
    name: '已认证企业',
    data: ['0', '0', '0', '10000', '80'],
    // data: data && [data[0]?.risk_network, data[0]?.risk_app, data[0]?.risk_attack, data[0]?.risk_data_leak, data[0]?.risk_mobile_app],
    type: 'bar',
    smooth: true,
    stack: 'total',
    emphasis: {
      focus: 'series',
      disabled: true,
    },
    startValue: 100,
    lineStyle: {
      color: '#2878FF',
      width: 1,
    },
    itemStyle: {
++          color: (params:any) => {
++            if (params.value === 105.05) { // undefined的空数据处理 颜色灰色
 ++             return '#ccc'
 ++           }
  ++          return 'rgba(15, 175, 255, 1)'
 ++         },
      borderRadius: [7, 0, 0, 7],
      borderWidth: 0,
    },
    barWidth: 15,
    barMinHeight: 10,
  },

窗口变化自适应

只需要在执行函数时进行窗口监听视图大小变化,进而重绘就可以了
resize()方法

import { ECharts } from 'echarts';
const scatterChart = ref<ECharts | null>(null);
onMounted(() => {
  window.onresize = () => {
    // console.log('视图大小变化')
    scatterChart.value?.resize();
  };
})

侧边导航展开收起对echarts图的影响

当侧边栏有展开收起时,echarts图不会自适应,这个时候需要重绘我们的echarts图,
我想的是既然窗口能监听,那么dom元素是否也可以监听

https://developer.mozilla.org/zh-CN/docs/Web/API/ResizeObserver/observe

	<div
    id="riskTypeColumnar"
    ref="refriskTypeColumnar"
  />
  const refriskTypeColumnar = ref<HTMLElement |null>(null)
 	const resizeObserver = new ResizeObserver((entries:any) => {
	  scatterChart.value?.resize();
	});
	onMounted(() => {
++   resizeObserver.observe(refriskTypeColumnar.value);
	  window.onresize = () => {
	    // console.log('视图大小变化')
	    scatterChart.value?.resize();
	  };
	})
	注意:需要给它父级dom设置宽度

代码

	<template>
	 <div
	    style="position: absolute;
	    left: 0px;
	    top: 19.5px;
	    font-weight: 500;
	    font-size: 16px;
	    line-height: 25px;
	    color: #181818;"
	  >
	    风险分布
	  </div>
	  <div
	    id="riskTypeColumnar"
	    ref="refriskTypeColumnar"
	  />
	</template>

<script setup lang="ts">
import {
  ref, onUnmounted, markRaw, watch, onMounted,
} from 'vue';
import { ECharts } from 'echarts';
import { overviewRiskDistribution } from '@/api/user';
const scatterChart = ref<ECharts | null>(null);
const refriskTypeColumnar = ref<HTMLElement |null>(null)
const riskTotal = ref<any>(0);
const assetsTotal = ref<any>(0);
const getTableData = async () => {
  const params:any = {
    scope: 0,
  };
  const { code, msg, data } = await overviewRiskDistribution(params);

  if (scatterChart.value) {
    scatterChart.value?.dispose();
  }
  const arr = data.map((item:any) => ({
    risk_network: item.risk_network || 105.05,
    risk_app: item.risk_app || 105.05,
    risk_attack: item.risk_attack || 105.05,
    risk_data_leak: item.risk_data_leak || 105.05,
    risk_mobile_app: item.risk_mobile_app || 105.05,
    // risk_network: item.risk_network || undefined,
    // risk_app: item.risk_app || undefined,
    // risk_attack: item.risk_attack || undefined,
    // risk_data_leak: item.risk_data_leak || undefined,
    // risk_mobile_app: item.risk_mobile_app || undefined,
  }))
  initContainer(arr)
};
onUnmounted(() => {
  scatterChart.value?.dispose();
});
const initContainer = async (data:any) => {
  const echarts = await import('echarts');
  scatterChart.value = markRaw(echarts.init((document as any).getElementById('riskTypeColumnar')));
  renderMap(data)
};
const renderMap = (data:any) => {
  const option = {
    legend: {
      type: 'scroll',
      pageButtonItemGap: 2,
      itemWidth: 10,
      itemHeight: 6,
      itemGap: 30,
      icon: 'rect',
      data: [{
        name: '已认证企业',
        itemStyle: { color: '#0FAFFF' },
        icon: 'roundRect',
      }, {
        name: '三方供应商',
        itemStyle: { color: '#24CFF1' },
        icon: 'roundRect',
      }],
      pageTextStyle: {
        fontSize: 6,
      },
      bottom: 0,
    },
    itemStyle: {
      borderWidth: 2,
      borderColor: '#fff',
    },
    tooltip: {
      padding: 0,
      backgroundColor: 'rgba(255,255,255,0)',
      trigger: 'axis',
      axisPointer: {
        type: 'shadow',
        axis: 'y',
      },
      formatter(params:any) {
        let tipHtml = '';
        tipHtml = `${''
            + ''
            + ''}${params[0]?.axisValue}`
            + ''
            + ''
            + '

' + `${params[0]?.color};margin:0 3px;">` + `${params[0]?.seriesName}` // eslint-disable-next-line no-unsafe-optional-chaining + `${params[0]?.value === 105.05 ? 0 : params[0]?.value}` + '

'
+ `

${params[1] ? 'block' : 'none'}">` + `${params[1]?.color};margin:0 3px;">` + `${params[1]?.seriesName}` // eslint-disable-next-line no-unsafe-optional-chaining + `${params[1]?.value === 105.05 ? 0 : params[1]?.value}` + '

'
+ '' return tipHtml; }, }, grid: { left: '3%', right: '4%', top: '0%', bottom: '10%', containLabel: true, }, yAxis: { type: 'category', boundaryGap: true, show: true, axisLine: { lineStyle: { opacity: 0, }, }, axisTick: { show: false }, data: ['网络风险', '应用风险', '攻击威胁', '数据泄漏', 'APP风险'], }, xAxis: { type: 'log', // type: 'value', show: true, axisLine: { show: false, }, }, series: [ { name: '已认证企业', data: data && [data[0]?.risk_network, data[0]?.risk_app, data[0]?.risk_attack, data[0]?.risk_data_leak, data[0]?.risk_mobile_app], type: 'bar', smooth: true, stack: 'total', emphasis: { focus: 'series', disabled: true, }, startValue: 100, lineStyle: { color: '#2878FF', width: 1, }, itemStyle: { color: (params:any) => { if (params.value === 105.05) { // undefined的空数据处理 颜色灰色 return '#ccc' } return 'rgba(15, 175, 255, 1)' }, borderRadius: [7, 0, 0, 7], borderWidth: 0, }, barWidth: 15, barMinHeight: 10, }, { name: '三方供应商', // data: ['0', '0', '0', '200', '800000'], data: data && [data[1]?.risk_network, data[1]?.risk_app, data[1]?.risk_attack, data[1]?.risk_data_leak, data[1]?.risk_mobile_app], type: 'bar', stack: 'total', smooth: true, emphasis: { focus: 'series', disabled: true, }, startValue: 10, // endValue: 10, lineStyle: { color: '#FF5A5A', width: 1, }, itemStyle: { color: (params:any) => { if (params.value === 105.05) { return '#ccc' } return 'rgba(36, 207, 241, 1)' }, borderRadius: [0, 7, 7, 0], borderWidth: 0, }, barWidth: 15, // 柱状图的宽度 barMinHeight: 10, // 柱状图的最小高度 }, ], }; scatterChart.value?.setOption(option as any, true); }; const resizeObserver = new ResizeObserver((entries:any) => { scatterChart.value?.resize(); }); // initContainer() getTableData() defineExpose({ initContainer, }); onMounted(() => { console.log('refriskTypeColumnar.value', refriskTypeColumnar.value) resizeObserver.observe(refriskTypeColumnar.value); window.onresize = () => { // console.log('视图大小变化') scatterChart.value?.resize(); }; }) </script> <style scoped> #riskTypeColumnar { width: 100%; margin-top: 55px; height: calc(100% - 55px); justify-content: center; position: relative; } </style>

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/940602.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-17
下一篇2022-05-17

发表评论

登录后才能评论

评论列表(0条)

    保存