vue练习 动态生成table数据,单击单元格显示嵌套的echars,单元格按照数据值大小颜色动态渐变
<template>
<div class="hello">
<el-table
:data="tableData"
style="width: 100%" :cell-style="cellStyle">
<el-table-column v-for=" v in cols" :key="v.prop"
:prop="v.prop"
:label="v.label"
width="180">
<template slot-scope="scope">
<el-popover v-if="scope.column.property!=='title'"
placement="top"
trigger="click"
@after-enter="afterEnter(scope)">
<!-- <div :ref="scope.column.id+scope.column.property+scope.$index">1111</div> -->
<div :id="scope.column.id+scope.column.property+scope.$index" style="width: 600px;height:400px;">1111</div>
<div slot="reference"> {{scope.row[v.prop]}}</div>
</el-popover>
<div v-else>
{{scope.row[v.prop]}}
</div>
</template>
</el-table-column>
</el-table>
<el-row>
<el-button type="primary" @click="generateData">生成数据</el-button>
</el-row>
</div>
</template>
<script>
var echarts = require('echarts');
export default {
name: 'colorList',
components: { },
data () {
return {
cols:[],
tableData: [],
colorsMap:new Map(),
sumColorsMap:new Map(),
numberArr:[]
}
},
created(){
this.generateData()
},
methods:{
afterEnter(scope){
const {row,column,$index} =scope
let id=column.id+column.property+$index
let myChart = echarts.init(document.getElementById(id));
// 指定图表的配置项和数据
var option = {
title: {
text: 'ECharts 入门示例'
},
tooltip: {},
legend: {
data:['销量',"利润占比"]
},
xAxis: {
data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
},
yAxis: [
{type: 'value',data: [-5, -10,15,20,25,30,35,40]},
{type: 'value',data: [-5,0,5,10,15,20]}
],
series: [{
name: '销量',
type: 'bar',
data: [-5, 20, 36, -10, 10, 20],
yAxisIndex:0
},
{
name: '利润占比',
type: 'line',
data: [0.05,-2.5,3.6,5.8,2.3,7.8],
yAxisIndex:1
}]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
},
getSummaries(tableData,cols) {
let keyArr=[]
for(let i=0;i< this.cols.length;i++){
if(this.cols[i].label)
keyArr.push(this.cols[i].label)
}
let sumObj={}
for(let j=0;j<keyArr.length;j++){
let valArr=[]
for(let i=0;i< tableData.length;i++){
if(tableData[i][keyArr[j]]){
valArr.push(tableData[i][keyArr[j]])
}
}
sumObj[keyArr[j]]=parseFloat(eval(valArr.join("+"))/valArr.length).toFixed(2) ||''
}
tableData.push(sumObj)
},
generateData(){
let newTableData=[]
this.cols=[]
this.tableData=[]
this.colorsMap=new Map()
this.numberArr=[]
let colLength=Math.ceil(Math.random()*5)
this.cols.push({"prop":"title","label":""})
for(let i=0;i<colLength;i++){
this.cols.push({"prop":"issuerCode"+i,"label":"issuerCode"+i})
}
let keyArr=[]
for(let i=0;i< this.cols.length;i++){
keyArr.push(this.cols[i].prop)
}
// console.log(keyArr)
for(let i=0;i<colLength;i++){
let obj={}
for(let j=0;j<keyArr.length;j++){
if(keyArr[j]==keyArr[i+1]){
//continue
obj[keyArr[j]]=''
continue
}
if(keyArr[j]=='title'){
obj[keyArr[j]]=keyArr[i+1]
}else{
obj[keyArr[j]]=parseFloat(Math.random()*10).toFixed(2)
}
}
newTableData.push(obj)
}
for(let i=0;i<newTableData.length;i++){
for(let j=0;j<keyArr.length;j++){
if(this.IsNaN(newTableData[i][keyArr[j]])){
this.numberArr.push(newTableData[i][keyArr[j]])
}
}
}
this.generateColorMap(this.numberArr,this.colorsMap)
this.getSummaries(newTableData,this.cols)
let sumNumberArr=[]
for(let j=0;j<keyArr.length;j++){
if(this.IsNaN(newTableData[newTableData.length-1][keyArr[j]])){
sumNumberArr.push(newTableData[newTableData.length-1][keyArr[j]])
}
}
this.generateColorMap(sumNumberArr,this.sumColorsMap)
this.tableData=newTableData
},
generateColorMap(sumNumberArr,map){
//去重
sumNumberArr=[...new Set(sumNumberArr)].sort()
if(sumNumberArr.length%2===0){
//偶数个
let min1=Math.min.apply(null,sumNumberArr)
let max1=Math.max.apply(null,sumNumberArr)
let mid=(min1+max1)/2;
let arr1=sumNumberArr.filter(e=>e<=mid).concat([mid]);
let arr2=sumNumberArr.filter(e=>e>=mid).concat([mid]);
let min2=Math.min.apply(null,arr1)
let max2=Math.max.apply(null,arr1)
for(let i=0;i<arr1.length;i++){
map.set(arr1[i], this.gerColorOfWeight1(min2,max2,this.toRgb(['#63BE7B'])[0],this.toRgb(['#FFEB84'])[0],arr1[i]),true)
}
let min3=Math.min.apply(null,arr2)
let max3=Math.max.apply(null,arr2)
for(let i=0;i<arr2.length;i++){
map.set(arr2[i], this.gerColorOfWeight1(min3,max3,this.toRgb(['#FFEB84'])[0],this.toRgb(['#F8696B'])[0],arr2[i]))
}
}else{
//奇数个
let arr1=sumNumberArr.slice(0,parseInt(sumNumberArr.length/2)+1);
let arr2=sumNumberArr.slice(parseInt(sumNumberArr.length/2),sumNumberArr.length);
console.log(sumNumberArr)
console.log(arr1)
console.log(arr2)
let min1=Math.min.apply(null,arr1)
let max1=Math.max.apply(null,arr1)
for(let i=0;i<arr1.length;i++){
map.set(arr1[i], this.gerColorOfWeight1(min1,max1,this.toRgb(['#63BE7B'])[0],this.toRgb(['#FFEB84'])[0],arr1[i]),true)
}
let min2=Math.min.apply(null,arr2)
let max2=Math.max.apply(null,arr2)
for(let i=0;i<arr2.length;i++){
map.set(arr2[i], this.gerColorOfWeight1(min2,max2,this.toRgb(['#FFEB84'])[0],this.toRgb(['#F8696B'])[0],arr2[i]))
}
}
},
cellStyle(obj){
const { row, column, rowIndex, columnIndex } = obj;
if(rowIndex==this.tableData.length-1){
return "background-color:" + this.sumColorsMap.get(row[column.label])
}
if(this.IsNaN(row[column.label])){
return "background-color:" + this.colorsMap.get(row[column.label])
}
return ""
},
IsNaN(val) {
if (parseFloat(val).toString() == "NaN") {
return false;
} else {
return true;
}
},
//将色盘组中的 16 进制颜色转换成rgb
toRgb(colors) {
let temp = [];
for (let i = 0; i < colors.length; i++) {
let color = {};
let rgb = this.colorRgb(colors[i]);//转换为rgb数组模式
color.r = rgb[0];
color.g = rgb[1];
color.b = rgb[2];
temp.push(color);
}
return temp;
},
//将hex表示方式转换为rgb表示方式(这里返回rgb数组模式)
colorRgb(sColor) {
let reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
sColor = sColor.toLowerCase();
if (sColor && reg.test(sColor)) {
if (sColor.length === 4) {
let sColorNew = "#";
for (let i = 1; i < 4; i += 1) {
sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1));
}
sColor = sColorNew;
}
//处理六位的颜色值
let sColorChange = [];
for (let i = 1; i < 7; i += 2) {
sColorChange.push(parseInt("0x" + sColor.slice(i, i + 2)));
}
return sColorChange;
} else {
return sColor;
}
},
gerColorOfWeight1(minNum,maxNum,colorStart,colorend,number,flag){ //颜色,根据数值均分
let colorR=(colorend["r"]-colorStart["r"])*(number-minNum)/(maxNum-minNum)+colorStart["r"]
let colorG=(colorend["g"]-colorStart["g"])*(number-minNum)/(maxNum-minNum)+colorStart["g"]
let colorB=(colorend["b"]-colorStart["b"])*(number-minNum)/(maxNum-minNum)+colorStart["b"]
let color= ''
if(flag){
color="rgb("+Math.ceil(colorR)+','+Math.ceil(colorG)+','+Math.ceil(colorB)+')'
}else{
color="rgb("+Math.floor(colorR)+','+Math.floor(colorG)+','+Math.floor(colorB)+')'
}
return color
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>