feat(视图):维度过滤与排序

This commit is contained in:
junjie 2021-04-27 13:58:25 +08:00
parent 0f644e7842
commit d861a4f816
4 changed files with 241 additions and 18 deletions

View File

@ -278,14 +278,36 @@ public class ChartViewService {
// 字段汇总 排序等 // 字段汇总 排序等
String[] field = yAxis.stream().map(y -> "CAST(" + y.getSummary() + "(" + y.getOriginName() + ") AS DECIMAL(20,2)) AS _" + y.getSummary() + "_" + (StringUtils.equalsIgnoreCase(y.getOriginName(), "*") ? "" : y.getOriginName())).toArray(String[]::new); String[] field = yAxis.stream().map(y -> "CAST(" + y.getSummary() + "(" + y.getOriginName() + ") AS DECIMAL(20,2)) AS _" + y.getSummary() + "_" + (StringUtils.equalsIgnoreCase(y.getOriginName(), "*") ? "" : y.getOriginName())).toArray(String[]::new);
String[] group = xAxis.stream().map(ChartViewFieldDTO::getOriginName).toArray(String[]::new); String[] group = xAxis.stream().map(ChartViewFieldDTO::getOriginName).toArray(String[]::new);
String[] order = yAxis.stream().filter(y -> StringUtils.isNotEmpty(y.getSort()) && !StringUtils.equalsIgnoreCase(y.getSort(), "none")) String[] xOrder = xAxis.stream().filter(f -> StringUtils.isNotEmpty(f.getSort()) && !StringUtils.equalsIgnoreCase(f.getSort(), "none"))
.map(y -> "_" + y.getSummary() + "_" + (StringUtils.equalsIgnoreCase(y.getOriginName(), "*") ? "" : y.getOriginName()) + " " + y.getSort()).toArray(String[]::new); .map(f -> f.getOriginName() + " " + f.getSort()).toArray(String[]::new);
String[] yOrder = yAxis.stream().filter(f -> StringUtils.isNotEmpty(f.getSort()) && !StringUtils.equalsIgnoreCase(f.getSort(), "none"))
.map(f -> "_" + f.getSummary() + "_" + (StringUtils.equalsIgnoreCase(f.getOriginName(), "*") ? "" : f.getOriginName()) + " " + f.getSort()).toArray(String[]::new);
String[] order = Arrays.copyOf(xOrder, xOrder.length + yOrder.length);
System.arraycopy(yOrder, 0, order, xOrder.length, yOrder.length);
String[] xFilter = xAxis.stream().filter(x -> CollectionUtils.isNotEmpty(x.getFilter()) && x.getFilter().size() > 0)
.map(x -> {
String[] s = x.getFilter().stream().map(f -> {
StringBuilder filter = new StringBuilder();
filter.append(" AND ").append(x.getOriginName()).append(transMysqlFilterTerm(f.getTerm()));
if (StringUtils.containsIgnoreCase(f.getTerm(), "null")) {
} else if (StringUtils.containsIgnoreCase(f.getTerm(), "in")) {
filter.append("('").append(StringUtils.join(f.getValue(), "','")).append("')");
} else if (StringUtils.containsIgnoreCase(f.getTerm(), "like")) {
filter.append("%").append(f.getValue()).append("%");
} else {
filter.append(f.getValue());
}
return filter.toString();
}).toArray(String[]::new);
return StringUtils.join(s, " ");
}).toArray(String[]::new);
String sql = MessageFormat.format("SELECT {0},{1} FROM {2} WHERE 1=1 {3} GROUP BY {4} ORDER BY null,{5}", String sql = MessageFormat.format("SELECT {0},{1} FROM {2} WHERE 1=1 {3} GROUP BY {4} ORDER BY null,{5}",
StringUtils.join(group, ","), StringUtils.join(group, ","),
StringUtils.join(field, ","), StringUtils.join(field, ","),
table, table,
transMysqlExtFilter(extFilterRequestList),// origin field filter and panel field filter xFilter.length > 0 ? StringUtils.join(xFilter, " ") : "" + transMysqlExtFilter(extFilterRequestList),// origin field filter and panel field filter
StringUtils.join(group, ","), StringUtils.join(group, ","),
StringUtils.join(order, ",")); StringUtils.join(order, ","));
if (sql.endsWith(",")) { if (sql.endsWith(",")) {
@ -296,7 +318,7 @@ public class ChartViewService {
.map(y -> { .map(y -> {
String[] s = y.getFilter().stream().map(f -> { String[] s = y.getFilter().stream().map(f -> {
StringBuilder filter = new StringBuilder(); StringBuilder filter = new StringBuilder();
filter.append("AND _").append(y.getSummary()).append("_").append(StringUtils.equalsIgnoreCase(y.getOriginName(), "*") ? "" : y.getOriginName()).append(transMysqlFilterTerm(f.getTerm())); filter.append(" AND _").append(y.getSummary()).append("_").append(StringUtils.equalsIgnoreCase(y.getOriginName(), "*") ? "" : y.getOriginName()).append(transMysqlFilterTerm(f.getTerm()));
if (StringUtils.containsIgnoreCase(f.getTerm(), "null")) { if (StringUtils.containsIgnoreCase(f.getTerm(), "null")) {
} else if (StringUtils.containsIgnoreCase(f.getTerm(), "in")) { } else if (StringUtils.containsIgnoreCase(f.getTerm(), "in")) {
filter.append("('").append(StringUtils.join(f.getValue(), "','")).append("')"); filter.append("('").append(StringUtils.join(f.getValue(), "','")).append("')");

View File

@ -6,7 +6,27 @@
{{ item.name }}<i class="el-icon-arrow-down el-icon--right" /> {{ item.name }}<i class="el-icon-arrow-down el-icon--right" />
</el-tag> </el-tag>
<el-dropdown-menu slot="dropdown"> <el-dropdown-menu slot="dropdown">
<el-dropdown-item icon="el-icon-edit-outline" :command="beforeClickItem('rename')"> <el-dropdown-item>
<el-dropdown placement="right-start" size="mini" style="width: 100%" @command="sort">
<span class="el-dropdown-link inner-dropdown-menu">
<span>
<i class="el-icon-sort" />
<span>{{ $t('chart.sort') }}</span>
<span class="summary-span">({{ $t('chart.'+item.sort) }})</span>
</span>
<i class="el-icon-arrow-right el-icon--right" />
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="beforeSort('none')">{{ $t('chart.none') }}</el-dropdown-item>
<el-dropdown-item :command="beforeSort('asc')">{{ $t('chart.asc') }}</el-dropdown-item>
<el-dropdown-item :command="beforeSort('desc')">{{ $t('chart.desc') }}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-dropdown-item>
<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')">
<span>{{ $t('chart.show_name_set') }}</span> <span>{{ $t('chart.show_name_set') }}</span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item icon="el-icon-delete" divided :command="beforeClickItem('remove')"> <el-dropdown-item icon="el-icon-delete" divided :command="beforeClickItem('remove')">
@ -49,6 +69,9 @@ export default {
case 'remove': case 'remove':
this.removeItem() this.removeItem()
break break
case 'filter':
this.editFilter()
break
default: default:
break break
} }
@ -58,6 +81,20 @@ export default {
type: type type: type
} }
}, },
sort(param) {
// console.log(param)
this.item.sort = param.type
this.$emit('onDimensionItemChange', this.item)
},
beforeSort(type) {
return {
type: type
}
},
editFilter() {
this.item.index = this.index
this.$emit('editItemFilter', this.item)
},
showRename() { showRename() {
this.item.index = this.index this.item.index = this.index
this.item.renameType = 'dimension' this.item.renameType = 'dimension'

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 }}</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: 'DimensionFilterEditor',
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>
.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

@ -174,7 +174,7 @@
@end="end2" @end="end2"
> >
<transition-group class="draggable-group"> <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" @onNameEdit="showRename" /> <dimension-item v-for="(item,index) in view.xaxis" :key="item.id" :index="index" :item="item" @onDimensionItemChange="dimensionItemChange" @onDimensionItemRemove="dimensionItemRemove" @editItemFilter="showDimensionEditFilter" @onNameEdit="showRename" />
</transition-group> </transition-group>
</draggable> </draggable>
</el-row> </el-row>
@ -189,7 +189,7 @@
@end="end2" @end="end2"
> >
<transition-group class="draggable-group"> <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" @editItemFilter="showEditFilter" @onNameEdit="showRename" /> <quota-item v-for="(item,index) in view.yaxis" :key="item.id" :index="index" :item="item" @onQuotaItemChange="quotaItemChange" @onQuotaItemRemove="quotaItemRemove" @editItemFilter="showQuotaEditFilter" @onNameEdit="showRename" />
</transition-group> </transition-group>
</draggable> </draggable>
</el-row> </el-row>
@ -217,7 +217,7 @@
<!--指标过滤器--> <!--指标过滤器-->
<el-dialog <el-dialog
:title="$t('chart.add_filter')" :title="$t('chart.add_filter')"
:visible="filterEdit" :visible="quotaFilterEdit"
:show-close="false" :show-close="false"
width="800px" width="800px"
class="dialog-css" class="dialog-css"
@ -228,6 +228,19 @@
<el-button type="primary" size="mini" @click="saveQuotaFilter">{{ $t('chart.confirm') }}</el-button> <el-button type="primary" size="mini" @click="saveQuotaFilter">{{ $t('chart.confirm') }}</el-button>
</div> </div>
</el-dialog> </el-dialog>
<el-dialog
:title="$t('chart.add_filter')"
:visible="dimensionFilterEdit"
:show-close="false"
width="800px"
class="dialog-css"
>
<dimension-filter-editor :item="dimensionItem" />
<div slot="footer" class="dialog-footer">
<el-button size="mini" @click="closeDimensionFilter">{{ $t('chart.cancel') }}</el-button>
<el-button type="primary" size="mini" @click="saveDimensionFilter">{{ $t('chart.confirm') }}</el-button>
</div>
</el-dialog>
</el-row> </el-row>
</template> </template>
@ -263,11 +276,12 @@ import XAxisSelector from '../components/component-style/XAxisSelector'
import YAxisSelector from '../components/component-style/YAxisSelector' import YAxisSelector from '../components/component-style/YAxisSelector'
import BackgroundColorSelector from '../components/component-style/BackgroundColorSelector' import BackgroundColorSelector from '../components/component-style/BackgroundColorSelector'
import QuotaFilterEditor from '../components/filter/QuotaFilterEditor' import QuotaFilterEditor from '../components/filter/QuotaFilterEditor'
import DimensionFilterEditor from '../components/filter/DimensionFilterEditor'
import TableNormal from '../components/table/TableNormal' import TableNormal from '../components/table/TableNormal'
export default { export default {
name: 'ChartEdit', name: 'ChartEdit',
components: { TableNormal, DatasetChartDetail, QuotaFilterEditor, BackgroundColorSelector, FilterItem, XAxisSelector, YAxisSelector, TooltipSelector, LabelSelector, LegendSelector, TitleSelector, SizeSelector, ColorSelector, ChartComponent, QuotaItem, DimensionItem, draggable }, components: { DimensionFilterEditor, TableNormal, DatasetChartDetail, QuotaFilterEditor, BackgroundColorSelector, FilterItem, XAxisSelector, YAxisSelector, TooltipSelector, LabelSelector, LegendSelector, TitleSelector, SizeSelector, ColorSelector, ChartComponent, QuotaItem, DimensionItem, draggable },
props: { props: {
param: { param: {
type: Object, type: Object,
@ -304,7 +318,9 @@ export default {
chart: { chart: {
id: 'echart' id: 'echart'
}, },
filterEdit: false, dimensionFilterEdit: false,
dimensionItem: {},
quotaFilterEdit: false,
quotaItem: {}, quotaItem: {},
renameItem: false, renameItem: false,
itemForm: { itemForm: {
@ -363,11 +379,17 @@ export default {
view.sceneId = this.view.sceneId view.sceneId = this.view.sceneId
view.name = this.view.name ? this.view.name : this.table.name view.name = this.view.name ? this.view.name : this.table.name
view.tableId = this.view.tableId view.tableId = this.view.tableId
// view.xaxis.forEach(function(ele) { view.xaxis.forEach(function(ele) {
// if (!ele.summary || ele.summary === '') { // if (!ele.summary || ele.summary === '') {
// ele.summary = 'sum' // ele.summary = 'sum'
// } // }
// }) if (!ele.sort || ele.sort === '') {
ele.sort = 'none'
}
if (!ele.filter) {
ele.filter = []
}
})
view.yaxis.forEach(function(ele) { view.yaxis.forEach(function(ele) {
if (!ele.summary || ele.summary === '') { if (!ele.summary || ele.summary === '') {
if (ele.id === 'count') { if (ele.id === 'count') {
@ -574,12 +596,25 @@ export default {
this.save() this.save()
}, },
showEditFilter(item) { showDimensionEditFilter(item) {
this.dimensionItem = JSON.parse(JSON.stringify(item))
this.dimensionFilterEdit = true
},
closeDimensionFilter() {
this.dimensionFilterEdit = false
},
saveDimensionFilter() {
this.view.xaxis[this.dimensionItem.index].filter = this.dimensionItem.filter
this.save()
this.closeDimensionFilter()
},
showQuotaEditFilter(item) {
this.quotaItem = JSON.parse(JSON.stringify(item)) this.quotaItem = JSON.parse(JSON.stringify(item))
this.filterEdit = true this.quotaFilterEdit = true
}, },
closeQuotaFilter() { closeQuotaFilter() {
this.filterEdit = false this.quotaFilterEdit = false
}, },
saveQuotaFilter() { saveQuotaFilter() {
this.view.yaxis[this.quotaItem.index].filter = this.quotaItem.filter this.view.yaxis[this.quotaItem.index].filter = this.quotaItem.filter