echarts+react实现散点图的全选图例、缩放、自适应页面宽高、x轴文字竖直显示

一、初始数据

import selectPic from "@/assets/img/selectPic.png"
import unSelectPic from "@/assets/img/unSelectPic.png"
import open from "@/assets/img/icon_open.png"
import close from "@/assets/img/icon_close.png"  //引入图片
import * as echarts from 'echarts'   //引入echaarts

this.state = {
            pointByDeptList:[
{
			"baList":[
				{
					"attendingPhysicianName":"彭俊文",
					"diagName":"恶性肿瘤维持性化学治疗",
					"inhospNo":"10312540",
					"patientId":"1073014",
					"profitFeeTotal":1919.26,
					"totalFee":5831.67
				},
				{
					"attendingPhysicianName":"王浩",
					"diagName":"恶性肿瘤靶向治疗",
					"inhospNo":"10314518",
					"patientId":"1073014",
					"profitFeeTotal":1290.76,
					"totalFee":6460.17
				}
			],
			"deptName":"普外科"
		},
		{
			"baList":[
				{
					"attendingPhysicianName":"刘春蕾",
					"diagName":"2型糖尿病伴血糖控制不佳",
					"inhospNo":"10313022",
					"patientId":"1174552",
					"profitFeeTotal":1397.61,
					"totalFee":6388.78
				}
			],
			"deptName":"内分泌专科"
		},
		{
			"baList":[
				{
					"attendingPhysicianName":"肖士东",
					"diagName":"急性化脓性扁桃体炎",
					"inhospNo":"10313981",
					"patientId":"1322710",
					"profitFeeTotal":649.00,
					"totalFee":3110.40
				}
			],
			"deptName":"耳鼻咽喉科"
		},
],
            widthFlag: false,
            ksyksdtState: true,
            ksyksdtTitle: '全选科室',
            ksyksdtzoomState: false
        }

二、数据调用

componentDidMount() {
this.state.pointByDeptList.forEach(function (item) {
        item.name = item.deptName;
        var data = [];
        item.baList.forEach(function (dItem) {
        data.push([dItem.profitFeeTotal, dItem.totalFee, dItem.patientId, dItem.inhospNo, dItem.diagName, dItem.surgeryName, dItem.attendingPhysicianName]);
          });
            item.data = data;
        });

this.getSplashPic(this.state.pointByDeptList)
 window.addEventListener('resize', this.handleResize)

}   

componentWillUnmount() {
        window.removeEventListener('resize', this.handleResize)
    }  //销毁窗口事件

三、图表渲染

handleResize = async e => {
        if (e.target.innerWidth <= 1280) {
            await this.setState({
                widthFlag: false,
            })
            await this.getSplashPic(this.state.pointByDeptList)
        } else if (1280 < e.target.innerWidth) {
            await this.setState({
                widthFlag: true,
            })
            await this.getSplashPic(this.state.pointByDeptList)
        }
    }  //监听浏览器窗口大小

getSplashPic = (valData) => {
        var series = [];
        var lenged = []
        for (var i = 0; i < valData.length; i++) {
            lenged.push({ name: valData[i].deptName })
            series.push({
                name: valData[i].deptName,
                type: 'scatter',
                data: valData[i].data,
                symbolSize: '8',
                emphasis: {
                    focus: 'series',
                },
            })
        }
        lenged.unshift({ name: this.state.ksyksdtTitle, icon: 'image://' + selectPic })
        if (valData.length > 0) {
            series.unshift({
                name: this.state.ksyksdtTitle,
                type: 'scatter',
                data: valData[0].data,
                symbolSize: '0',
                color: "#000000"
            })
        }
        const aa = this.state.widthFlag
        const dd = parseInt(lenged.length / 8) * 30 + 65
        const ee = parseInt(lenged.length / 16) * 30 + 65
        var option = {
            title: {
                text: '科室盈亏散点图',
                x: 10,
                y: 15,                  // 标题距顶部边距
                textStyle: {
                    color: 'rgba(0,0,0,0.85)',
                    fontSize: 14,
                    fontWeight: 700
                }
            },
            legend: {
                bottom: 16,
                left: 18,
                icon: 'square',
                textStyle: {//文字颜色
                    fontSize: 12,
                    color: 'rgba(0,0,0,0.65)'
                },
                itemWidth: 10,
                itemHeight: 10,
                itemGap: 16,
                data: lenged
            },
            grid: {
                x: 60,  //左
                y: 80,  //上
                x2: 106, //右
                y2: !aa ? dd : ee,
                // containLabel: true,
            },
            xAxis: {
                name: '医保结余(元)',
                nameTextStyle: {
                    color: 'rgba(0,0,0,0.45)',
                    fontSize: 12,
                },
                axisLabel: {
                    interval: 'auto',
                    show: true,
                    textStyle: {
                        color: 'rgba(0,0,0,0.45)',  //更改坐标轴文字颜色
                        fontSize: 12      //更改坐标轴文字大小
                    },
                    color: "rgba(0,0,0,0.45)",
                    formatter: function (value) {
                        value = value.toString();
                        var maxlength = 5;
                        var newValue;
                        if (value.length > maxlength) {
                            newValue = value.substring(0, maxlength - 1) + '.';
                            return newValue.split("").join("\n")
                        } else {
                            return value.split("").join("\n");
                        }
                    },  //x轴数据竖直显示,超过5个字显示...
                },
                axisLine: {
                    lineStyle: {
                        color: '#d9d9d9' //更改坐标轴颜色
                    }
                },
                splitLine: {
                    show: true,
                    lineStyle: {
                        color: ['#e8e8e8'],
                        width: 1,
                        type: 'dashed'
                    }
                },
            },
            yAxis: {
                name: '费用(元)',
                nameTextStyle: {
                    color: 'rgba(0,0,0,0.45)',
                    fontSize: 12
                },
                splitLine: {
                    show: true,
                    lineStyle: {
                        color: ['#e8e8e8'],
                        width: 1,
                        type: 'dashed'
                    }
                },
                axisLabel: {
                    textStyle: {
                        align: 'right',
                        fontSize: 12     // 文字右对齐
                    },
                    color: "rgba(0,0,0,0.45)",
                },
                axisLine: {
                    lineStyle: {
                        color: '#d9d9d9', //更改坐标轴颜色
                    }
                }
            },
            dataZoom: [],
            tooltip: {
                position: 'bottom',
                textStyle: {
                    color: 'rgba(0,0,0,0.65)',
                    fontSize: 12,
                    fontWeight: 'normal'
                },
                formatter: function (param) {
                    let diagName = ''
                    let surgeryName = ''
                    if (param.data[5] != undefined) {
                        surgeryName = param.data[5].toString()
                    }
                    if (param.data[4] != undefined) {
                        diagName = param.data[4].toString()
                    }
                    const maxlength = 6;
                    if (diagName.length > maxlength) {
                        diagName = diagName.substring(0, maxlength - 1) + '...';
                    } else {
                        diagName;
                    }
                    if (surgeryName.length > maxlength) {
                        surgeryName = surgeryName.substring(0, maxlength - 1) + '...';
                    } else {
                        surgeryName;
                    }
                    return param.marker + param.seriesName + ":" + "<br/>" + "病案号:" + param.data[2] + "<br/>" + "住院号:" + param.data[3] + "<br/>" + "主诊断:" + diagName + "<br/>" + "主手术:" + surgeryName + "<br/>" + "主治医师:" + param.data[6] + "<br/>" + "医保结余:" + param.value[0] + "元" + "<br/>" + "总费用:" + param.value[1] + "元";
                }
            },
            color: ['#009fd4', '#6064f3', '#26bfbd', '#2e7be6', '#fa8e4b', '#61cef2', '#a6a8ff', '#75ebe9', '#80b5ff', '#ffe18c'],
            series: series,
        };
        var splashPic = echarts.getInstanceByDom(document.getElementById('splashPic'));
        if (splashPic == null || splashPic == undefined) {
            splashPic = echarts.init(document.getElementById('splashPic'));
        }

        var autoHeight = parseInt(lenged.length / 8) * 30;
        splashPic.getDom().style.height = autoHeight + 432 + "px"; 
       //根据内容图表高度自适应增加
        splashPic.clear()  //清除cavans缓存,图表重绘
        splashPic.resize();
        splashPic.setOption(option);
        splashPic.off('legendselectchanged')   //图表点击事件一次性调用两次,清除事件
        splashPic.on('legendselectchanged', async (e) => {
            var selectArr = option.legend.data;
            if (e.name === this.state.ksyksdtTitle) {//点击全选
                var that = this;
                await this.setState({
                    ksyksdtState: !that.state.ksyksdtState,
                })
                var obj = {};
                for (var key in selectArr) {
                    obj[selectArr[key].name] = this.state.ksyksdtState;
                }

                selectArr.splice(0, 1, { name: this.state.ksyksdtTitle, icon: 'image://' + (this.state.ksyksdtState ? selectPic : unSelectPic) })
                option.legend.selected = obj
                option.legend.data = selectArr
            } else { //点击其他科室
                var isAll = true;
                var selected = e.selected;
                for (var a in selected) {
                    if (a != this.state.ksyksdtTitle && selected[a] == false) {
                        isAll = false
                    }
                }
                selected[this.state.ksyksdtTitle] = isAll
                await this.setState({
                    ksyksdtState: isAll,
                })
                option.legend.selected = selected
                selectArr.splice(0, 1, { name: this.state.ksyksdtTitle, icon: 'image://' + (isAll ? selectPic : unSelectPic) })
                option.legend.data = selectArr
            }
            splashPic.clear()
            splashPic.resize();
            splashPic.setOption(option)
        })
        window.addEventListener("resize", function () {
            splashPic.resize();   //根据浏览器窗口大小视图自适应刷新
        });
    }

四、图表缩放功能

openOrCloseZoom = async () => {
        var that = this
        await this.setState({
            ksyksdtzoomState: !that.state.ksyksdtzoomState
        })
        var charts = echarts.getInstanceByDom(document.getElementById('splashPic')); //有的话就获取已有echarts实例的DOM节点。
        var op = charts.getOption()
        var dataZoom = [{
            type: 'inside'
        },
        {
            type: 'inside',
            orient: 'vertical'
        }]
        var dataZoom2 = []
        op.dataZoom = (that.state.ksyksdtzoomState ? dataZoom : dataZoom2)
        charts.clear()
        charts.resize();
        charts.setOption(op)
    }

五、dom代码段

<div class="splashStyl">
                <div class="tipAllstyl" style={{ display: this.state.ksyksdtzoomState ? "block" : "none" }}>
                                            <div class="tip_text" >滑动鼠标放大指定区域</div>
                                        </div>
                                        <div onClick={this.openOrCloseZoom} class="tip_image"><img src={this.state.ksyksdtzoomState ? close : open} alt="" style={{ width: 12, height: 12, display: 'inline-block' }}></img>
                                            <span class="tip_name">缩放</span>
                                        </div>
                                        <div id="splashPic" style={{ minWidth: 716, minHeight: 432 }}></div>
                                    </div>

六、页面效果展示

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值