一、初始数据
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>
六、页面效果展示