這是最近做的一個自定義程度比較高的圖表頁面(設計一頓操作),在vue項目中引用v-charts來做的,這裏更多的是一些需要根據設計稿來做圖表的一些配置例子。也是搞了好幾天,才基本達到設計稿的要求。大部分時間都是在看e-charts的配置文檔和搜索各路大俠的博客看。
<el-row class="chart-one" :gutter="20" style="padding:0 20px">
<el-col class="chart-area" :span="8" v-for="(item,index) in chartList" :key="index">
<div class="box chart" @click="currentClickChart = index">
<ve-histogram :events="chartEvents" :height="chartHeight" width="98%" :title="item.chartTitle"
:legend="item.legend" :dataZoom="item.dataZoom"
:grid="item.grid" :series="item.series" :xAxis="item.xAxis" :yAxis="item.yAxis"
:tooltip="item.tooltip"></ve-histogram>
</div>
</el-col>
</el-row>
上面代碼中item.chartEvents是處理點擊柱狀圖或者折線圖要處理的事件。使用如下,e對象包含點擊對象的一些可用信息
data(){
this.chartEvents = {
click: function (e) {
setTimeout(() => {
_this.$router.push("/report/customer?projectId=" + _this.selectedProjectId + "&month=" + e.name + "&type=" + (e.seriesIndex + 1));
}, 200)
}
};
returen:{
}
}
這裏已chartList中的一個爲例,下面是其中一個item的值:
{
dataZoom:[],
chartTitle: {
text: '{b_title|工位趨勢}{b_unit|(工位數/個)}',
top: "20",
left:"10",
textStyle: {
rich: {
b_title: {
fontSize: '14',
color: '#333333',
fontWeight: '600'
},
b_unit: {
color: '#999999',
fontSize: '14',
lineHeight: '20'
}
}
},
},
legend: {
align: 'left',
right: '10',
top: "24",
itemGap:26,
itemHeight:10,
textStyle: {
color: "#999999",
padding:[0,-8]
},
data: [
{
name: "新租戶",
icon: "path://M4,2c1.1,0,2,0.9,2,2S5.1,6,4,6S2,5.1,2,4S2.9,2,4,2 M4,0C1.8,0,0,1.8,0,4s1.8,4,4,4s4-1.8,4-4S6.2,0,4,0L4,0z"
},
{
name: "老租戶",
icon: "path://M4,2c1.1,0,2,0.9,2,2S5.1,6,4,6S2,5.1,2,4S2.9,2,4,2 M4,0C1.8,0,0,1.8,0,4s1.8,4,4,4s4-1.8,4-4S6.2,0,4,0L4,0z"
},
{
name: "退租",
icon: "path://M4,2c1.1,0,2,0.9,2,2S5.1,6,4,6S2,5.1,2,4S2.9,2,4,2 M4,0C1.8,0,0,1.8,0,4s1.8,4,4,4s4-1.8,4-4S6.2,0,4,0L4,0z"
},
// {name:"工位均價",icon:"path://M4,2c1.1,0,2,0.9,2,2S5.1,6,4,6S2,5.1,2,4S2.9,2,4,2 M4,0C1.8,0,0,1.8,0,4s1.8,4,4,4s4-1.8,4-4S6.2,0,4,0L4,0z"}
]
},
grid: {
top: '80',
bottom: "30"
},
tooltip: {
show: true,
backgroundColor: "rgba(242,246,252,0.7)",
trigger: 'axis',
axisPointer: {
type: 'shadow',
shadowStyle: {
color: 'rgba(223,225,231,0.50)',
opacity: "0.4"
}
},
textStyle: {
color: "#333333"
},
formatter: '<div style="padding: 10px">' +
'<span>{a1}</span>: <span style="color: #2089FF">{c1}</span><br />' +
'<span>{a0}</span>:<span style="color:#FFC300;">{c0}</span><br />' +
'<span>{a2}</span>: <span style="color:#FF535C ">{c2}</span><br />' +
'</div>'
},
xAxis: [
{
type: 'category',
axisLabel: {
color: "#9AA3AB"
},
data: []
}
],
yAxis: [
{
max: 700,
axisTick: false,
type: 'value',
axisLabel: {
formatter: '{value}',
color: "#999999"
},
splitLine: {
lineStyle: {
color: "#EEEEEE",
opacity: 0.6
}
}
},
{
axisTick: false,
type: 'value',
axisLabel: {
show: false,
formatter: '¥ {value}',
color: "#999999"
},
splitLine: {
show:false,
lineStyle: {
color: "#EEEEEE",
opacity: 0.8
}
}
}
],
series: [
{
barWidth: 8,
type: "bar",
color: "#FFC300",
name: "老租戶",
data: [],
stack: '收入'
},
{
barWidth: 8, type: "bar", color: "#2089FF",
itemStyle: {normal: {barBorderRadius: [4, 4, 0, 0]},},
label: {
show: true,
position: 'top',
textStyle: {color: '#333333', fontSize: 12},
formatter: function (param) {
if(typeof _this.chartList[2].series[param.seriesIndex - 1].data[param.dataIndex] === "object"){
return param.value + (_this.chartList[2].series[param.seriesIndex - 1].data[param.dataIndex]).value
}
return param.value + _this.chartList[2].series[param.seriesIndex - 1].data[param.dataIndex]
}
}, name: "新租戶", data: [], stack: '收入'
},
{
barWidth: 8, type: "bar", color: "#FF535C",
itemStyle: {normal: {barBorderRadius: [4, 4, 0, 0]}}, barGap: "125%",
label: {
show: true,
position: 'top',
textStyle: {color: '#333333', fontSize: 12},
},
name: "退租", data: []
},
{
type: "line",
color: "#00D79F",
smooth: false,
yAxisIndex: 1,
label: {
show: true, position: [-25, -20], textStyle: {color: '#00D79F', fontSize: 12}
, formatter: function (param) {
return param.value + "元/月"
}
},
name: "工位均價",
data: [],
itemStyle:{
normal : {
lineStyle:{
borderType:"dotted"
}
}
},
symbol:"circle"
},
{
type: "line",
color: "#00D79F",
smooth: false,
yAxisIndex: 1,
label: {
show: true, position: [-25, -20], textStyle: {color: '#00D79F', fontSize: 12}
, formatter: function (param) {
return param.value + "元/月"
}
},
name: "工位均價",
data: [],
itemStyle:{
normal:{
color:'#00D79F',
lineStyle:{
type: 'dashed'
}
}
},
}
]
}
上面是v-charts裏面使用,效果圖:
折線圖的虛實線比柱狀圖稍微麻煩一點
這個是處理柱狀圖虛實數據的,大於當前時間是虛數,小於則是實數。transDashed(data,color)是series的data值,color是顏色
transLineDshed(solid,dottedList,data)是折線圖的數據處理,因爲折線圖虛實都需要一個series,所以處理跟柱狀圖會有差異。這表solid參數是實線的數據,dottedList是虛線的數據,注意虛實共同的點在2個數組裏面都要有。
transDashed(data,color){
let list = bee.getMonthBetween(this.monthRange[0], this.monthRange[1]);
for(let i=0;i<list.length;i++){
if(new Date(list[i]).getTime()>new Date(bee.getCurrentYearMonth()).getTime()){
data[i] = {value:data[i],itemStyle: {normal: {color: '#ffffff',borderColor:color,borderType:"dashed"}}};
}
}
},
transLineDashed(solid,dottedList,data){
solid.length = 0;
dottedList.length = 0;
let list = bee.getMonthBetween(this.monthRange[0], this.monthRange[1]);
for(let i=0;i<list.length;i++){
if(new Date(list[i]).getTime() === new Date(bee.getCurrentYearMonth()).getTime()){
//設置交匯點實心
dottedList.push({value:data[i],symbol:"circle"});
solid.push({value:data[i],symbol:"circle"});
continue
}
if(new Date(list[i]).getTime()>new Date(bee.getCurrentYearMonth()).getTime()){
dottedList.push(data[i]);
solid.push("")
}else{
dottedList.push("");
solid.push(data[i])
}
}
},
上述方法使用例子
//更新工位趨勢數據
getStationData() {
ax.post("****************", this.searchEl).then(res => {
let list = [[], [], [], []];
let data = res.result.list;
this.setDataZoom(this.chartList[2],data.length);
let max = 0;
let averageMax = 0;
for (let i = 0; i < data.length; i++) {
list[0].push(data[i].fixed ? data[i].fixed : 0);
list[1].push(data[i].increment ? data[i].increment : 0);
list[2].push(data[i].terminate ? data[i].terminate : 0);
list[3].push(data[i].average ? data[i].average : 0);
if (list[0][i] + list[1][i] >= max) {
max = list[0][i] + list[1][i]
}
if (list[3][i] > averageMax) {
averageMax = list[3][i]
}
if(list[3][i] === 0){
list[3][i] = ""
}
}
this.transDashed(list[0],"#FFC300");
this.transDashed(list[2],"#FF535C");
//設置柱狀圖和折線圖的視覺分離
this.chartList[2].yAxis[0].max = Math.ceil(max/100)*100*2;
this.chartList[2].yAxis[1].max = parseInt(averageMax/100)*100+500;
//給前三個series統一賦值
for (let i = 0; i < this.chartList[2].series.length-2; i++) {
this.chartList[2].series[i].data = list[i];
}
//處理折線圖的虛線,並特殊賦值
this.transLineDashed(this.chartList[2].series[3].data,this.chartList[2].series[4].data,list[3]);
});
},
有疑問歡迎留言哦