Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
D
datax-cloud
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
黄营
datax-cloud
Commits
86cf65a3
Commit
86cf65a3
authored
Nov 19, 2020
by
yuwei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
项目初始化
parent
ddca17e6
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
159 additions
and
74 deletions
+159
-74
ChartServiceImpl.java
...ax/service/data/visual/service/impl/ChartServiceImpl.java
+22
-5
index.vue
datax-ui/src/components/PivotTable/index.vue
+135
-67
visual-chart.js
datax-ui/src/utils/visual-chart.js
+2
-2
No files found.
datax-modules/data-visual-service-parent/data-visual-service/src/main/java/cn/datax/service/data/visual/service/impl/ChartServiceImpl.java
View file @
86cf65a3
...
@@ -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
);
...
...
datax-ui/src/components/PivotTable/index.vue
View file @
86cf65a3
<
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
...
...
datax-ui/src/utils/visual-chart.js
View file @
86cf65a3
...
@@ -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
}
}
}
}
},
},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment