动态加载的实现
-
constructor() 中定义组件全局变量 this.chart
constructor(props) { super(props); this.state = {} this.chart = {}; }
这样就可以在该组件全局而不仅仅是某个方法内部使用了。
-
初始化图表
draw = (list) => { this.chart = new G2.Chart({ container: 'chart', forceFit: true, height: 500, padding: 70 }); this.chart.source(list, { ref_date: { range: [0,1] } }); this.chart.tooltip({ crosshairs: { type: 'line' } }); ... ... ... this.chart.line().position('ref_date*value').color('name'); this.chart.render(); }
这样就定义好了图表参数。
该方法只会执行一次,如果多次执行就会生成多个图表,这样就需要用到另一种比较复杂的方法来操作了,因为要使用到节点。
-
动态加载
g2的动态加载就依赖与一个方法:chart.changeData(list) 在此就能意识到将chart写入全局的意义了,数据(list)的发生变化,changeData方法必然不能够在 draw() 方法中执行,因为那样会多生成一个图表,既然如此,还不如直接选择通过dom操作,每次数据更新删除旧节点了,通过chart.render()方法就可以了,也就没必要使用changeData()方法了,所以要想使用changeData方法就需要能在其它方法中使用chart,所以将chart定义在全局是很必要的。
接下来就很简单了,每次数据改变setState的时候,回调里面调用一下该方法就行了。
handleRadio = (e) => { this.setState({ type: e.target.value },() => { this.chart.changeData(newList); }) }
图例的自定义显示
比如要实现图示中表单样式的图例:
表格样式为:menu | name | name |
---|---|---|
一级菜单 | 用户中心 | 违规查询 |
二级菜单 | 用户中心-我要充值/用户中心-个人中心 | 违规查询-违规查询/违规查询-罚单代缴 |
要实现这样的legend样式,只能拼字符串了,官方文档也有说明: 图例html实现
修改this.chart.legend 属性
this.chart.legend({
useHtml: true,
hoverable: true,
containerTpl: '<div class="g2-legend"><table class="g2-legend-list"></table></div>',
itemTpl: (value, color, checked, index) => {
checked = checked ? 'checked' : 'unChecked';
const { priArr, secArr, priNum, secNum } = this.priSecArr;
priArr.forEach(item => {
...
数据处理
...
})
secArr.forEach(item => {
...
数据处理
...
})
if(index === priNum + secNum - 1) {
let str_pri = '', str_sec = ''; // 两个 tr标签
// 这里面用到的类名都是g2规定好的,不能乱设置
priArr.forEach(item => {
var markerDom = '<div class="g2-legend-marker" style="display:inline-block;background-color:' + item.color + ';width:9px;height:9px;border-radius:50%;margin-right:4px;vertical-align:baseline"></div>';
var nameDom = '<div class="legend-item-name" style="display:inline-block">' + item.value + '</div>';
str_pri += '<td style="padding: 0 15px;text-align: left" class="g2-legend-list-item item-' + item.index + ' ' + item.checked + '" data-value="' + item.value + '" data-color="' + item.color +'">' + markerDom + nameDom + '</td>'
})
secArr.forEach(item => {
str_sec += '<td style="vertical-align:top;padding:9px 0;text-align:left">'
if(item.length > 0) {
item.forEach(i => {
var markerDom = '<div class="g2-legend-marker" style="display:inline-block;background-color:' + i.color + ';width:9px;height:9px;border-radius:50%;margin-right:4px;vertical-align:baseline"></div>';
var nameDom = '<div class="legend-item-name" style="display:inline-block">' + i.value + '</div>';
str_sec += '<div style="padding:0 15px" class="g2-legend-list-item item-' + i.index + ' ' + i.checked + '" data-value="' + i.value + '" data-color="' + i.color +'">' + markerDom + nameDom + '</div>'
})
}
str_sec += '</td>';
})
str_pri = '<tr><td>一级菜单</td>' + str_pri + '</tr>';
str_sec = '<tr><td style="vertical-align:top;padding:9px 0;">二级菜单</td>' + str_sec + '</tr>';
return '<tbody class="g2-legend-list-item item-0">' + str_pri + str_sec + '</tbody>'
} else {
return '<td></td>'
}
},
'g2-legend': {
position: 'unset!important',
display: 'flex',
justifyContent: 'center'
}
})
反正去试一下就知道怎么玩了。
X轴最右侧刻度值显示不全
如图:
就是这么个情况,要解决也非常简单,给chart添加一个padding就好了
this.chart = new G2.chart({
container: 'chart',
forceFit: true,
height: 500
padding: 70 //就是这里
})
这样就完事儿了。