Commit 86cf65a3 by yuwei

项目初始化

parent ddca17e6
...@@ -18,8 +18,10 @@ import cn.datax.service.data.visual.service.ChartService; ...@@ -18,8 +18,10 @@ import cn.datax.service.data.visual.service.ChartService;
import cn.datax.service.data.visual.mapstruct.ChartMapper; import cn.datax.service.data.visual.mapstruct.ChartMapper;
import cn.datax.service.data.visual.dao.ChartDao; import cn.datax.service.data.visual.dao.ChartDao;
import cn.datax.common.base.BaseServiceImpl; import cn.datax.common.base.BaseServiceImpl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Propagation;
...@@ -125,11 +127,26 @@ public class ChartServiceImpl extends BaseServiceImpl<ChartDao, ChartEntity> imp ...@@ -125,11 +127,26 @@ public class ChartServiceImpl extends BaseServiceImpl<ChartDao, ChartEntity> imp
List<ChartItem> groups = new ArrayList<>(); List<ChartItem> groups = new ArrayList<>();
groups.addAll(rows); groups.addAll(rows);
groups.addAll(columns); groups.addAll(columns);
String groupJoining = groups.stream().map(s -> s.getCol()).collect(Collectors.joining(", ", " ", ",")); sql.append("SELECT");
sql.append("SELECT").append(groupJoining); String groupJoining = null;
String measureJoining = Optional.ofNullable(measures).orElse(new ArrayList<>()).stream().map(s -> new StringBuilder().append(s.getAggregateType()).append("(").append(s.getCol()).append(") AS ").append(s.getCol())).collect(Collectors.joining(", ", " ", " ")); String measureJoining = null;
sql.append(measureJoining); if (CollUtil.isNotEmpty(groups)) {
sql.append("FROM (").append(setSql).append(") TEMP_VIEW ").append("GROUP BY ").append(groups.stream().map(s -> s.getCol()).collect(Collectors.joining(", "))); groupJoining = groups.stream().map(s -> s.getCol()).collect(Collectors.joining(", ", " ", " "));
sql.append(groupJoining);
}
if (CollUtil.isNotEmpty(measures)) {
if (StrUtil.isNotBlank(groupJoining)) {
sql.append(",");
} else {
sql.append(" ");
}
measureJoining = measures.stream().map(s -> new StringBuilder().append(s.getAggregateType()).append("(").append(s.getCol()).append(") AS ").append(s.getCol())).collect(Collectors.joining(", ", " ", " "));
sql.append(measureJoining);
}
sql.append("FROM (").append(setSql).append(") TEMP_VIEW");
if (CollUtil.isNotEmpty(groups)) {
sql.append(" GROUP BY ").append(groups.stream().map(s -> s.getCol()).collect(Collectors.joining(", ")));
}
List<Map<String, Object>> data = dbQuery.queryList(sql.toString()); List<Map<String, Object>> data = dbQuery.queryList(sql.toString());
Map<String, Object> map = new HashMap<>(2); Map<String, Object> map = new HashMap<>(2);
map.put("data", data); map.put("data", data);
......
<template> <template>
<div class="table-responsive"> <div class="table-responsive">
<table> <table>
<!-- Table header -->
<thead> <thead>
<tr v-for="(tr, index) in combineHeads" :key="index"> <tr v-for="(tr, index) in combineHeads" :key="index">
<th <th v-for="cell in tr" :key="cell.__index" :rowspan="cell.rowspan" :colspan="cell.colspan">
v-for="cell in tr" <div :class="{ 'col-corner-bg': cell.isCorner }" :style="{ 'min-height': _getMinHeightByRowCount(cell.rowspan) }">
:key="cell.__index"
:rowspan="cell.rowspan"
:colspan="cell.colspan"
>
<div
:class="{ 'col-corner-bg': cell.isCorner }"
:style="{ 'min-height': _getMinHeightByRowCount(cell.rowspan) }"
>
{{ cell.isCorner ? (rowPaths.length + ' x ' + colPaths.length) : cell.value }} {{ cell.isCorner ? (rowPaths.length + ' x ' + colPaths.length) : cell.value }}
</div> </div>
</th> </th>
</tr> </tr>
</thead> </thead>
<!-- Table body -->
<tbody> <tbody>
<tr v-for="(tr, index) in combineValues" :key="tr.__index"> <tr v-for="(tr, index) in combineValues" :key="index">
<td <!-- Row headers -->
v-for="cell in tr.data" <th v-for="cell in tr.head" :key="cell.__index" v-if="!cell.isRowspan" :rowspan="cell.rowspan" :colspan="cell.colspan">
:key="cell.__index" <div :style="{ 'min-height': _getMinHeightByRowCount(cell.rowspan) }">
:rowspan="cell.rowspan" {{ cell.value }}
:colspan="cell.colspan" </div>
> </th>
<div <!-- Values -->
:class="{ 'col-corner-bg': cell.isCorner }" <td v-for="cell in tr.data" :key="cell.__index" :rowspan="cell.rowspan" :colspan="cell.colspan">
:style="{ 'min-height': _getMinHeightByRowCount(cell.rowspan) }" <div :style="{ 'min-height': _getMinHeightByRowCount(cell.rowspan) }">
>
{{ cell.value }} {{ cell.value }}
</div> </div>
</td> </td>
...@@ -65,10 +58,6 @@ export default { ...@@ -65,10 +58,6 @@ export default {
values: { values: {
type: Array, type: Array,
default: () => [] default: () => []
},
summary: {
type: Array,
default: () => []
} }
}, },
data: () => ({ data: () => ({
...@@ -86,6 +75,10 @@ export default { ...@@ -86,6 +75,10 @@ export default {
combineValues: [] combineValues: []
}), }),
computed: { computed: {
watchAllProps() {
const { rows, columns, values, data } = this
return { rows, columns, values, data }
},
rowPaths() { rowPaths() {
const _paths = this._combinePaths( const _paths = this._combinePaths(
...this.localRows.map(({ values }) => values) ...this.localRows.map(({ values }) => values)
...@@ -109,7 +102,8 @@ export default { ...@@ -109,7 +102,8 @@ export default {
if (valuesLen) { if (valuesLen) {
_rows.push([]) _rows.push([])
} }
// todo: 仅有 values 的时候会有一个空的path // 计算合并单元格
const colSpans = {}
this.colPaths.forEach((path, pathIndex) => { this.colPaths.forEach((path, pathIndex) => {
// 条件值 // 条件值
const pathValues = path.split(this.Separator) const pathValues = path.split(this.Separator)
...@@ -124,19 +118,47 @@ export default { ...@@ -124,19 +118,47 @@ export default {
currPath.push(currVal) currPath.push(currVal)
const baseX = rowIndex const baseX = rowIndex
const baseY = this.localRows.length + pathIndex const baseY = this.localRows.length + pathIndex
row.push( if (!isLastRow) {
Object.assign( // 计算合并行数
cellData, let compareVal = valuesLen
mergeBaseInfo({ for (let i = rowIndex; i < this.localColumns.length - 1; i++) {
__index: `${baseX}-${baseY}`, compareVal *= this.localColumns[rowIndex + 1].values.length
x: baseX, }
y: baseY, const currColSpan = colSpans[rowIndex] || {}
path: currPath.filter((item) => !!item), const currColSpanVal = (currColSpan[currPath.join(this.Separator)] || 0) + 1
// 最后一行是 values,替换显示文本 currColSpan[currPath.join(this.Separator)] = currColSpanVal
value: valuesLen && isLastRow && currVal ? this.localValues.find(({ key }) => key === currVal).label : currVal colSpans[rowIndex] = currColSpan
}) // 合并单元格:起始单元格加入
if (currColSpanVal === 1) {
row.push(
Object.assign(
cellData,
mergeBaseInfo({
__index: `${baseX}-${baseY}`,
x: baseX,
y: baseY,
colspan: compareVal,
path: currPath.filter((item) => !!item),
value: currVal
})
)
)
}
} else {
row.push(
Object.assign(
cellData,
mergeBaseInfo({
__index: `${baseX}-${baseY}`,
x: baseX,
y: baseY,
path: currPath.filter((item) => !!item),
// 最后一行是 values,替换显示文本
value: this.localValues.find(({ key }) => key === currVal).label
})
)
) )
) }
}) })
}) })
return _rows return _rows
...@@ -145,14 +167,18 @@ export default { ...@@ -145,14 +167,18 @@ export default {
rowHeads() { rowHeads() {
// 共有多少列 // 共有多少列
const _columns = [] const _columns = []
// 左上角特殊处理 // 左上角特殊处理, 有行维、列维时才有
_columns.push(mergeBaseInfo({ const columnsLen = this.localColumns.length
__index: `0-0`, const rowsLen = this.localRows.length
colspan: this.localRows.length, if (rowsLen && columnsLen) {
rowspan: this.localColumns.length, _columns.push(mergeBaseInfo({
// 左上角标记 __index: `0-0`,
isCorner: true colspan: this.localRows.length,
})) rowspan: this.localColumns.length,
// 左上角标记
isCorner: true
}))
}
this.localRows.forEach(({ label }, index) => { this.localRows.forEach(({ label }, index) => {
_columns.push(mergeBaseInfo({ _columns.push(mergeBaseInfo({
__index: `${this.localColumns.length}-${index}`, __index: `${this.localColumns.length}-${index}`,
...@@ -165,26 +191,65 @@ export default { ...@@ -165,26 +191,65 @@ export default {
}, },
// 行对应的值 // 行对应的值
rowHeadValues() { rowHeadValues() {
return this.localRows.length let _values = []
? this.rowPaths.map((path, index) => { const rowsLen = this.localRows.length
if (rowsLen) {
// 计算合并单元格
const rowSpans = {}
_values = this.rowPaths.map((path, pathIndex) => {
const values = path.split(this.Separator) const values = path.split(this.Separator)
const currPath = [] const currPath = []
return this.localRows.map((item, rowIndex) => { return this.localRows.map((item, rowIndex) => {
const _index = rowIndex const currVal = values[rowIndex] || ''
const _currVal = values[_index] || '' const baseX = this.localColumns.length + +Boolean(this.localValues.length) + pathIndex
const baseX = this.localColumns.length + +Boolean(this.localValues.length) + index const baseY = rowIndex
const baseY = _index currPath.push(currVal)
currPath.push(_currVal) // 是否为最后列
return mergeBaseInfo({ const isLastCol = rowIndex === rowsLen - 1
__index: `${baseX}-${baseY}`, if (!isLastCol) {
value: _currVal, // 计算合并列数
x: baseX, let compareVal = 1
y: baseY, for (let i = rowIndex; i < rowsLen - 1; i++) {
path: currPath.filter((item) => !!item) compareVal *= (this.localRows[rowIndex + 1].values || []).length
}) }
const currRowSpan = rowSpans[rowIndex] || {}
const currRowSpanVal = (currRowSpan[currPath.join(this.Separator)] || 0) + 1
currRowSpan[currPath.join(this.Separator)] = currRowSpanVal
rowSpans[rowIndex] = currRowSpan
// 合并单元格
if (currRowSpanVal === 1) {
return mergeBaseInfo({
__index: `${baseX}-${baseY}`,
value: currVal,
x: baseX,
y: baseY,
rowspan: compareVal,
path: currPath.filter((item) => !!item)
})
} else {
return mergeBaseInfo({
__index: `${baseX}-${baseY}`,
value: currVal,
x: baseX,
y: baseY,
path: currPath.filter((item) => !!item),
// 是否合并单元格,遍历时判断不显示
isRowspan: true
})
}
} else {
return mergeBaseInfo({
__index: `${baseX}-${baseY}`,
value: currVal,
x: baseX,
y: baseY,
path: currPath.filter((item) => !!item)
})
}
}) })
}) })
: [] }
return _values
}, },
// 计算所有对应条件的值 // 计算所有对应条件的值
dataValues() { dataValues() {
...@@ -249,6 +314,11 @@ export default { ...@@ -249,6 +314,11 @@ export default {
}) })
} }
}, },
watch: {
watchAllProps() {
this.init()
}
},
created: function() { created: function() {
this.init() this.init()
}, },
...@@ -261,9 +331,7 @@ export default { ...@@ -261,9 +331,7 @@ export default {
this.handleCombineHeads() this.handleCombineHeads()
this.handleCombineValues() this.handleCombineValues()
} else { } else {
console.warn( console.warn('[Warn]: props.rows, props.columns, props.values at least one is not empty.')
'[Warn]: props.rows, props.columns, props.values at least one is not empty.'
)
} }
}, },
// clone data // clone data
...@@ -273,7 +341,7 @@ export default { ...@@ -273,7 +341,7 @@ export default {
this.localValues = JSON.parse(JSON.stringify(this.values)) this.localValues = JSON.parse(JSON.stringify(this.values))
this.localData = Object.freeze(this.data) this.localData = Object.freeze(this.data)
}, },
// set the `values` attribute to rows and columns // set the `values` `merges` attribute to rows and columns
setValuesToColAndRow() { setValuesToColAndRow() {
const rowKeys = this.localRows.map(({ key }) => key) const rowKeys = this.localRows.map(({ key }) => key)
const columnKeys = this.localColumns.map(({ key }) => key) const columnKeys = this.localColumns.map(({ key }) => key)
...@@ -305,9 +373,9 @@ export default { ...@@ -305,9 +373,9 @@ export default {
for (let i = 0; i < valueRowCount; i++) { for (let i = 0; i < valueRowCount; i++) {
const _currRowHeadValue = this.rowHeadValues[i] || [] const _currRowHeadValue = this.rowHeadValues[i] || []
const _currValue = this.dataValues[i] || {} const _currValue = this.dataValues[i] || {}
const _row = [..._currRowHeadValue, ...(_currValue.data || [])] const _row = [...(_currValue.data || [])]
combineValues.push( combineValues.push(
Object.assign({}, _currValue, { data: _row }) Object.assign({}, { head: [..._currRowHeadValue] }, { data: _row })
) )
} }
this.combineValues = combineValues this.combineValues = combineValues
......
...@@ -4,9 +4,9 @@ const chartTypes = [ ...@@ -4,9 +4,9 @@ const chartTypes = [
status: true, status: true,
component: 'ChartTable', component: 'ChartTable',
rule: { rule: {
text: '0个或多个 行维;0个或多个 列维;0个或多个 指标', text: '1个或多个 行维;0个或多个 列维;1个或多个 指标',
check(rows, columns, measures) { check(rows, columns, measures) {
return rows.length >= 0 && columns.length >= 0 && measures.length >= 0 return rows.length >= 1 && columns.length >= 0 && measures.length >= 1
} }
} }
}, },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment