最近做了一个微信公众号项目,使用Echarts绘制降雨量曲线、水库水位及库容曲线、大坝断面监测等图表。通过查阅官方文档及示例、度娘,与Echarts的距离更近了一步。
总结一下,不能直接在官网上找到答案的用法,有以下几处:
- x轴为value类型的用法
- 双Y轴的用法
- 自定义图形的绘制,包括line、text、polygon等的组合
- 贝塞尔曲线(待定)
先看下2个页面
x轴为value类型的用法
在绘制大坝剖面轮廓的时候,需要根据实际图纸大坝的宽度高度,以及各关键点位的坐标做数据的预处理。
大坝高度宽度及各关键点位坐标计算完成后,写入配置文件。官网示例中多是category类型的,value的没找到,网上搜索了一下,可以用二维数组作为series的data
series : [
{
name:"大坝轮廓",
type:'line',
symbol: "none",
data: [
[damX[0],damY[0]],
[damX[1],damY[1]],
[damX[2],damY[2]],
[damX[3],damY[3]],
[damX[4],damY[4]],
[damX[5],damY[5]],
[damX[6],damY[6]],
[damX[7],damY[7]],
[damX[8],damY[8]]
],
areaStyle: {
normal: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: 'rgba(245,238,188,0.7)',
}, {
offset: 1, color: 'rgba(161,152,37,0.7)',
}],
globalCoord: false // 缺省为 false
},
}
},
lineStyle: {
color: "rgb(9,9,9)"
}
}
]
此处,我做了一点渐变色的填充。填充示例可以查阅官网series-line.areaStyle. color 属性。
双Y轴的用法
在水库水位库容页面,需要用到双Y轴同时显示水位高度与库容大小。双Y轴的实现其实比较简单,主要是series里的yAxisIndex属性设置。
{
name:chartdata.line_text[1],
type:'line',
data:chartdata.capatityList,
showAllSymbol: true,
markPoint : {
label:{
normal:{
textStyle:{
color:'#fff',
fontWeight:'bold'
}
}
},
data : chartdata.KRPoint
},
yAxisIndex:1
}
数据变化较小,像一条停止的心脏线:D。分别加了markpoint标识出最大水位与最大库容。同时这也是用户最关注的点。
自定义图形的绘制,包括line、text、polygon等的组合
大坝断面监测图中,包括大坝轮廓、设计水位、实际水位、测压管轮廓,渗压几个部分的绘制。大坝轮廓绘制如上。
设计水位的绘制比较简单,就是一条线段。用的是虚线(不是实际的水位),给出markpoint来标识警示水位。需要确定的是2个点,起始点X=0,Y=设计水位。终点的x需要计算,计算方法是根据图纸中的数据(按三角形处理)x=((designFL - 13.3)*33.9/13.3),Y=设计水位。
实际水位刚开始我也按线段处理,后来发现画出来的图不太美观,做个填充更合适点,表示实际水位以下、测压管渗压部分,都是有水。
这里的填充,是类型为custom的填充,与大坝 轮廓中type=‘line’的填充方式不同。这里也包括了多边形的绘制。在官网上没看到多边形的代码示例,刚开始不知道shape怎么设置points以及如何写return。后面查阅参考了一个博客,https://blog.youkuaiyun.com/qq_20042935/article/details/89847775
{
name:"当前水位",
type: "custom",
renderItem: function (params, api) {
polyPoints.push(api.coord([api.value(0), api.value(1)]));
var start = api.coord([0, chartdata.waterLevel]);
return {
type: 'group',
children: [{
type: 'polygon',
shape: {
points: echarts.graphic.clipPointsByRect(polyPoints, {
x: params.coordSys.x,
y: params.coordSys.y,
width: params.coordSys.width,
height: params.coordSys.height
})
},
style: api.style({
fill: "rgb(37,183,239)",
stroke: 'transparent'
})
}, {
type: 'text',
style:{
text:chartdata.waterLevel+"m" , //水位数据标志
x:start[0]+ 10,
y:start[1]+10
}
}]
};
},
data:[
[0,13.3],
[((chartdata.waterLevel - 13.3)*33.9/13.3),chartdata.waterLevel],
[0,chartdata.waterLevel]
]
},
data就是三角形的3个点的坐标。
这里的start点,实际也可以利用dataindex来计算。我直接写死了。在测压管轮廓的图像绘制中,我用到了params的属性dataindex,表示data数组中的下标,代码如下:
{
name:"测压管轮廓",
type: "custom",
renderItem: function (params, api) {
// var categoryIndex = api.value(0);
var start = api.coord([api.value(0), api.value(1)]);
var end = api.coord([api.value(2), api.value(3)]);
var height = api.size([0, 1])[1] * (api.value(3) - api.value(1));
var rectShape = echarts.graphic.clipRectByRect({
x: start[0],
y: end[1],
width: end[0] - start[0],
height: height
}, {
x: params.coordSys.x,
y: params.coordSys.y,
width: params.coordSys.width,
height: params.coordSys.height
});
return {
type: 'group',
children: [{
type: 'rect',
shape: rectShape,
style: api.style({fill: 'transparent', stroke: 'black'})
}, {
type: 'line',
shape: {
x1:start[0],y1:end[1],x2:start[0] + 50,y2:end[1]
},
style: api.style({stroke: 'black'})
}, {
type: 'text',
style:{
text:api.value(3)+'m',
x:start[0] + 5,
y:end[1]-10
}
}, {
type: 'text',
style:{
text:pressureName[params.dataIndex],
x:start[0] - 25,
y:start[1]-10
}
}]
};
},
encode: {
x: [1, 3], // 表示维度 3、1 映射到 x 轴。
y: [2, 4] // 表示维度 2、4 映射到 y 轴。
},
data: [
[piezometer_fracture[0],piezometer_fracture[1],piezometer_fracture[2],piezometer_fracture[3]],
[piezometer_fracture[4],piezometer_fracture[5],piezometer_fracture[6],piezometer_fracture[7]],
[piezometer_fracture[8],piezometer_fracture[9],piezometer_fracture[10],piezometer_fracture[11]],
[piezometer_fracture[12],piezometer_fracture[13],piezometer_fracture[14],piezometer_fracture[15]]
]
},
测压管的名称如C11,C10,C9,C8等,单独保存在一个数组中,根据断面的不同,名称有所不同。从左到右绘制,对应pressureName的各元素。
贝塞尔曲线
各测压管的渗压水位,连成一条线就是大坝的浸润线示意图。在custom类型的series中,有一种类型是返回series-custom.renderItem.return_bezierCurve. type = bezierCurve。这里指的是绘制二次或三次贝塞尔曲线。在该项目中,我仅用smooth:0.4平滑了一下。可能跟实际的浸润线有所出入。后面如果要调整浸润线的形态的话,可以用上贝塞尔曲线了。
此处查阅了贝塞尔曲线调整参数对应实际曲线的资料。http://blogs.sitepointstatic.com/examples/tech/canvas-curves/bezier-curve.html
具体就是要调整shape属性中的起始点,结束点,以及控制点的值(1或2个控制点)来满足要求。
问题最大的一段可能是:
这里接的都是实际的数据,但是第一段浸润线也应该不对。渗压管的水位按说不能跟实际水位差这么多的。
待客户验收前再来调整。