| | |
| | | :maxHeight="tableHeight" |
| | | :cell-style="tableCellStyle" |
| | | :header-cell-style="tableHeaderCellStyle" |
| | | :data="chunkTableData[pager.index - 1]" |
| | | :data="tableData" |
| | | @row-click="recordSelectChange" |
| | | rowClassName="cursor-pointer" |
| | | :spanMethod="objectSpanMethod" |
| | | class="w-full h-full" |
| | | highlightCurrentRow |
| | | :rowClassName="tableRowClassName" |
| | | cellClassName="text-sm" |
| | | headerCellClassName="text-sm" |
| | | > |
| | |
| | | // 添加合计行 |
| | | if (last?.length > 0) { |
| | | const totalRow = new Array(last.length); |
| | | totalRow[0] = '合计'; |
| | | |
| | | let lastGroupIndex = tableCols.value.findLastIndex((item, index) => index !== rateColIndex && index !== valueColIndex); |
| | | lastGroupIndex = lastGroupIndex === -1 ? 0 : lastGroupIndex; |
| | | totalRow[lastGroupIndex] = '合计'; |
| | | // 比例列 |
| | | totalRow[rateColIndex] = '100%'; |
| | | // 合计总数 |
| | | totalRow[valueColIndex] = sumValue + ''; |
| | | |
| | | (totalRow as any).isTotal = true; |
| | | current.push(totalRow); |
| | | } |
| | | } |
| | | return current; |
| | | }; |
| | | |
| | | const tableRowClassName = ({ row, rowIndex }) => { |
| | | let className = 'cursor-pointer'; |
| | | if (row.isTotal) { |
| | | const bgColor = '!bg-[#c5d9f1]'; |
| | | className += ` font-bold ${bgColor} hover:${bgColor} active:${bgColor}`; |
| | | } |
| | | return className; |
| | | }; |
| | | // 统计表格,需要增加累计值行,以及比例列 |
| | | const tableValues = ref(getTableValues(props.data)); |
| | |
| | | return values; |
| | | } |
| | | |
| | | const groupData = _.groupBy(values, (item, index) => { |
| | | const groupValue = item[curGroupIndex]; |
| | | return groupValue; |
| | | }); |
| | | |
| | | |
| | | const groupData = getItemMap(values,curGroupIndex,true) |
| | | // 顺延下一个分组 |
| | | i++; |
| | | // 重新排布一下位置,保证 group 相邻,同时打上 rowspan |
| | | const result = Object.values(groupData).reduce((preVal, curVal) => { |
| | | const result = Object.values(Array.from(groupData.values())).reduce((preVal, curVal) => { |
| | | curVal.map((item, index) => { |
| | | // 行列作为 key |
| | | const key = `${j + index},${curGroupIndex}`; |
| | |
| | | j += curVal.length; |
| | | return preVal; |
| | | }, []); |
| | | return result; |
| | | }; |
| | | |
| | | const getItemMap = <T>(arr: T[], defaultProps = 'ID', isMultiple = false) => { |
| | | if (!arr || arr.length === 0) return {}; |
| | | |
| | | const result = arr.reduce((acc, curr) => { |
| | | if (isMultiple) { |
| | | if (!acc.get(curr[defaultProps])) { |
| | | acc.set(curr[defaultProps], [curr]); |
| | | } else { |
| | | {/* acc[curr[defaultProps]].push(curr); */} |
| | | acc.get(curr[defaultProps]).push(curr); |
| | | } |
| | | } else { |
| | | acc.set(curr[defaultProps], curr); |
| | | } |
| | | return acc; |
| | | }, new Map()) as Map<string, T | T[]>; |
| | | |
| | | return result; |
| | | }; |
| | | |
| | |
| | | // 计算每一列最长的标题字符串和标题字符串长度 |
| | | for (const item of tableValues.value) { |
| | | item.map((subItem, index) => { |
| | | const subItemLen = subItem?.gblen(); |
| | | // subItem 可能是 数字 |
| | | const subItemLen = (subItem +'')?.gblen(); |
| | | if (maxLenList[index] < subItemLen) { |
| | | maxLenList[index] = subItemLen; |
| | | maxStrList[index] = subItem; |
| | |
| | | } |
| | | if (tableCols.value.length > 0) { |
| | | cellRowSpanMap.clear(); |
| | | tableValues.value = buildGroupData(tableValues.value); |
| | | // tableValues.value = buildGroupData(tableValues.value); |
| | | calcColWidth(width); |
| | | nextTick(() => { |
| | | calcPagerHeight(); |
| | |
| | | tableRef.value.doLayout(); |
| | | |
| | | // pager.index = 1; |
| | | chunkTableData.value = _.chunk(tableValues.value ?? [], pager.size); |
| | | chunkTableData.value = (_.chunk(tableValues.value ?? [], pager.size)); |
| | | }; |
| | | |
| | | //#endregion |
| | | |
| | | const tableData = computed(()=>buildGroupData(chunkTableData.value[pager.index - 1])) |
| | | |
| | | const reloadTable = () => { |
| | | // 重新计算宽度 |
| | |
| | | groupTitle = groupCols[groupCols.length - 1].title; |
| | | |
| | | const data = groupValues.map((item) => { |
| | | const groupName = item.filter((item, index) => !excludeIndex.includes(index) && index !== valueColIndex).join(','); |
| | | const groupName = item.filter((item, index) => !excludeIndex.includes(index) && index !== valueColIndex).join('_'); |
| | | const value = item[valueColIndex]; |
| | | return { |
| | | value, |
| | |
| | | }); |
| | | |
| | | return data; |
| | | }; |
| | | |
| | | const getTooltip = () => { |
| | | return { |
| | | trigger: 'item', |
| | | valueFormatter: (value) => `${value} / ${toPercent(sumValue === 0 ? 0 : (value as number) / sumValue, true, 2)}`, |
| | | } as any; |
| | | }; |
| | | |
| | | const getCommonOption = () => { |
| | |
| | | // orient:'vertical', |
| | | top: 33, |
| | | left: 'center', |
| | | }, |
| | | tooltip: { |
| | | trigger: 'item', |
| | | valueFormatter: (value) => `${value} / ${toPercent(sumValue === 0 ? 0 : (value as number) / sumValue, true, 2)}`, |
| | | }, |
| | | } as echarts.EChartsOption; |
| | | }; |
| | |
| | | // return value; |
| | | // } |
| | | // }, |
| | | width:86, |
| | | overflow:'truncate', |
| | | width: 86, |
| | | overflow: 'truncate', |
| | | // nameTruncate: { |
| | | // maxWidth: 52, |
| | | // }, |
| | |
| | | } |
| | | |
| | | const option: echarts.EChartsOption = { |
| | | ...getCommonOption, |
| | | tooltip: getTooltip(), |
| | | ...getCommonOption(), |
| | | |
| | | toolbox: { |
| | | show: true, |
| | | feature: { |
| | |
| | | activeChartType = ChartTypeEnum.Bar; |
| | | chartInstance.value.setOption( |
| | | { |
| | | ...getCommonOption, |
| | | tooltip: getTooltip(), |
| | | ...getCommonOption(), |
| | | |
| | | toolbox: option.toolbox, |
| | | ...getBarOption(chartData), |
| | |
| | | activeChartType = ChartTypeEnum.Pie; |
| | | chartInstance.value.setOption( |
| | | { |
| | | ...getCommonOption, |
| | | tooltip: getTooltip(), |
| | | ...getCommonOption(), |
| | | toolbox: option.toolbox, |
| | | ...getPieOption(chartData), |
| | | }, |