feat: S2明细表

This commit is contained in:
junjie 2022-01-31 12:07:10 +08:00
parent ea1649510f
commit 66b75928b3
6 changed files with 459 additions and 4 deletions

View File

@ -14,7 +14,7 @@
},
"dependencies": {
"@antv/g2plot": "^2.3.32",
"@antv/s2": "^1.6.0",
"@antv/s2": "^1.7.0",
"@riophae/vue-treeselect": "0.4.0",
"@tinymce/tinymce-vue": "^3.2.8",
"axios": "^0.21.1",

View File

@ -37,6 +37,16 @@
@onChartClick="chartClick"
@onJumpClick="jumpClick"
/>
<chart-component-s2
v-if="charViewS2ShowFlag"
:ref="element.propValue.id"
class="chart-class"
:chart="chart"
:track-menu="trackMenu"
:search-count="searchCount"
@onChartClick="chartClick"
@onJumpClick="jumpClick"
/>
<table-normal
v-if="tableShowFlag"
:ref="element.propValue.id"
@ -71,10 +81,11 @@ import { areaMapping } from '@/api/map/map'
import ChartComponentG2 from '@/views/chart/components/ChartComponentG2'
import EditBarView from '@/components/canvas/components/Editor/EditBarView'
import { customAttrTrans, customStyleTrans, recursionTransObj } from '@/components/canvas/utils/style'
import ChartComponentS2 from '@/views/chart/components/ChartComponentS2'
export default {
name: 'UserView',
components: { EditBarView, ChartComponent, TableNormal, LabelNormal, DrillPath, ChartComponentG2 },
components: { ChartComponentS2, EditBarView, ChartComponent, TableNormal, LabelNormal, DrillPath, ChartComponentG2 },
props: {
element: {
type: Object,
@ -169,8 +180,11 @@ export default {
charViewG2ShowFlag() {
return this.httpRequest.status && this.chart.type && !this.chart.type.includes('table') && !this.chart.type.includes('text') && this.renderComponent() === 'antv'
},
charViewS2ShowFlag() {
return this.httpRequest.status && this.chart.type && this.chart.type.includes('table') && !this.chart.type.includes('text') && this.renderComponent() === 'antv'
},
tableShowFlag() {
return this.httpRequest.status && this.chart.type && this.chart.type.includes('table')
return this.httpRequest.status && this.chart.type && this.chart.type.includes('table') && this.renderComponent() === 'echarts'
},
labelShowFlag() {
return this.httpRequest.status && this.chart.type && this.chart.type.includes('text')

View File

@ -0,0 +1,10 @@
export function getCustomTheme(chart) {
const theme = {}
const background = {
color: '#00000000'
}
theme.background = background
return theme
}

View File

@ -0,0 +1,59 @@
import { TableSheet } from '@antv/s2'
import { getCustomTheme } from '@/views/chart/chart/common/common_table'
export function baseTableInfo(s2, container, chart, action, tableData) {
const containerDom = document.getElementById(container)
// data
const fields = chart.data.fields
if (!fields || fields.length === 0) {
if (s2) {
s2.destroy()
}
return
}
const columns = []
const meta = []
fields.forEach(ele => {
columns.push(ele.dataeaseName)
meta.push({
field: ele.dataeaseName,
name: ele.name
})
})
// data config
const s2DataConfig = {
fields: {
columns: columns
},
meta: meta,
data: tableData
}
// options
const s2Options = {
width: containerDom.offsetWidth,
height: containerDom.offsetHeight,
// showSeriesNumber: true
style: {
cellCfg: {
width: 500
}
}
}
// 开始渲染
if (s2) {
s2.destroy()
}
s2 = new TableSheet(containerDom, s2DataConfig, s2Options)
// theme
const customTheme = getCustomTheme(chart)
s2.setThemeCfg({ theme: customTheme })
return s2
}

View File

@ -0,0 +1,362 @@
<template>
<div ref="chartContainer" style="padding: 0;width: 100%;height: 100%;overflow: hidden;" :style="bg_class">
<view-track-bar ref="viewTrack" :track-menu="trackMenu" class="track-bar" :style="trackBarStyleTime" @trackClick="trackClick" />
<span v-if="chart.type" v-show="title_show" ref="title" :style="title_class" style="cursor: default;display: block;">
<p style="padding:6px 10px 0 10px;margin: 0;overflow: hidden;white-space: pre;text-overflow: ellipsis;">{{ chart.title }}</p>
</span>
<div style="width: 100%;overflow: hidden;padding: 8px;" :style="{height:chartHeight,background:container_bg_class.background}">
<div v-if="chart.type === 'table-info'" :id="chartId" style="width: 100%;overflow: hidden;" class="table-dom" />
<el-row v-show="chart.type === 'table-info'" class="table-page">
<span class="total-style">
{{ $t('chart.total') }}
<span>{{ (chart.data && chart.data.tableRow)?chart.data.tableRow.length:0 }}</span>
{{ $t('chart.items') }}
</span>
<el-pagination
small
:current-page="currentPage.page"
:page-sizes="[10,20,50,100]"
:page-size="currentPage.pageSize"
:pager-count="5"
layout="prev, pager, next"
:total="currentPage.show"
class="page-style"
@current-change="pageClick"
@size-change="pageChange"
/>
</el-row>
</div>
</div>
</template>
<script>
import { uuid } from 'vue-uuid'
import ViewTrackBar from '@/components/canvas/components/Editor/ViewTrackBar'
import { hexColorToRGBA } from '@/views/chart/chart/util'
import { baseTableInfo } from '@/views/chart/chart/table/table-info'
export default {
name: 'ChartComponentS2',
components: { ViewTrackBar },
props: {
chart: {
type: Object,
required: true
},
filter: {
type: Object,
required: false,
default: function() {
return {}
}
},
trackMenu: {
type: Array,
required: false,
default: function() {
return ['drill']
}
},
searchCount: {
type: Number,
required: false,
default: 0
}
},
data() {
return {
myChart: null,
chartId: uuid.v1(),
showTrackBar: true,
trackBarStyle: {
position: 'absolute',
left: '0px',
top: '0px'
},
pointParam: null,
dynamicAreaCode: null,
borderRadius: '0px',
chartHeight: '100%',
title_class: {
margin: '0 0',
width: '100%',
fontSize: '18px',
color: '#303133',
textAlign: 'left',
fontStyle: 'normal',
fontWeight: 'normal',
background: hexColorToRGBA('#ffffff', 0)
},
container_bg_class: {
background: hexColorToRGBA('#ffffff', 0)
},
title_show: true,
antVRenderStatus: false,
currentPage: {
page: 1,
pageSize: 20,
show: 0
},
tableData: []
}
},
computed: {
trackBarStyleTime() {
return this.trackBarStyle
},
bg_class() {
return {
borderRadius: this.borderRadius
}
}
},
watch: {
chart: {
handler(newVal, oldVla) {
this.initData()
this.initTitle()
this.calcHeightDelay()
new Promise((resolve) => { resolve() }).then(() => {
this.drawView()
})
},
deep: true
},
resize() {
this.drawEcharts()
}
},
mounted() {
this.preDraw()
},
methods: {
initData() {
let datas = []
if (this.chart.data) {
this.fields = JSON.parse(JSON.stringify(this.chart.data.fields))
const attr = JSON.parse(this.chart.customAttr)
this.currentPage.pageSize = parseInt(attr.size.tablePageSize ? attr.size.tablePageSize : 20)
datas = JSON.parse(JSON.stringify(this.chart.data.tableRow))
if (this.chart.type === 'table-info') {
//
this.currentPage.show = datas.length
const pageStart = (this.currentPage.page - 1) * this.currentPage.pageSize
const pageEnd = pageStart + this.currentPage.pageSize
datas = datas.slice(pageStart, pageEnd)
}
} else {
this.fields = []
datas = []
this.resetPage()
}
this.tableData = datas
},
preDraw() {
this.initData()
this.initTitle()
this.calcHeightDelay()
new Promise((resolve) => { resolve() }).then(() => {
this.drawView()
})
const that = this
window.onresize = function() {
that.initData()
that.initTitle()
that.calcHeightDelay()
new Promise((resolve) => { resolve() }).then(() => {
that.drawView()
})
}
},
drawView() {
const chart = this.chart
// type
// if (chart.data) {
this.antVRenderStatus = true
if (!chart.data || (!chart.data.datas && !chart.data.series)) {
chart.data = {
datas: [{}],
series: [
{
data: [0]
}
]
}
}
if (chart.type === 'table-info') {
this.myChart = baseTableInfo(this.myChart, this.chartId, chart, this.antVAction, this.tableData)
} else {
if (this.myChart) {
this.antVRenderStatus = false
this.myChart.destroy()
}
}
if (this.myChart && this.searchCount > 0) {
this.myChart.options.animation = false
}
if (this.myChart && this.antVRenderStatus) {
this.myChart.render()
}
this.setBackGroundBorder()
},
antVAction(param) {
console.log(param)
if (this.chart.type === 'treemap') {
this.pointParam = param.data.data
} else {
this.pointParam = param.data
}
if (this.trackMenu.length < 2) { //
this.trackClick(this.trackMenu[0])
} else { //
this.trackBarStyle.left = param.x + 'px'
this.trackBarStyle.top = (param.y + 10) + 'px'
this.$refs.viewTrack.trackButtonClick()
}
},
setBackGroundBorder() {
if (this.chart.customStyle) {
const customStyle = JSON.parse(this.chart.customStyle)
if (customStyle.background) {
this.borderRadius = (customStyle.background.borderRadius || 0) + 'px'
}
}
},
chartResize() {
this.initData()
this.initTitle()
this.calcHeightDelay()
new Promise((resolve) => { resolve() }).then(() => {
this.drawView()
})
},
trackClick(trackAction) {
const param = this.pointParam
if (!param || !param.data || !param.data.dimensionList) {
//
if (this.chart.type === 'map') {
this.$warning(this.$t('panel.no_drill_field'))
}
return
}
const linkageParam = {
option: 'linkage',
viewId: this.chart.id,
dimensionList: this.pointParam.data.dimensionList,
quotaList: this.pointParam.data.quotaList
}
const jumpParam = {
option: 'jump',
viewId: this.chart.id,
dimensionList: this.pointParam.data.dimensionList,
quotaList: this.pointParam.data.quotaList
}
switch (trackAction) {
case 'drill':
this.$emit('onChartClick', this.pointParam)
break
case 'linkage':
this.$store.commit('addViewTrackFilter', linkageParam)
break
case 'jump':
this.$emit('onJumpClick', jumpParam)
break
default:
break
}
},
// title and bg
initTitle() {
if (this.chart.customStyle) {
const customStyle = JSON.parse(this.chart.customStyle)
if (customStyle.text) {
this.title_show = customStyle.text.show
// this.title_class.fontSize = customStyle.text.fontSize + 'px'
this.title_class.color = customStyle.text.color
this.title_class.textAlign = customStyle.text.hPosition
this.title_class.fontStyle = customStyle.text.isItalic ? 'italic' : 'normal'
this.title_class.fontWeight = customStyle.text.isBolder ? 'bold' : 'normal'
if (this.$refs.title) {
this.$refs.title.style.fontSize = customStyle.text.fontSize + 'px'
}
}
if (customStyle.background) {
this.title_class.background = hexColorToRGBA(customStyle.background.color, customStyle.background.alpha)
this.borderRadius = (customStyle.background.borderRadius || 0) + 'px'
this.container_bg_class.background = hexColorToRGBA(customStyle.background.color, customStyle.background.alpha)
}
}
},
calcHeightRightNow() {
this.$nextTick(() => {
if (this.$refs.chartContainer) {
const currentHeight = this.$refs.chartContainer.offsetHeight
if (this.$refs.title) {
const titleHeight = this.$refs.title.offsetHeight
this.chartHeight = (currentHeight - titleHeight) + 'px'
}
}
})
},
calcHeightDelay() {
this.calcHeightRightNow()
setTimeout(() => {
this.calcHeightRightNow()
}, 100)
},
pageChange(val) {
this.currentPage.pageSize = val
this.initData()
this.drawView()
},
pageClick(val) {
this.currentPage.page = val
this.initData()
this.drawView()
},
resetPage() {
this.currentPage = {
page: 1,
pageSize: 20,
show: 0
}
}
}
}
</script>
<style scoped lang="scss">
.table-dom{
height:calc(100% - 36px);
}
.table-page{
display: flex;
align-items: center;
justify-content: flex-end;
width: 100%;
overflow: hidden;
margin-top: 8px;
}
.page-style{
margin-right: auto;
}
.total-style{
flex: 1;
font-size: 12px;
color: #606266;
white-space:nowrap;
}
.page-style >>> .el-input__inner{
height: 24px;
}
</style>

View File

@ -769,8 +769,16 @@
class="chart-class"
@onChartClick="chartClick"
/>
<chart-component-s2
v-if="httpRequest.status && chart.type && chart.type.includes('table') && !chart.type.includes('text') && renderComponent() === 'antv'"
ref="dynamicChart"
:chart-id="chart.id"
:chart="chart"
class="chart-class"
@onChartClick="chartClick"
/>
<table-normal
v-if="httpRequest.status && chart.type && chart.type.includes('table')"
v-if="httpRequest.status && chart.type && chart.type.includes('table') && renderComponent() === 'echarts'"
:show-summary="chart.type === 'table-normal'"
:chart="chart"
class="table-class"
@ -973,10 +981,12 @@ import SizeSelectorAntV from '@/views/chart/components/shape-attr/SizeSelectorAn
import SplitSelectorAntV from '@/views/chart/components/component-style/SplitSelectorAntV'
import CompareEdit from '@/views/chart/components/compare/CompareEdit'
import { compareItem } from '@/views/chart/chart/compare'
import ChartComponentS2 from '@/views/chart/components/ChartComponentS2'
export default {
name: 'ChartEdit',
components: {
ChartComponentS2,
CompareEdit,
SplitSelectorAntV,
SizeSelectorAntV,