Commit 86cf65a3 by yuwei

项目初始化

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