import { Widget } from "./Widget";
import * as echarts from "echarts";
import { List } from "../dataType/List";
import { PrintObject } from "../models/PrintObject";
import { Http } from "../Http";
import { AstHelper } from "@gvol-org/geovis-brain-core";
/**
* @class ui.Chart
* @since ui
*/
export class Chart extends Widget {
chartType: string = 'scatter';; //图表类型:bar,line,pie,scatter,radar,gauge等
options: object; //选项
seriesNames: any;
cht: any;
values: Array<object>;
axis: number;
xLabels: any;
/**
* 图表组件
* @hideconstructor
* @param {Array<Array<object>>} [dataTable] 构造图表的数组数据
* @param {string} [chartType] 图表类型,如:bar,line,pie等
* @param {object} [options] 图表选项
* @returns ui.Chart
*/
constructor(dataTable?: Array<Array<any>> | List<any>, chartType?: string, options?: object) {
let div;
if (typeof process === 'undefined') {
//浏览器环境
div = document.createElement("div");
div.style.width = "100%";
div.style.height = "300px";
div.classList.add('ui-chart-div');
}
super(div);
if (!(this instanceof Chart)) {
return new Chart(dataTable, chartType, options);
}
if (typeof process === 'undefined') {
let myChart = echarts.init(this.el as HTMLElement);
this.cht = myChart;
if (dataTable instanceof PrintObject) {
if (dataTable["order"]) {
dataTable['chain'] = AstHelper.relativeChain(dataTable["order"]);
}
this.cht.showLoading({
text: '图表生成中...',
color: '#ccc',
textColor: '#000',
maskColor: 'rgba(255, 255, 255, 0.3)',
zlevel: 0,
});
//请求接口
// let codeContent = "print(" + dataTable['expressions'] + ");";
// Http.getPrintRequest(codeContent).then(response => {
// console.log("chart构造函数获取数据", response);
// if (response) {
// this.cht.hideLoading();
// dataTable=response.prints[0];
Http.getPrintRequest(dataTable['chain']).then(response => {
console.log("chart构造函数获取数据", response);
if (response && response.data.status == 'success') {
this.cht.hideLoading();
dataTable = response.data.detail;
/* 返回数据需为以下格式
dataTable= [
[{ "label": "year", "type": "string" }, { "label": "0.0-1.22:裸地", "type": "number" }, { "label": "1.23-1.50:低等植被长势", "type": "number" }, { "label": "1.5-1.75:中等植被长势", "type": "number" }, { "label": "1.75-2.0:较高植被长势", "type": "number" }, { "label": "2.0-4.0:高等植被长势", "type": "number" }],
["2020", 2.578709716809507, 33.32349489165202, 48.01429897591766, 9.752853693549952, 6.361170965907709],
["2021", 2.284657853412817, 25.774618916786412, 46.651513046034715, 13.76110115428395, 11.561510519406642],
["2022", 2.208449727129774, 19.796828302278143, 49.17050662898666, 17.880108798682926, 10.97386249845042]
];*/
this.setVasAndLabel(dataTable);
this.setChartType(this.chartType);
}
});
this.values = [[]];
this.xLabels = [];
}
else {
this.setVasAndLabel(dataTable);
}
if (chartType) {
this.setChartType(chartType);
}
if (options) {
this.setOptions(options);
}
}
}
/**
* 获取图表类型
* @return {String} String
*/
getChartType() {
return this.chartType;
}
/**
* 获取图表选项
* @return {String} Object
*/
getOptions() {
return this.options;
}
/**
* 设置图表类型
* @param {String} chartType 设置的图表类型
* @return ui.Chart
*/
setChartType(chartType: string) {
this.chartType = chartType;
this.set();
return this;
}
/**
* 设置图表的选项
* @param {Object} options 设置的图表的选项
* @return ui.Chart
*/
setOptions(options: object) {
this.options = options;
this.set();
return this;
}
/**
* 设置图表图例
* @param {any} seriesNames 设置图表图例的内容
* @return ui.Chart
*/
setSeriesNames(seriesNames: any) {
this.seriesNames = seriesNames;
this.set();
return this;
}
private set() {
if (this.cht) {
let option = {
toolbox: {
show: true,
feature: {
saveAsImage: { title: "保存为图片" },
dataView: { title: "数据视图", lang: ['数据视图', '关闭', '刷新'] },
},
},
legend: {
bottom: 0,
type: 'scroll'
},
grid: {
left: '20%',
right: '20%'
},
};
if (this.chartType === "pie") {
option["tooltip"] = {
trigger: "item",
formatter: "{a} <br/>{b} : {c} ({d}%)",
};
} else {
option["tooltip"] = {
trigger: "axis",
valueFormatter: (value: any) => {
value = parseFloat(value);
return value.toFixed(3);
}
};
if (this.chartType === "radar") {
option["radar"] = {
center: ["50%", "50%"],
radius: 80,
indicator: this.generateData(this.xLabels),
};
} else {
option["xAxis"] = {
type: "category",
data: this.xLabels,
};
option["yAxis"] = {
type: "value",
axisLine: {
show: true,
},
};
}
}
if (this.values) {
let ses: any[] = [];
let k: number = 0;
this.values.forEach((item: any) => {
if (this.chartType === "pie") {
item = this.generateData(this.xLabels, item);
}
if (this.chartType === "radar") {
item = {
value: item,
name: this.seriesNames != null ? this.seriesNames[k] : "",
};
ses.push(item);
} else {
ses.push({
data: item,
type: this.chartType,
radius: "65%",
});
}
k++;
});
if (this.chartType === "radar") {
option["series"] = {
type: "radar",
tooltip: {
trigger: "item",
},
data: ses,
};
} else {
option["series"] = ses;
}
}
if (this.seriesNames) {
if ( option["series"]) {
for (let index = 0; index < option["series"].length; index++) {
const element = option["series"][index];
element["name"] = this.seriesNames[index];
}
}
}
if (this.options) {
if (this.options["title"]) {
option["title"] = {
text: this.options["title"],
left: "center",
};
}
if (this.options["xAxis"]) {
option["xAxis"] = this.options["xAxis"];
if (this.xLabels) {
option["xAxis"]['type'] = "category";
option["xAxis"]['data'] = this.xLabels;
}
}
if (this.options["yAxis"]) {
option["yAxis"] = this.options["yAxis"];
}
if (this.options["series"]) {
if (option["series"]) {
for (const key in this.options["series"]) {
let obj = this.options["series"][key];
if (option["series"][key]) {
for (const item in obj) {
if (item == "color") {
option["series"][key]["itemStyle"] = {};
option["series"][key]["itemStyle"][item] = obj[item];
}
else if (item == "lineColor" || item == "lineWidth") {
option["series"][key]["lineStyle"] = {};
option["series"][key]["lineStyle"][item.replace('line', '').toLowerCase()] = obj[item];
}
else {
option["series"][key][item] = obj[item];
}
}
}
// option["series"][key] = option["series"][key];
}
}
else {
option["series"] = this.options["series"];
}
}
if (this.options["isStacked"]) {
//堆叠
option["series"].forEach((element: any) => {
element["stack"] = "total";
});
}
if (this.options["colors"]) {
//颜色
for (let index = 0; index < this.options["colors"].length; index++) {
const color = this.options["colors"][index];
if (option["series"][index]) {
option["series"][index]["itemStyle"] = {};
option["series"][index]["itemStyle"]["color"] = color;
}
}
}
}
// console.log("option",JSON.stringify(option));
if (this.chartType == "radar" || this.chartType == "pie") {
this.cht.clear();
}
this.cht.setOption(option);
}
}
private generateData(labels: [], data?: []) {
let res = [];
for (let index = 0; index < labels.length; index++) {
const name = labels[index];
if (data && data[index]) {
const value = data[index];
res.push({ name: name, value: value });
} else {
res.push({ name: name });
}
}
return res;
}
private transposition(arr: any) {
//数组行列互换
const newArr = arr[0].map((col: any, i: any) => arr.map((row: any) => row[i]));
return newArr;
}
private getSeries(labels: any) {
let arrs: any = [];
let maxLegth = 0;
labels.forEach((label: any) => {
let arr = [];
for (let index = 0; index < this.xLabels.length; index++) {
const element = this.xLabels[index];
if (element == label) {
arr.push(index);
}
}
arrs.push(arr);
if (arr.length > maxLegth) {
maxLegth = arr.length;
}
});
let series = [];
for (let j = 0; j < maxLegth; j++) {
let sers: any = [];
arrs.forEach((a: any) => {
if (j < a.length) {
sers.push(this.values[0][a[j]]);
}
else {
sers.push(0);
}
});
series.push(sers);
}
console.log("去重后的series", series);
return series;
}
private setVasAndLabel(dataTable: any) {
if (dataTable && dataTable['length'] > 0) {
//创建
let values = [];
this.axis = 0;
let labels = [];
for (let index = 0; index < dataTable['length']; index++) {
const element = dataTable[index];
if (index == 0) {
//表头
let seriesNames = element.map((item: any) => { return item['label'] });
let names = seriesNames.slice(0);
names.shift();
this.seriesNames = names;
}
else {
labels.push(element[0]);
let ele = element.slice(0);
ele.shift();
values.push(ele);
}
}
this.values = this.transposition(values);
this.xLabels = labels;
}
}
}