mirror of
https://github.com/dataease/dataease.git
synced 2025-02-25 20:42:55 +08:00
feat: 透视表合计、小计
This commit is contained in:
parent
62f7cdd5e0
commit
e275e533f5
@ -1044,7 +1044,18 @@ export default {
|
||||
value_error: 'Value illegal',
|
||||
threshold: 'Threshold',
|
||||
threshold_range: 'Range',
|
||||
gauge_threshold_format_error: 'Format Error'
|
||||
gauge_threshold_format_error: 'Format Error',
|
||||
total_cfg: 'Total Config',
|
||||
col_cfg: 'Column',
|
||||
row_cfg: 'Row',
|
||||
total_show: 'Total',
|
||||
total_position: 'Position',
|
||||
total_label: 'Alias',
|
||||
sub_total_show: 'Sub Total',
|
||||
total_pos_top: 'Top',
|
||||
total_pos_bottom: 'Bottom',
|
||||
total_pos_left: 'Left',
|
||||
total_pos_right: 'Right'
|
||||
},
|
||||
dataset: {
|
||||
sheet_warn: 'There are multiple sheet pages, and the first one is extracted by default',
|
||||
|
@ -1044,7 +1044,18 @@ export default {
|
||||
value_error: '值必須為數值',
|
||||
threshold: '閾值',
|
||||
threshold_range: '閾值區間',
|
||||
gauge_threshold_format_error: '格式錯誤'
|
||||
gauge_threshold_format_error: '格式錯誤',
|
||||
total_cfg: '總計配置',
|
||||
col_cfg: '列匯總',
|
||||
row_cfg: '行匯總',
|
||||
total_show: '總計',
|
||||
total_position: '位置',
|
||||
total_label: '別名',
|
||||
sub_total_show: '小計',
|
||||
total_pos_top: '頂部',
|
||||
total_pos_bottom: '底部',
|
||||
total_pos_left: '左側',
|
||||
total_pos_right: '右側'
|
||||
},
|
||||
dataset: {
|
||||
sheet_warn: '有多個 Sheet 頁,默認抽取第一個',
|
||||
|
@ -1047,7 +1047,18 @@ export default {
|
||||
value_error: '值必须为数值',
|
||||
threshold: '阈值',
|
||||
threshold_range: '阈值区间',
|
||||
gauge_threshold_format_error: '格式错误'
|
||||
gauge_threshold_format_error: '格式错误',
|
||||
total_cfg: '总计配置',
|
||||
col_cfg: '列汇总',
|
||||
row_cfg: '行汇总',
|
||||
total_show: '总计',
|
||||
total_position: '位置',
|
||||
total_label: '别名',
|
||||
sub_total_show: '小计',
|
||||
total_pos_top: '顶部',
|
||||
total_pos_bottom: '底部',
|
||||
total_pos_left: '左侧',
|
||||
total_pos_right: '右侧'
|
||||
},
|
||||
dataset: {
|
||||
sheet_warn: '有多个 Sheet 页,默认抽取第一个',
|
||||
|
@ -78,6 +78,38 @@ export const DEFAULT_TOOLTIP = {
|
||||
},
|
||||
formatter: ''
|
||||
}
|
||||
export const DEFAULT_TOTAL = {
|
||||
row: {
|
||||
showGrandTotals: true,
|
||||
showSubTotals: true,
|
||||
reverseLayout: false,
|
||||
reverseSubLayout: false,
|
||||
label: '总计',
|
||||
subLabel: '小计',
|
||||
subTotalsDimensions: [],
|
||||
calcTotals: {
|
||||
aggregation: 'SUM'
|
||||
},
|
||||
calcSubTotals: {
|
||||
aggregation: 'SUM'
|
||||
}
|
||||
},
|
||||
col: {
|
||||
showGrandTotals: true,
|
||||
showSubTotals: true,
|
||||
reverseLayout: false,
|
||||
reverseSubLayout: false,
|
||||
label: '总计',
|
||||
subLabel: '小计',
|
||||
subTotalsDimensions: [],
|
||||
calcTotals: {
|
||||
aggregation: 'SUM'
|
||||
},
|
||||
calcSubTotals: {
|
||||
aggregation: 'SUM'
|
||||
}
|
||||
}
|
||||
}
|
||||
export const DEFAULT_TITLE_STYLE = {
|
||||
show: true,
|
||||
fontSize: '18',
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { TableSheet, S2Event, PivotSheet } from '@antv/s2'
|
||||
import { getCustomTheme, getSize } from '@/views/chart/chart/common/common_table'
|
||||
import { DEFAULT_TOTAL } from '@/views/chart/chart/chart'
|
||||
|
||||
export function baseTableInfo(s2, container, chart, action, tableData) {
|
||||
const containerDom = document.getElementById(container)
|
||||
@ -281,11 +282,31 @@ export function baseTablePivot(s2, container, chart, action, tableData) {
|
||||
data: tableData
|
||||
}
|
||||
|
||||
// total config
|
||||
let totalCfg = {}
|
||||
const chartObj = JSON.parse(JSON.stringify(chart))
|
||||
if (chartObj.customAttr) {
|
||||
let customAttr = null
|
||||
if (Object.prototype.toString.call(chartObj.customAttr) === '[object Object]') {
|
||||
customAttr = JSON.parse(JSON.stringify(chartObj.customAttr))
|
||||
} else {
|
||||
customAttr = JSON.parse(chartObj.customAttr)
|
||||
}
|
||||
if (customAttr.totalCfg) {
|
||||
totalCfg = customAttr.totalCfg
|
||||
} else {
|
||||
totalCfg = JSON.parse(JSON.stringify(DEFAULT_TOTAL))
|
||||
}
|
||||
}
|
||||
totalCfg.row.subTotalsDimensions = r
|
||||
totalCfg.col.subTotalsDimensions = c
|
||||
|
||||
// options
|
||||
const s2Options = {
|
||||
width: containerDom.offsetWidth,
|
||||
height: containerDom.offsetHeight,
|
||||
style: getSize(chart)
|
||||
style: getSize(chart),
|
||||
totals: totalCfg
|
||||
}
|
||||
|
||||
// 开始渲染
|
||||
|
182
frontend/src/views/chart/components/shape-attr/TotalCfg.vue
Normal file
182
frontend/src/views/chart/components/shape-attr/TotalCfg.vue
Normal file
@ -0,0 +1,182 @@
|
||||
<template>
|
||||
<div style="width: 100%">
|
||||
<el-col>
|
||||
<el-form ref="totalForm" :model="totalForm" label-width="80px" size="mini">
|
||||
<el-divider content-position="center" class="divider-style">{{ $t('chart.row_cfg') }}</el-divider>
|
||||
<el-form-item :label="$t('chart.total_show')" class="form-item">
|
||||
<el-checkbox v-model="totalForm.row.showGrandTotals" @change="changeTotalCfg">{{ $t('chart.show') }}</el-checkbox>
|
||||
</el-form-item>
|
||||
<div v-show="totalForm.row.showGrandTotals">
|
||||
<el-form-item :label="$t('chart.total_position')" class="form-item">
|
||||
<el-radio-group v-model="totalForm.row.reverseLayout" @change="changeTotalCfg">
|
||||
<el-radio :label="true">{{ $t('chart.total_pos_top') }}</el-radio>
|
||||
<el-radio :label="false">{{ $t('chart.total_pos_bottom') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('chart.total_label')" class="form-item">
|
||||
<el-input v-model="totalForm.row.label" style="width: 160px;" :placeholder="$t('chart.total_label')" size="mini" clearable @change="changeTotalCfg" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<el-form-item :label="$t('chart.sub_total_show')" class="form-item">
|
||||
<el-checkbox v-model="totalForm.row.showSubTotals" :disabled="rowNum < 2" @change="changeTotalCfg">{{ $t('chart.show') }}</el-checkbox>
|
||||
</el-form-item>
|
||||
<div v-show="totalForm.row.showSubTotals">
|
||||
<el-form-item :label="$t('chart.total_position')" class="form-item">
|
||||
<el-radio-group v-model="totalForm.row.reverseSubLayout" :disabled="rowNum < 2" @change="changeTotalCfg">
|
||||
<el-radio :label="true">{{ $t('chart.total_pos_top') }}</el-radio>
|
||||
<el-radio :label="false">{{ $t('chart.total_pos_bottom') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('chart.total_label')" class="form-item">
|
||||
<el-input v-model="totalForm.row.subLabel" :disabled="rowNum < 2" style="width: 160px;" :placeholder="$t('chart.total_label')" size="mini" clearable @change="changeTotalCfg" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<el-divider content-position="center" class="divider-style">{{ $t('chart.col_cfg') }}</el-divider>
|
||||
<el-form-item :label="$t('chart.total_show')" class="form-item">
|
||||
<el-checkbox v-model="totalForm.col.showGrandTotals" @change="changeTotalCfg">{{ $t('chart.show') }}</el-checkbox>
|
||||
</el-form-item>
|
||||
<div v-show="totalForm.col.showGrandTotals">
|
||||
<el-form-item :label="$t('chart.total_position')" class="form-item">
|
||||
<el-radio-group v-model="totalForm.col.reverseLayout" @change="changeTotalCfg">
|
||||
<el-radio :label="true">{{ $t('chart.total_pos_left') }}</el-radio>
|
||||
<el-radio :label="false">{{ $t('chart.total_pos_right') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('chart.total_label')" class="form-item">
|
||||
<el-input v-model="totalForm.col.label" style="width: 160px;" :placeholder="$t('chart.total_label')" size="mini" clearable @change="changeTotalCfg" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<el-form-item :label="$t('chart.sub_total_show')" class="form-item">
|
||||
<el-checkbox v-model="totalForm.col.showSubTotals" :disabled="colNum < 2" @change="changeTotalCfg">{{ $t('chart.show') }}</el-checkbox>
|
||||
</el-form-item>
|
||||
<div v-show="totalForm.col.showSubTotals">
|
||||
<el-form-item :label="$t('chart.total_position')" class="form-item">
|
||||
<el-radio-group v-model="totalForm.col.reverseSubLayout" :disabled="colNum < 2" @change="changeTotalCfg">
|
||||
<el-radio :label="true">{{ $t('chart.total_pos_left') }}</el-radio>
|
||||
<el-radio :label="false">{{ $t('chart.total_pos_right') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('chart.total_label')" class="form-item">
|
||||
<el-input v-model="totalForm.col.subLabel" :disabled="colNum < 2" style="width: 160px;" :placeholder="$t('chart.total_label')" size="mini" clearable @change="changeTotalCfg" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { DEFAULT_TOTAL } from '@/views/chart/chart/chart'
|
||||
|
||||
export default {
|
||||
name: 'TotalCfg',
|
||||
props: {
|
||||
chart: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
totalForm: JSON.parse(JSON.stringify(DEFAULT_TOTAL))
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
rowNum() {
|
||||
const chart = JSON.parse(JSON.stringify(this.chart))
|
||||
if (chart.xaxisExt) {
|
||||
let arr = null
|
||||
if (Object.prototype.toString.call(chart.xaxisExt) === '[object Object]') {
|
||||
arr = JSON.parse(JSON.stringify(chart.xaxisExt))
|
||||
} else {
|
||||
arr = JSON.parse(chart.xaxisExt)
|
||||
}
|
||||
return arr.length
|
||||
}
|
||||
return 0
|
||||
},
|
||||
colNum() {
|
||||
const chart = JSON.parse(JSON.stringify(this.chart))
|
||||
if (chart.xaxis) {
|
||||
let arr = null
|
||||
if (Object.prototype.toString.call(chart.xaxis) === '[object Object]') {
|
||||
arr = JSON.parse(JSON.stringify(chart.xaxis))
|
||||
} else {
|
||||
arr = JSON.parse(chart.xaxis)
|
||||
}
|
||||
return arr.length
|
||||
}
|
||||
return 0
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'chart': {
|
||||
handler: function() {
|
||||
this.initData()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initData()
|
||||
},
|
||||
methods: {
|
||||
initData() {
|
||||
const chart = JSON.parse(JSON.stringify(this.chart))
|
||||
if (chart.customAttr) {
|
||||
let customAttr = null
|
||||
if (Object.prototype.toString.call(chart.customAttr) === '[object Object]') {
|
||||
customAttr = JSON.parse(JSON.stringify(chart.customAttr))
|
||||
} else {
|
||||
customAttr = JSON.parse(chart.customAttr)
|
||||
}
|
||||
if (customAttr.totalCfg) {
|
||||
this.totalForm = customAttr.totalCfg
|
||||
} else {
|
||||
this.totalForm = JSON.parse(JSON.stringify(DEFAULT_TOTAL))
|
||||
}
|
||||
}
|
||||
},
|
||||
changeTotalCfg() {
|
||||
this.$emit('onTotalCfgChange', this.totalForm)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.shape-item{
|
||||
padding: 6px;
|
||||
border: none;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.form-item-slider>>>.el-form-item__label{
|
||||
font-size: 12px;
|
||||
line-height: 38px;
|
||||
}
|
||||
.form-item>>>.el-form-item__label{
|
||||
font-size: 12px;
|
||||
}
|
||||
.el-select-dropdown__item{
|
||||
padding: 0 20px;
|
||||
}
|
||||
span{font-size: 12px}
|
||||
|
||||
.el-form-item{
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.el-divider--horizontal {
|
||||
margin: 10px 0
|
||||
}
|
||||
.divider-style>>>.el-divider__text{
|
||||
color: #606266;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
padding: 0 10px;
|
||||
}
|
||||
</style>
|
@ -310,7 +310,8 @@ import {
|
||||
DEFAULT_BACKGROUND_COLOR,
|
||||
DEFAULT_SPLIT,
|
||||
DEFAULT_FUNCTION_CFG,
|
||||
DEFAULT_THRESHOLD
|
||||
DEFAULT_THRESHOLD,
|
||||
DEFAULT_TOTAL
|
||||
} from '../chart/chart'
|
||||
|
||||
export default {
|
||||
@ -755,7 +756,8 @@ export default {
|
||||
tableColor: DEFAULT_COLOR_CASE,
|
||||
size: DEFAULT_SIZE,
|
||||
label: DEFAULT_LABEL,
|
||||
tooltip: DEFAULT_TOOLTIP
|
||||
tooltip: DEFAULT_TOOLTIP,
|
||||
totalCfg: DEFAULT_TOTAL
|
||||
})
|
||||
view.customStyle = JSON.stringify({
|
||||
text: DEFAULT_TITLE_STYLE,
|
||||
|
@ -676,6 +676,18 @@
|
||||
@onTooltipChange="onTooltipChange"
|
||||
/>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item
|
||||
v-show="view.type === 'table-pivot'"
|
||||
name="totalCfg"
|
||||
:title="$t('chart.total_cfg')"
|
||||
>
|
||||
<total-cfg
|
||||
:param="param"
|
||||
class="attr-selector"
|
||||
:chart="chart"
|
||||
@onTotalCfgChange="onTotalCfgChange"
|
||||
/>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</el-row>
|
||||
<el-row>
|
||||
@ -1046,6 +1058,7 @@ import {
|
||||
DEFAULT_THRESHOLD,
|
||||
DEFAULT_TITLE_STYLE,
|
||||
DEFAULT_TOOLTIP,
|
||||
DEFAULT_TOTAL,
|
||||
DEFAULT_XAXIS_STYLE,
|
||||
DEFAULT_YAXIS_EXT_STYLE,
|
||||
DEFAULT_YAXIS_STYLE
|
||||
@ -1089,9 +1102,11 @@ import PluginCom from '@/views/system/plugin/PluginCom'
|
||||
import FunctionCfg from '@/views/chart/components/senior/FunctionCfg'
|
||||
import AssistLine from '@/views/chart/components/senior/AssistLine'
|
||||
import Threshold from '@/views/chart/components/senior/Threshold'
|
||||
import TotalCfg from '@/views/chart/components/shape-attr/TotalCfg'
|
||||
export default {
|
||||
name: 'ChartEdit',
|
||||
components: {
|
||||
TotalCfg,
|
||||
Threshold,
|
||||
AssistLine,
|
||||
FunctionCfg,
|
||||
@ -1167,7 +1182,8 @@ export default {
|
||||
color: DEFAULT_COLOR_CASE,
|
||||
size: DEFAULT_SIZE,
|
||||
label: DEFAULT_LABEL,
|
||||
tooltip: DEFAULT_TOOLTIP
|
||||
tooltip: DEFAULT_TOOLTIP,
|
||||
totalCfg: DEFAULT_TOTAL
|
||||
},
|
||||
customStyle: {
|
||||
text: DEFAULT_TITLE_STYLE,
|
||||
@ -1728,6 +1744,11 @@ export default {
|
||||
this.calcStyle()
|
||||
},
|
||||
|
||||
onTotalCfgChange(val) {
|
||||
this.view.customAttr.totalCfg = val
|
||||
this.calcStyle()
|
||||
},
|
||||
|
||||
onChangeXAxisForm(val) {
|
||||
this.view.customStyle.xAxis = val
|
||||
this.calcStyle()
|
||||
|
Loading…
Reference in New Issue
Block a user