feat(视图): 表格支持阈值设置

This commit is contained in:
junjun 2022-07-18 10:42:27 +08:00
parent c731df25e1
commit ae7ec67161
7 changed files with 597 additions and 14 deletions

View File

@ -1121,7 +1121,15 @@ export default {
open: 'Open',
row: 'Row',
interval: 'Interval',
max_more_than_mix: 'Max must more than Min'
max_more_than_mix: 'Max must more than Min',
field: 'Field',
textColor: 'Text Color',
backgroundColor: 'Background Color',
field_can_not_empty: 'Field can not empty',
conditions_can_not_empty: 'Conditions can not be emptyif unnecessaryplease delete the field',
remark: 'Remark',
remark_edit: 'Edit Remark',
remark_bg_color: 'Background Fill'
},
dataset: {
params_work: 'Effective only when editing SQL',

View File

@ -1121,7 +1121,15 @@ export default {
open: '開啟',
row: '行數',
interval: '間隔',
max_more_than_mix: '最大值必須大於最小值'
max_more_than_mix: '最大值必須大於最小值',
field: '字段',
textColor: '文字顏色',
backgroundColor: '背景顏色',
field_can_not_empty: '字段不能為空',
conditions_can_not_empty: '字段的條件不能為空,若無條件,請直接刪除該字段',
remark: '備註',
remark_edit: '編輯備註',
remark_bg_color: '背景填充'
},
dataset: {
params_work: '僅在編輯 sql 時生效',

View File

@ -1123,7 +1123,15 @@ export default {
open: '开启',
row: '行数',
interval: '间隔',
max_more_than_mix: '最大值必须大于最小值'
max_more_than_mix: '最大值必须大于最小值',
field: '字段',
textColor: '文字颜色',
backgroundColor: '背景颜色',
field_can_not_empty: '字段不能为空',
conditions_can_not_empty: '字段的条件不能为空,若无条件,请直接删除该字段',
remark: '备注',
remark_edit: '编辑备注',
remark_bg_color: '背景填充'
},
dataset: {
params_work: '仅在编辑sql时生效',

View File

@ -144,7 +144,10 @@ export const DEFAULT_TITLE_STYLE = {
hPosition: 'left',
vPosition: 'top',
isItalic: false,
isBolder: true
isBolder: true,
remarkShow: false,
remark: '',
remarkBackgroundColor: '#ffffffff'
}
export const DEFAULT_TITLE_STYLE_DARK = {
@ -337,7 +340,8 @@ export const DEFAULT_FUNCTION_CFG = {
}
export const DEFAULT_THRESHOLD = {
gaugeThreshold: '',
labelThreshold: []
labelThreshold: [],
tableThreshold: []
}
export const DEFAULT_SCROLL = {
open: false,

View File

@ -44,14 +44,67 @@
<span :title="item.value">{{ item.value }}</span>
</el-col>
<el-col :span="8">
<span :style="{width:'14px', height:'14px', backgroundColor: item.color}" />
<span :style="{width:'14px', height:'14px', backgroundColor: item.color, border: 'solid 1px #e1e4e8'}" />
</el-col>
</el-row>
</el-col>
</el-col>
</el-col>
<!--编辑阈值-->
<!--表格-->
<el-col v-if="chart.type && (chart.render === 'antv' && chart.type.includes('table'))">
<el-col>
<el-button
:title="$t('chart.edit')"
icon="el-icon-edit"
type="text"
size="small"
style="width: 24px;margin-left: 4px;"
@click="editTableThreshold"
/>
<el-col style="padding: 0 18px;max-height: 500px;overflow-y: auto;">
<el-row v-for="(fieldItem,fieldIndex) in thresholdForm.tableThreshold" :key="fieldIndex">
<el-row class="field-style">
<span>
<svg-icon v-if="fieldItem.field.deType === 0" icon-class="field_text" class="field-icon-text" />
<svg-icon v-if="fieldItem.field.deType === 1" icon-class="field_time" class="field-icon-time" />
<svg-icon v-if="fieldItem.field.deType === 2 || fieldItem.field.value === 3" icon-class="field_value" class="field-icon-value" />
<svg-icon v-if="fieldItem.field.deType === 5" icon-class="field_location" class="field-icon-location" />
</span>
<span :title="fieldItem.field.name" class="field-text">{{ fieldItem.field.name }}</span>
</el-row>
<el-row v-for="(item,index) in fieldItem.conditions" :key="index" class="line-style">
<el-col :span="6">
<span v-if="item.term === 'eq'" :title="$t('chart.filter_eq')">{{ $t('chart.filter_eq') }}</span>
<span v-else-if="item.term === 'not_eq'" :title="$t('chart.filter_not_eq')">{{ $t('chart.filter_not_eq') }}</span>
<span v-else-if="item.term === 'lt'" :title="$t('chart.filter_lt')">{{ $t('chart.filter_lt') }}</span>
<span v-else-if="item.term === 'gt'" :title="$t('chart.filter_gt')">{{ $t('chart.filter_gt') }}</span>
<span v-else-if="item.term === 'le'" :title="$t('chart.filter_le')">{{ $t('chart.filter_le') }}</span>
<span v-else-if="item.term === 'ge'" :title="$t('chart.filter_ge')">{{ $t('chart.filter_ge') }}</span>
<span v-else-if="item.term === 'like'" :title="$t('chart.filter_like')">{{ $t('chart.filter_like') }}</span>
<span v-else-if="item.term === 'not like'" :title="$t('chart.filter_not_like')">{{ $t('chart.filter_not_like') }}</span>
<span v-else-if="item.term === 'null'" :title="$t('chart.filter_null')">{{ $t('chart.filter_null') }}</span>
<span v-else-if="item.term === 'not_null'" :title="$t('chart.filter_not_null')">{{ $t('chart.filter_not_null') }}</span>
<span v-else-if="item.term === 'empty'" :title="$t('chart.filter_empty')">{{ $t('chart.filter_empty') }}</span>
<span v-else-if="item.term === 'not_empty'" :title="$t('chart.filter_not_empty')">{{ $t('chart.filter_not_empty') }}</span>
</el-col>
<el-col :span="6">
<span v-if="!item.term.includes('null') && !item.term.includes('empty')" :title="item.value">{{ item.value }}</span>
<span v-else>&nbsp;</span>
</el-col>
<el-col :span="6">
<span :title="$t('chart.textColor')" :style="{width:'14px', height:'14px', backgroundColor: item.color, border: 'solid 1px #e1e4e8'}" />
</el-col>
<el-col :span="6">
<span :title="$t('chart.backgroundColor')" :style="{width:'14px', height:'14px', backgroundColor: item.backgroundColor, border: 'solid 1px #e1e4e8'}" />
</el-col>
</el-row>
</el-row>
</el-col>
</el-col>
</el-col>
<!--编辑指标卡阈值-->
<el-dialog
v-if="editLabelThresholdDialog"
v-dialogDrag
@ -60,6 +113,7 @@
:show-close="false"
width="50%"
class="dialog-css"
append-to-body
>
<text-threshold-edit :threshold="thresholdForm.labelThreshold" @onLabelThresholdChange="thresholdChange" />
<div slot="footer" class="dialog-footer">
@ -67,16 +121,36 @@
<el-button type="primary" size="mini" @click="changeLabelThreshold">{{ $t('chart.confirm') }}</el-button>
</div>
</el-dialog>
<!--编辑表格阈值-->
<el-dialog
v-if="editTableThresholdDialog"
v-dialogDrag
:title="$t('chart.threshold')"
:visible="editTableThresholdDialog"
:show-close="false"
width="50%"
class="dialog-css"
append-to-body
>
<table-threshold-edit :threshold="thresholdForm.tableThreshold" :chart="chart" @onTableThresholdChange="tableThresholdChange" />
<div slot="footer" class="dialog-footer">
<el-button size="mini" @click="closeTableThreshold">{{ $t('chart.cancel') }}</el-button>
<el-button type="primary" size="mini" @click="changeTableThreshold">{{ $t('chart.confirm') }}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { DEFAULT_THRESHOLD } from '@/views/chart/chart/chart'
import TextThresholdEdit from '@/views/chart/components/senior/dialog/TextThresholdEdit'
import TableThresholdEdit from '@/views/chart/components/senior/dialog/TableThresholdEdit'
export default {
name: 'Threshold',
components: { TextThresholdEdit },
components: { TableThresholdEdit, TextThresholdEdit },
props: {
chart: {
type: Object,
@ -87,7 +161,9 @@ export default {
return {
thresholdForm: JSON.parse(JSON.stringify(DEFAULT_THRESHOLD)),
editLabelThresholdDialog: false,
thresholdArr: []
thresholdArr: [],
editTableThresholdDialog: false,
tableThresholdArr: []
}
},
watch: {
@ -115,9 +191,14 @@ export default {
if (!this.thresholdForm.labelThreshold) {
this.thresholdForm.labelThreshold = []
}
if (!this.thresholdForm.tableThreshold) {
this.thresholdForm.tableThreshold = []
}
} else {
this.thresholdForm = JSON.parse(JSON.stringify(DEFAULT_THRESHOLD))
}
this.thresholdArr = JSON.parse(JSON.stringify(this.thresholdForm.labelThreshold))
this.tableThresholdArr = JSON.parse(JSON.stringify(this.thresholdForm.tableThreshold))
}
},
changeThreshold() {
@ -192,6 +273,68 @@ export default {
},
thresholdChange(val) {
this.thresholdArr = val
},
tableThresholdChange(val) {
this.tableThresholdArr = val
},
editTableThreshold() {
this.editTableThresholdDialog = true
},
closeTableThreshold() {
this.editTableThresholdDialog = false
},
changeTableThreshold() {
// check line config
for (let i = 0; i < this.tableThresholdArr.length; i++) {
const field = this.tableThresholdArr[i]
if (!field.fieldId) {
this.$message({
message: this.$t('chart.field_can_not_empty'),
type: 'error',
showClose: true
})
return
}
if (!field.conditions || field.conditions.length === 0) {
this.$message({
message: this.$t('chart.conditions_can_not_empty'),
type: 'error',
showClose: true
})
return
}
for (let j = 0; j < field.conditions.length; j++) {
const ele = field.conditions[j]
if (!ele.term || ele.term === '') {
this.$message({
message: this.$t('chart.exp_can_not_empty'),
type: 'error',
showClose: true
})
return
}
if (!ele.value) {
this.$message({
message: this.$t('chart.value_can_not_empty'),
type: 'error',
showClose: true
})
return
}
if ((field.field.deType === 2 || field.field.deType === 3 || field.field.deType === 4) && parseFloat(ele.value).toString() === 'NaN') {
this.$message({
message: this.$t('chart.value_error'),
type: 'error',
showClose: true
})
return
}
}
}
this.thresholdForm.tableThreshold = JSON.parse(JSON.stringify(this.tableThresholdArr))
this.changeThreshold()
this.closeTableThreshold()
}
}
}
@ -253,4 +396,18 @@ span{
.dialog-css >>> .el-dialog__body {
padding: 10px 20px 20px;
}
.field-style{
display: flex;
align-items: center;
justify-content: start;
}
.field-text{
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: #8492a6;
font-size: 12px;
}
</style>

View File

@ -0,0 +1,398 @@
<template>
<el-col>
<el-button icon="el-icon-plus" circle size="mini" style="margin-bottom: 10px;" @click="addThreshold" />
<div style="max-height: 50vh;overflow-y: auto;">
<div v-for="(fieldItem,fieldIndex) in thresholdArr" :key="fieldIndex" class="field-item">
<el-row style="margin-top: 6px;">
<span class="color-title">{{ $t('chart.field') }}</span>
<el-select v-model="fieldItem.fieldId" size="mini" @change="addField(fieldItem)">
<el-option
v-for="fieldOption in fields"
:key="fieldOption.id"
:label="fieldOption.name"
:value="fieldOption.id"
>
<span style="float: left">
<svg-icon v-if="fieldOption.deType === 0" icon-class="field_text" class="field-icon-text" />
<svg-icon v-if="fieldOption.deType === 1" icon-class="field_time" class="field-icon-time" />
<svg-icon
v-if="fieldOption.deType === 2 || fieldOption.value === 3"
icon-class="field_value"
class="field-icon-value"
/>
<svg-icon v-if="fieldOption.deType === 5" icon-class="field_location" class="field-icon-location" />
</span>
<span style="float: left; color: #8492a6; font-size: 12px">{{ fieldOption.name }}</span>
</el-option>
</el-select>
<el-button
type="text"
icon="el-icon-plus"
circle
size="mini"
style="margin-bottom: 10px;margin-left: 10px;"
@click="addConditions(fieldItem)"
/>
<el-button
icon="el-icon-delete"
circle
size="mini"
style="margin-bottom: 10px;float: right;"
@click="removeThreshold(fieldIndex)"
/>
</el-row>
<el-row v-for="(item,index) in fieldItem.conditions" :key="index" class="line-item">
<el-col :span="4">
<el-select v-model="item.term" size="mini" @change="changeThreshold">
<el-option-group
v-for="(group,idx) in fieldItem.options"
:key="idx"
:label="group.label"
>
<el-option
v-for="opt in group.options"
:key="opt.value"
:label="opt.label"
:value="opt.value"
/>
</el-option-group>
</el-select>
</el-col>
<el-col :span="8" style="text-align: center;">
<el-input
v-show="!item.term.includes('null') && !item.term.includes('empty')"
v-model="item.value"
class="value-item"
:placeholder="$t('chart.drag_block_label_value')"
size="mini"
clearable
@change="changeThreshold"
/>
</el-col>
<el-col :span="4" style="display: flex;align-items: center;justify-content: center;">
<span class="color-title">{{ $t('chart.textColor') }}</span>
<el-color-picker
v-model="item.color"
show-alpha
class="color-picker-style"
:predefine="predefineColors"
@change="changeThreshold"
/>
</el-col>
<el-col :span="4" style="display: flex;align-items: center;justify-content: center;">
<span class="color-title">{{ $t('chart.backgroundColor') }}</span>
<el-color-picker
v-model="item.backgroundColor"
show-alpha
class="color-picker-style"
:predefine="predefineColors"
@change="changeThreshold"
/>
</el-col>
<el-col :span="4">
<el-button
type="text"
icon="el-icon-delete"
circle
style="float: right"
@click="removeCondition(fieldItem,index)"
/>
</el-col>
</el-row>
</div>
</div>
<div class="tip">提示请勿重复选择字段若同一字段重复配置则只有最后的字段配置生效</div>
</el-col>
</template>
<script>
import { COLOR_PANEL } from '@/views/chart/chart/chart'
export default {
name: 'TableThresholdEdit',
props: {
threshold: {
type: Array,
required: true
},
chart: {
type: Object,
required: true
}
},
data() {
return {
thresholdArr: [],
fields: [],
thresholdObj: {
fieldId: '',
field: {},
conditions: []
},
thresholdCondition: {
term: 'eq',
field: '0',
value: '',
color: '#ff0000ff',
backgroundColor: '#ffffffff'
},
textOptions: [
{
label: '',
options: [{
value: 'eq',
label: this.$t('chart.filter_eq')
}, {
value: 'not_eq',
label: this.$t('chart.filter_not_eq')
}]
},
{
label: '',
options: [{
value: 'like',
label: this.$t('chart.filter_like')
}, {
value: 'not like',
label: this.$t('chart.filter_not_like')
}]
},
{
label: '',
options: [{
value: 'null',
label: this.$t('chart.filter_null')
}, {
value: 'not_null',
label: this.$t('chart.filter_not_null')
}]
},
{
label: '',
options: [{
value: 'empty',
label: this.$t('chart.filter_empty')
}, {
value: 'not_empty',
label: this.$t('chart.filter_not_empty')
}]
}
],
dateOptions: [
{
label: '',
options: [{
value: 'eq',
label: this.$t('chart.filter_eq')
}, {
value: 'not_eq',
label: this.$t('chart.filter_not_eq')
}]
},
{
label: '',
options: [{
value: 'lt',
label: this.$t('chart.filter_lt')
}, {
value: 'gt',
label: this.$t('chart.filter_gt')
}]
},
{
label: '',
options: [{
value: 'le',
label: this.$t('chart.filter_le')
}, {
value: 'ge',
label: this.$t('chart.filter_ge')
}]
}
],
valueOptions: [
{
label: '',
options: [{
value: 'eq',
label: this.$t('chart.filter_eq')
}, {
value: 'not_eq',
label: this.$t('chart.filter_not_eq')
}]
},
{
label: '',
options: [{
value: 'lt',
label: this.$t('chart.filter_lt')
}, {
value: 'gt',
label: this.$t('chart.filter_gt')
}]
},
{
label: '',
options: [{
value: 'le',
label: this.$t('chart.filter_le')
}, {
value: 'ge',
label: this.$t('chart.filter_ge')
}]
}
],
predefineColors: COLOR_PANEL
}
},
mounted() {
this.init()
},
methods: {
init() {
this.thresholdArr = JSON.parse(JSON.stringify(this.threshold))
this.initFields()
},
initOptions(item) {
if (item.field) {
if (item.field.deType === 0 || item.field.deType === 5) {
item.options = JSON.parse(JSON.stringify(this.textOptions))
} else if (item.field.deType === 1) {
item.options = JSON.parse(JSON.stringify(this.dateOptions))
} else {
item.options = JSON.parse(JSON.stringify(this.valueOptions))
}
item.conditions && item.conditions.forEach(ele => {
ele.term = ''
})
}
},
initFields() {
//
if (this.chart.type === 'table-info') {
if (Object.prototype.toString.call(this.chart.xaxis) === '[object Array]') {
this.fields = JSON.parse(JSON.stringify(this.chart.xaxis))
} else {
this.fields = JSON.parse(this.chart.xaxis)
}
} else if (this.chart.type === 'table-pivot') {
if (Object.prototype.toString.call(this.chart.yaxis) === '[object Array]') {
this.fields = JSON.parse(JSON.stringify(this.chart.yaxis))
} else {
this.fields = JSON.parse(this.chart.yaxis)
}
} else {
if (Object.prototype.toString.call(this.chart.xaxis) === '[object Array]') {
this.fields = this.fields.concat(JSON.parse(JSON.stringify(this.chart.xaxis)))
} else {
this.fields = this.fields.concat(JSON.parse(this.chart.xaxis))
}
if (Object.prototype.toString.call(this.chart.yaxis) === '[object Array]') {
this.fields = this.fields.concat(JSON.parse(JSON.stringify(this.chart.yaxis)))
} else {
this.fields = this.fields.concat(JSON.parse(this.chart.yaxis))
}
}
//
// this.fields = this.fields.filter(ele => ele.deType !== 1)
},
addThreshold() {
this.thresholdArr.push(JSON.parse(JSON.stringify(this.thresholdObj)))
this.changeThreshold()
},
removeThreshold(index) {
this.thresholdArr.splice(index, 1)
this.changeThreshold()
},
changeThreshold() {
this.$emit('onTableThresholdChange', this.thresholdArr)
},
addConditions(item) {
item.conditions.push(JSON.parse(JSON.stringify(this.thresholdCondition)))
this.changeThreshold()
},
removeCondition(item, index) {
item.conditions.splice(index, 1)
this.changeThreshold()
},
addField(item) {
// get field
if (this.fields && this.fields.length > 0) {
this.fields.forEach(ele => {
if (item.fieldId === ele.id) {
item.field = JSON.parse(JSON.stringify(ele))
this.initOptions(item)
}
})
}
this.changeThreshold()
}
}
}
</script>
<style scoped>
.field-item {
width: 100%;
border-radius: 4px;
border: 1px solid #DCDFE6;
padding: 4px 14px;
margin-bottom: 10px;
}
.line-item {
width: 100%;
display: flex;
justify-content: left;
align-items: center;
}
.form-item >>> .el-form-item__label {
font-size: 12px;
}
span {
font-size: 12px;
}
.value-item {
position: relative;
display: inline-block;
width: 200px !important;
}
.select-item {
position: relative;
display: inline-block;
width: 100px !important;
}
.el-select-dropdown__item {
padding: 0 20px;
font-size: 12px;
}
.color-picker-style {
cursor: pointer;
z-index: 1003;
width: 28px;
height: 28px;
}
.color-picker-style >>> .el-color-picker__trigger {
width: 28px;
height: 28px;
}
.color-title {
margin-right: 6px;
color: #909399;
}
.tip {
color: #F56C6C;
font-size: 12px;
}
</style>

View File

@ -697,12 +697,12 @@
<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' || view.type === 'table-normal' || view.type === 'table-info'"
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.includes('table'))"
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') || view.type.includes('table'))"
v-if="view.type && (view.type.includes('bar') || view.type.includes('line') || view.type.includes('mix') || view.type === 'table-normal' || view.type === 'table-info')"
>
<span class="padding-lr">{{ $t('chart.senior_cfg') }}</span>
<el-collapse v-model="attrActiveNames" class="style-collapse">
@ -714,7 +714,7 @@
@onFunctionCfgChange="onFunctionCfgChange"
/>
</el-collapse-item>
<el-collapse-item v-if="view.type && (view.type.includes('table'))" name="scroll" :title="$t('chart.scroll_cfg')">
<el-collapse-item v-if="view.type && (view.type === 'table-normal' || view.type === 'table-info')" name="scroll" :title="$t('chart.scroll_cfg')">
<scroll-cfg
:param="param"
class="attr-selector"
@ -725,7 +725,7 @@
</el-collapse>
</el-row>
<el-row
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.render === 'antv' && view.type.includes('table')))"
>
<span class="padding-lr">{{ $t('chart.analyse_cfg') }}</span>
<el-collapse v-model="styleActiveNames" class="style-collapse">
@ -742,7 +742,7 @@
/>
</el-collapse-item>
<el-collapse-item
v-if="view.type && (view.type.includes('gauge') || view.type === 'text')"
v-if="view.type && (view.type.includes('gauge') || view.type === 'text' || (view.render === 'antv' && view.type.includes('table')))"
name="threshold"
:title="$t('chart.threshold')"
>