feat(视图): 1.初步增加结果过滤,条件之间暂时只支持'且'逻辑;2.fix设置显示名bug;3.一些样式调整

This commit is contained in:
junjie 2021-03-25 11:34:46 +08:00
parent 470f8cddae
commit b3a53f9a64
10 changed files with 303 additions and 83 deletions

View File

@ -2,6 +2,8 @@ package io.dataease.dto.chart;
import lombok.Data;
import java.util.List;
/**
* @Author gin
* @Date 2021/3/11 1:18 下午
@ -29,4 +31,6 @@ public class ChartViewFieldDTO {
private String summary;
private String sort;
private List<ChartViewFieldFilterDTO> filter;
}

View File

@ -0,0 +1,15 @@
package io.dataease.dto.chart;
import lombok.Getter;
import lombok.Setter;
/**
* @Author gin
* @Date 2021/3/25 10:31 上午
*/
@Getter
@Setter
public class ChartViewFieldFilterDTO {
private String term;
private String value;
}

View File

@ -174,6 +174,41 @@ public class ChartViewService {
sql = sql.substring(0, sql.length() - 1);
}
// 如果是对结果字段过滤则再包裹一层sql
return sql;
String[] resultFilter = yAxis.stream().filter(y -> CollectionUtils.isNotEmpty(y.getFilter()) && y.getFilter().size() > 0)
.map(y -> {
String[] s = y.getFilter().stream().map(f -> "AND _" + y.getSummary() + "_" + y.getOriginName() + transMysqlFilterTerm(f.getTerm()) + f.getValue()).toArray(String[]::new);
return StringUtils.join(s, " ");
}).toArray(String[]::new);
if (resultFilter.length == 0) {
return sql;
} else {
String filterSql = MessageFormat.format("SELECT * FROM {0} WHERE 1=1 {1}",
"(" + sql + ") AS tmp",
StringUtils.join(resultFilter, " "));
return filterSql;
}
}
public String transMysqlFilterTerm(String term) {
switch (term) {
case "eq":
return "=";
case "not_eq":
return "<>";
case "lt":
return "<";
case "le":
return "<=";
case "gt":
return ">";
case "ge":
return ">=";
case "null":
return "IS NULL";
case "not_null":
return "IS NOT NULL";
default:
return "";
}
}
}

View File

@ -681,7 +681,19 @@ export default {
filter: '过滤',
none: '无',
background: '背景',
alpha: '透明度'
alpha: '透明度',
add_filter: '添加过滤',
no_limit: '无限制',
filter_eq: '等于',
filter_not_eq: '不等于',
filter_lt: '小于',
filter_le: '小于等于',
filter_gt: '大于',
filter_ge: '大于等于',
filter_null: '为空',
filter_not_null: '不为空',
filter_include: '包含',
filter_not_include: '不包含'
},
dataset: {
datalist: '数据集',

View File

@ -11,7 +11,7 @@
<el-form-item :label="$t('chart.color')" class="form-item">
<colorPicker v-model="colorForm.color" style="margin-top: 6px;cursor: pointer;z-index: 999;border: solid 1px black" @change="changeBackgroundStyle" />
</el-form-item>
<el-form-item :label="$t('chart.alpha')" class="form-item">
<el-form-item :label="$t('chart.not_alpha')" class="form-item form-item-slider">
<el-slider v-model="colorForm.alpha" show-input :show-input-controls="false" input-size="mini" @change="changeBackgroundStyle" />
</el-form-item>
</el-form>

View File

@ -15,18 +15,6 @@
</el-dropdown-menu>
</span>
</el-dropdown>
<el-dialog :title="$t('chart.show_name_set')" :visible="renameItem" :show-close="false" width="30%">
<el-form ref="itemForm" :model="itemForm" :rules="itemFormRules">
<el-form-item :label="$t('commons.name')" prop="name">
<el-input v-model="itemForm.name" size="mini" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button size="mini" @click="closeRename()">{{ $t('chart.cancel') }}</el-button>
<el-button type="primary" size="mini" @click="saveRename(itemForm)">{{ $t('chart.confirm') }}</el-button>
</div>
</el-dialog>
</span>
</template>
@ -45,15 +33,6 @@ export default {
},
data() {
return {
renameItem: false,
itemForm: {
name: ''
},
itemFormRules: {
name: [
{ required: true, message: this.$t('commons.input_content'), trigger: 'change' }
]
}
}
},
mounted() {
@ -80,22 +59,9 @@ export default {
}
},
showRename() {
this.itemForm.name = this.item.name
this.renameItem = true
},
closeRename() {
this.renameItem = false
this.resetRename()
},
saveRename(param) {
this.item.name = param.name
this.$emit('onDimensionItemChange', this.item)
this.closeRename()
},
resetRename() {
this.itemForm = {
name: ''
}
this.item.index = this.index
this.item.renameType = 'dimension'
this.$emit('onNameEdit', this.item)
},
removeItem() {
this.item.index = this.index

View File

@ -59,7 +59,7 @@
</el-dropdown-menu>
</el-dropdown>
</el-dropdown-item>
<el-dropdown-item icon="el-icon-files">
<el-dropdown-item icon="el-icon-files" :command="beforeClickItem('filter')">
<span>{{ $t('chart.filter') }}...</span>
</el-dropdown-item>
<el-dropdown-item icon="el-icon-edit-outline" divided :command="beforeClickItem('rename')">
@ -71,18 +71,6 @@
</el-dropdown-menu>
</span>
</el-dropdown>
<el-dialog :title="$t('chart.show_name_set')" :visible="renameItem" :show-close="false" width="30%">
<el-form ref="itemForm" :model="itemForm" :rules="itemFormRules">
<el-form-item :label="$t('commons.name')" prop="name">
<el-input v-model="itemForm.name" size="mini" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button size="mini" @click="closeRename()">{{ $t('chart.cancel') }}</el-button>
<el-button type="primary" size="mini" @click="saveRename(itemForm)">{{ $t('chart.confirm') }}</el-button>
</div>
</el-dialog>
</span>
</template>
@ -101,15 +89,6 @@ export default {
},
data() {
return {
renameItem: false,
itemForm: {
name: ''
},
itemFormRules: {
name: [
{ required: true, message: this.$t('commons.input_content'), trigger: 'change' }
]
}
}
},
mounted() {
@ -127,6 +106,9 @@ export default {
case 'remove':
this.removeItem()
break
case 'filter':
this.editFilter()
break
default:
break
}
@ -167,28 +149,18 @@ export default {
type: type
}
},
showRename() {
this.itemForm.name = this.item.name
this.renameItem = true
},
closeRename() {
this.renameItem = false
this.resetRename()
},
saveRename(param) {
this.item.name = param.name
this.$emit('onQuotaItemChange', this.item)
this.closeRename()
},
resetRename() {
this.itemForm = {
name: ''
}
this.item.index = this.index
this.item.renameType = 'quota'
this.$emit('onNameEdit', this.item)
},
removeItem() {
this.item.index = this.index
this.$emit('onQuotaItemRemove', this.item)
},
editFilter() {
this.item.index = this.index
this.$emit('editItemFilter', this.item)
}
}
}

View File

@ -0,0 +1,129 @@
<template>
<el-col>
<el-button icon="el-icon-plus" circle size="mini" style="margin-bottom: 10px;" @click="addFilter" />
<el-row v-for="(f,index) in item.filter" :key="index" class="filter-item">
<el-col :span="4">
<span>{{ item.name }} ({{ $t('chart.'+item.summary) }})</span>
</el-col>
<el-col :span="8">
<el-select v-model="f.term" size="mini">
<el-option-group
v-for="(group,idx) in 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="6">
<el-input v-model="f.value" class="value-item" :placeholder="$t('chart.no_limit')" size="mini" clearable />
</el-col>
<el-col :span="6">
<el-button type="text" icon="el-icon-delete" circle style="float: right" @click="removeFilter(index)" />
</el-col>
</el-row>
</el-col>
</template>
<script>
export default {
name: 'QuotaFilterEditor',
props: {
item: {
type: Object,
required: true
}
},
data() {
return {
options: [{
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')
}]
},
{
label: '',
options: [{
value: 'null',
label: this.$t('chart.filter_null')
}, {
value: 'not_null',
label: this.$t('chart.filter_not_null')
}]
}]
}
},
mounted() {
},
methods: {
addFilter() {
this.item.filter.push({
term: 'eq',
value: ''
})
},
removeFilter(index) {
this.item.filter.splice(index, 1)
}
}
}
</script>
<style scoped lang="scss">
.filter-item{
width: 100%;
border-radius: 4px;
border: 1px solid #DCDFE6;
padding: 4px 14px;
margin-bottom: 10px;
display: flex;
justify-content: left;
align-items: center;
}
.form-item>>>.el-form-item__label{
font-size: 12px;
}
span{
font-size: 12px;
}
.value-item>>>.el-input{
position: relative;
display: inline-block;
width: 80px!important;
}
.el-select-dropdown__item{
padding: 0 20px;
font-size: 12px;
}
</style>

View File

@ -528,7 +528,7 @@ export default {
yAxis: DEFAULT_YAXIS_STYLE,
background: DEFAULT_BACKGROUND_COLOR
})
view.customFilter = JSON.stringify({})
view.customFilter = JSON.stringify([])
post('/chart/view/save', view).then(response => {
this.selectTableFlag = false
this.$store.dispatch('chart/setTableId', null)

View File

@ -151,7 +151,7 @@
@end="end2"
>
<transition-group class="draggable-group">
<dimension-item v-for="(item,index) in view.xaxis" :key="item.id" :index="index" :item="item" @onDimensionItemChange="dimensionItemChange" @onDimensionItemRemove="dimensionItemRemove" />
<dimension-item v-for="(item,index) in view.xaxis" :key="item.id" :index="index" :item="item" @onDimensionItemChange="dimensionItemChange" @onDimensionItemRemove="dimensionItemRemove" @onNameEdit="showRename" />
</transition-group>
</draggable>
</el-row>
@ -166,7 +166,7 @@
@end="end2"
>
<transition-group class="draggable-group">
<quota-item v-for="(item,index) in view.yaxis" :key="item.id" :index="index" :item="item" @onQuotaItemChange="quotaItemChange" @onQuotaItemRemove="quotaItemRemove" />
<quota-item v-for="(item,index) in view.yaxis" :key="item.id" :index="index" :item="item" @onQuotaItemChange="quotaItemChange" @onQuotaItemRemove="quotaItemRemove" @editItemFilter="showEditFilter" @onNameEdit="showRename" />
</transition-group>
</draggable>
</el-row>
@ -176,6 +176,34 @@
</el-row>
</el-col>
</el-row>
<!--显示名修改-->
<el-dialog :title="$t('chart.show_name_set')" :visible="renameItem" :show-close="false" width="30%">
<el-form ref="itemForm" :model="itemForm" :rules="itemFormRules">
<el-form-item :label="$t('commons.name')" prop="name">
<el-input v-model="itemForm.name" size="mini" clearable />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button size="mini" @click="closeRename()">{{ $t('chart.cancel') }}</el-button>
<el-button type="primary" size="mini" @click="saveRename">{{ $t('chart.confirm') }}</el-button>
</div>
</el-dialog>
<!--指标过滤器-->
<el-dialog
:title="$t('chart.add_filter')"
:visible="filterEdit"
:show-close="false"
width="800px"
class="dialog-css"
>
<quota-filter-editor :item="quotaItem" />
<div slot="footer" class="dialog-footer">
<el-button size="mini" @click="closeQuotaFilter">{{ $t('chart.cancel') }}</el-button>
<el-button type="primary" size="mini" @click="saveQuotaFilter">{{ $t('chart.confirm') }}</el-button>
</div>
</el-dialog>
</el-row>
</template>
@ -207,10 +235,11 @@ import TooltipSelector from '../components/shape-attr/TooltipSelector'
import XAxisSelector from '../components/component-style/XAxisSelector'
import YAxisSelector from '../components/component-style/YAxisSelector'
import BackgroundColorSelector from '../components/component-style/BackgroundColorSelector'
import QuotaFilterEditor from '../components/filter/QuotaFilterEditor'
export default {
name: 'ChartEdit',
components: { BackgroundColorSelector, FilterItem, XAxisSelector, YAxisSelector, TooltipSelector, LabelSelector, LegendSelector, TitleSelector, SizeSelector, ColorSelector, ChartComponent, QuotaItem, DimensionItem, draggable },
components: { QuotaFilterEditor, BackgroundColorSelector, FilterItem, XAxisSelector, YAxisSelector, TooltipSelector, LabelSelector, LegendSelector, TitleSelector, SizeSelector, ColorSelector, ChartComponent, QuotaItem, DimensionItem, draggable },
data() {
return {
table: {},
@ -240,6 +269,17 @@ export default {
moveId: -1,
chart: {
id: 'echart'
},
filterEdit: false,
quotaItem: {},
renameItem: false,
itemForm: {
name: ''
},
itemFormRules: {
name: [
{ required: true, message: this.$t('commons.input_content'), trigger: 'change' }
]
}
}
},
@ -305,6 +345,9 @@ export default {
if (!ele.sort || ele.sort === '') {
ele.sort = 'none'
}
if (!ele.filter) {
ele.filter = []
}
})
if (view.type.startsWith('pie') || view.type.startsWith('funnel')) {
if (view.yaxis.length > 1) {
@ -490,6 +533,40 @@ export default {
onChangeBackgroundForm(val) {
this.view.customStyle.background = val
this.save()
},
showEditFilter(item) {
this.quotaItem = JSON.parse(JSON.stringify(item))
this.filterEdit = true
},
closeQuotaFilter() {
this.filterEdit = false
},
saveQuotaFilter() {
this.view.yaxis[this.quotaItem.index].filter = this.quotaItem.filter
this.save()
this.closeQuotaFilter()
},
showRename(val) {
this.itemForm = JSON.parse(JSON.stringify(val))
this.renameItem = true
},
saveRename() {
if (this.itemForm.renameType === 'quota') {
this.view.yaxis[this.itemForm.index].name = this.itemForm.name
} else if (this.itemForm.renameType === 'dimension') {
this.view.xaxis[this.itemForm.index].name = this.itemForm.name
}
this.save()
this.closeRename()
},
closeRename() {
this.renameItem = false
this.resetRename()
},
resetRename() {
this.itemForm = {}
}
}
}
@ -623,4 +700,14 @@ export default {
.chart-class{
height: calc(100% - 124px);
}
.dialog-css>>>.el-dialog__title {
font-size: 14px;
}
.dialog-css >>> .el-dialog__header {
padding: 20px 20px 0;
}
.dialog-css >>> .el-dialog__body {
padding: 10px 20px 20px;
}
</style>