加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
index.ts 10.77 KB
一键复制 编辑 原始数据 按行查看 历史
xuliangzhan 提交于 2024-05-27 13:55 . fix
import { h } from 'vue'
import XEUtils from 'xe-utils'
import { VXETableCore, VxeTableDefines, VxeGlobalInterceptorHandles, VxeGlobalMenusHandles } from 'vxe-table'
let VXETableInstance: VXETableCore
let globalEcharts: any
interface CMItem {
id: string;
$chart: any;
}
declare module 'vxe-table' {
export interface TableInternalData {
_chartModals: CMItem[];
}
}
function createChartModal (getOptions: (params: VxeGlobalMenusHandles.MenuMethodParams) => any) {
const menuOpts: VxeGlobalMenusHandles.MenusOption = {
menuMethod (params) {
const { $table, menu } = params
const { internalData } = $table
let { _chartModals } = internalData
if (!_chartModals) {
_chartModals = internalData._chartModals = []
}
const cmItem: CMItem = {
id: XEUtils.uniqueId(),
$chart: null
}
_chartModals.push(cmItem)
if (VXETableInstance.modal) {
VXETableInstance.modal.open({
id: cmItem.id,
resize: true,
mask: false,
lockView: false,
escClosable: true,
width: 600,
minWidth: 500,
height: 400,
minHeight: 300,
title: menu.name,
showZoom: true,
className: 'vxe-table--ignore-areas-clear vxe-table--charts',
slots: {
default () {
return [
h('div', {
class: 'vxe-chart--wrapper'
}, [
h('div', {
class: 'vxe-chart--panel'
})
])
]
}
},
onShow (evntParams) {
const { $modal } = evntParams
const { refElem } = $modal.getRefMaps()
const elem = refElem.value
const chartElem: HTMLDivElement | null = elem ? elem.querySelector('.vxe-chart--wrapper') : null
if (chartElem) {
const $chart = (globalEcharts || (window as any).echarts).init(chartElem)
$chart.setOption(getOptions(params))
cmItem.$chart = $chart
}
},
onHide (evntParams) {
const { $modal } = evntParams
XEUtils.remove(_chartModals, item => item.id === $modal.props.id)
if (cmItem.$chart) {
cmItem.$chart.dispose()
cmItem.$chart = null
}
},
onZoom () {
if (cmItem.$chart) {
cmItem.$chart.resize()
}
}
})
}
}
}
return menuOpts
}
interface legendOpts {
data: any[];
}
const menuMap = {
CHART_BAR_X_AXIS: createChartModal((params) => {
const { $table, menu } = params
const cellAreas = $table.getCellAreas()
const { rows, cols } = cellAreas[0]
const { params: chartParams = {} } = menu
const { category } = chartParams
const categoryColumn = $table.getColumnByField(category) || cols[0]
const serieColumns = cols.filter((column) => column.field !== categoryColumn.field)
const legendOpts: legendOpts = {
data: []
}
const seriesOpts: any[] = []
const yAxisOpts = {
type: 'category',
data: rows.map((row) => XEUtils.get(row, categoryColumn.field))
}
// const seriesLabel = {
// normal: {
// show: true
// }
// }
serieColumns.forEach((column) => {
legendOpts.data.push(column.title)
seriesOpts.push({
name: column.title,
type: 'bar',
// label: seriesLabel,
data: rows.map((row) => XEUtils.get(row, column.field))
})
})
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
grid: {
left: '4%',
right: '4%',
bottom: '3%',
containLabel: true
},
legend: legendOpts,
xAxis: {
type: 'value'
},
yAxis: yAxisOpts,
series: seriesOpts
}
return option
}),
CHART_BAR_Y_AXIS: createChartModal((params) => {
const { $table, menu } = params
const cellAreas = $table.getCellAreas()
const { rows, cols } = cellAreas[0]
const { params: chartParams = {} } = menu
const { category } = chartParams
const categoryColumn = $table.getColumnByField(category) || cols[0]
const serieColumns = cols.filter((column) => column.field !== categoryColumn.field)
const legendOpts: legendOpts = {
data: []
}
const seriesOpts: any[] = []
const xAxisOpts = {
type: 'category',
data: rows.map((row) => XEUtils.get(row, categoryColumn.field))
}
// const seriesLabel = {
// normal: {
// show: true
// }
// }
serieColumns.forEach((column) => {
legendOpts.data.push(column.title)
seriesOpts.push({
name: column.title,
type: 'bar',
// label: seriesLabel,
data: rows.map((row) => XEUtils.get(row, column.field))
})
})
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
grid: {
left: '4%',
right: '4%',
bottom: '3%',
containLabel: true
},
legend: legendOpts,
xAxis: xAxisOpts,
yAxis: {
type: 'value'
},
series: seriesOpts
}
return option
}),
CHART_LINE: createChartModal((params) => {
const { $table, menu } = params
const cellAreas = $table.getCellAreas()
const { rows, cols } = cellAreas[0]
const { params: chartParams = {} } = menu
const { category } = chartParams
const categoryColumn = $table.getColumnByField(category) || cols[0]
const serieColumns = cols.filter((column) => column.field !== categoryColumn.field)
const legendOpts: legendOpts = {
data: []
}
const seriesOpts: any[] = []
const xAxisOpts = {
type: 'category',
data: rows.map((row) => XEUtils.get(row, categoryColumn.field))
}
serieColumns.forEach((column) => {
legendOpts.data.push(column.title)
seriesOpts.push({
name: column.title,
type: 'line',
data: rows.map((row) => XEUtils.get(row, column.field))
})
})
const option = {
tooltip: {
trigger: 'axis'
},
legend: legendOpts,
grid: {
left: '4%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: xAxisOpts,
yAxis: {
type: 'value'
},
series: seriesOpts
}
return option
}),
CHART_PIE: createChartModal((params) => {
const { $table, menu } = params
const cellAreas = $table.getCellAreas()
const { rows, cols } = cellAreas[0]
const { params: chartParams = {} } = menu
const { category } = chartParams
const categoryColumn = $table.getColumnByField(category) || cols[0]
const serieColumns = cols.filter((column) => column.field !== categoryColumn.field)
const serieColumn = serieColumns[0]
const legendData = rows.map((row) => XEUtils.get(row, categoryColumn.field))
const seriesData: any[] = []
rows.forEach((row) => {
seriesData.push({
name: XEUtils.get(row, categoryColumn.field),
value: XEUtils.get(row, serieColumn.field)
})
})
const option = {
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
legend: {
type: 'scroll',
orient: 'vertical',
right: 10,
top: 20,
bottom: 20,
data: legendData
// selected: data.selected
},
grid: {
left: '4%',
right: '4%',
bottom: '3%',
containLabel: true
},
series: [
{
name: serieColumn.title,
type: 'pie',
radius: '50%',
center: ['40%', '50%'],
data: seriesData
}
]
}
return option
})
}
function checkPrivilege (item: VxeTableDefines.MenuFirstOption | VxeTableDefines.MenuChildOption, params: VxeGlobalInterceptorHandles.InterceptorShowMenuParams) {
const { $table, column } = params
const { code, params: chartParams = {} } = item
switch (code) {
case 'CHART_BAR_X_AXIS':
case 'CHART_BAR_Y_AXIS':
case 'CHART_LINE':
case 'CHART_PIE': {
item.disabled = !column
if (column) {
const cellAreas = $table.getCellAreas()
const validArea = cellAreas.length === 1
item.disabled = !validArea
if (validArea) {
const { rows, cols } = cellAreas[0]
const { category } = chartParams
switch (code) {
case 'CHART_BAR_X_AXIS':
case 'CHART_BAR_Y_AXIS':
case 'CHART_LINE': {
if (category) {
const serieColumns = cols.filter((column) => column.field !== category)
item.disabled = !rows.length || serieColumns.length < 1
} else {
item.disabled = !rows.length || cols.length < 2
}
break
}
case 'CHART_PIE': {
if (category) {
const serieColumns = cols.filter((column) => column.field !== category)
item.disabled = !rows.length || serieColumns.length !== 1
} else {
item.disabled = !rows.length || cols.length !== 2
}
break
}
}
}
}
break
}
}
}
function handleBeforeDestroyEvent (params: VxeGlobalInterceptorHandles.InterceptorParams) {
const { $table } = params
const { internalData } = $table
const { _chartModals } = internalData
if (_chartModals && VXETableInstance.modal) {
_chartModals.slice(0).reverse().forEach((item) => {
VXETableInstance.modal.close(item.id)
})
}
}
function handlePrivilegeEvent (params: VxeGlobalInterceptorHandles.InterceptorShowMenuParams) {
params.options.forEach((list) => {
list.forEach((item) => {
checkPrivilege(item, params)
if (item.children) {
item.children.forEach((child) => {
checkPrivilege(child, params)
})
}
})
})
}
/**
* 基于 vxe-table 表格的扩展插件,支持渲染 echarts 图表
*/
export const VXETablePluginCharts = {
install (vxetable: VXETableCore, options?: {
echarts?: any
}) {
VXETableInstance = vxetable
globalEcharts = options ? options.echarts : null
// 检查版本
if (!/^(4)\./.test(vxetable.version) && !/v4/i.test((vxetable as any).v)) {
console.error('[vxe-table-plugin-charts 4.x] Version vxe-table 4.x is required')
}
vxetable.interceptor.add('unmounted', handleBeforeDestroyEvent)
vxetable.interceptor.add('event.showMenu', handlePrivilegeEvent)
vxetable.menus.mixin(menuMap)
}
}
if (typeof window !== 'undefined' && window.VXETable && window.VXETable.use) {
window.VXETable.use(VXETablePluginCharts)
}
export default VXETablePluginCharts
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化