forked from github/dataease
feat: 表格滚动
This commit is contained in:
parent
2421b5c80c
commit
a3e8f31e71
@ -1113,7 +1113,13 @@ export default {
|
||||
chart_field_edit: 'Chart Field Manage',
|
||||
copy_field: 'Copy Field',
|
||||
calc_field: 'Calculate Field',
|
||||
form_type: 'From Type'
|
||||
form_type: 'From Type',
|
||||
scroll_cfg: 'Scroll Config',
|
||||
scroll: 'Scroll',
|
||||
open: 'Open',
|
||||
row: 'Row',
|
||||
interval: 'Interval',
|
||||
max_more_than_mix: 'Max must more than Min'
|
||||
},
|
||||
dataset: {
|
||||
select_year: 'Select Year',
|
||||
|
@ -1113,7 +1113,13 @@ export default {
|
||||
chart_field_edit: '視圖字段管理',
|
||||
copy_field: '復製字段',
|
||||
calc_field: '計算字段',
|
||||
form_type: '類別'
|
||||
form_type: '類別',
|
||||
scroll_cfg: '滾動設置',
|
||||
scroll: '滾動',
|
||||
open: '開啟',
|
||||
row: '行數',
|
||||
interval: '間隔',
|
||||
max_more_than_mix: '最大值必須大於最小值'
|
||||
},
|
||||
dataset: {
|
||||
select_year: '選擇年',
|
||||
|
@ -1115,7 +1115,13 @@ export default {
|
||||
chart_field_edit: '视图字段管理',
|
||||
copy_field: '复制字段',
|
||||
calc_field: '计算字段',
|
||||
form_type: '类别'
|
||||
form_type: '类别',
|
||||
scroll_cfg: '滚动设置',
|
||||
scroll: '滚动',
|
||||
open: '开启',
|
||||
row: '行数',
|
||||
interval: '间隔',
|
||||
max_more_than_mix: '最大值必须大于最小值'
|
||||
},
|
||||
dataset: {
|
||||
select_year: '选择年',
|
||||
|
@ -339,6 +339,11 @@ export const DEFAULT_THRESHOLD = {
|
||||
gaugeThreshold: '',
|
||||
labelThreshold: []
|
||||
}
|
||||
export const DEFAULT_SCROLL = {
|
||||
open: false,
|
||||
row: 1,
|
||||
interval: 2000
|
||||
}
|
||||
// chart config
|
||||
export const BASE_BAR = {
|
||||
title: {
|
||||
|
@ -100,7 +100,9 @@ export default {
|
||||
show: 0
|
||||
},
|
||||
tableData: [],
|
||||
showPage: false
|
||||
showPage: false,
|
||||
scrollTimer: null,
|
||||
scrollTop: 0
|
||||
}
|
||||
},
|
||||
|
||||
@ -133,6 +135,9 @@ export default {
|
||||
mounted() {
|
||||
this.preDraw()
|
||||
},
|
||||
beforeDestroy() {
|
||||
clearInterval(this.scrollTimer)
|
||||
},
|
||||
methods: {
|
||||
initData() {
|
||||
let datas = []
|
||||
@ -208,6 +213,7 @@ export default {
|
||||
|
||||
if (this.myChart && this.antVRenderStatus) {
|
||||
this.myChart.render()
|
||||
this.initScroll()
|
||||
}
|
||||
this.setBackGroundBorder()
|
||||
},
|
||||
@ -371,6 +377,34 @@ export default {
|
||||
pageSize: 20,
|
||||
show: 0
|
||||
}
|
||||
},
|
||||
|
||||
initScroll() {
|
||||
clearInterval(this.scrollTimer)
|
||||
// 首先回到最顶部,然后计算行高*行数作为top,最后判断:如果top<数据量*行高,继续滚动,否则回到顶部
|
||||
const customAttr = JSON.parse(this.chart.customAttr)
|
||||
const senior = JSON.parse(this.chart.senior)
|
||||
|
||||
this.scrollTop = 0
|
||||
this.myChart.store.set('scrollY', this.scrollTop)
|
||||
this.myChart.render()
|
||||
|
||||
if (senior.scrollCfg.open && (this.chart.type === 'table-normal' || (this.chart.type === 'table-info' && !this.showPage))) {
|
||||
const rowHeight = customAttr.size.tableItemHeight
|
||||
const headerHeight = customAttr.size.tableTitleHeight
|
||||
|
||||
this.scrollTimer = setInterval(() => {
|
||||
const top = rowHeight * senior.scrollCfg.row
|
||||
const dom = document.getElementById(this.chartId)
|
||||
if ((dom.offsetHeight - headerHeight + this.scrollTop) < rowHeight * this.chart.data.tableRow.length) {
|
||||
this.scrollTop += top
|
||||
} else {
|
||||
this.scrollTop = 0
|
||||
}
|
||||
this.myChart.store.set('scrollY', this.scrollTop)
|
||||
this.myChart.render()
|
||||
}, senior.scrollCfg.interval)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
116
frontend/src/views/chart/components/senior/ScrollCfg.vue
Normal file
116
frontend/src/views/chart/components/senior/ScrollCfg.vue
Normal file
@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<div style="width: 100%;display: block;">
|
||||
<el-row class="scroll-style">
|
||||
<el-form ref="scrollForm" :model="scrollForm" label-width="80px" size="mini">
|
||||
<el-form-item :label="$t('chart.scroll')" class="form-item">
|
||||
<el-checkbox v-model="scrollForm.open" @change="changeScrollCfg">{{ $t('chart.open') }}</el-checkbox>
|
||||
<el-tooltip class="item" effect="dark" placement="bottom">
|
||||
<div slot="content">
|
||||
明细表仅在分页模式为"下拉"时生效。
|
||||
</div>
|
||||
<i class="el-icon-info" style="cursor: pointer;color: gray;font-size: 12px;" />
|
||||
</el-tooltip>
|
||||
</el-form-item>
|
||||
<span v-show="scrollForm.open">
|
||||
<el-form-item :label="$t('chart.row')" class="form-item">
|
||||
<el-input-number v-model="scrollForm.row" :min="1" :max="1000" :precision="0" size="mini" @change="changeScrollCfg" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('chart.interval') + '(ms)'" class="form-item">
|
||||
<el-input-number v-model="scrollForm.interval" :min="500" :step="1000" :precision="0" size="mini" @change="changeScrollCfg" />
|
||||
</el-form-item>
|
||||
</span>
|
||||
</el-form>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { DEFAULT_SCROLL } from '@/views/chart/chart/chart'
|
||||
|
||||
export default {
|
||||
name: 'ScrollCfg',
|
||||
props: {
|
||||
chart: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
scrollForm: JSON.parse(JSON.stringify(DEFAULT_SCROLL))
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'chart': {
|
||||
handler: function() {
|
||||
this.initData()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initData()
|
||||
},
|
||||
methods: {
|
||||
initData() {
|
||||
const chart = JSON.parse(JSON.stringify(this.chart))
|
||||
if (chart.senior) {
|
||||
let senior = null
|
||||
if (Object.prototype.toString.call(chart.senior) === '[object Object]') {
|
||||
senior = JSON.parse(JSON.stringify(chart.senior))
|
||||
} else {
|
||||
senior = JSON.parse(chart.senior)
|
||||
}
|
||||
if (senior.scrollCfg) {
|
||||
this.scrollForm = senior.scrollCfg
|
||||
} else {
|
||||
this.scrollForm = JSON.parse(JSON.stringify(DEFAULT_SCROLL))
|
||||
}
|
||||
}
|
||||
},
|
||||
changeScrollCfg() {
|
||||
this.$emit('onScrollCfgChange', this.scrollForm)
|
||||
}
|
||||
}
|
||||
}
|
||||
</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;
|
||||
}
|
||||
|
||||
.switch-style{
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
margin-top: -4px;
|
||||
}
|
||||
.color-picker-style{
|
||||
cursor: pointer;
|
||||
z-index: 1003;
|
||||
}
|
||||
|
||||
.scroll-style >>> .el-input-number--mini {
|
||||
width: 120px !important;
|
||||
}
|
||||
</style>
|
@ -119,7 +119,9 @@ export default {
|
||||
show: 0
|
||||
},
|
||||
showPage: false,
|
||||
columnWidth: DEFAULT_SIZE.tableColumnWidth
|
||||
columnWidth: DEFAULT_SIZE.tableColumnWidth,
|
||||
scrollTimer: null,
|
||||
scrollTop: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -143,6 +145,9 @@ export default {
|
||||
this.chartResize()
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
clearInterval(this.scrollTimer)
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.resetHeight()
|
||||
@ -224,6 +229,10 @@ export default {
|
||||
} else {
|
||||
this.height = 'auto'
|
||||
}
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.initScroll()
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
@ -355,6 +364,42 @@ export default {
|
||||
pageSize: 20,
|
||||
show: 0
|
||||
}
|
||||
},
|
||||
|
||||
initScroll() {
|
||||
clearInterval(this.scrollTimer)
|
||||
// 首先回到最顶部,然后计算行高*行数作为top,最后判断:如果top<数据量*行高,继续滚动,否则回到顶部
|
||||
const customAttr = JSON.parse(this.chart.customAttr)
|
||||
const senior = JSON.parse(this.chart.senior)
|
||||
|
||||
const scrollContainer = document.getElementsByClassName(this.chart.id)[0].getElementsByClassName('elx-table--body-wrapper')[0]
|
||||
|
||||
this.scrollTop = 0
|
||||
setTimeout(() => {
|
||||
scrollContainer.scrollTo({
|
||||
top: this.scrollTop,
|
||||
behavior: this.scrollTop === 0 ? 'instant' : 'smooth'
|
||||
})
|
||||
}, 0)
|
||||
|
||||
if (senior.scrollCfg.open && (this.chart.type === 'table-normal' || (this.chart.type === 'table-info' && !this.showPage))) {
|
||||
let rowHeight = customAttr.size.tableItemHeight
|
||||
if (rowHeight < 36) {
|
||||
rowHeight = 36
|
||||
}
|
||||
this.scrollTimer = setInterval(() => {
|
||||
const top = rowHeight * senior.scrollCfg.row
|
||||
if (scrollContainer.clientHeight + scrollContainer.scrollTop < scrollContainer.scrollHeight) {
|
||||
this.scrollTop += top
|
||||
} else {
|
||||
this.scrollTop = 0
|
||||
}
|
||||
scrollContainer.scrollTo({
|
||||
top: this.scrollTop,
|
||||
behavior: this.scrollTop === 0 ? 'instant' : 'smooth'
|
||||
})
|
||||
}, senior.scrollCfg.interval)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,8 +32,8 @@
|
||||
</span>
|
||||
</el-row>
|
||||
<el-row class="view-panel-row">
|
||||
<el-tabs :stretch="true" class="tab-header">
|
||||
<el-tab-pane :label="$t('chart.chart_data')" class="padding-tab" style="width: 350px">
|
||||
<el-tabs v-model="tabActive" :stretch="true" class="tab-header">
|
||||
<el-tab-pane name="data" :label="$t('chart.chart_data')" class="padding-tab" style="width: 350px">
|
||||
<div v-if="view.dataFrom==='template'" class="view-panel-Mask">
|
||||
<span style="opacity: 1;">
|
||||
<el-button
|
||||
@ -95,7 +95,7 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-if="fieldShow" class="field-split">
|
||||
<div v-if="fieldShow && tabActive === 'data'" class="field-split">
|
||||
<fu-split-pane top="50%" direction="vertical">
|
||||
<template v-slot:top>
|
||||
<div class="padding-lr field-height">
|
||||
@ -669,7 +669,7 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('chart.chart_style')" class="padding-tab" style="width: 350px">
|
||||
<el-tab-pane name="style" :label="$t('chart.chart_style')" class="padding-tab" style="width: 350px">
|
||||
<chart-style
|
||||
v-if="chartProperties || view.isPlugin"
|
||||
:param="param"
|
||||
@ -694,19 +694,19 @@
|
||||
@onChangeBackgroundForm="onChangeBackgroundForm"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('chart.senior')" class="padding-tab" style="width: 350px;">
|
||||
<el-tab-pane name="senior" :label="$t('chart.senior')" class="padding-tab" style="width: 350px;">
|
||||
<el-row class="view-panel">
|
||||
<div
|
||||
v-if="view.type && (view.type.includes('bar') || view.type.includes('line') || view.type.includes('mix') || view.type.includes('gauge')) || view.type === 'text'"
|
||||
v-if="view.type && (view.type.includes('bar') || view.type.includes('line') || view.type.includes('mix') || view.type.includes('gauge')) || view.type === 'text' || view.type === 'table-normal' || view.type === 'table-info'"
|
||||
style="overflow:auto;border-right: 1px solid #e6e6e6;height: 100%;width: 100%;"
|
||||
class="attr-style theme-border-class"
|
||||
>
|
||||
<el-row
|
||||
v-if="view.type && (view.type.includes('bar') || view.type.includes('line') || view.type.includes('mix'))"
|
||||
v-if="view.type && (view.type.includes('bar') || view.type.includes('line') || view.type.includes('mix') || view.type.includes('table'))"
|
||||
>
|
||||
<span class="padding-lr">{{ $t('chart.senior_cfg') }}</span>
|
||||
<el-collapse v-model="attrActiveNames" class="style-collapse">
|
||||
<el-collapse-item name="function" :title="$t('chart.function_cfg')">
|
||||
<el-collapse-item v-if="view.type && (view.type.includes('bar') || view.type.includes('line') || view.type.includes('mix'))" name="function" :title="$t('chart.function_cfg')">
|
||||
<function-cfg
|
||||
:param="param"
|
||||
class="attr-selector"
|
||||
@ -714,6 +714,14 @@
|
||||
@onFunctionCfgChange="onFunctionCfgChange"
|
||||
/>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item v-if="false && view.type && (view.type.includes('table'))" name="scroll" :title="$t('chart.scroll_cfg')">
|
||||
<scroll-cfg
|
||||
:param="param"
|
||||
class="attr-selector"
|
||||
:chart="chart"
|
||||
@onScrollCfgChange="onScrollChange"
|
||||
/>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</el-row>
|
||||
<el-row
|
||||
@ -1077,12 +1085,14 @@ import { pluginTypes } from '@/api/chart/chart'
|
||||
import ValueFormatterEdit from '@/views/chart/components/value-formatter/ValueFormatterEdit'
|
||||
import ChartStyle from '@/views/chart/view/ChartStyle'
|
||||
import CustomSortEdit from '@/views/chart/components/compare/CustomSortEdit'
|
||||
import ScrollCfg from '@/views/chart/components/senior/ScrollCfg'
|
||||
import ChartFieldEdit from '@/views/chart/view/ChartFieldEdit'
|
||||
import CalcChartFieldEdit from '@/views/chart/view/CalcChartFieldEdit'
|
||||
|
||||
export default {
|
||||
name: 'ChartEdit',
|
||||
components: {
|
||||
ScrollCfg,
|
||||
CalcChartFieldEdit,
|
||||
ChartFieldEdit,
|
||||
CustomSortEdit,
|
||||
@ -1231,7 +1241,8 @@ export default {
|
||||
showEditChartField: false,
|
||||
currEditField: {},
|
||||
editChartCalcField: false,
|
||||
fieldShow: false
|
||||
fieldShow: false,
|
||||
tabActive: 'data'
|
||||
|
||||
}
|
||||
},
|
||||
@ -1953,6 +1964,11 @@ export default {
|
||||
this.calcStyle()
|
||||
},
|
||||
|
||||
onScrollChange(val) {
|
||||
this.view.senior.scrollCfg = val
|
||||
this.calcStyle()
|
||||
},
|
||||
|
||||
showDimensionEditFilter(item) {
|
||||
this.dimensionItem = JSON.parse(JSON.stringify(item))
|
||||
this.dimensionFilterEdit = true
|
||||
@ -2695,6 +2711,7 @@ export default {
|
||||
.drag-list {
|
||||
height: calc(100% - 26px);
|
||||
overflow: auto;
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.item-dimension {
|
||||
@ -3062,4 +3079,12 @@ span {
|
||||
height: calc(100% - 40px);
|
||||
}
|
||||
|
||||
.field-split >>> .fu-split-pane__left{
|
||||
padding-right: 0!important;
|
||||
}
|
||||
|
||||
.field-split >>> .fu-split-pane__right{
|
||||
padding-left: 0!important;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
Loading…
Reference in New Issue
Block a user