这是最近做的一个自定义程度比较高的图表页面(设计一顿操作),在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]);
});
},
有疑问欢迎留言哦