当前位置:网站首页>Cyclic multiple scatter
Cyclic multiple scatter
2022-07-24 08:34:00 【lvxinaidou】
markline & max min yAsix
import {
Component, OnInit } from '@angular/core';
import {
WelcomeService } from './services/welcome.service';
import * as _ from 'lodash';
import {
NzFormatEmitEvent } from 'ng-zorro-antd/tree';
import * as echarts from 'echarts';
import {
HttpClient } from '@angular/common/http';
import {
cloneDeep } from 'lodash';
import {
saveAs } from 'file-saver';
interface TreeNodes {
title: string;
key: string;
expanded?: boolean;
children?: Array<TreeNodes>;
isLeaf?:boolean;
}
export interface TableColumn {
level1: string;
level2: string;
level3: string;
level4: string;
level5: string;
level6: string;
level7: string;
level8: string;
rowspan0?:number;
rowspan1?:number;
rowspan2?:number;
rowspan3?:number;
rowspan4?:number;
isWarning?: any;
}
@Component({
selector: 'app-welcome',
templateUrl: './welcome.component.html',
styleUrls: ['./welcome.component.less']
})
export class WelcomeComponent implements OnInit{
public myTreeChart: any;
public treeCharts: any[] = [];
public chartNames: Array<string> = [];
public nodeValueByTime:Array<any>= [];
public optionsData:any = {
};
public nodes:Array<TreeNodes> = [];
defaultExpandedKeys:Array<string> = [];
defaultCheckedKeys: Array<string> = [];
public startTime:any = new Date(new Date().getTime() - 60*60*24*6*1000);
public endTime:any = new Date(new Date().getTime() - 60*60*24*1000);
date = [this.startTime, this.endTime];
public keyIndex:number = 0;
public tempEquipmentSelectionList: Array<any> = [' Machine 1', ' Machine 2']
public colors: Array<string> = ['#d223e7', '#4962FC', '#4962FC', '#18D070', '#3F77FE', '#01C2F9', '#4962FC', '#4B7CF3' , '#dd3ee5', '#12e78c', '#fe8104', '#01C2F9', '#F4CB29', '#FD9E06']
constructor(
private welcomeService: WelcomeService,
private http: HttpClient
) {
}
ngOnInit() {
// Get the tree list
this.getTreeLists();
// this.getTableData();
}
tableViewData:any = [];
getTableData() {
this.http.get('../assets/jsons/test.json').subscribe((data:any) => {
this.transferTableData(data.table, data.merge);
});
}
transferTableData(table:any, merge:any) {
let tableArray:Array<TableColumn> = [];
table.forEach((item: any) => {
const keysArr = Object.keys(item);
tableArray.push({
level1: item[keysArr[0]],
level2: item[keysArr[1]],
level3: item[keysArr[2]],
level4: item[keysArr[3]],
level5: item[keysArr[4]],
level6: item[keysArr[5]],
level7: item[keysArr[6]],
level8: item[keysArr[7]],
isWarning: true
});
});
merge.forEach((item:any) => {
const rowspanData = item.endRow - item.startRow + 1;
if (item.startCol === 4 && item.endCol === 4) {
tableArray[item.startRow].rowspan4 = rowspanData;
} else if(item.startCol === 3 && item.endCol === 3) {
tableArray[item.startRow].rowspan3 = rowspanData;
} else if(item.startCol === 2 && item.endCol === 2) {
tableArray[item.startRow].rowspan2 = rowspanData;
} else if(item.startCol === 1 && item.endCol === 1) {
tableArray[item.startRow].rowspan1 = rowspanData;
} else if(item.startCol === 0 && item.endCol === 0) {
tableArray[item.startRow].rowspan0 = rowspanData;
this.tableViewData.push(cloneDeep(tableArray).splice(item.startRow, rowspanData));
}
});
console.log( this.tableViewData);
}
public showMarkLineStatus: boolean = false;
showMarkLine() : void {
this.showMarkLineStatus = !this.showMarkLineStatus;
console.log(this.showMarkLineStatus);
this.getEchartOptions();
setTimeout(() => {
this.initCharts(this.nodeValueByTime);
},0);
}
initValue(): void {
this.defaultExpandedKeys = [];
this.defaultCheckedKeys = [];
this.chartNames = [];
this.treeCharts = [];
}
getTreeLists() {
this.welcomeService.getTreesList().subscribe((res:any) => {
this.nodes = res;
this.defaultExpandedKeys = []; // init value
this.defaultCheckedKeys = []; // init value
this.addTreeKey(this.nodes);
this.getDefaultKkeys(this.nodes[0]);
this.defaultCheckedKeys = [this.nodes[0].key];
// Get the data of nodes in different time periods
this.getNodeValueByTime();
});
}
addTreeKey(nodes:any) {
nodes.forEach(((item:any) => {
item.key = this.keyIndex++;
if (item?.children) {
item?.children.forEach((e:any) => {
e.key = this.keyIndex++;
this.addTreeKey((e?.children || []));
})
}
}))
}
getDefaultKkeys(currentNode:any) {
if(currentNode) {
currentNode.checked = true;
}
if (currentNode?.children) {
this.defaultExpandedKeys.push(currentNode.key);
currentNode?.children.forEach((item:any) => {
item.checked = true;
this.getDefaultKkeys(item);
})
}
}
getNodeValueByTime() {
// console.log(this.nodes);
const [startTime, endTime]=[this.startTime.getTime(), this.endTime.getTime()]
// this.initValue();
this.welcomeService.getNodeValueByTime(this.nodes, startTime, endTime, this.tempEquipmentSelectionList).subscribe((res:any) => {
this.nodeValueByTime = res;
console.log(this.nodeValueByTime)
this.getEchartOptions();
setTimeout(() => {
this.initCharts(this.nodeValueByTime);
// console.log(this.nodeValueByTime);
},0)
});
}
initCharts(data:any) {
this.treeCharts = []; // init value
data.forEach((item:any, index:number) => {
const className = `.diagram${
index}`;
// console.log(className);
this.treeCharts.push({
index: index,chartNames: this.chartNames[index], chart: echarts.init(document.querySelector(className) as any)})
});
this.nodeValueByTime.forEach((item:any,index: number) => {
console.log(this.treeCharts[index]);
this.setEchartOptions(this.treeCharts[index].chart, index);
});
}
getEchartOptions() {
let options:any = {
seriesData: [],
legendData:[],
xAxisData: [],
keyTexts: [],
sDatasss:[],
maxValues:[],
minValues: []
}
this.chartNames = []; // init value
this.nodeValueByTime.forEach((item:any, index:number) => {
let sDatas:any = [];
let xDatas:any = [];
let lDatas:any = [];
let sDatass: any = [];
let maxData:any = [];
let minData:any = [];
this.chartNames.push(item.nodeName);
options.keyTexts.push(item.nodeName);
if(item.max) {
maxData.push(item.max);
}
if(item.min){
minData.push(item.min)
}
item.nodeValues.forEach((node:any, index: number) => {
lDatas.push(node.equipment);
let sDatasTemp:any = [];
node.value.forEach((v:any) => {
xDatas.push(this.transferStingDate(v.date)),
v.points.forEach((p:any) => {
sDatasTemp.push([this.transferStingDate(p.time), p.value]);
sDatass.push(p.value);
if (p.value) {
maxData.push(p.value);
minData.push(p.value);
}
const sDatasObj = {
name:node.equipment,
itemStyle: {
color: this.colors[index],
borderColor: '#f00',
borderWidth:5
},
type: 'scatter',
symbolSize: 20,
data: [[this.transferStingDate(p.time), p.value]],
}
const marklineOjb = {
symbol: 'none',
lineStyle:{
type:'solid',color:'red'},
data:[
{
name:'top',yAxis:2},
{
name:'bottom',yAxis: -10}
]
}
if (this.showMarkLineStatus) {
sDatas.push(Object.assign(cloneDeep(sDatasObj), {
markLine:marklineOjb
}))
} else {
sDatas.push(sDatasObj);
}
// sDatas.push({
// name:node.equipment,
// itemStyle: {
// color: this.colors[index],
// borderColor: '#f00',
// borderWidth:5
// },
// type: 'scatter',
// symbolSize: 20,
// data: [[this.transferStingDate(p.time), p.value]],
// markLine: {
// symbol: 'none',
// lineStyle:{type:'solid',color:'red'},
// data:[
// {name:'top',yAxis:-10},
// {name:'bottom',yAxis: 2}
// ]
// }
// })
});
})
// sDatas.push({name:node.equipment, type: 'scatter', symbolSize: 20, data: sDatasTemp})
});
options.seriesData.push(sDatas);
options.xAxisData.push([...new Set(xDatas)]);
options.legendData.push(lDatas);
options.sDatasss.push(sDatass);
options.maxValues.push(maxData);
options.minValues.push(minData);
});
if (this.showMarkLineStatus) {
options.seriesData.forEach((sItem:any, index: number) => {
let maxV:any = Math.max.apply(null,options.maxValues[index].map(Number));
let minV:any = Math.min.apply(null,options.minValues[index].map(Number));
sItem.forEach((currentSeries:any) => {
console.log(currentSeries);
currentSeries.markLine.data[0].yAxis = this.nodeValueByTime[index].max?this.nodeValueByTime[index].max:'none';
currentSeries.markLine.data[1].yAxis = this.nodeValueByTime[index].min?this.nodeValueByTime[index].min:'none';;
})
this.yAxisMax.push(maxV);
this.yAxisMin.push(minV);
})
// console.log(options.seriesData);
// console.log(this.yAxisMax);
// console.log(this.yAxisMin);
}
this.optionsData = options;
// console.log(this.optionsData);
// console.log(this.optionsData.sDatasss);
// console.log(this.optionsData.maxValues);
// console.log(this.optionsData.minValues);
}
public yAxisMax: Array<number> = [];
public yAxisMin: Array<number> = [];
setEchartOptions(myTreeChart:any, index:number){
let yMax:number | null, yMin:number | null;
if(this.yAxisMax[index] && this.yAxisMin[index] && this.showMarkLineStatus) {
yMax = this.yAxisMax[index] + (this.yAxisMax[index]-this.yAxisMin[index])/2;
yMin = this.yAxisMin[index] - (this.yAxisMax[index]-this.yAxisMin[index])/2;
// yMax = this.yAxisMax[index];
// yMin = this.yAxisMin[index];
} else {
yMax = null;
yMin = null;
}
if(typeof yMax === 'number') {
yMax = parseInt(yMax.toString(), 10)
}
if(typeof yMin === 'number') {
yMin = parseInt(yMin.toString(), 10)
}
myTreeChart.showLoading();
let setOptionData = {
key: {
text: this.optionsData.keyTexts[index]
},
tooltip: {
trigger: 'axis'
},
legend: {
data: this.optionsData.legendData[index],
itemStyle: {
borderColor: 'none'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
name: ' date ',
nameLocation: 'end',
axisTick: {
alignWithLabel: true },
axisLine: {
symbol: ['none', 'arrow'], symbolOffset: 10, symbolSize: [6, 15], onZero: true },
data: this.optionsData.xAxisData[index]
},
yAxis: {
type: 'value',
grid: {
top: '200' },
axisLine: {
symbol: ['none', 'arrow'], show: true, symbolOffset: 10, symbolSize: [6, 15], onZero: true },
max: yMax,
min: yMin
},
series: this.optionsData.seriesData[index],
graphic: {
type: 'text', // type : Text
left: 'center',
top: 'middle',
silent: true, // Not responding to events
invisible: this.optionsData.sDatasss[index].every((item:any)=>{
return item!==""}), // Data is hidden
style: {
fill: '#9d9d9d',
fontWeight: 'bold',
text: ' Temporarily no data ',
fontFamily: 'Microsoft YaHei',
fontSize: '25px'
}
}
}
console.log(setOptionData);
myTreeChart.clear();
myTreeChart.setOption(setOptionData);
myTreeChart.hideLoading();
}
downloadImage() {
const canvasLists = document.querySelectorAll('canvas');
console.log(canvasLists);
if (canvasLists && canvasLists.length) {
const mainCanvas = document.createElement('canvas');
const mcContext = mainCanvas.getContext('2d');
if (mcContext) {
mainCanvas.width = 1500;
mainCanvas.height = 500 * canvasLists.length;
mcContext.fillStyle = 'white';
mcContext.fillRect(0, 0 , mainCanvas.width, mainCanvas.height);
(canvasLists || []).forEach((item:any, index: number) => {
let row = index;
let column = 0;
mcContext.drawImage(item, column * 600 + 50, row * 400 + 100);
})
let url = mainCanvas.toDataURL('image/png');
let a = document.createElement('a');
a.download = 'test Screenshot of chart ';
a.href = url;
a.click();
}
}
}
nzEvent(event: NzFormatEmitEvent): void {
// console.log(this.nodes);
this.getNodeValueByTime();
}
onChange(result: Date[]): void {
[this.startTime, this.endTime]=[...this.date];
this.getNodeValueByTime();
}
transferStingDate(timestamp:any) {
let date = new Date(timestamp);
return `${
date.getFullYear()}-${
(date.getMonth() + 1 )}-${
date.getDate()}`
}
}
tree.json
[
{
"title": "Ws Base version ",
"children": [
{
"title": "EMBMWA-C1",
"children": [
{
"title": "RA1",
"children": [
{
"title": "Rot", "isLeaf": true },
{
"title": "Mag", "isLeaf": true }
]
},
{
"title": "RA2",
"children": [
{
"title": "Trans X", "isLeaf": true },
{
"title": "Rot", "isLeaf": true },
{
"title": "Mag", "isLeaf": true }
]
},
{
"title": "IS",
"children": [
{
"title": "Trans X", "isLeaf": true },
{
"title": "Rot", "isLeaf": true },
{
"title": "Mag", "isLeaf": true }
]
}
]
}
]
},
{
"title": " Environmental stability check ",
"children": [
{
"title": " from ctlog Extract the following test items ",
"children": [
{
"title": "Plans_ref", "isLeaf": true },
{
"title": "Thens", "isLeaf": true }
]
}
]
}
]
The query value json
[
{
"nodeName": "Rot",
"nodeValues": [
{
"equipment": "mot-008",
"value": [
{
"date": 1640966400000,
"points": [
{
"time": 1640988007000,
"value": "0.98"
},
{
"time": 1640995209000,
"value": "0.38"
}
]
},
{
"date": 1641052800000,
"points": [
{
"time": 1641070809000,
"value": "1.98"
},
{
"time": 1641078008000,
"value": "2.38"
},
{
"time": 1641085207000,
"value": "3.48"
}
]
},
{
"date": 1641139200000,
"points": [
{
"time": 1641175200000,
"value": "2.98"
},
{
"time": 1641168000000,
"value": "4.38"
}
]
},
{
"date": 1641254400000,
"points": [
{
"time": 1641254400000,
"value": "4.98"
},
{
"time": 1641261600000,
"value": "5.38"
}
]
},
{
"date": 1641348000000,
"points": [
{
"time": 1641348000000,
"value": "6.98"
},
{
"time": 1641344400000,
"value": "7.38"
}
]
}
]
},
{
"equipment": "mot-009",
"value": [
{
"date": 1640966400000,
"points": [
{
"time": 1640988007000,
"value": "0.98"
},
{
"time":1640995209000,
"value": "0.38"
},
{
"time": 1641002402000,
"value": "0.48"
},
{
"time": 1641009604000,
"value": "0.58"
}
]
},
{
"date": 1641052800000,
"points": [
{
"time": 1641070809000,
"value": "0.98"
},
{
"time": 1641078008000,
"value": "0.38"
},
{
"time": 1641085207000,
"value": "0.48"
}
]
}
]
}
]
},
{
"nodeName": "Mot",
"nodeValues": [
{
"equipment": "mot-008",
"value": [
{
"date": 1640966400000,
"points": [
{
"time": 1640988007000,
"value": "0.98"
},
{
"time": 1640995209000,
"value": "0.38"
}
]
},
{
"date": 1641052800000,
"points": [
{
"time": 1641070809000,
"value": "1.98"
},
{
"time": 1641078008000,
"value": "2.38"
},
{
"time": 1641085207000,
"value": "3.48"
}
]
},
{
"date": 1641139200000,
"points": [
{
"time": 1641175200000,
"value": "2.98"
},
{
"time": 1641168000000,
"value": "4.38"
}
]
},
{
"date": 1641254400000,
"points": [
{
"time": 1641254400000,
"value": "4.98"
},
{
"time": 1641261600000,
"value": "5.38"
}
]
},
{
"date": 1641348000000,
"points": [
{
"time": 1641348000000,
"value": "6.98"
},
{
"time": 1641344400000,
"value": "7.38"
}
]
}
]
},
{
"equipment": "mot-009",
"value": [
{
"date": 1640966400000,
"points": [
{
"time": 1640988007000,
"value": "0.98"
},
{
"time":1640995209000,
"value": "0.38"
},
{
"time": 1641002402000,
"value": "0.48"
},
{
"time": 1641009604000,
"value": "0.58"
}
]
},
{
"date": 1641052800000,
"points": [
{
"time": 1641070809000,
"value": "0.98"
},
{
"time": 1641078008000,
"value": "0.38"
},
{
"time": 1641085207000,
"value": "0.48"
}
]
}
]
}
]
}
]
html
<section class="welcome-page">
<div>
<nz-range-picker [(ngModel)]="date" (ngModelChange)="onChange($event)"></nz-range-picker>
</div>
<span class="tree">
<nz-tree
[nzData]="nodes"
nzCheckable
nzMultiple
(nzCheckBoxChange)="nzEvent($event)"
[nzExpandedKeys]="defaultExpandedKeys"
[nzCheckedKeys]="defaultCheckedKeys"
></nz-tree>
</span>
<span *ngFor="let echartItem of chartNames; let i = index;" class="{
{'diagram'+ ' ' + 'diagram' + i}}"></span>
<div>
</div>
</section>
ts
import {
Component, OnInit } from '@angular/core';
import {
WelcomeService } from './services/welcome.service';
import * as _ from 'lodash';
import {
NzFormatEmitEvent } from 'ng-zorro-antd/tree';
import * as echarts from 'echarts';
import {
HttpClient } from '@angular/common/http';
interface TreeNodes {
title: string;
key: string;
expanded?: boolean;
children?: Array<TreeNodes>;
isLeaf?:boolean;
}
@Component({
selector: 'app-welcome',
templateUrl: './welcome.component.html',
styleUrls: ['./welcome.component.less']
})
export class WelcomeComponent implements OnInit{
public myTreeChart: any;
public treeCharts: any[] = [];
public chartNames: Array<string> = [];
public nodeValueByTime = [];
public optionsData:any = {
};
public nodes:Array<TreeNodes> = [];
defaultExpandedKeys:Array<string> = [];
defaultCheckedKeys: Array<string> = [];
public startTime:any = new Date(new Date().getTime() - 60*60*24*6*1000);
public endTime:any = new Date(new Date().getTime() - 60*60*24*1000);
date = [this.startTime, this.endTime];
public keyIndex:number = 0;
public tempEquipmentSelectionList: Array<any> = [' Machine 1', ' Machine 2']
constructor(
private welcomeService: WelcomeService,
private http: HttpClient
) {
}
ngOnInit() {
// Get the tree list
this.getTreeLists();
}
initValue() {
this.defaultExpandedKeys = [];
this.defaultCheckedKeys = [];
this.chartNames = [];
this.treeCharts = [];
}
getTreeLists() {
this.welcomeService.getTreesList().subscribe((res:any) => {
this.nodes = res;
this.defaultExpandedKeys = []; // init value
this.defaultCheckedKeys = []; // init value
this.addTreeKey(this.nodes);
this.getDefaultKkeys(this.nodes[0]);
this.defaultCheckedKeys = [this.nodes[0].key];
// Get the data of nodes in different time periods
this.getNodeValueByTime();
});
}
addTreeKey(nodes:any) {
nodes.forEach(((item:any) => {
item.key = this.keyIndex++;
if (item?.children) {
item?.children.forEach((e:any) => {
e.key = this.keyIndex++;
this.addTreeKey((e?.children || []));
})
}
}))
}
getDefaultKkeys(currentNode:any) {
if (currentNode?.children) {
this.defaultExpandedKeys.push(currentNode.key);
currentNode?.children.forEach((item:any) => {
this.getDefaultKkeys(item);
})
}
}
getNodeValueByTime() {
console.log(this.nodes);
const [startTime, endTime]=[this.startTime.getTime(), this.endTime.getTime()]
// this.initValue();
this.welcomeService.getNodeValueByTime(this.nodes, startTime, endTime, this.tempEquipmentSelectionList).subscribe((res:any) => {
this.nodeValueByTime = res;
console.log(this.nodeValueByTime)
this.getEchartOptions();
setTimeout(() => {
this.initCharts(this.nodeValueByTime);
console.log(this.nodeValueByTime);
},0)
});
}
initCharts(data:any) {
this.treeCharts = []; // init value
data.forEach((item:any, index:number) => {
const className = `.diagram${
index}`;
console.log(className);
this.treeCharts.push({
index: index,chartNames: this.chartNames[index], chart: echarts.init(document.querySelector(className) as any)})
});
this.nodeValueByTime.forEach((item:any,index: number) => {
this.setEchartOptions(this.treeCharts[index].chart, index);
});
}
getEchartOptions() {
let options:any = {
seriesData: [],
legendData:[],
xAxisData: [],
keyTexts: [],
}
this.chartNames = []; // init value
this.nodeValueByTime.forEach((item:any, index:number) => {
let sDatas:any = [];
let xDatas:any = [];
let lDatas:any = [];
this.chartNames.push(item.nodeName);
options.keyTexts.push(item.nodeName);
item.nodeValues.forEach((node:any) => {
lDatas.push(node.equipment);
let sDatasTemp:any = [];
node.value.forEach((v:any) => {
xDatas.push(this.transferStingDate(v.date)),
v.points.forEach((p:any) => {
sDatasTemp.push([this.transferStingDate(p.time), p.value]);
});
})
sDatas.push({
name:node.equipment, type: 'scatter', symbolSize: 20, data: sDatasTemp})
});
options.seriesData.push(sDatas);
options.xAxisData.push([...new Set(xDatas)]);
options.legendData.push(lDatas);
});
this.optionsData = options;
console.log(this.optionsData);
}
setEchartOptions(myTreeChart:any, index:number){
myTreeChart.showLoading();
let setOptionData = {
key: {
text: this.optionsData.keyTexts[index]
},
tooltip: {
trigger: 'axis'
},
legend: {
data: this.optionsData.legendData[index]
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
name: ' date ',
nameLocation: 'end',
axisTick: {
alignWithLabel: true },
axisLine: {
symbol: ['none', 'arrow'], symbolOffset: 10, symbolSize: [6, 15], onZero: true },
data: this.optionsData.xAxisData[index]
},
yAxis: {
type: 'value',
grid: {
top: '200' },
axisLine: {
symbol: ['none', 'arrow'], show: true, symbolOffset: 10, symbolSize: [6, 15], onZero: true },
},
series: this.optionsData.seriesData[index]
}
console.log(setOptionData);
myTreeChart.setOption(setOptionData);
myTreeChart.hideLoading();
}
nzEvent(event: NzFormatEmitEvent): void {
console.log(this.nodes);
this.getNodeValueByTime();
}
onChange(result: Date[]): void {
[this.startTime, this.endTime]=[...this.date];
this.getNodeValueByTime();
}
transferStingDate(timestamp:any) {
let date = new Date(timestamp);
return `${
date.getFullYear()}-${
(date.getMonth() + 1 )}-${
date.getDate()}`
}
}
servcies
getNodeValueByTime(nodes:Array<any>, startTime:any, endTime:any, tempEquipmentSelectionList: Array<any>) {
const params = {
startTime: startTime,
endTime: endTime,
nodes: nodes,
tempEquipmentSelectionList:tempEquipmentSelectionList
}
console.log(params);
// let url = `${environment.ASSETS_URL}/${WelcomeConstant.NODE_VALUE_BY_TIME}`
let url = `${
environment.ASSETS_URL}/${
WelcomeConstant.NODE_VLAUE_BY_TIMETAP}`
return this.http.get(url)
// return this.http.post(url, params)
.pipe(
catchError((error => {
return throwError({
errorMessage: 'test error http'})}))
)
}
getTreesList() {
let url = `${
environment.ASSETS_URL}/${
WelcomeConstant.TREE_LIST}`
return this.http.get(url)
.pipe(
catchError((error => {
return throwError({
errorMessage: 'test error http'})}))
)
}
Running effect :
Bulk download echarts chart
downloadImage() {
const canvasLists = document.querySelectorAll('canvas');
console.log(canvasLists);
if (canvasLists && canvasLists.length) {
const mainCanvas = document.createElement('canvas');
const mcContext = mainCanvas.getContext('2d');
if (mcContext) {
mainCanvas.width = 1500;
mainCanvas.height = 500 * canvasLists.length;
mcContext.fillStyle = 'white';
mcContext.fillRect(0, 0 , mainCanvas.width, mainCanvas.height);
(canvasLists || []).forEach((item:any, index: number) => {
let row = index;
let column = 0;
mcContext.drawImage(item, column * 600 + 50, row * 400 + 100);
})
let url = mainCanvas.toDataURL('image/png');
let a = document.createElement('a');
a.download = 'test Screenshot of chart ';
a.href = url;
a.click();
}
}
}
边栏推荐
- Wechat applet file types and functions
- 栈/堆/队列刷题(下)
- Ansible automatic operation and maintenance
- Kotlin学习笔记1——变量、函数
- Selenium webdriver page refresh
- You can't access this shared folder because your organization's security policies prevent unauthenticated guests from accessing it. These policies can help protect your computer from unsafe or malicio
- Brief notes on the key points of distributed system principle introduction
- Figure storage geabase
- 2022.7.11 overall solution
- Typescript decorator
猜你喜欢

2、 Encapsulation and tool classes for adding, deleting, modifying and checking in midway

About the big hole of wechat applet promise

Optimization of MySQL paging query

【一起上水硕系列】June总结+no 焦虑+July计划+如何考试+如何提升

Is gamefi in decline or in the future?

JQ native write bullet frame mask layer
![[wechat applet development (II)] custom navigation bar](/img/87/d390b50d1bd23acee9b46fbe7fe180.png)
[wechat applet development (II)] custom navigation bar

Hack the box - File Inclusion module detailed Chinese tutorial

Why does the metauniverse need NFT?
![[wechat applet development] (I) development environment and applet official account application](/img/94/b93d5fb6d9e3515a1f218cc4ec6eef.png)
[wechat applet development] (I) development environment and applet official account application
随机推荐
Do you know the private domain traffic in app?
mysql SUBSTRING_ Application of index in business scenarios
Shanghai issued a document to support the entry of NFT cultural exchange: the trend of digital collections has arrived!
「题解」蝙蝠侠的麻烦
情人节
Kotin fragment the correct way to get ViewModel instances
[Yum] configuration and use of Yum source
Using golang to implement RPC (1)
Assemble | find the maximum and minimum values
About the big hole of wechat applet promise
Wargames bandit (21-33) problem solving essay
Beandefinition three ways to load beans
Advantages and disadvantages of redis and ZK implementing distributed locks
Larave uses sanctum for API authentication
Wxml template concise tutorial
"Explanation" change exchange
Private traffic + apps, new opportunities for e-commerce drainage
栈/堆/队列刷题(下)
Go: how to gracefully time out
[ByteDance] ByteDance access (including login and payment)