共计 10893 个字符,预计需要花费 28 分钟才能阅读完成。
//————– 初始数据局部 ——————–
// 拼数据
let series: any = [];
// 寄存多层 x 轴数据的 series
const seriesextends: KeyValue[] = [];
// x 轴的层数
const xlevel: number = details[0].xaxisValue.length;
// 折线图的个数
const yAxisLineNum: number = details[0].yaxisLine.length;
// 柱型图的个数
const yAxisBarNum: number = details[0].yaxisBar.length;
// 最多的 x 的值
const xNum: number = details.length;
// lenged 中 data 的值
const yName: string[] = [];
// 初始化 yAxisLineListObject 的列表
let yAxisLineListObject = {
// yAxisLineValue1:['num1','num2','num3','num4']
};
for (let i: number = 0; i < yAxisLineNum; i++) {
const tempyaxislinevalue: string[] = [];
for (let j = 0; j < details.length; j++) {tempyaxislinevalue.push(details[j].yaxisLine[i].yvalue);
}
yAxisLineListObject = Object.assign({}, yAxisLineListObject, {[details[0].yaxisLine[i].yfield]: tempyaxislinevalue,
});
}
// console.log(yAxisLineListObject);
// 初始化 yAxisBarListObject 的列表
let yAxisBarListObject = {
// yAxisLineValue1:['num1','num2','num3','num4']
};
for (let i: number = 0; i < yAxisBarNum; i++) {
const tempyaxisbarvalue: string[] = [];
for (let j = 0; j < details.length; j++) {tempyaxisbarvalue.push(details[j].yaxisBar[i].yvalue);
}
yAxisBarListObject = Object.assign({}, yAxisBarListObject, {[details[0].yaxisBar[i].yfield]: tempyaxisbarvalue,
});
}
// console.log(yAxisBarListObject);
// 向 series 里填充 y 的折线图数据
for (let i: number = 0; i < Object.keys(yAxisLineListObject).length; i++) {
yName.push(Object.keys(yAxisLineListObject)[i]);
series.push({data: Object.values(yAxisLineListObject)[i],
type: 'line',
name: Object.keys(yAxisLineListObject)[i],
yAxisIndex: 0,
// xAxisIndex: 0,
});
}
// console.log(series);
// 向 series 里填充 y 的柱状图数据
for (let i: number = 0; i < Object.keys(yAxisBarListObject).length; i++) {
yName.push(Object.keys(yAxisBarListObject)[i]);
series.push({data: Object.values(yAxisBarListObject)[i],
type: 'bar',
name: Object.keys(yAxisBarListObject)[i],
yAxisIndex: 1,
// xAxisIndex: 1,
});
}
// 寄存所有层维度数据的数组
const xAxisArray: any = [];
// 先按维度的档次拼接 x 的名字
const tempxaxisname = [];
for (let i: number = 0; i < details.length; i++) {
const tempxaxislevelname: string[] = [];
tempxaxislevelname.push(details[i].xaxisValue[0]);
for (let j: number = 1; j < xlevel; j++) {
tempxaxislevelname.push(tempxaxislevelname[j - 1] + ',' + details[i].xaxisValue[j],
);
}
tempxaxisname.push(tempxaxislevelname);
}
// console.log(tempxaxisname, ‘ 按档次拼接好的 x 的名字 —————‘);
// 设置 x 轴的数据
const xAxisData: any = [
// {value: 星期 1}
];
for (let i: number = 0; i < details.length; i++) {
xAxisData.push({['value']: tempxaxisname[i][xlevel - 1],
['textStyle']: {['fontSize']: 8,
},
});
}
// 分维度取出 x 轴的名字数组
for (let i: number = 0; i < xlevel; i++) {
let tempxxaisvalue: KeyValue = {};
// 该层循环确定一个维度上的名称和所占的单元格的长度
for (let j = 0; j < details.length; j++) {
if (Object.keys(tempxxaisvalue)[Object.keys(tempxxaisvalue).length - 1] ===
tempxaxisname[j][i]
) {
// 如果和最初一位反复,则合并单元格,长度 +1
// console.log("反复,须要合并");
const lastkey =
Object.keys(tempxxaisvalue)[Object.keys(tempxxaisvalue).length - 1];
// console.log(lastkey);
tempxxaisvalue[lastkey]++;
} else {// console.log("不反复,不须要合并");
tempxxaisvalue = Object.assign({}, tempxxaisvalue, {[tempxaxisname[j][i]]: 1,
});
}
}
xAxisArray.push(tempxxaisvalue);
}
// 外层循环走完所有的维度都曾经拼成了一个对象数组,对象外面别离包裹着每一层维度的名称和对应的长度,一个对象就是一个维度
// console.log(
// xAxisArray,
// ‘ 要给多层 x 轴进行渲染的 xAxisArray 对象数据 —————-‘,
// );
xAxisArray.reverse();
// 设置 grid 的值
const grid: any = [
{
top: 100,
bottom: (xlevel + 2) * 30,
},
{
top: 100,
bottom: (xlevel + 2) * 30,
},
];
// 设置多层的 x 轴,配置 series,grid,xAxis,yAxis
const xAxisExtends: any = [];
const yAxisExtends: any = [];
for (let i: number = 0; i < xlevel; i++) {
grid.push({
height: 30,
bottom: (xlevel - i + 1) * 30,
tooltip: {// show: false,},
});
xAxisExtends.push({
type: 'category',
gridIndex: i + 2,
axisLine: {show: false},
axisLabel: {show: false},
axisTick: {show: false},
});
yAxisExtends.push({
type: 'value',
gridIndex: i + 2,
axisLine: {show: false},
axisLabel: {show: false},
axisTick: {show: false},
});
// 以后该维度的名字字符串和对应的所占单元格长度的字符串
const tempsingleXAxisName: string[] = Object.keys(xAxisArray[i]);
const tempsingleXAxisLength: number[] = Object.values(xAxisArray[i]);
// console.log(xAxisArray);
// 顺次填入该维度的所有呈现的名称与匹配的所占单元格的长度
for (let j: number = 0; j < Object.keys(xAxisArray[i]).length; j++) {
// 设置填充进 bar 中的 name 的内容和款式,当长度大于以后 bar 的宽度时,以省略号显示
let tempXAxisname: String = '';
// tempsingleXAxisName[j].substring(tempsingleXAxisName[j].lastIndexOf(',')+1) 为要展现的全副的字符串
if (tempsingleXAxisName[j].substring(tempsingleXAxisName[j].lastIndexOf(',') + 1,
).length >
(tempsingleXAxisLength[j] / xNum) * 100 - 1
)
tempXAxisname =
tempsingleXAxisName[j]
.substring(tempsingleXAxisName[j].lastIndexOf(',') + 1)
.substring(0, Math.floor((tempsingleXAxisLength[j] / xNum) * 100)) +
'..';
else
tempXAxisname = tempsingleXAxisName[j].substring(tempsingleXAxisName[j].lastIndexOf(',') + 1,
);
seriesextends.push({
type: 'bar',
barWidth: (tempsingleXAxisLength[j] / xNum) * 100 + '%',
data: [{name: tempXAxisname, value: 1}],
barGap: 0,
label: {
show: true,
position: 'inside',
formatter: '{b}',
// offset: [0, 10],
},
itemStyle: {
color: 'none',
borderColor: '#000',
borderWidth: 1,
},
animation: false,
tooltip: {formatter: tempsingleXAxisName[j].substring(tempsingleXAxisName[j].lastIndexOf(',') + 1,
),
},
// barWidth:
xAxisIndex: i + 2,
yAxisIndex: i + 2,
});
}
// console.log(series,'+++++++++++');
}
//——————————————————————————————————————
//echarts 中 option 设置
let option: EChartsOption;
option = {
title: {text: titleinfo,},
tooltip: {
trigger: 'item',
axisPointer: {type: 'shadow',},
},
grid: grid,
legend: {data: yName,},
xAxis: [
{
type: 'category',
data: xAxisData,
position: 'bottom',
gridIndex: 0,
nameTextStyle: {fontSize: 8,},
axisTick: {
length: 30,
interval: 0,
},
axisLabel: {show: false},
},
{
type: 'category',
gridIndex: 0,
data: xAxisData,
axisLine: {show: false},
axisLabel: {show: false},
axisTick: {show: false},
},
// 上面都是多的 x 轴
...xAxisExtends,
],
yAxis: [
{
type: 'value',
name: '折线图数据',
gridIndex: 0,
min: 'dataMin',
axisLabel: {formatter: function (value: number) {// console.log(value,'y 轴的值');
// console.log(value.toExponential(2),'解决后的 y 轴的值');
return value.toExponential(1);
},
},
},
{
type: 'value',
name: '柱形图数据',
gridIndex: 0,
position: 'right',
max: 'dataMax',
min: 'dataMin',
axisLabel: {formatter: function (value: number) {// console.log(value,'y 轴的值');
// console.log(value.toExponential(2),'解决后的 y 轴的值');
return value.toExponential(1);
},
},
},
// 上面都是多的 y 轴
...yAxisExtends,
],
series: [...series, ...seriesextends],
toolbox: [
{
feature: {
dataZoom: {
show: true,
// type: ['zoom'],
yAxisIndex: false,
xAxisIndex: 0,
},
},
// right:-25
},
],
};
//———————————————————————————————————————————————————
// 缩放的监听,管制多层 x 轴的变动
myChart.on(‘datazoom’, (params: any) => {
// console.log(xAxisData, 'on 监听外面的 xAxisData----------');
let slicestart: number = 0;
let sliceend: number = 0;
// 回退到最初始的状态时
if (params.batch[0].start === 0) {
slicestart = 0;
sliceend = details.length - 1;
}
// 有 startValue 值的时候(惯例缩放)else if (params.batch[0].startValue) {slicestart = params.batch[0].startValue;
sliceend = params.batch[0].endValue;
}
setdatazoom(slicestart, sliceend);
});
function setdatazoom(slicestart: number, sliceend: number) {
const slicelength: number = sliceend - slicestart + 1;
// 缩放之后的 x 轴的更新的 data
const sliceXAXisData = xAxisData.slice(slicestart, sliceend + 1);
// console.log(
// sliceXAXisData,
// 'sliceXAXisData+++++ 缩放时候的 x 轴的 data 数据 +',
// );
// 寄存所有层维度数据的数组
const slicexAxisArray: any = [];
// 先按维度的档次拼接 x 的名字
const slicetempxaxisname = [];
for (let i: number = slicestart; i < sliceend + 1; i++) {const tempxaxislevelname: string[] = [];
tempxaxislevelname.push(details[i].xaxisValue[0]);
for (let j: number = 1; j < xlevel; j++) {
tempxaxislevelname.push(tempxaxislevelname[j - 1] + ',' + details[i].xaxisValue[j],
);
}
slicetempxaxisname.push(tempxaxislevelname);
}
// console.log(
// slicetempxaxisname,
// '缩放后按档次拼接好的 x 的名字 ---------------',
// );
// 分维度取出 x 轴的名字数组
for (let i: number = 0; i < xlevel; i++) {let tempxxaisvalue: KeyValue = {};
// 该层循环确定一个维度上的名称和所占的单元格的长度
for (let j: number = 0; j < slicetempxaxisname.length; j++) {
if (Object.keys(tempxxaisvalue)[Object.keys(tempxxaisvalue).length - 1
] === slicetempxaxisname[j][i]
) {
// 如果和最初一位反复,则合并单元格,长度 +1
// console.log("反复,须要合并");
const lastkey =
Object.keys(tempxxaisvalue)[Object.keys(tempxxaisvalue).length - 1
];
// console.log(lastkey);
tempxxaisvalue[lastkey]++;
} else {// console.log("不反复,不须要合并");
tempxxaisvalue = Object.assign({}, tempxxaisvalue, {[slicetempxaxisname[j][i]]: 1,
});
}
}
slicexAxisArray.push(tempxxaisvalue);
}
// 外层循环走完所有的维度都曾经拼成了一个对象数组,对象外面别离包裹着每一层维度的名称和对应的长度,一个对象就是一个维度
// console.log(
// slicexAxisArray,
// '缩放时要给多层 x 轴进行渲染的 xAxisArray 对象数据 ----------------',
// );
slicexAxisArray.reverse();
const sliceseriesextends = [];
for (let i: number = 0; i < xlevel; i++) {
// 以后该维度的名字字符串和对应的所占单元格长度的字符串
const slicetempsingleXAxisName: string[] = Object.keys(slicexAxisArray[i],
);
const slicetempsingleXAxisLength: number[] = Object.values(slicexAxisArray[i],
);
// console.log(slicetempsingleXAxisName,'datazoomtempsingleXAxisName..................');
// console.log(slicetempsingleXAxisLength,'datazoomtempsingleXAxisLength..................');
// 顺次填入该维度的所有呈现的名称与匹配的所占单元格的长度
for (
let j: number = 0;
j < Object.keys(slicexAxisArray[i]).length;
j++
) {
// 设置填充进 bar 中的 name 的内容和款式,当长度大于以后 bar 的宽度时,以省略号显示
let slicetempXAxisname: String = '';
//slicetempsingleXAxisName[j].substring(slicetempsingleXAxisName[j].lastIndexOf(',')+1) 为要展现的全副的字符串
if (slicetempsingleXAxisName[j].substring(slicetempsingleXAxisName[j].lastIndexOf(',') + 1,
).length >
(slicetempsingleXAxisLength[j] / slicelength) * 100 - 1
) {
slicetempXAxisname =
slicetempsingleXAxisName[j]
.substring(slicetempsingleXAxisName[j].lastIndexOf(',') + 1)
.substring(
0,
Math.floor((slicetempsingleXAxisLength[j] / slicelength) * 100,
),
) + '..';
} else
slicetempXAxisname = slicetempsingleXAxisName[j].substring(slicetempsingleXAxisName[j].lastIndexOf(',') + 1,
);
sliceseriesextends.push({
type: 'bar',
barWidth: (slicetempsingleXAxisLength[j] / slicelength) * 100 + '%',
data: [{name: slicetempXAxisname, value: 1}],
barGap: 0,
label: {
show: true,
position: 'inside',
formatter: '{b}',
// offset: [0, 10],
},
itemStyle: {
color: 'none',
borderColor: '#000',
borderWidth: 1,
},
animation: false,
tooltip: {formatter: slicetempsingleXAxisName[j].substring(slicetempsingleXAxisName[j].lastIndexOf(',') + 1,
),
},
// barWidth:
xAxisIndex: i + 2,
yAxisIndex: i + 2,
});
}
}
// console.log(sliceseriesextends, 'sliceseriesextends+++++++++++');
myChart.setOption(
{series: [...series, ...sliceseriesextends],
yAxis: [
{
type: 'value',
name: '折线图数据',
gridIndex: 0,
min: 'dataMin',
max: 'dataMax',
axisLabel: {formatter: function (value: number) {// console.log(value,'y 轴的值');
// console.log(value.toExponential(2),'解决后的 y 轴的值');
return value.toExponential(1);
},
},
},
{
type: 'value',
name: '柱形图数据',
gridIndex: 0,
position: 'right',
max: 'dataMax',
min: 'dataMin',
axisLabel: {formatter: function (value: number) {// console.log(value,'y 轴的值');
// console.log(value.toExponential(2),'解决后的 y 轴的值');
return value.toExponential(1);
},
},
},
// 上面都是多的 y 轴
...yAxisExtends,
],
},
{replaceMerge: ['series', 'yAxis'], // 替换合并 series,默认一般合并
},
);
}
//———————————————————————————————————————————————————————————-
// 原始数据 details 的格局
details: [
{
yaxisBar: [
{
yfield: 'firstPassCPU',
yvalue: '1E-14',
},
{
yfield: 'firstPassCPK',
yvalue: '-1E-14',
},
],
yaxisLine: [
{
yfield: 'firstPassCP',
yvalue: '0',
},
],
xaxisValue: [
'20211023',
'AGD142M208-D001',
'1000:GSM824_Idle_Current',
],
},
{
yaxisBar: [
{
yfield: 'firstPassCPU',
yvalue: '8E-15',
},
{
yfield: 'firstPassCPK',
yvalue: '-8E-15',
},
],
yaxisLine: [
{
yfield: 'firstPassCP',
yvalue: '0',
},
],
xaxisValue: [
'20211023',
'AGD142M208-D001',
'1001:GSM824_Max_Pout_0dBm_Drive',
],
},
}