forked from github/dataease
feat(视图): 视图 指标 增加sum min等常用汇总方式
This commit is contained in:
parent
b1194fd843
commit
d8c66325a9
@ -0,0 +1,30 @@
|
||||
package io.dataease.dto.chart;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author gin
|
||||
* @Date 2021/3/11 1:18 下午
|
||||
*/
|
||||
@Data
|
||||
public class ChartViewFieldDTO {
|
||||
private String id;
|
||||
|
||||
private String tableId;
|
||||
|
||||
private String originName;
|
||||
|
||||
private String name;
|
||||
|
||||
private String type;
|
||||
|
||||
private Boolean checked;
|
||||
|
||||
private Integer columnIndex;
|
||||
|
||||
private Long lastSyncTime;
|
||||
|
||||
private Integer deType;
|
||||
|
||||
private String summary;
|
||||
}
|
@ -12,6 +12,7 @@ import io.dataease.datasource.provider.ProviderFactory;
|
||||
import io.dataease.datasource.request.DatasourceRequest;
|
||||
import io.dataease.datasource.service.DatasourceService;
|
||||
import io.dataease.dto.chart.ChartViewDTO;
|
||||
import io.dataease.dto.chart.ChartViewFieldDTO;
|
||||
import io.dataease.dto.chart.Series;
|
||||
import io.dataease.dto.dataset.DataTableInfoDTO;
|
||||
import io.dataease.service.dataset.DataSetTableFieldsService;
|
||||
@ -76,9 +77,9 @@ public class ChartViewService {
|
||||
|
||||
public ChartViewDTO getData(String id) throws Exception {
|
||||
ChartViewWithBLOBs view = chartViewMapper.selectByPrimaryKey(id);
|
||||
List<DatasetTableField> xAxis = new Gson().fromJson(view.getXAxis(), new TypeToken<List<DatasetTableField>>() {
|
||||
List<ChartViewFieldDTO> xAxis = new Gson().fromJson(view.getXAxis(), new TypeToken<List<ChartViewFieldDTO>>() {
|
||||
}.getType());
|
||||
List<DatasetTableField> yAxis = new Gson().fromJson(view.getYAxis(), new TypeToken<List<DatasetTableField>>() {
|
||||
List<ChartViewFieldDTO> yAxis = new Gson().fromJson(view.getYAxis(), new TypeToken<List<ChartViewFieldDTO>>() {
|
||||
}.getType());
|
||||
|
||||
List<String> x = new ArrayList<>();
|
||||
@ -88,25 +89,25 @@ public class ChartViewService {
|
||||
BeanUtils.copyBean(dto, view);
|
||||
return dto;
|
||||
}
|
||||
List<String> xIds = xAxis.stream().map(DatasetTableField::getId).collect(Collectors.toList());
|
||||
List<String> yIds = yAxis.stream().map(DatasetTableField::getId).collect(Collectors.toList());
|
||||
List<DatasetTableField> xList = dataSetTableFieldsService.getListByIds(xIds);
|
||||
List<DatasetTableField> yList = dataSetTableFieldsService.getListByIds(yIds);
|
||||
// List<String> xIds = xAxis.stream().map(DatasetTableField::getId).collect(Collectors.toList());
|
||||
// List<String> yIds = yAxis.stream().map(DatasetTableField::getId).collect(Collectors.toList());
|
||||
// List<DatasetTableField> xList = dataSetTableFieldsService.getListByIds(xIds);
|
||||
// List<DatasetTableField> yList = dataSetTableFieldsService.getListByIds(yIds);
|
||||
|
||||
// 获取数据源
|
||||
// 获取数据集
|
||||
DatasetTable table = dataSetTableService.get(view.getTableId());
|
||||
// todo 判断连接方式,直连或者定时抽取 table.mode
|
||||
Datasource ds = datasourceService.get(table.getDataSourceId());
|
||||
|
||||
DatasourceProvider datasourceProvider = ProviderFactory.getProvider(ds.getType());
|
||||
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||
datasourceRequest.setDatasource(ds);
|
||||
DataTableInfoDTO dataTableInfoDTO = new Gson().fromJson(table.getInfo(), DataTableInfoDTO.class);
|
||||
datasourceRequest.setTable(dataTableInfoDTO.getTable());
|
||||
datasourceRequest.setQuery(getSQL(ds.getType(), dataTableInfoDTO.getTable(), xList, yList));
|
||||
datasourceRequest.setQuery(getSQL(ds.getType(), dataTableInfoDTO.getTable(), xAxis, yAxis));
|
||||
List<String[]> data = datasourceProvider.getData(datasourceRequest);
|
||||
|
||||
// todo 处理结果,目前做一个单系列图表,后期图表组件再扩展
|
||||
for (DatasetTableField y : yList) {
|
||||
for (ChartViewFieldDTO y : yAxis) {
|
||||
Series series1 = new Series();
|
||||
series1.setName(y.getName());
|
||||
series1.setType(view.getType());
|
||||
@ -116,16 +117,16 @@ public class ChartViewService {
|
||||
for (String[] d : data) {
|
||||
StringBuilder a = new StringBuilder();
|
||||
BigDecimal b = new BigDecimal("0");
|
||||
for (int i = 0; i < xList.size(); i++) {
|
||||
if (i == xList.size() - 1) {
|
||||
for (int i = 0; i < xAxis.size(); i++) {
|
||||
if (i == xAxis.size() - 1) {
|
||||
a.append(d[i]);
|
||||
} else {
|
||||
a.append(d[i]).append("\n");
|
||||
}
|
||||
}
|
||||
x.add(a.toString());
|
||||
for (int i = xList.size(); i < xList.size() + yList.size(); i++) {
|
||||
int j = i - xList.size();
|
||||
for (int i = xAxis.size(); i < xAxis.size() + yAxis.size(); i++) {
|
||||
int j = i - xAxis.size();
|
||||
series.get(j).getData().add(new BigDecimal(d[i]));
|
||||
}
|
||||
}
|
||||
@ -139,7 +140,7 @@ public class ChartViewService {
|
||||
return dto;
|
||||
}
|
||||
|
||||
public String getSQL(String type, String table, List<DatasetTableField> xAxis, List<DatasetTableField> yAxis) {
|
||||
public String getSQL(String type, String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis) {
|
||||
DatasourceTypes datasourceType = DatasourceTypes.valueOf(type);
|
||||
switch (datasourceType) {
|
||||
case mysql:
|
||||
@ -150,10 +151,10 @@ public class ChartViewService {
|
||||
}
|
||||
}
|
||||
|
||||
public String transMysqlSQL(String table, List<DatasetTableField> xAxis, List<DatasetTableField> yAxis) {
|
||||
// TODO 此处sum后期由用户前端传入
|
||||
String[] field = yAxis.stream().map(y -> "sum(" + y.getOriginName() + ")").toArray(String[]::new);
|
||||
String[] group = xAxis.stream().map(DatasetTableField::getOriginName).toArray(String[]::new);
|
||||
public String transMysqlSQL(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis) {
|
||||
// TODO 字段汇总 排序等
|
||||
String[] field = yAxis.stream().map(y -> "CAST(" + y.getSummary() + "(" + y.getOriginName() + ") AS DECIMAL(10,2))").toArray(String[]::new);
|
||||
String[] group = xAxis.stream().map(ChartViewFieldDTO::getOriginName).toArray(String[]::new);
|
||||
return MessageFormat.format("SELECT {0},{1} FROM {2} GROUP BY {3}", StringUtils.join(group, ","), StringUtils.join(field, ","), table, StringUtils.join(group, ","));
|
||||
}
|
||||
}
|
||||
|
@ -592,7 +592,15 @@ export default {
|
||||
x_axis: '横轴',
|
||||
y_axis: '纵轴',
|
||||
chart: '视图',
|
||||
close: '关闭'
|
||||
close: '关闭',
|
||||
summary: '汇总方式',
|
||||
fast_calc: '快速计算',
|
||||
sum: '求和',
|
||||
avg: '平均',
|
||||
max: '最大值',
|
||||
min: '最小值',
|
||||
std: '标准差',
|
||||
var_samp: '方差'
|
||||
},
|
||||
dataset: {
|
||||
datalist: '数据集',
|
||||
|
66
frontend/src/views/chart/components/DimensionItem.vue
Normal file
66
frontend/src/views/chart/components/DimensionItem.vue
Normal file
@ -0,0 +1,66 @@
|
||||
<template>
|
||||
<span>
|
||||
<el-dropdown trigger="click" size="small">
|
||||
<span class="el-dropdown-link">
|
||||
<span
|
||||
class="item-axis"
|
||||
>
|
||||
{{ item.name }}<i class="el-icon-arrow-down el-icon--right" />
|
||||
<span />
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item icon="el-icon-edit-outline">
|
||||
item1
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-delete">
|
||||
item2
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</span>
|
||||
</span>
|
||||
</el-dropdown>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'DimensionItem',
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.item-axis {
|
||||
padding: 1px 6px;
|
||||
margin: 0 3px 2px 3px;
|
||||
border: solid 1px #eee;
|
||||
background-color: #f1f1f1;
|
||||
text-align: left;
|
||||
height: 24px;
|
||||
line-height: 22px;
|
||||
display: inline-block;
|
||||
color: #1890ff;
|
||||
border-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.item-axis:hover {
|
||||
background-color: #fdfdfd;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
95
frontend/src/views/chart/components/QuotaItem.vue
Normal file
95
frontend/src/views/chart/components/QuotaItem.vue
Normal file
@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<span>
|
||||
<el-dropdown trigger="click" size="small">
|
||||
<span class="el-dropdown-link">
|
||||
<span
|
||||
class="item-axis"
|
||||
>
|
||||
{{ item.name }}<span class="summary-span">({{ $t('chart.'+item.summary) }})</span><i class="el-icon-arrow-down el-icon--right" />
|
||||
<span />
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item icon="el-icon-notebook-2">
|
||||
<el-dropdown placement="right-start" size="small" @command="summary">
|
||||
<span class="el-dropdown-link">
|
||||
{{ $t('chart.summary') }}<span class="summary-span">({{ $t('chart.'+item.summary) }})</span><i class="el-icon-arrow-right el-icon--right" />
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item :command="beforeSummary('sum')">{{ $t('chart.sum') }}</el-dropdown-item>
|
||||
<el-dropdown-item :command="beforeSummary('avg')">{{ $t('chart.avg') }}</el-dropdown-item>
|
||||
<el-dropdown-item :command="beforeSummary('max')">{{ $t('chart.max') }}</el-dropdown-item>
|
||||
<el-dropdown-item :command="beforeSummary('min')">{{ $t('chart.min') }}</el-dropdown-item>
|
||||
<el-dropdown-item :command="beforeSummary('std')">{{ $t('chart.std') }}</el-dropdown-item>
|
||||
<el-dropdown-item :command="beforeSummary('var_samp')">{{ $t('chart.var_samp') }}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-delete">
|
||||
item4
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</span>
|
||||
</span>
|
||||
</el-dropdown>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'QuotaItem',
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
summary(param) {
|
||||
console.log(param)
|
||||
this.item.summary = param.type
|
||||
this.$emit('onQuotaSummaryChange', this.item)
|
||||
},
|
||||
beforeSummary(type) {
|
||||
return {
|
||||
type: type
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.item-axis {
|
||||
padding: 1px 6px;
|
||||
margin: 0 3px 2px 3px;
|
||||
border: solid 1px #eee;
|
||||
background-color: #f1f1f1;
|
||||
text-align: left;
|
||||
height: 24px;
|
||||
line-height: 22px;
|
||||
display: inline-block;
|
||||
color: #1890ff;
|
||||
border-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.item-axis:hover {
|
||||
background-color: #fdfdfd;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.summary-span{
|
||||
margin-left: 4px;
|
||||
color: #878d9f;;
|
||||
}
|
||||
</style>
|
@ -23,7 +23,7 @@
|
||||
<span>{{ $t('chart.dimension') }}</span>
|
||||
<draggable
|
||||
v-model="dimension"
|
||||
:options="{group:{name: 'itxst',pull:'clone'},sort: true}"
|
||||
:options="{group:{name: 'dimension',pull:'clone'},sort: true}"
|
||||
animation="300"
|
||||
:move="onMove"
|
||||
style="height: 90%;overflow:auto"
|
||||
@ -39,7 +39,7 @@
|
||||
<span>{{ $t('chart.quota') }}</span>
|
||||
<draggable
|
||||
v-model="quota"
|
||||
:options="{group:{name: 'itxst',pull:'clone'},sort: true}"
|
||||
:options="{group:{name: 'quota',pull:'clone'},sort: true}"
|
||||
animation="300"
|
||||
:move="onMove"
|
||||
style="height: 90%;overflow:auto"
|
||||
@ -100,73 +100,32 @@
|
||||
<el-row style="width: 100%;height: 100%;" class="padding-lr">
|
||||
<el-row style="margin-top: 10px;">
|
||||
<el-row style="display:flex;height: 32px;">
|
||||
<span style="line-height: 32px;width: 60px;text-align: right;">{{ $t('chart.x_axis') }}</span>
|
||||
<span style="line-height: 32px;width: 60px;text-align: right;">{{ $t('chart.dimension') }}</span>
|
||||
<draggable
|
||||
v-model="view.xaxis"
|
||||
group="itxst"
|
||||
group="dimension"
|
||||
animation="300"
|
||||
:move="onMove"
|
||||
style="width:100%;height: 100%;margin:0 10px;border-radius: 4px;border: 1px solid #DCDFE6;overflow-x: auto;display: flex;align-items: center;"
|
||||
@end="end2"
|
||||
>
|
||||
<transition-group class="draggable-group">
|
||||
<el-dropdown v-for="(item) in view.xaxis" :key="item.id" trigger="click" size="mini">
|
||||
<span class="el-dropdown-link">
|
||||
<span
|
||||
class="item-axis"
|
||||
>
|
||||
{{ item.name }}<i class="el-icon-arrow-down el-icon--right" />
|
||||
<span />
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item icon="el-icon-edit-outline">
|
||||
item1
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-delete">
|
||||
item2
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</span>
|
||||
</span>
|
||||
</el-dropdown>
|
||||
<dimension-item v-for="(item) in view.xaxis" :key="item.id" :item="item" />
|
||||
</transition-group>
|
||||
</draggable>
|
||||
</el-row>
|
||||
<el-row style="display:flex;height: 32px;margin-top: 10px;">
|
||||
<span style="line-height: 32px;width: 60px;text-align: right;">{{ $t('chart.y_axis') }}</span>
|
||||
<span style="line-height: 32px;width: 60px;text-align: right;">{{ $t('chart.quota') }}</span>
|
||||
<draggable
|
||||
v-model="view.yaxis"
|
||||
group="itxst"
|
||||
group="quota"
|
||||
animation="300"
|
||||
:move="onMove"
|
||||
style="width:100%;height: 100%;margin:0 10px;border-radius: 4px;border: 1px solid #DCDFE6;overflow-x: auto;display: flex;align-items: center;"
|
||||
@end="end2"
|
||||
>
|
||||
<transition-group class="draggable-group">
|
||||
<el-dropdown v-for="(item) in view.yaxis" :key="item.id" trigger="click" size="mini">
|
||||
<span class="el-dropdown-link">
|
||||
<span
|
||||
class="item-axis"
|
||||
>
|
||||
{{ item.name }}<i class="el-icon-arrow-down el-icon--right" />
|
||||
<span />
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item icon="el-icon-edit-outline">
|
||||
<el-dropdown placement="right-start" size="mini">
|
||||
<span class="el-dropdown-link">
|
||||
item3<i class="el-icon-arrow-right el-icon--right" />
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item>sub1</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-delete">
|
||||
item4
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</span>
|
||||
</span>
|
||||
</el-dropdown>
|
||||
<quota-item v-for="(item) in view.yaxis" :key="item.id" :item="item" @onQuotaSummaryChange="quotaSummaryChange" />
|
||||
</transition-group>
|
||||
</draggable>
|
||||
</el-row>
|
||||
@ -185,10 +144,12 @@
|
||||
import { post } from '@/api/dataset/dataset'
|
||||
import draggable from 'vuedraggable'
|
||||
import { BASE_BAR } from '../chart/chart'
|
||||
import DimensionItem from '../components/DimensionItem'
|
||||
import QuotaItem from '../components/QuotaItem'
|
||||
|
||||
export default {
|
||||
name: 'ChartEdit',
|
||||
components: { draggable },
|
||||
components: { QuotaItem, DimensionItem, draggable },
|
||||
data() {
|
||||
return {
|
||||
table: {},
|
||||
@ -301,6 +262,16 @@ export default {
|
||||
view.sceneId = this.sceneId
|
||||
view.name = this.table.name
|
||||
view.tableId = this.$store.state.chart.tableId
|
||||
view.xaxis.forEach(function(ele) {
|
||||
if (!ele.summary || ele.summary === '') {
|
||||
ele.summary = 'sum'
|
||||
}
|
||||
})
|
||||
view.yaxis.forEach(function(ele) {
|
||||
if (!ele.summary || ele.summary === '') {
|
||||
ele.summary = 'sum'
|
||||
}
|
||||
})
|
||||
view.xaxis = JSON.stringify(view.xaxis)
|
||||
view.yaxis = JSON.stringify(view.yaxis)
|
||||
post('/chart/view/save', view).then(response => {
|
||||
@ -419,6 +390,17 @@ export default {
|
||||
return true
|
||||
},
|
||||
|
||||
quotaSummaryChange(item) {
|
||||
console.log(item)
|
||||
// 更新item
|
||||
this.view.yaxis.forEach(function(ele) {
|
||||
if (ele.id === item.id) {
|
||||
ele.summary = item.summary
|
||||
}
|
||||
})
|
||||
this.save()
|
||||
},
|
||||
|
||||
myEcharts(option) {
|
||||
// 基于准备好的dom,初始化echarts实例
|
||||
var myChart = this.$echarts.init(document.getElementById('echart'))
|
||||
@ -483,26 +465,6 @@ export default {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.item-axis {
|
||||
padding: 1px 8px;
|
||||
margin: 0 3px 2px 3px;
|
||||
border: solid 1px #eee;
|
||||
background-color: #f1f1f1;
|
||||
text-align: left;
|
||||
height: 24px;
|
||||
line-height: 22px;
|
||||
display: inline-block;
|
||||
color: #1890ff;
|
||||
border-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.item-axis:hover {
|
||||
background-color: #fdfdfd;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user