在ReactJS调试ECharts期间,遇到一个诡异的现象:
同样的配置代码:
// continue to update by model and by consultant this.processNewAddByModelDict(resultDict, ”); this.processNewAddByConsultantDict(resultDict, ‘’); processNewAddByModelDict(resultDict, filteredDataName) { console.log(‘processNewAddByModelDict: resultDict=’, resultDict, ‘ ,filteredDataName=’, filteredDataName ); let newNewAddByModelDict = this.state.newAddByModelDict; let carModelNameList = []; let carModelNumList = []; let carModalInfoDictList = resultDict.hopeNumByCarList; carModalInfoDictList.map((eachDict) => { let curName = eachDict.NAME; carModelNameList.push(curName); let curNum = eachDict.CUS_NUM; carModelNumList.push(curNum); }); console.log(‘filteredDataName=’, filteredDataName, ‘ ,carModelNameList=’, carModelNameList, ‘ ,carModelNumList=’, carModelNumList ); let curEchartsOption = this.generateNewAddByModelEchartsOption( filteredDataName, carModelNameList, carModelNumList ); newNewAddByModelDict.echartsOption = curEchartsOption; this.setState({ newAddByModelDict : newNewAddByModelDict }); } generateNewAddByModelEchartsOption( filteredDataName = ”, carModelNameList = [], carModelNumList = [] ){ console.log(‘generateNewAddByModelEchartsOption: filteredDataName=’, filteredDataName, ‘ ,carModelNameList=’, carModelNameList, ‘ ,carModelNumList=’, carModelNumList, ); let curEchartsOption = { title : { // text:’本月新增有望客户分类(按车型分)’, text: ”, // textStyle: { // fontWeight: ‘normal’, // fontSize: ’14’ // }, // subtext:datName, // subtext: ‘DCC’, subtext: filteredDataName, subtextStyle: { fontWeight: ‘normal’, fontSize: ’14’, color: ‘red’ }, top: 10, left: 10 }, tooltip: { trigger: ‘axis’ // trigger: ‘item’ }, // toolbox: { // feature: { // dataView: {show: false, readOnly: true}, // magicType: {show: false, type: [‘bar’]}, // restore: {show: false}, // saveAsImage: {show: false} // } // }, legend: { left: ‘65%’, // top: 33, top: 10, data: [‘新增有望客户’] }, grid: { bottom: 80 }, xAxis: [ { type: ‘category’, axisLabel: { interval: 0, rotate: 60 }, // data:hopeNameArr // data: [‘Yeti野帝’, ‘SK’, ‘全新晶锐’, ‘明锐旅行车’, ‘2017款昕锐’, ‘2017款明锐’, ‘明锐经典款’, ‘2017款昕动’, ‘Yeti’], data: carModelNameList, } ], yAxis: [ { type: ‘value’, min: 0, //max: 200, // interval: 30, axisLabel: { formatter: ‘{value}’ } } ], series: [ { name: ‘新增有望客户’, type: ‘bar’, // barWidth: 20,//柱图宽度 barWidth: ‘50%’, label: { normal: { show: true, color: ‘red’, position: ‘top’, textStyle: { color: ‘black’, fontFamily: ‘verdana’, fontSize: 12, fontStyle: ‘normal’ } } }, itemStyle: { // normal:{color:’#C0DDAD’ } // normal:{color:’#3398DB’ } normal: { color: ValueColor.DARK_BLUE } }, // data:hopeNameArrNum // data: [9, 26, 10, 1, 2, 37, 27, 1, 1] data: carModelNumList } ] }; return curEchartsOption; } processNewAddByConsultantDict(resultDict, filteredDataName) { console.log(‘processNewAddByConsultantDict: resultDict=’, resultDict, ‘ ,filteredDataName=’, filteredDataName ); let newDict = this.state.newAddByConsultantDict; let consultantNameList = []; let consultantNumList = []; let consultantPercentList = []; let consultantInfoDictList = resultDict.hopeCoseList; consultantInfoDictList.map((eachDict) => { let curName = eachDict.USER_NAME; consultantNameList.push(curName); let curNum = eachDict.HOPE_NUM; consultantNumList.push(curNum); let curPercent = eachDict.HOPE_PRECENT; consultantPercentList.push(curPercent); }); console.log(‘filteredDataName=’, filteredDataName, ‘ ,consultantNameList=’, consultantNameList, ‘ ,consultantNumList=’, consultantNumList, ‘ ,consultantPercentList=’, consultantPercentList, ); let curEchartsOption = this.generateNewAddByConsultantEchartsOption( filteredDataName, consultantNameList, consultantNumList, consultantPercentList ); newDict.echartsOption = curEchartsOption; this.setState({ newAddByConsultantDict : newDict }); } generateNewAddByConsultantEchartsOption( filteredDataName = ”, consultantNameList = [], consultantNumList = [], consultantPercentList = [], ){ console.log(‘generateNewAddByConsultantEchartsOption: filteredDataName=’, filteredDataName, ‘ ,consultantNameList=’, consultantNameList, ‘ ,consultantNumList=’, consultantNumList, ‘ ,consultantPercentList=’, consultantPercentList, ); let curEchartsOption = { title : { // text: ‘本月新增有望客户分类(按销售顾问分)’, text: ”, textStyle: { fontWeight: ‘normal’, fontSize: ’14’ }, // subtext: names, // subtext: ‘DCC’, subtext: filteredDataName, subtextStyle: { fontWeight: ‘normal’, fontSize: ’14’, color: ‘red’ }, top: 10, left: 40 }, tooltip: { trigger: ‘axis’, // trigger: ‘item’, }, grid:{ bottom: 80 }, toolbox: { feature: { dataView: { show: false, readOnly: false }, magicType: { show: false, type: [‘line’, ‘bar’] }, restore: { show: false }, //重置 saveAsImage: { show: false } //保存图片 } }, legend: { left: ‘right’, //orient : ‘vertical’, //align:’left’, // top: 33, top: 10, data: [ ‘有望客户’,’有望目标完成率’ ] }, xAxis: [ { axisLabel: { interval: 0, rotate: 60 }, type: ‘category’, // data: hopeCoseNameArr // data: [0, 89] // data: [‘吴兆军’, ‘洪嘉盛’] data: consultantNameList } ], yAxis: [ { type: ‘value’, min: 0, //interval: 4, axisLabel: { formatter: ‘{value} ‘ } }, { type: ‘value’, name: ”, min: 0, //interval 间隔值 //interval: 20, axisLabel: { formatter: ‘{value} %’ } } ], series: [ { name: ‘有望目标完成率’, type: ‘line’, yAxisIndex: 1, label: { normal: { show: true, color: ‘red’, // color: ValueColor.GREEN, position: ‘top’, formatter: ‘{c}%’, textStyle: { color: ‘black’, fontSize: 12, fontStyle: ‘normal’ } } }, itemStyle: { normal: { // color: ‘#70AD47’ color: ValueColor.GREEN } }, // data: hopeCosePrecentArr // data: [2, 8] data: consultantPercentList }, { name: ‘有望客户’, type: ‘bar’, // barWidth : 20,//柱图宽度 barWidth : ‘30%’, label: { normal: { show: true, // color: ‘red’, color: ValueColor.GREEN, position: ‘inside’, textStyle: { color: ‘black’, fontFamily: ‘verdana’, fontSize: 12, fontStyle: ‘normal’ } } }, itemStyle: { normal: { // color: ‘#70AD47’ color: ValueColor.DARK_BLUE } }, // data: hopeCoseNumArr // data: [26, 89] data: consultantNumList } ] }; return curEchartsOption; } render() { console.log(`ProspectMonitor render`); return ( 。。。 <div className=”chart”> <ReactEcharts option={this.state.newAddByModelDict.echartsOption} onEvents={this.onClickByModelEvents} /> </div> 。。。 <div className=”chart”> <ReactEcharts option={this.state.newAddByConsultantDict.echartsOption} onEvents={this.onClickByModelEvents} /> </div> 。。。 |
但是显示出来的效果却是:
第一列中的提示内容中诡异的多出了一些内容:
而其它列,则没有多余的内容,显示是正常的:
而别人的同样的ECharts的配置中,却没有此问题:
然后去调试找原因。
把generateNewAddByModelEchartsOption中去掉了legend的data:
legend: { left: ‘65%’, // top: 33, top: 10, // data: [‘新增有望客户’] }, |
结果:
原先问题依旧,但更多出了legend的更多图例:
更加诡异了。
调试到最后,终于找到原因了:
是最开始的时候,为了不让newAddByModelDict和newAddByConsultantDict的echartsOption不为null,不会导致ECharts显示异常,所以当时初始化时,给了这2个option都是,前面一个表的option的默认空值:
export default class ProspectMonitor extends Component { state = { 。。。 completeProgressDict : { title: ”, boxType : ‘box-primary’, isFiltered: false, monthTarget: 0, monthCompleted: 0, completePercent: 0, // echartsOption: null echartsOption: this.generateCompleteProgressEchartsOption() }, newAddByModelDict : { title: ‘本月新增有望客户分类(按车型分)’, boxType : ‘box-success’, isFiltered: false, // legendTitleList: [‘新增有望客户’], // echartsOption: null echartsOption: this.generateCompleteProgressEchartsOption() }, newAddByConsultantDict : { title: ‘本月新增有望客户分类(按销售顾问分)’, boxType : ‘box-danger’, isFiltered: false, // legendTitleList: [‘有望客户’, ‘有望目标完成率’], // echartsOption: null echartsOption: this.generateCompleteProgressEchartsOption() } }; |
而其中有一堆的DCC,电话等图例:
generateCompleteProgressEchartsOption( completePercent = 0, percentColor = COMPLETE_COLOR.NORMAL, dccNum = 0, telNum = 0, intoShopNum = 0, outExpandNum = 0, secondaryNetNum = 0, lackNum = 0, ){ console.log(‘generateCompleteProgressEchartsOption: completePercent=’, completePercent, ‘ ,percentColor=’, percentColor, ‘ ,dccNum=’, dccNum, ‘ ,telNum=’, telNum, ‘ ,intoShopNum=’, intoShopNum, ‘ ,outExpandNum=’, outExpandNum, ‘ ,secondaryNetNum=’, secondaryNetNum, ‘ ,lackNum=’, lackNum, ); let curEchartsOption = { title: { show: true, text: `${completePercent}%`, textStyle: { color: percentColor, align: ‘right’, verticalAlign: ‘middle’ }, left: ‘right’, top: ‘middle’, }, tooltip : { trigger: ‘item’ }, legend: { show: true, x: ‘center’, y: ‘bottom’, // bottom: -5, bottom: 5, data: [ ‘DCC’, ‘电话’, ‘进店’, ‘外拓’, ‘二级网点’, ‘缺口’ ] }, xAxis: { show: false, type: ‘value’ }, yAxis: { show: false, type: ‘category’ }, series: [ { name: ‘DCC’, type: ‘bar’, stack: ‘总量’, label: { normal: { show: true, position: ‘inside’ } }, itemStyle: { normal: { color: ValueColor.DARK_BLUE } }, data: [dccNum] }, { name: ‘电话’, type: ‘bar’, stack: ‘总量’, label: { normal: { show: true, position: ‘inside’ } }, itemStyle: { normal: { color: ValueColor.GREEN } }, data: [telNum] }, { name: ‘进店’, type: ‘bar’, stack: ‘总量’, label: { normal: { show: true, position: ‘inside’ } }, itemStyle: { normal: { color: ValueColor.YELLOW } }, data: [intoShopNum] }, { name: ‘外拓’, type: ‘bar’, stack: ‘总量’, label: { normal: { show: true, position: ‘inside’ } }, itemStyle: { normal: { color: ValueColor.LIGHT_BLUE } }, data: [outExpandNum] }, { name: ‘二级网点’, type: ‘bar’, stack: ‘总量’, label: { normal: { show: true, position: ‘inside’ } }, itemStyle: { normal: { color: ValueColor.GRAY } }, data: [secondaryNetNum] }, { name: ‘缺口’, type: ‘bar’, stack: ‘总量’, label: { normal: { show: true, position: ‘inside’ } }, itemStyle: { normal: { color: ValueColor.RED } }, data: [lackNum] } ] }; return curEchartsOption; } |
然后,即使后序,用:
this.setState({ newAddByModelDict : newNewAddByModelDict }); this.setState({ newAddByConsultantDict : newDict }); |
已经彻底更新掉了ECharts的option,但是也会导致:
之前最开始赋值的option中,部分内容竟然是残留了下来,导致后序的Eharts的渲染出现多余的内容。
改为,同一类的表的空的配置:
newAddByModelDict : { title: ‘本月新增有望客户分类(按车型分)’, boxType : ‘box-success’, isFiltered: false, // legendTitleList: [‘新增有望客户’], // echartsOption: null // echartsOption: this.generateCompleteProgressEchartsOption() echartsOption: this.generateNewAddByModelEchartsOption() }, newAddByConsultantDict : { title: ‘本月新增有望客户分类(按销售顾问分)’, boxType : ‘box-danger’, isFiltered: false, // legendTitleList: [‘有望客户’, ‘有望目标完成率’], // echartsOption: null echartsOption: this.generateCompleteProgressEchartsOption() // echartsOption: this.generateNewAddByConsultantEchartsOption() } |
即可正常显示了:
【总结】
此处问题的原因找到了:
感觉应该算是ECharts的bug:
最开始初始化时,设置了一个空的配置(但是是属于另外一种类型,比如时二维数组的柱状图)
然后后序更新option配置为另外一个配置,比如一位数组的柱状图
结果会导致,一位数组中的第一列中的tooltip提示内容中,会显示出原先二维数组的图例的内容。
希望ECharts可以以后可以解决这个bug。
其中,此处的ECharts的版本是:
ReactJS中用到的:
import ReactEcharts from ‘echarts-for-react’; |
版本是:
“echarts-for-react”: “^1.4.4”,
其中用到的ECharts,应该是3.x的版本。