最近有需求,看了一下Echarts的关系网络图可以实现,但是图出来后发现图例的图标显示的都一样,看了文档后,觉得不符合我的要求,就改了下代码,最终的chart如下(每一类一种图标):
改动如下:
legend.js 里面_buildItem方法里
itemType = data[i].icon || this._getSomethingByName(itemName).type;
这是获取图例的图标类型的,可以看下
/**
* 根据名称返回series数据或data
*/
_getSomethingByName: function (name) {
var series = this.option.series;
var data;
for (var i = 0, l = series.length; i < l; i++) {
if (series[i].name === name) {
// 系列名称优先
return {
type: series[i].type,
series: series[i],
seriesIndex: i,
data: null,
dataIndex: -1
};
}
if (
series[i].type === ecConfig.CHART_TYPE_PIE
|| series[i].type === ecConfig.CHART_TYPE_RADAR
|| series[i].type === ecConfig.CHART_TYPE_CHORD
|| series[i].type === ecConfig.CHART_TYPE_FORCE
|| series[i].type === ecConfig.CHART_TYPE_FUNNEL
|| series[i].type === ecConfig.CHART_TYPE_TREEMAP
) {
data = series[i].categories || series[i].data || series[i].nodes;
for (var j = 0, k = data.length; j < k; j++) {
if (data[j].name === name) {
return {
type: series[i].type,
series: series[i],
seriesIndex: i,
data: data[j],
dataIndex: j
};
}
}
}
}
return {
type: 'bar',
series: null,
seriesIndex: -1,
data: null,
dataIndex: -1
};
},
可以看出,获取图标type,先从series里面获取(首先series的type在上面这几个类型中),获取不到默认就是bar,但是force只有一个series,所以图例所有图标都是force类型的。
看到这,就知道怎么改了,我自己定义了一个方法(_genLegendTypeByName)从category里面获取,每个category是个对象,里面定义name和type属性(我在后台封装好了),改动之后代码如下:
itemType = data[i].icon || this._getLegendTypeByName(itemName).type;
if(!itemType || itemType == '') {
itemType = data[i].icon || this._getSomethingByName(itemName).type;
}
这样如果category里面没有定义话,还使用_getSomethingByName方法获取,不会出错,获取到type之后,还有个问题
// 图形
itemShape = this._getItemShapeByType(
lastX, lastY,
itemWidth, itemHeight,
(this._selectedMap[itemName] && this._hasDataMap[itemName] ? color : '#ccc'),
itemType,
color
);
这里获根据之前获得的type封装shape对象
_getItemShapeByType: function (x, y, width, height, color, itemType, defaultColor) {
var highlightColor = color === '#ccc' ? defaultColor : color;
var itemShape = {
zlevel: this.getZlevelBase(),
z: this.getZBase(),
style: {
iconType: 'legendicon' + itemType ,
x: x,
y: y,
width: width,
height: height,
color: color,
strokeColor: color,
lineWidth: 2
},
highlightStyle: {
color: highlightColor,
strokeColor: highlightColor,
lineWidth: 1
},
hoverable: this.legendOption.selectedMode,
clickable: this.legendOption.selectedMode
};
上面这个方法图标的类型已经变成了'legendicon'+type,最终生成图标的方法在icon.js里面
/**
* 创建矩形路径
* @param {Context2D} ctx Canvas 2D上下文
* @param {Object} style 样式
*/
buildPath : function (ctx, style, refreshNextFrame) {
if (this.iconLibrary[style.iconType]) {
this.iconLibrary[style.iconType].call(this, ctx, style, refreshNextFrame);
}
else {
ctx.moveTo(style.x, style.y);
ctx.lineTo(style.x + style.width, style.y);
ctx.lineTo(style.x + style.width, style.y + style.height);
ctx.lineTo(style.x, style.y + style.height);
ctx.lineTo(style.x, style.y);
ctx.closePath();
}
return;
},
但是这里iconLibrary内容如下:
看到没有,legendicon开头的就那么几种,所以你要想用triangle这些,就把_getItemShapeByType里面iconType改下就可以了