fastlion-amis
Version:
一种MIS页面生成工具
395 lines (394 loc) • 12.4 kB
text/typescript
import { standardValueText, uuid } from "../../../utils/helper";
type ChartProps = {
type: string,
selectedXAxisData: string | string[],
selectedYAxisData: string[],
data: obj[],
columns: any[],
primaryField: string,
barValue?: string[],
chartTitle: string
}
export const getChartSchema = ({ type, selectedXAxisData, selectedYAxisData, data, columns, primaryField,
barValue, chartTitle }: ChartProps) => {
let defaultSchame: obj = {}
if(['line', 'bar', 'area', 'bar-vertical', 'line-bar'].includes(type)) {
defaultSchame = {
"height": "100%",
"width": "100%",
"type": "chart",
"name": uuid(),
"className": "w-full",
"config": {
"title": [
{
// subtext: chartTitle,
left: "4%",
text: chartTitle
}
],
"legend": {
// "top": "2%",
"bottom": "2%",
"show": true,
"data": ['a']
},
"tooltip": {
"show": true,
"trigger": "axis"
},
"series": [],
"xAxis": {
data: ['1'],
type: 'category'
},
"yAxis": {},
"grid": {
"left": "5%",
"containLabel": true
},
"dataZoom": [],
"toolbox": {
"feature": {
// "saveAsImage": {
// "show": true,
// "type": "png"
// },
// "myExport": {
// "show": true,
// "api": {
// "method": "post",
// "url": "/api/v1/export/PAGE_CHARTS_LINE/download/default_export?keepDataFormat=true&exportType=1&exportFields=REPORT_DATE,CREATE_ORDER_CNT,SENT_ORDER_CNT,COMMIT_ORDER_CNT&dataFilterPageId=PAGE_CHARTS_LINE&p_n=PAGE_CHARTS_LIST,PAGE_CHARTS_LINE"
// },
// "title": chartTitle
// }
}
},
"color": colorList
}
}
const xAxis = data.map(item => item[selectedXAxisData as string]);
const targetCol = columns.find(item => item.name === (selectedXAxisData as string));
if(type === 'bar-vertical') {
const targetCol = columns.find(item => item.name === (selectedXAxisData as string));
defaultSchame.config.yAxis = {
data: xAxis,
type: 'category',
name: targetCol.label || selectedXAxisData,
nameLocation: 'end'
}
defaultSchame.config.xAxis = {}
} else {
defaultSchame.config.xAxis = {
data: xAxis,
type: 'category',
name: targetCol.label || selectedXAxisData,
nameLocation: 'end'
}
}
defaultSchame.config.legend.data = selectedYAxisData.map(item => columns.find(col => col.name === item)?.label || item);
const series = selectedYAxisData.map((yAxisItem, index) => {
return {
data: data.map(item => item[yAxisItem]),
type: getItemType(type === 'line-bar' ? (barValue?.includes(yAxisItem) ? 'bar' : 'line') : type),
smooth: type === 'area' ? 0.5 : 0,
name: columns.find(col => col.name === yAxisItem)?.label || yAxisItem,
areaStyle: type === 'area' ? { "color": areaColorList[index] } : null,
label: {
formatter: function(params: any) {
const findCol = columns.find(col => col.name === yAxisItem)
const { prefix, suffix, kilobitSeparator, precision, pristine } = findCol;
return standardValueText(params.value, {
prefix: prefix || pristine.prefix,
suffix: suffix || pristine.suffix,
kilobitSeparator: kilobitSeparator || pristine.kilobitSeparator,
precision: precision || pristine.precision
})
},
position: 'top',
show: true
},
tooltip: {
valueFormatter: function(value: any) {
const [_, val] = formatValue(value, yAxisItem, columns);
return val;
}
}
}
})
defaultSchame.config.series = series as any;
}
//散点图
if(['scatter', 'scatter-size'].includes(type)) {
defaultSchame = {
"height": "100%",
"width": "100%",
"type": "chart",
"name": uuid(),
"className": "w-full",
config: {
"title": [
{
// subtext: chartTitle,
left: "4%",
text: chartTitle
}
],
"legend": {
"bottom": "2%"
},
"tooltip": {
formatter: function(params: any) {
const [keyCol, keyValue] = formatValue(params.value[2], primaryField, columns);
const [xCol, xColValue] = formatValue(params.value[0], selectedXAxisData[0], columns);
const [yCol, yColValue] = formatValue(params.value[1], selectedXAxisData[1], columns);
let showValue = '';
let showField: any = {};
if(selectedYAxisData[0]) {
const [col, val] = formatValue(params.value[3], selectedYAxisData[0], columns);
showField = col;
showValue = val;
}
return keyCol.label + ': '+ keyValue + '<br/>' + xCol.label + ': ' + xColValue + '<br/>' + yCol.label + ': ' + yColValue + (showValue ? '<br/>' + showField.label + ': ' + showValue : '')
},
"show": true,
"trigger": "item"
},
"series": [
{
"data": [
[
28604,
77,
"Australia\r"
]
],
"symbolSize": 20,
"type": "scatter"
}
],
"xAxis": {
"type": "value"
},
"yAxis": {
"type": "value"
},
"grid": {
"left": "5%",
"containLabel": true
},
"dataZoom": [],
"toolbox": {}
}
}
const series = data.map(item => [item[selectedXAxisData[0]], item[selectedXAxisData[1]], item[primaryField || selectedXAxisData[0]], item[selectedYAxisData[0]]])
defaultSchame.config.series = [
{
symbolSize: type === 'scatter-size' ? function (data: obj[]) {
return data[3];
} : 20,
type: "scatter",
data: series
}
]
const xCol = columns.find(item => item.name === (selectedXAxisData[0]));
const yCol = columns.find(item => item.name === (selectedXAxisData[1]));
defaultSchame.config.xAxis = {
type: "value",
name: xCol?.label || selectedXAxisData[0],
nameLocation: 'end'
}
defaultSchame.config.yAxis = {
type: "value",
name: yCol?.label || selectedXAxisData[1],
nameLocation: 'end'
}
}
//饼图,环形图
if(['pie', 'ring'].includes(type)) {
defaultSchame = {
"height": "100%",
"width": "100%",
"type": "chart",
"name": uuid(),
"className": "w-full",
config: {
"title": [
{
// "subtext": chartTitle,
"left": "4%",
"text": chartTitle
}
],
"legend": {
"bottom": "2%"
},
"tooltip": {
"trigger": "item"
},
"series": [
{
"data": [
{
"CREATE_ORDER_CNT": 20,
"REPORT_DATE": "20240102",
"name": "男装",
"value": 20,
"TYPE": "男装"
}
],
"avoidLabelOverlap": true,
"tooltip": {
"valueFormatter": "function (value) { return window._standardValueText(value, {prefix:'',suffix:'',kilobitSeparator:null,precision:0}) }"
},
"label": {
"formatter": "{b} {d}%"
},
"type": "pie",
"radius": "20%"
}
],
"toolbox": {}
}
}
const series = data.map(item => ({
value: item[selectedYAxisData[0]],
name: item[selectedXAxisData as string]
}))
defaultSchame.config.series = [{
"avoidLabelOverlap": true,
"tooltip": {
"valueFormatter": function(value: any) {
const [_, val] = formatValue(value, selectedYAxisData[0], columns)
return val;
}
},
"label": {
"formatter": "{b} {d}%"
},
"type": getItemType(type),
"radius": type === 'ring' ? ["50%", "70%"] : "40%" ,
data: series
}];
}
//漏斗图
if(['funnel'].includes(type)) {
defaultSchame = {
"height": "100%",
"width": "100%",
"type": "chart",
"name": uuid(),
"className": "w-full",
config: {
"title": [
{
"subtext": chartTitle,
"left": "4%"
}
],
"legend": {
"bottom": "2%"
},
"tooltip": {
"trigger": "item"
},
"series": [
{
"data": [
{
"name": "确认订单金额",
"tooltip": {
"valueFormatter": "function (value) { return window._standardValueText(value, {prefix:'¥',suffix:'',kilobitSeparator:false,precision:2}) }"
},
"value": 3146
},
{
"name": "发货订单金额",
"tooltip": {
"valueFormatter": "function (value) { return window._standardValueText(value, {prefix:'¥',suffix:'',kilobitSeparator:false,precision:2}) }"
},
"value": 4146
},
{
"name": "创建订单金额",
"tooltip": {
"valueFormatter": "function (value) { return window._standardValueText(value, {prefix:'¥',suffix:'',kilobitSeparator:false,precision:2}) }"
},
"value": 2146.78
}
],
"type": "funnel"
}
],
"toolbox": {},
"color": colorList
}
}
const series = data.map(dataItem => {
return {
name: dataItem[selectedXAxisData as string],
value: dataItem[selectedYAxisData[0]],
tooltip: {
valueFormatter: function(value: any) {
const [_, val] = formatValue(value, selectedYAxisData[0], columns)
return val;
}
}
}
})
defaultSchame.config.series = [{
data: series,
type: getItemType(type)
}]
}
return defaultSchame
}
const getItemType = (type: string) => {
switch (type) {
case 'area':
case 'line':
return 'line';
case 'bar-vertical':
case 'bar':
return 'bar';
case 'scatter':
case 'scatter-size':
return 'scatter';
case 'pie':
case 'ring':
return 'pie';
case 'funnel':
return 'funnel';
default:
return 'line';
}
}
const formatValue = (value: string, fieldName: string, columns: any[]) => {
const targetCol = columns.find(item => item.name === fieldName);
const { prefix, suffix, kilobitSeparator, precision, pristine } = targetCol;
const keyValue = standardValueText(value, {
prefix: prefix || pristine.prefix,
suffix: suffix || pristine.suffix,
kilobitSeparator: kilobitSeparator || pristine.kilobitSeparator,
precision: precision || pristine.precision
})
return [targetCol, keyValue]
}
const colorList = [
"#F5222D",
"#9254DE",
"#0958D9",
"#08979C",
"#EB2F96",
"#FAAD14",
"#ee6666",
"#7CB305",
"#ADC6FF",
"#fc8452",
"#5CDBD3"
]
const areaColorList = [
'rgba(245,34,45, 0.5)', 'rgba(146,84,222, 0.5)', 'rgba(9, 88, 217, 0.5)', 'rgba(8, 151, 156, 0.5)',
'rgba(235,47,150, 0.5)', 'rgba(250,173,20, 0.5)', 'rgba(238,102,102, 0.5)', 'rgba(124,179,5, 0.5)',
'rgba(173, 198, 255, 0.5)', 'rgba(252,132,82, 0.5)','rgba(92,219,211, 0.5)'
]