dataease/frontend/src/views/chart/components/ChartComponentS2.vue

471 lines
14 KiB
Vue
Raw Normal View History

2022-01-31 12:07:10 +08:00
<template>
<div ref="chartContainer" style="padding: 0;width: 100%;height: 100%;overflow: hidden;" :style="bg_class">
2022-01-31 12:07:10 +08:00
<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;">
2022-07-25 10:07:33 +08:00
<div>
<p style="padding:6px 4px 0;margin: 0;overflow: hidden;white-space: pre;text-overflow: ellipsis;display: inline;">{{ chart.title }}</p>
<title-remark v-if="remarkCfg.show" style="text-shadow: none!important;" :remark-cfg="remarkCfg" />
2022-07-25 10:07:33 +08:00
</div>
2022-01-31 12:07:10 +08:00
</span>
<div ref="tableContainer" style="width: 100%;overflow: hidden;" :style="{background:container_bg_class.background}">
2022-02-07 13:13:50 +08:00
<div v-if="chart.type === 'table-normal'" :id="chartId" style="width: 100%;overflow: hidden;" :class="chart.drill ? 'table-dom-normal-drill' : 'table-dom-normal'" />
<div v-if="chart.type === 'table-info'" :id="chartId" style="width: 100%;overflow: hidden;" :class="chart.drill ? (showPage ? 'table-dom-info-drill' : 'table-dom-info-drill-pull') : (showPage ? 'table-dom-info' : 'table-dom-info-pull')" />
2022-02-08 13:50:43 +08:00
<div v-if="chart.type === 'table-pivot'" :id="chartId" style="width: 100%;overflow: hidden;" class="table-dom-normal" />
<el-row v-show="showPage" class="table-page">
2022-01-31 12:07:10 +08:00
<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'
2022-07-25 10:07:33 +08:00
import { getRemark, hexColorToRGBA } from '@/views/chart/chart/util'
2022-02-08 13:50:43 +08:00
import { baseTableInfo, baseTableNormal, baseTablePivot } from '@/views/chart/chart/table/table-info'
2022-07-25 10:07:33 +08:00
import TitleRemark from '@/views/chart/view/TitleRemark'
import { DEFAULT_TITLE_STYLE } from '@/views/chart/chart/chart'
2022-01-31 12:07:10 +08:00
export default {
name: 'ChartComponentS2',
2022-07-25 10:07:33 +08:00
components: { TitleRemark, ViewTrackBar },
2022-01-31 12:07:10 +08:00
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: ''
2022-01-31 12:07:10 +08:00
},
container_bg_class: {
background: hexColorToRGBA('#ffffff', 0)
},
title_show: true,
antVRenderStatus: false,
currentPage: {
page: 1,
pageSize: 20,
show: 0
},
tableData: [],
2022-06-26 15:56:21 +08:00
showPage: false,
scrollTimer: null,
2022-07-25 10:07:33 +08:00
scrollTop: 0,
remarkCfg: {
show: false,
content: ''
}
2022-01-31 12:07:10 +08:00
}
},
computed: {
trackBarStyleTime() {
return this.trackBarStyle
},
bg_class() {
return {
borderRadius: this.borderRadius
2022-01-31 12:07:10 +08:00
}
}
},
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()
},
2022-06-26 15:56:21 +08:00
beforeDestroy() {
clearInterval(this.scrollTimer)
},
2022-01-31 12:07:10 +08:00
methods: {
initData() {
let datas = []
this.showPage = false
2022-02-15 15:56:51 +08:00
if (this.chart.data && this.chart.data.fields) {
2022-01-31 12:07:10 +08:00
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))
2022-04-20 14:26:36 +08:00
if (this.chart.type === 'table-info' && (attr.size.tablePageMode === 'page' || !attr.size.tablePageMode) && datas.length > this.currentPage.pageSize) {
2022-01-31 12:07:10 +08:00
// 计算分页
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)
this.showPage = true
2022-01-31 12:07:10 +08:00
}
} 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)
2022-02-01 15:30:09 +08:00
} else if (chart.type === 'table-normal') {
this.myChart = baseTableNormal(this.myChart, this.chartId, chart, this.antVAction, this.tableData)
2022-02-08 13:50:43 +08:00
} else if (chart.type === 'table-pivot') {
this.myChart = baseTablePivot(this.myChart, this.chartId, chart, this.antVAction, this.tableData)
2022-01-31 12:07:10 +08:00
} 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()
2022-06-26 15:56:21 +08:00
this.initScroll()
2022-01-31 12:07:10 +08:00
}
this.setBackGroundBorder()
},
antVAction(param) {
2022-02-05 12:47:34 +08:00
const cell = this.myChart.getCell(param.target)
const meta = cell.getMeta()
const nameIdMap = this.chart.data.fields.reduce((pre, next) => {
pre[next['dataeaseName']] = next['id']
return pre
}, {})
let rowData
if (this.chart.type === 'table-pivot') {
rowData = { ...meta.rowQuery, ...meta.colQuery }
rowData[meta.valueField] = meta.fieldValue
} else if (this.showPage) {
const rowIndex = (this.currentPage.page - 1) * this.currentPage.pageSize + meta.rowIndex
rowData = this.chart.data.tableRow[rowIndex]
} else {
rowData = this.chart.data.tableRow[meta.rowIndex]
}
2022-02-05 12:47:34 +08:00
const dimensionList = []
for (const key in rowData) {
dimensionList.push({ id: nameIdMap[key], value: rowData[key] })
}
2022-02-05 12:47:34 +08:00
this.pointParam = {
data: {
dimensionList: dimensionList,
quotaList: [],
name: meta.fieldValue
2022-02-05 12:47:34 +08:00
}
}
2022-01-31 12:07:10 +08:00
if (this.trackMenu.length < 2) { // 只有一个事件直接调用
this.trackClick(this.trackMenu[0])
} else { // 视图关联多个事件
2022-02-07 13:13:50 +08:00
this.trackBarStyle.left = param.x + 'px'
this.trackBarStyle.top = (param.y + 10) + 'px'
2022-01-31 12:07:10 +08:00
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'
}
}
2022-01-31 12:07:10 +08:00
},
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',
name: this.pointParam.data.name,
2022-01-31 12:07:10 +08:00
viewId: this.chart.id,
dimensionList: this.pointParam.data.dimensionList,
quotaList: this.pointParam.data.quotaList
}
const jumpParam = {
option: 'jump',
name: this.pointParam.data.name,
2022-01-31 12:07:10 +08:00
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'
}
this.title_class.fontFamily = customStyle.text.fontFamily ? customStyle.text.fontFamily : DEFAULT_TITLE_STYLE.fontFamily
this.title_class.letterSpacing = (customStyle.text.letterSpace ? customStyle.text.letterSpace : DEFAULT_TITLE_STYLE.letterSpace) + 'px'
this.title_class.textShadow = customStyle.text.fontShadow ? '2px 2px 4px' : 'none'
2022-01-31 12:07:10 +08:00
}
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)
}
2022-01-31 12:07:10 +08:00
}
2022-07-25 10:07:33 +08:00
this.initRemark()
2022-01-31 12:07:10 +08:00
},
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'
2022-02-08 13:50:43 +08:00
this.$refs.tableContainer.style.height = this.chartHeight
2022-01-31 12:07:10 +08:00
}
}
})
},
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
}
2022-06-26 15:56:21 +08:00
},
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 && senior.scrollCfg && senior.scrollCfg.open && (this.chart.type === 'table-normal' || (this.chart.type === 'table-info' && !this.showPage))) {
2022-06-26 15:56:21 +08:00
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)
}
2022-07-25 10:07:33 +08:00
},
initRemark() {
this.remarkCfg = getRemark(this.chart)
2022-01-31 12:07:10 +08:00
}
}
}
</script>
<style scoped lang="scss">
2022-02-01 15:30:09 +08:00
.table-dom-info{
2022-01-31 12:07:10 +08:00
height:calc(100% - 36px);
}
.table-dom-info-pull{
height:calc(100%);
}
2022-02-01 15:30:09 +08:00
.table-dom-normal{
height:100%;
}
2022-02-07 13:13:50 +08:00
.table-dom-info-drill{
height:calc(100% - 36px - 12px);
}
.table-dom-info-drill-pull{
height:calc(100% - 12px);
}
2022-02-07 13:13:50 +08:00
.table-dom-normal-drill{
height:calc(100% - 12px);
}
2022-01-31 12:07:10 +08:00
.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;
}
fix(frontend): 修复 css 中不再支持的样式深度选择符号 >>> 导致命令行报错的问题 (#2806) * fix: 执行 eslint 命令, 修复代码 * fix(frontend): justify-content 不支持的值 start, end 改为 flex-start, flex-end * Update format-utils.js 去掉注释 * fix(frontend): 修复 css 中不再支持的样式深度选择符号 >>> 导致命令行报错的问题, 替换为 ::v-deep * Update DateFormat.vue * Update FrameLinks.vue * Update Hyperlinks.vue * Update HyperlinksDialog.vue * Update LinkageField.vue * Update VideoLinks.vue * Update DeNumberRange.vue * Update DeSelectGrid.vue * Update index.scss * Update index.vue * Update BackgroundColorSelector.vue * Update LegendSelector.vue * Update LegendSelectorAntV.vue * Update SplitSelector.vue * Update SplitSelectorAntV.vue * Update TitleSelector.vue * Update TitleSelectorAntV.vue * Update XAxisSelector.vue * Update XAxisSelectorAntV.vue * Update YAxisExtSelector.vue * Update YAxisExtSelectorAntV.vue * Update YAxisSelector.vue * Update YAxisSelectorAntV.vue * Update QuotaFilterEditor.vue * Update ResultFilterEditor.vue * Update LabelNormal.vue * Update LabelNormalText.vue * Update AssistLine.vue * Update FunctionCfg.vue * Update ScrollCfg.vue * Update Threshold.vue * Update ColorSelector.vue * Update LabelSelector.vue * Update SizeSelector.vue * Update TooltipSelector.vue * Update TooltipSelectorAntV.vue * Update TotalCfg.vue * Update TableNormal.vue * Update ChartStyle.vue * Update AddCustom.vue * Update AddExcel.vue * Update DatasetChartDetail.vue * Update DatasetGroupSelector.vue * Update DatasetGroupSelectorTree.vue * Update CalcFieldEdit.vue * Update FieldEdit.vue * Update TabDataPreview.vue * Update UnionView.vue * Update UpdateInfo.vue * Update Group.vue * Update all.vue * Update readed.vue * Update unread.vue * Update index.vue * Update index.vue * Update index.vue * Update PanelBackgroundColorSelector.vue * Update PanelColorSelector.vue * Update ViewAttribute.vue * Update SubjectTemplateItem.vue * Update multiplexing.vue * Update filterDialog.vue * Update PanelList.vue * Update PanelMain.vue * Update PanelDetailInfo.vue * Update MapSettingLeft.vue * Update index.vue * Update DatasetTaskList.vue * Update TaskRecord.vue * Update dataset.vue * Update personPwd.vue * Update privateForm.vue Co-authored-by: 王嘉豪 <42510293+ziyujiahao@users.noreply.github.com>
2022-08-05 18:24:27 +08:00
.page-style ::v-deep .el-input__inner{
2022-01-31 12:07:10 +08:00
height: 24px;
}
fix(frontend): 修复 css 中不再支持的样式深度选择符号 >>> 导致命令行报错的问题 (#2806) * fix: 执行 eslint 命令, 修复代码 * fix(frontend): justify-content 不支持的值 start, end 改为 flex-start, flex-end * Update format-utils.js 去掉注释 * fix(frontend): 修复 css 中不再支持的样式深度选择符号 >>> 导致命令行报错的问题, 替换为 ::v-deep * Update DateFormat.vue * Update FrameLinks.vue * Update Hyperlinks.vue * Update HyperlinksDialog.vue * Update LinkageField.vue * Update VideoLinks.vue * Update DeNumberRange.vue * Update DeSelectGrid.vue * Update index.scss * Update index.vue * Update BackgroundColorSelector.vue * Update LegendSelector.vue * Update LegendSelectorAntV.vue * Update SplitSelector.vue * Update SplitSelectorAntV.vue * Update TitleSelector.vue * Update TitleSelectorAntV.vue * Update XAxisSelector.vue * Update XAxisSelectorAntV.vue * Update YAxisExtSelector.vue * Update YAxisExtSelectorAntV.vue * Update YAxisSelector.vue * Update YAxisSelectorAntV.vue * Update QuotaFilterEditor.vue * Update ResultFilterEditor.vue * Update LabelNormal.vue * Update LabelNormalText.vue * Update AssistLine.vue * Update FunctionCfg.vue * Update ScrollCfg.vue * Update Threshold.vue * Update ColorSelector.vue * Update LabelSelector.vue * Update SizeSelector.vue * Update TooltipSelector.vue * Update TooltipSelectorAntV.vue * Update TotalCfg.vue * Update TableNormal.vue * Update ChartStyle.vue * Update AddCustom.vue * Update AddExcel.vue * Update DatasetChartDetail.vue * Update DatasetGroupSelector.vue * Update DatasetGroupSelectorTree.vue * Update CalcFieldEdit.vue * Update FieldEdit.vue * Update TabDataPreview.vue * Update UnionView.vue * Update UpdateInfo.vue * Update Group.vue * Update all.vue * Update readed.vue * Update unread.vue * Update index.vue * Update index.vue * Update index.vue * Update PanelBackgroundColorSelector.vue * Update PanelColorSelector.vue * Update ViewAttribute.vue * Update SubjectTemplateItem.vue * Update multiplexing.vue * Update filterDialog.vue * Update PanelList.vue * Update PanelMain.vue * Update PanelDetailInfo.vue * Update MapSettingLeft.vue * Update index.vue * Update DatasetTaskList.vue * Update TaskRecord.vue * Update dataset.vue * Update personPwd.vue * Update privateForm.vue Co-authored-by: 王嘉豪 <42510293+ziyujiahao@users.noreply.github.com>
2022-08-05 18:24:27 +08:00
.page-style ::v-deep button{
background: transparent!important;
}
fix(frontend): 修复 css 中不再支持的样式深度选择符号 >>> 导致命令行报错的问题 (#2806) * fix: 执行 eslint 命令, 修复代码 * fix(frontend): justify-content 不支持的值 start, end 改为 flex-start, flex-end * Update format-utils.js 去掉注释 * fix(frontend): 修复 css 中不再支持的样式深度选择符号 >>> 导致命令行报错的问题, 替换为 ::v-deep * Update DateFormat.vue * Update FrameLinks.vue * Update Hyperlinks.vue * Update HyperlinksDialog.vue * Update LinkageField.vue * Update VideoLinks.vue * Update DeNumberRange.vue * Update DeSelectGrid.vue * Update index.scss * Update index.vue * Update BackgroundColorSelector.vue * Update LegendSelector.vue * Update LegendSelectorAntV.vue * Update SplitSelector.vue * Update SplitSelectorAntV.vue * Update TitleSelector.vue * Update TitleSelectorAntV.vue * Update XAxisSelector.vue * Update XAxisSelectorAntV.vue * Update YAxisExtSelector.vue * Update YAxisExtSelectorAntV.vue * Update YAxisSelector.vue * Update YAxisSelectorAntV.vue * Update QuotaFilterEditor.vue * Update ResultFilterEditor.vue * Update LabelNormal.vue * Update LabelNormalText.vue * Update AssistLine.vue * Update FunctionCfg.vue * Update ScrollCfg.vue * Update Threshold.vue * Update ColorSelector.vue * Update LabelSelector.vue * Update SizeSelector.vue * Update TooltipSelector.vue * Update TooltipSelectorAntV.vue * Update TotalCfg.vue * Update TableNormal.vue * Update ChartStyle.vue * Update AddCustom.vue * Update AddExcel.vue * Update DatasetChartDetail.vue * Update DatasetGroupSelector.vue * Update DatasetGroupSelectorTree.vue * Update CalcFieldEdit.vue * Update FieldEdit.vue * Update TabDataPreview.vue * Update UnionView.vue * Update UpdateInfo.vue * Update Group.vue * Update all.vue * Update readed.vue * Update unread.vue * Update index.vue * Update index.vue * Update index.vue * Update PanelBackgroundColorSelector.vue * Update PanelColorSelector.vue * Update ViewAttribute.vue * Update SubjectTemplateItem.vue * Update multiplexing.vue * Update filterDialog.vue * Update PanelList.vue * Update PanelMain.vue * Update PanelDetailInfo.vue * Update MapSettingLeft.vue * Update index.vue * Update DatasetTaskList.vue * Update TaskRecord.vue * Update dataset.vue * Update personPwd.vue * Update privateForm.vue Co-authored-by: 王嘉豪 <42510293+ziyujiahao@users.noreply.github.com>
2022-08-05 18:24:27 +08:00
.page-style ::v-deep li{
background: transparent!important;
}
2022-01-31 12:07:10 +08:00
</style>