echart实现custom自定义色块功能
之前完成了一個比較復雜的功能。但是一直沒有時間(懶)把這個代碼分享出來,趁著一個人加班的機會順便寫個博客。下面是實現的具體展示。
這個圖是用來展示機器在一定時間內參數修改的次數。就是說一定時間范圍內,兩次修改的間隔在五分鐘之內,則把他們歸為同一個色塊。橫坐標是統計時間的跨度,縱坐標是這段時間內修改的次數。
同樣顏色的色塊代表的是同一臺機器,所以就可以非常直觀明了的表現機器修改的次數,如果在比較短的時間內出現大量改動,那么就會出現非常細長的色塊。我覺得這個功能非常好,雖然需求是領導從別的公司借鑒過來的,不過具體實現都是我自己完成的,花了我兩天時間。
好了,不吹牛了,上代碼。
首先是在后臺統計,統計某時間內機器修改次數。主要就幾個參數,機器id,開始時間,結束時間,持續時間,修改次數。統計過后按開始時間正序排序,不然的話形成的圖形就比較亂。
然后是前臺代碼,這個是入口
$(function(){loadParaChart(); }); function loadParaChart(){//主方法var query = getFormData();//查詢條件,主要是開始時間和結束時間query["top"] = 10;$.ajax({type:"get",url:url,data:query,dataType:"json",success:function(result){if(result.statusCode == 200){var list = result.data;var o = calculateDataChart(list);//將后臺數據處理成echart需要的數據//總的開始時間var startTime = +new Date(query.startTime.replace("-","/"));//總的結束時間,因為是yyyy-MM-dd的格式,所以我加了一天var endTime = +new Date(query.endTime.replace("-","/")) + 24*60*60*1000;loadChart(o,startTime,endTime,o.max)//生成圖表}else{commPageAjaxDone(result);}}}); }?這個是計算色塊的長寬和位置,主要是避免重疊,具體原理是把計算后的色塊加入到列表里,然后新加入的色塊先給個固定位置,然后遍歷已有的色塊,如果和某個色塊重疊則把新色塊的位置提到該色塊的下面,然后重新遍歷,直到新色塊和所有舊色塊不重疊為止。依次類推。當然還是有優化的空間的。我只做了初步的優化,比如先把橫向方位不會重疊的色塊排除。
var baseHeight = 0.5;//色塊的基本長度 function getMax(count){//獲得色塊的長度return baseHeight + 0.05 * count; } function calculateDataChart(list){var data = [];var max = 1;var machineMap = {};var machines = [];var colorList = ["#588d81" ,"#a6fb52","#1871c6","#e18213","#60ec4c" ];//顏色列表,前五個機器固定顏色$.each(list,function(i, n){//將后臺的數據處理后變成色塊的位置信息var duration = n.duration;if(duration < 60000) duration = 60000;//色塊有最小寬度,避免太窄而無法被選中var temp = getMax(n.count);//獲得色塊長度var color = "";if(machineMap.hasOwnProperty(n.machineId)){color = machineMap[n.machineId];}else{if(colorList.length > 0){color = colorList.shift();}else{color = randomColor();//顏色用完后,后面的機器隨機顏色}machines.push({name:n.machineName,color:color});machineMap[n.machineId] = color;}var index = dealOverlay(data, n);//獲得色塊的y軸起始位置,核心代碼//計算整個坐標系的最大高度if(max < temp + baseHeight + index + 1) max = temp + baseHeight + index + 1;data.push({name: n.machineName,machineId:n.machineId,startTime:n.startTime,endTime:n.endTime,value: [index,n.startTime,n.startTime + duration,n.duration,n.count],itemStyle: {normal: {color: color}},});});return {machines:machines,data:data,max:max}; } //oldObject 已經被計算過確定位置的色塊 //n 新加入的色塊 function dealOverlay(oldObject, n){var data =$.grep(oldObject,function(o,i){//首先過濾掉時間軸不會重復的老色塊,因為不會影響新色塊的縱坐標位置if (n.startTime > o.value[2] || n.endTime < o.value[1])return false;return true;});var index = 0.5;index = overlay(data, n, index);//重疊算法計算新色塊的高度return index; } function overlay(data, n, index){//重疊算法$.each(data,function(i, o){//o 某色塊對象var value = o.value;//index起始位置大于該色塊的最大高度,或者新的色塊最大高度小于該色塊的起始位置,也就是不重復if(index > value[0] + getMax(value[4]) || index + getMax(n.count) < value[0]){return true;}else{//如果重復了,那么將index改成該色塊的最大高度加上一個固定高度,然后再重新遍歷計算//注意,index改變后必須重新遍歷一遍,因為之前index不重疊的色塊,index改變后有可能會重疊index = overlay(data, n, value[0] + getMax(value[4]) + baseHeight);return false;}});return index; }然后是echart的代碼
function loadChart(obj,startTime,endTime,max){var machines = obj.machines;data = obj.data;var duration = (endTime - startTime);var series = [{type: 'custom',//類型,自定義renderItem: renderItem,//自定義圖形設置,關鍵代碼itemStyle: {normal: {opacity: 0.8}},label:{normal: {show: true,position: 'inside',formatter:function(a){var data = a.data;if(a.value[3] > duration/20){var str = data.name + "在" +transformTime(a.value[3])+ "內修改了" +a.value[4] + "次";var n = parseInt(9 * 20 * a.value[3]/duration);var reg = eval("/.{"+n+"}\x01?/g");str=str.replace(/[^\x00-\xff]/g,"$&\x01").replace(reg,"$&\n").replace(/\x01/g,"");return str;}return "";},color:"black"}},encode: {x: [1, 2],y: 0},data: data},];$.each(machines,function(i,n){//因為自定義模式沒有圖例,所以我借用了bar模式的圖例series.push({name:n.name,type:'bar',itemStyle: {normal: {color: n.color, //這里的圖例要注意,顏色設置和儀表盤的顏色對應起來}}});});// Generate mock datavar option = {tooltip: {formatter: function (params) {var startDate = new Date(params.value[1]).format("yyyy-MM-dd HH:mm:ss")var endDate = new Date(params.value[2]).format("yyyy-MM-dd HH:mm:ss")var result = params.marker + params.name + ' 修改了'+ params.value[4]+"次</br>"+ startDate+"到"+endDate;return result;}},legend: {data:machines,x: 'left',y: 'top',},grid: {left:50,right:50},xAxis: {type:"time",boundaryGap: false,min: startTime,max: endTime,scale: true,position:"top",axisLabel: {formatter: function (val) {var date = new Date(val).format("MM-dd HH");return date;}}},yAxis: {type:"value",inverse: true,show:false,scale: true,max:max,minInterval: 1,},dataZoom:[{type:"inside",filter:"empty",xAxisIndex: 0,},{type: 'slider',filter:"empty",xAxisIndex: 0,},],series: series};var myChart = echarts.init(document.getElementById("paraDataChart"));window.onresize = function(){//適應屏幕的變化,重新計算圖形myChart.resize();}myChart.setOption(option);myChart.dispatchAction({type: 'dataZoom',// 可選,dataZoom 組件的 index,多個 dataZoom 組件時有用,默認為 0dataZoomIndex: [0,1,2,3],// 開始位置的百分比,0 - 100start: 0,// 結束位置的百分比,0 - 100end: 100,})myChart.on('datazoom', function (params) {//忘了有什么用。。var opt = myChart.getOption();var dz = opt.dataZoom[0];duration = dz.endValue - dz.startValue;});myChart.on('legendselectchanged',function(params){//點擊圖例可以隱藏對應的機器色塊console.log(params);var selected = params.selected;var opt = myChart.getOption();opt.series[0].data = $.grep(data,function(n,i){if(selected[n.name]){return true;}else{return false;}});myChart.setOption(opt,true);});myChart.on('click',function(params){//色塊點擊事件console.log(params.data);});}); }下面是echart自定義模式的核心代碼,其實就是爛大街的東西,直接官網看一下,然后自己嘗試一下
function renderItem(params, api) {var categoryIndex = api.value(0);var count = api.value(4);var start = api.coord([api.value(1), 0]);//var end = api.coord([api.value(2), 0]);//var yheight = api.size([0, categoryIndex])[1];//色塊y軸起始var height = api.size([0, getMax(count)])[1];//色塊長度var rectShape = echarts.graphic.clipRectByRect({x: start[0],y: start[1] + yheight,width: end[0] - start[0],height: height}, {x: params.coordSys.x,y: params.coordSys.y,width: params.coordSys.width,height: params.coordSys.height});var style = api.style();var renderItem = rectShape && {type: 'rect',shape: rectShape,style: style};return renderItem; }完
總結
以上是生活随笔為你收集整理的echart实现custom自定义色块功能的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ElasticSearch自定义分析器(
- 下一篇: CMake中执行shell命令之exec