feat: S2 pivot

This commit is contained in:
junjie 2022-02-08 13:50:43 +08:00
parent 253e48107a
commit 95641feef7
19 changed files with 561 additions and 26 deletions

View File

@ -13,6 +13,8 @@ import lombok.ToString;
public class ChartViewWithBLOBs extends ChartView implements Serializable {
@ApiModelProperty("x轴")
private String xAxis;
@ApiModelProperty("x轴(Row)")
private String xAxisExt;
@ApiModelProperty("y轴")
private String yAxis;
@ApiModelProperty("副y轴")

View File

@ -18,6 +18,7 @@
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.dataease.base.domain.ChartViewWithBLOBs">
<result column="x_axis" jdbcType="LONGVARCHAR" property="xAxis" />
<result column="x_axis_ext" jdbcType="LONGVARCHAR" property="xAxisExt" />
<result column="y_axis" jdbcType="LONGVARCHAR" property="yAxis" />
<result column="y_axis_ext" jdbcType="LONGVARCHAR" property="yAxisExt" />
<result column="ext_stack" jdbcType="LONGVARCHAR" property="extStack" />
@ -91,8 +92,8 @@
create_by, create_time, update_time, style_priority
</sql>
<sql id="Blob_Column_List">
x_axis, y_axis, y_axis_ext, ext_stack, ext_bubble, custom_attr, custom_style, custom_filter,
drill_fields, snapshot
x_axis, x_axis_ext, y_axis, y_axis_ext, ext_stack, ext_bubble, custom_attr, custom_style,
custom_filter, drill_fields, snapshot
</sql>
<select id="selectByExampleWithBLOBs" parameterType="io.dataease.base.domain.ChartViewExample" resultMap="ResultMapWithBLOBs">
select
@ -147,18 +148,20 @@
table_id, `type`, render,
result_count, result_mode, title,
create_by, create_time, update_time,
style_priority, x_axis, y_axis,
y_axis_ext, ext_stack, ext_bubble,
custom_attr, custom_style, custom_filter,
drill_fields, snapshot)
style_priority, x_axis, x_axis_ext,
y_axis, y_axis_ext, ext_stack,
ext_bubble, custom_attr, custom_style,
custom_filter, drill_fields, snapshot
)
values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{sceneId,jdbcType=VARCHAR},
#{tableId,jdbcType=VARCHAR}, #{type,jdbcType=VARCHAR}, #{render,jdbcType=VARCHAR},
#{resultCount,jdbcType=INTEGER}, #{resultMode,jdbcType=VARCHAR}, #{title,jdbcType=VARCHAR},
#{createBy,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT},
#{stylePriority,jdbcType=VARCHAR}, #{xAxis,jdbcType=LONGVARCHAR}, #{yAxis,jdbcType=LONGVARCHAR},
#{yAxisExt,jdbcType=LONGVARCHAR}, #{extStack,jdbcType=LONGVARCHAR}, #{extBubble,jdbcType=LONGVARCHAR},
#{customAttr,jdbcType=LONGVARCHAR}, #{customStyle,jdbcType=LONGVARCHAR}, #{customFilter,jdbcType=LONGVARCHAR},
#{drillFields,jdbcType=LONGVARCHAR}, #{snapshot,jdbcType=LONGVARCHAR})
#{stylePriority,jdbcType=VARCHAR}, #{xAxis,jdbcType=LONGVARCHAR}, #{xAxisExt,jdbcType=LONGVARCHAR},
#{yAxis,jdbcType=LONGVARCHAR}, #{yAxisExt,jdbcType=LONGVARCHAR}, #{extStack,jdbcType=LONGVARCHAR},
#{extBubble,jdbcType=LONGVARCHAR}, #{customAttr,jdbcType=LONGVARCHAR}, #{customStyle,jdbcType=LONGVARCHAR},
#{customFilter,jdbcType=LONGVARCHAR}, #{drillFields,jdbcType=LONGVARCHAR}, #{snapshot,jdbcType=LONGVARCHAR}
)
</insert>
<insert id="insertSelective" parameterType="io.dataease.base.domain.ChartViewWithBLOBs">
insert into chart_view
@ -205,6 +208,9 @@
<if test="xAxis != null">
x_axis,
</if>
<if test="xAxisExt != null">
x_axis_ext,
</if>
<if test="yAxis != null">
y_axis,
</if>
@ -276,6 +282,9 @@
<if test="xAxis != null">
#{xAxis,jdbcType=LONGVARCHAR},
</if>
<if test="xAxisExt != null">
#{xAxisExt,jdbcType=LONGVARCHAR},
</if>
<if test="yAxis != null">
#{yAxis,jdbcType=LONGVARCHAR},
</if>
@ -356,6 +365,9 @@
<if test="record.xAxis != null">
x_axis = #{record.xAxis,jdbcType=LONGVARCHAR},
</if>
<if test="record.xAxisExt != null">
x_axis_ext = #{record.xAxisExt,jdbcType=LONGVARCHAR},
</if>
<if test="record.yAxis != null">
y_axis = #{record.yAxis,jdbcType=LONGVARCHAR},
</if>
@ -404,6 +416,7 @@
update_time = #{record.updateTime,jdbcType=BIGINT},
style_priority = #{record.stylePriority,jdbcType=VARCHAR},
x_axis = #{record.xAxis,jdbcType=LONGVARCHAR},
x_axis_ext = #{record.xAxisExt,jdbcType=LONGVARCHAR},
y_axis = #{record.yAxis,jdbcType=LONGVARCHAR},
y_axis_ext = #{record.yAxisExt,jdbcType=LONGVARCHAR},
ext_stack = #{record.extStack,jdbcType=LONGVARCHAR},
@ -478,6 +491,9 @@
<if test="xAxis != null">
x_axis = #{xAxis,jdbcType=LONGVARCHAR},
</if>
<if test="xAxisExt != null">
x_axis_ext = #{xAxisExt,jdbcType=LONGVARCHAR},
</if>
<if test="yAxis != null">
y_axis = #{yAxis,jdbcType=LONGVARCHAR},
</if>
@ -523,6 +539,7 @@
update_time = #{updateTime,jdbcType=BIGINT},
style_priority = #{stylePriority,jdbcType=VARCHAR},
x_axis = #{xAxis,jdbcType=LONGVARCHAR},
x_axis_ext = #{xAxisExt,jdbcType=LONGVARCHAR},
y_axis = #{yAxis,jdbcType=LONGVARCHAR},
y_axis_ext = #{yAxisExt,jdbcType=LONGVARCHAR},
ext_stack = #{extStack,jdbcType=LONGVARCHAR},

View File

@ -219,6 +219,11 @@ public class ChartViewService {
}
List<ChartViewFieldDTO> xAxis = new Gson().fromJson(view.getXAxis(), new TypeToken<List<ChartViewFieldDTO>>() {
}.getType());
if (StringUtils.equalsIgnoreCase(view.getType(), "table-pivot")) {
List<ChartViewFieldDTO> xAxisExt = new Gson().fromJson(view.getXAxisExt(), new TypeToken<List<ChartViewFieldDTO>>() {
}.getType());
xAxis.addAll(xAxisExt);
}
List<ChartViewFieldDTO> yAxis = new Gson().fromJson(view.getYAxis(), new TypeToken<List<ChartViewFieldDTO>>() {
}.getType());
if (StringUtils.equalsIgnoreCase(view.getType(), "chart-mix")) {

View File

@ -0,0 +1,2 @@
ALTER TABLE `chart_view` ADD COLUMN `x_axis_ext` LONGTEXT COMMENT 'table-row' AFTER `x_axis`;
UPDATE `chart_view` SET `x_axis_ext` = '[]';

View File

@ -60,6 +60,6 @@
</javaClientGenerator>
<!--要生成的数据库表 -->
<table tableName="dataset_column_permissions"/>
<table tableName="chart_view"/>
</context>
</generatorConfiguration>

View File

@ -1 +1 @@
<svg t="1630896178915" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1969" width="200" height="200"><path d="M85.333333 170.666667h853.333334v170.666666H85.333333zM85.333333 384h170.666667v469.333333H85.333333z" p-id="1970"></path><path d="M298.666667 384h640v128H298.666667z" opacity=".6" p-id="1971"></path><path d="M298.666667 554.666667h298.666666v128H298.666667zM640 554.666667h298.666667v128H640z" p-id="1972"></path><path d="M298.666667 725.333333h298.666666v128H298.666667zM640 725.333333h298.666667v128H640z" opacity=".6" p-id="1973"></path></svg>
<svg t="1644288854112" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1947" width="200" height="200"><path d="M85.333333 170.666667h853.333334v170.666666H85.333333zM85.333333 384h170.666667v469.333333H85.333333z" p-id="1948"></path><path d="M298.666667 384h640v128H298.666667z" opacity=".6" p-id="1949"></path><path d="M298.666667 554.666667h640v128H298.666667z" p-id="1950"></path><path d="M298.666667 725.333333h640v128H298.666667z" opacity=".6" p-id="1951"></path></svg>

Before

Width:  |  Height:  |  Size: 603 B

After

Width:  |  Height:  |  Size: 519 B

View File

@ -0,0 +1 @@
<svg t="1630896178915" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1969" width="200" height="200"><path d="M85.333333 170.666667h853.333334v170.666666H85.333333zM85.333333 384h170.666667v469.333333H85.333333z" p-id="1970"></path><path d="M298.666667 384h640v128H298.666667z" opacity=".6" p-id="1971"></path><path d="M298.666667 554.666667h298.666666v128H298.666667zM640 554.666667h298.666667v128H640z" p-id="1972"></path><path d="M298.666667 725.333333h298.666666v128H298.666667zM640 725.333333h298.666667v128H640z" opacity=".6" p-id="1973"></path></svg>

After

Width:  |  Height:  |  Size: 603 B

View File

@ -1020,7 +1020,9 @@ export default {
table_config: 'Table Config',
table_column_width_config: 'Column Width',
table_column_adapt: 'Adapt',
table_column_custom: 'Custom'
table_column_custom: 'Custom',
chart_table_pivot: 'Pivot Table',
table_pivot_row: 'Data Row'
},
dataset: {
sheet_warn: 'There are multiple sheet pages, and the first one is extracted by default',

View File

@ -1020,7 +1020,9 @@ export default {
table_config: '表格配置',
table_column_width_config: '列寬調整',
table_column_adapt: '自適應',
table_column_custom: '自定義'
table_column_custom: '自定義',
chart_table_pivot: '透視表',
table_pivot_row: '數據行'
},
dataset: {
sheet_warn: '有多個 Sheet 頁,默認抽取第一個',

View File

@ -1022,7 +1022,9 @@ export default {
table_config: '表格配置',
table_column_width_config: '列宽调整',
table_column_adapt: '自适应',
table_column_custom: '自定义'
table_column_custom: '自定义',
chart_table_pivot: '透视表',
table_pivot_row: '数据行'
},
dataset: {
sheet_warn: '有多个 Sheet 页,默认抽取第一个',

View File

@ -6,10 +6,40 @@ export function getCustomTheme(chart) {
background: {
color: '#00000000'
},
cornerCell: {
cell: {
backgroundColor: hexColorToRGBA(DEFAULT_COLOR_CASE.tableHeaderBgColor, DEFAULT_COLOR_CASE.alpha)
},
text: {
fill: DEFAULT_COLOR_CASE.tableFontColor,
fontSize: DEFAULT_SIZE.tableTitleFontSize
},
bolderText: {
fill: DEFAULT_COLOR_CASE.tableFontColor,
fontSize: DEFAULT_SIZE.tableTitleFontSize
}
},
rowCell: {
cell: {
backgroundColor: hexColorToRGBA(DEFAULT_COLOR_CASE.tableHeaderBgColor, DEFAULT_COLOR_CASE.alpha)
},
text: {
fill: DEFAULT_COLOR_CASE.tableFontColor,
fontSize: DEFAULT_SIZE.tableTitleFontSize
},
bolderText: {
fill: DEFAULT_COLOR_CASE.tableFontColor,
fontSize: DEFAULT_SIZE.tableTitleFontSize
}
},
colCell: {
cell: {
backgroundColor: hexColorToRGBA(DEFAULT_COLOR_CASE.tableHeaderBgColor, DEFAULT_COLOR_CASE.alpha)
},
text: {
fill: DEFAULT_COLOR_CASE.tableFontColor,
fontSize: DEFAULT_SIZE.tableTitleFontSize
},
bolderText: {
fill: DEFAULT_COLOR_CASE.tableFontColor,
fontSize: DEFAULT_SIZE.tableTitleFontSize
@ -32,15 +62,29 @@ export function getCustomTheme(chart) {
// color
if (customAttr.color) {
const c = JSON.parse(JSON.stringify(customAttr.color))
theme.cornerCell.cell.backgroundColor = hexColorToRGBA(c.tableHeaderBgColor, c.alpha)
theme.cornerCell.bolderText.fill = c.tableFontColor
theme.cornerCell.text.fill = c.tableFontColor
theme.rowCell.cell.backgroundColor = hexColorToRGBA(c.tableHeaderBgColor, c.alpha)
theme.rowCell.bolderText.fill = c.tableFontColor
theme.rowCell.text.fill = c.tableFontColor
theme.colCell.cell.backgroundColor = hexColorToRGBA(c.tableHeaderBgColor, c.alpha)
theme.colCell.bolderText.fill = c.tableFontColor
theme.colCell.text.fill = c.tableFontColor
theme.dataCell.cell.backgroundColor = hexColorToRGBA(c.tableItemBgColor, c.alpha)
theme.dataCell.text.fill = c.tableFontColor
}
// size
if (customAttr.size) {
const s = JSON.parse(JSON.stringify(customAttr.size))
theme.cornerCell.bolderText.fontSize = parseInt(s.tableTitleFontSize)
theme.cornerCell.text.fontSize = parseInt(s.tableTitleFontSize)
theme.rowCell.bolderText.fontSize = parseInt(s.tableTitleFontSize)
theme.rowCell.text.fontSize = parseInt(s.tableTitleFontSize)
theme.colCell.bolderText.fontSize = parseInt(s.tableTitleFontSize)
theme.colCell.text.fontSize = parseInt(s.tableTitleFontSize)
theme.dataCell.text.fontSize = parseInt(s.tableItemFontSize)
}
}

View File

@ -1,10 +1,10 @@
import { TableSheet, S2Event } from '@antv/s2'
import { TableSheet, S2Event, PivotSheet } from '@antv/s2'
import { getCustomTheme, getSize } from '@/views/chart/chart/common/common_table'
export function baseTableInfo(s2, container, chart, action, tableData) {
const containerDom = document.getElementById(container)
// data
// fields
const fields = chart.data.fields
if (!fields || fields.length === 0) {
if (s2) {
@ -102,7 +102,7 @@ export function baseTableInfo(s2, container, chart, action, tableData) {
export function baseTableNormal(s2, container, chart, action, tableData) {
const containerDom = document.getElementById(container)
// data
// fields
const fields = chart.data.fields
if (!fields || fields.length === 0) {
if (s2) {
@ -190,3 +190,111 @@ export function baseTableNormal(s2, container, chart, action, tableData) {
return s2
}
export function baseTablePivot(s2, container, chart, action, tableData) {
const containerDom = document.getElementById(container)
// row and column
const columnFields = JSON.parse(chart.xaxis)
const rowFields = JSON.parse(chart.xaxisExt)
const valueFields = JSON.parse(chart.yaxis)
const c = []; const r = []; const v = []
columnFields.forEach(ele => {
c.push(ele.dataeaseName)
})
rowFields.forEach(ele => {
r.push(ele.dataeaseName)
})
valueFields.forEach(ele => {
v.push(ele.dataeaseName)
})
// fields
const fields = chart.data.fields
if (!fields || fields.length === 0) {
if (s2) {
s2.destroy()
}
return
}
const columns = []
const meta = []
// add drill list
if (chart.drill) {
const drillFields = JSON.parse(chart.drillFields)
const drillField = drillFields[chart.drillFilters.length]
const drillFilters = JSON.parse(JSON.stringify(chart.drillFilters))
const drillExp = drillFilters[drillFilters.length - 1].datasetTableField
// 移除所有下钻字段
const removeField = []
for (let i = 0; i < chart.drillFilters.length; i++) {
const ele = chart.drillFilters[i].datasetTableField
removeField.push(ele.dataeaseName)
}
// build field
fields.forEach(ele => {
if (removeField.indexOf(ele.dataeaseName) < 0) {
// 用下钻字段替换当前字段
if (drillExp.dataeaseName === ele.dataeaseName) {
columns.push(drillField.dataeaseName)
meta.push({
field: drillField.dataeaseName,
name: drillField.name
})
} else {
columns.push(ele.dataeaseName)
meta.push({
field: ele.dataeaseName,
name: ele.name
})
}
}
})
} else {
fields.forEach(ele => {
columns.push(ele.dataeaseName)
meta.push({
field: ele.dataeaseName,
name: ele.name
})
})
}
// data config
const s2DataConfig = {
fields: {
rows: r,
columns: c,
values: v
},
meta: meta,
data: tableData
}
// options
const s2Options = {
width: containerDom.offsetWidth,
height: containerDom.offsetHeight,
style: getSize(chart)
}
// 开始渲染
if (s2) {
s2.destroy()
}
s2 = new PivotSheet(containerDom, s2DataConfig, s2Options)
// click
s2.on(S2Event.DATA_CELL_CLICK, action)
// theme
const customTheme = getCustomTheme(chart)
s2.setThemeCfg({ theme: customTheme })
return s2
}

View File

@ -4,9 +4,10 @@
<span v-if="chart.type" v-show="title_show" ref="title" :style="title_class" style="cursor: default;display: block;">
<p style="padding:6px 10px 0 10px;margin: 0;overflow: hidden;white-space: pre;text-overflow: ellipsis;">{{ chart.title }}</p>
</span>
<div style="width: 100%;overflow: hidden;padding: 8px;" :style="{height:chartHeight,background:container_bg_class.background}">
<div ref="tableContainer" style="width: 100%;overflow: hidden;padding: 8px;" :style="{background:container_bg_class.background}">
<div v-if="chart.type === 'table-normal'" :id="chartId" style="width: 100%;overflow: hidden;" :class="chart.drill ? 'table-dom-normal-drill' : 'table-dom-normal'" />
<div v-if="chart.type === 'table-info'" :id="chartId" style="width: 100%;overflow: hidden;" :class="chart.drill ? 'table-dom-info-drill' : 'table-dom-info'" />
<div v-if="chart.type === 'table-pivot'" :id="chartId" style="width: 100%;overflow: hidden;" class="table-dom-normal" />
<el-row v-show="chart.type === 'table-info'" class="table-page">
<span class="total-style">
{{ $t('chart.total') }}
@ -34,7 +35,7 @@
import { uuid } from 'vue-uuid'
import ViewTrackBar from '@/components/canvas/components/Editor/ViewTrackBar'
import { hexColorToRGBA } from '@/views/chart/chart/util'
import { baseTableInfo, baseTableNormal } from '@/views/chart/chart/table/table-info'
import { baseTableInfo, baseTableNormal, baseTablePivot } from '@/views/chart/chart/table/table-info'
export default {
name: 'ChartComponentS2',
@ -189,6 +190,8 @@ export default {
this.myChart = baseTableInfo(this.myChart, this.chartId, chart, this.antVAction, this.tableData)
} else if (chart.type === 'table-normal') {
this.myChart = baseTableNormal(this.myChart, this.chartId, chart, this.antVAction, this.tableData)
} else if (chart.type === 'table-pivot') {
this.myChart = baseTablePivot(this.myChart, this.chartId, chart, this.antVAction, this.tableData)
} else {
if (this.myChart) {
this.antVRenderStatus = false
@ -338,6 +341,7 @@ export default {
if (this.$refs.title) {
const titleHeight = this.$refs.title.offsetHeight
this.chartHeight = (currentHeight - titleHeight) + 'px'
this.$refs.tableContainer.style.height = this.chartHeight
}
}
})

View File

@ -0,0 +1,248 @@
<template>
<span>
<el-tag v-if="!hasDataPermission('manage',param.privileges)" size="small" class="item-axis" :type="item.groupType === 'q'?'success':''">
<span style="float: left">
<svg-icon v-if="item.deType === 0" icon-class="field_text" class="field-icon-text" />
<svg-icon v-if="item.deType === 1" icon-class="field_time" class="field-icon-time" />
<svg-icon v-if="item.deType === 2 || item.deType === 3" icon-class="field_value" class="field-icon-value" />
<svg-icon v-if="item.deType === 5" icon-class="field_location" class="field-icon-location" />
<svg-icon v-if="item.sort === 'asc'" icon-class="sort-asc" class-name="field-icon-sort" />
<svg-icon v-if="item.sort === 'desc'" icon-class="sort-desc" class-name="field-icon-sort" />
</span>
<span class="item-span-style" :title="item.name">{{ item.name }}</span>
<span v-if="item.deType === 1" class="summary-span">
{{ $t('chart.' + item.dateStyle) }}
</span>
</el-tag>
<el-dropdown v-else trigger="click" size="mini" @command="clickItem">
<span class="el-dropdown-link">
<el-tag size="small" class="item-axis" :type="item.groupType === 'q'?'success':''">
<span style="float: left">
<svg-icon v-if="item.deType === 0" icon-class="field_text" class="field-icon-text" />
<svg-icon v-if="item.deType === 1" icon-class="field_time" class="field-icon-time" />
<svg-icon v-if="item.deType === 2 || item.deType === 3" icon-class="field_value" class="field-icon-value" />
<svg-icon v-if="item.deType === 5" icon-class="field_location" class="field-icon-location" />
<svg-icon v-if="item.sort === 'asc'" icon-class="sort-asc" class-name="field-icon-sort" />
<svg-icon v-if="item.sort === 'desc'" icon-class="sort-desc" class-name="field-icon-sort" />
</span>
<span class="item-span-style" :title="item.name">{{ item.name }}</span>
<span v-if="item.deType === 1" class="summary-span">
{{ $t('chart.' + item.dateStyle) }}
</span>
<i class="el-icon-arrow-down el-icon--right" style="position: absolute;top: 6px;right: 10px;" />
</el-tag>
<el-dropdown-menu slot="dropdown">
<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-item">({{ $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 v-show="item.deType === 1" divided>
<el-dropdown placement="right-start" size="mini" style="width: 100%" @command="dateStyle">
<span class="el-dropdown-link inner-dropdown-menu">
<span>
<i class="el-icon-c-scale-to-original" />
<span>{{ $t('chart.dateStyle') }}</span>
<span class="summary-span-item">({{ $t('chart.'+item.dateStyle) }})</span>
</span>
<i class="el-icon-arrow-right el-icon--right" />
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="beforeDateStyle('y')">{{ $t('chart.y') }}</el-dropdown-item>
<el-dropdown-item :command="beforeDateStyle('y_M')">{{ $t('chart.y_M') }}</el-dropdown-item>
<el-dropdown-item :command="beforeDateStyle('y_M_d')">{{ $t('chart.y_M_d') }}</el-dropdown-item>
<el-dropdown-item :command="beforeDateStyle('H_m_s')" divided>{{ $t('chart.H_m_s') }}</el-dropdown-item>
<el-dropdown-item :command="beforeDateStyle('y_M_d_H_m')">{{ $t('chart.y_M_d_H_m') }}</el-dropdown-item>
<el-dropdown-item :command="beforeDateStyle('y_M_d_H_m_s')">{{ $t('chart.y_M_d_H_m_s') }}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-dropdown-item>
<el-dropdown-item v-show="item.deType === 1">
<el-dropdown placement="right-start" size="mini" style="width: 100%" @command="datePattern">
<span class="el-dropdown-link inner-dropdown-menu">
<span>
<i class="el-icon-timer" />
<span>{{ $t('chart.datePattern') }}</span>
<span class="summary-span-item">({{ $t('chart.'+item.datePattern) }})</span>
</span>
<i class="el-icon-arrow-right el-icon--right" />
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="beforeDatePattern('date_sub')">{{ $t('chart.date_sub') }}(1990-01-01)</el-dropdown-item>
<el-dropdown-item :command="beforeDatePattern('date_split')">{{ $t('chart.date_split') }}(1990/01/01)</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-dropdown-item>
<el-dropdown-item icon="el-icon-edit-outline" divided :command="beforeClickItem('rename')">
<span>{{ $t('chart.show_name_set') }}</span>
</el-dropdown-item>
<el-dropdown-item icon="el-icon-delete" divided :command="beforeClickItem('remove')">
<span>{{ $t('chart.delete') }}</span>
</el-dropdown-item>
</el-dropdown-menu>
</span>
</el-dropdown>
</span>
</template>
<script>
export default {
name: 'DimensionExtItem',
props: {
param: {
type: Object,
required: true
},
item: {
type: Object,
required: true
},
index: {
type: Number,
required: true
}
},
data() {
return {
}
},
mounted() {
},
methods: {
clickItem(param) {
if (!param) {
return
}
switch (param.type) {
case 'rename':
this.showRename()
break
case 'remove':
this.removeItem()
break
case 'filter':
this.editFilter()
break
default:
break
}
},
beforeClickItem(type) {
return {
type: type
}
},
sort(param) {
// console.log(param)
this.item.sort = param.type
this.$emit('onDimensionItemChange', this.item)
},
beforeSort(type) {
return {
type: type
}
},
dateStyle(param) {
// console.log(param)
this.item.dateStyle = param.type
this.$emit('onDimensionItemChange', this.item)
},
beforeDateStyle(type) {
return {
type: type
}
},
datePattern(param) {
this.item.datePattern = param.type
this.$emit('onDimensionItemChange', this.item)
},
beforeDatePattern(type) {
return {
type: type
}
},
editFilter() {
this.item.index = this.index
this.$emit('editItemFilter', this.item)
},
showRename() {
this.item.index = this.index
this.item.renameType = 'dimensionExt'
this.$emit('onNameEdit', this.item)
},
removeItem() {
this.item.index = this.index
this.item.removeType = 'dimensionExt'
this.$emit('onDimensionItemRemove', this.item)
}
}
}
</script>
<style scoped>
.item-axis {
padding: 1px 6px;
margin: 0 3px 2px 3px;
text-align: left;
height: 24px;
line-height: 22px;
display: flex;
border-radius: 4px;
box-sizing: border-box;
white-space: nowrap;
width: 159px;
}
.item-axis:hover {
background-color: #fdfdfd;
cursor: pointer;
}
span {
font-size: 12px;
}
.summary-span{
margin-left: 4px;
color: #878d9f;
position: absolute;
right: 25px;
}
.inner-dropdown-menu{
display: flex;
justify-content: space-between;
align-items: center;
width: 100%
}
.item-span-style{
display: inline-block;
width: 70px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.summary-span-item{
margin-left: 4px;
color: #878d9f;
}
</style>

View File

@ -190,6 +190,7 @@ export default {
},
removeItem() {
this.item.index = this.index
this.item.removeType = 'dimension'
this.$emit('onDimensionItemRemove', this.item)
}
}

View File

@ -124,7 +124,7 @@
</el-tooltip>
</el-form-item>
<el-form-item v-show="sizeForm.tableColumnMode === 'custom'" label="" class="form-item form-item-slider">
<el-slider v-model="sizeForm.tableColumnWidth" :min="100" :max="500" show-input :show-input-controls="false" input-size="mini" @change="changeBarSizeCase" />
<el-slider v-model="sizeForm.tableColumnWidth" :min="10" :max="500" show-input :show-input-controls="false" input-size="mini" @change="changeBarSizeCase" />
</el-form-item>
</el-form>

View File

@ -768,6 +768,7 @@ export default {
})
view.stylePriority = 'view' //
view.xaxis = JSON.stringify([])
view.xaxisExt = JSON.stringify([])
view.yaxis = JSON.stringify([])
view.yaxisExt = JSON.stringify([])
view.extStack = JSON.stringify([])

View File

@ -238,6 +238,45 @@
/>
</span>
</el-row>
<!--xAxisExt-->
<el-row
v-if="view.type === 'table-pivot'"
class="padding-lr"
>
<span style="width: 80px;text-align: right;">
<span>{{ $t('chart.table_pivot_row') }}</span>
/
<span>{{ $t('chart.dimension') }}</span>
</span>
<draggable
v-model="view.xaxisExt"
:disabled="!hasDataPermission('manage',param.privileges)"
group="drag"
animation="300"
:move="onMove"
class="drag-block-style"
@add="addXaxisExt"
@update="calcData(true)"
>
<transition-group class="draggable-group">
<dimension-ext-item
v-for="(item,index) in view.xaxisExt"
:key="item.id"
:param="param"
:index="index"
:item="item"
@onDimensionItemChange="dimensionItemChange"
@onDimensionItemRemove="dimensionItemRemove"
@editItemFilter="showDimensionEditFilter"
@onNameEdit="showRename"
/>
</transition-group>
</draggable>
<div v-if="!view.xaxisExt || view.xaxisExt.length === 0" class="drag-placeholder-style">
<span class="drag-placeholder-style-span">{{ $t('chart.placeholder_field') }}</span>
</div>
</el-row>
<!--xAxis-->
<el-row
v-if="view.type !=='text' && view.type !== 'gauge' && view.type !== 'liquid'"
class="padding-lr"
@ -289,6 +328,7 @@
<span class="drag-placeholder-style-span">{{ $t('chart.placeholder_field') }}</span>
</div>
</el-row>
<!--yaxis-->
<el-row v-if="view.type !=='table-info'" class="padding-lr" style="margin-top: 6px;">
<span style="width: 80px;text-align: right;">
<span v-if="view.type && view.type.includes('table')">{{ $t('chart.drag_block_table_data_column') }}</span>
@ -342,6 +382,7 @@
<span class="drag-placeholder-style-span">{{ $t('chart.placeholder_field') }}</span>
</div>
</el-row>
<!--yAxisExt-->
<el-row v-if="view.type && view.type === 'chart-mix'" class="padding-lr" style="margin-top: 6px;">
<span style="width: 80px;text-align: right;">
<span>{{ $t('chart.drag_block_value_axis_ext') }}</span>
@ -378,6 +419,7 @@
<span class="drag-placeholder-style-span">{{ $t('chart.placeholder_field') }}</span>
</div>
</el-row>
<!--extStack-->
<el-row v-if="view.type && view.type.includes('stack')" class="padding-lr" style="margin-top: 6px;">
<span style="width: 80px;text-align: right;">
<span>{{ $t('chart.stack_item') }}</span>
@ -411,6 +453,7 @@
<span class="drag-placeholder-style-span">{{ $t('chart.placeholder_field') }}</span>
</div>
</el-row>
<!--extBubble-->
<el-row v-if="view.type && view.type.includes('scatter')" class="padding-lr" style="margin-top: 6px;">
<span style="width: 80px;text-align: right;">
<span>{{ $t('chart.bubble_size') }}</span>
@ -483,7 +526,7 @@
</div>
</el-row>
<el-row
v-if="view.type && !(view.type.includes('table') && view.render === 'echarts') && !view.type.includes('text') && !view.type.includes('gauge') && view.type !== 'liquid' && view.type !== 'word-cloud'"
v-if="view.type && !(view.type.includes('table') && view.render === 'echarts') && !view.type.includes('text') && !view.type.includes('gauge') && view.type !== 'liquid' && view.type !== 'word-cloud' && view.type !== 'table-pivot'"
class="padding-lr"
style="margin-top: 6px;"
>
@ -778,7 +821,7 @@
@onChartClick="chartClick"
/>
<table-normal
v-if="httpRequest.status && chart.type && chart.type.includes('table') && renderComponent() === 'echarts'"
v-if="httpRequest.status && chart.type && chart.type.includes('table') && renderComponent() === 'echarts' && chart.type !== 'table-pivot'"
:show-summary="chart.type === 'table-normal'"
:chart="chart"
class="table-class"
@ -982,10 +1025,12 @@ import SplitSelectorAntV from '@/views/chart/components/component-style/SplitSel
import CompareEdit from '@/views/chart/components/compare/CompareEdit'
import { compareItem } from '@/views/chart/chart/compare'
import ChartComponentS2 from '@/views/chart/components/ChartComponentS2'
import DimensionExtItem from '@/views/chart/components/drag-item/DimensionExtItem'
export default {
name: 'ChartEdit',
components: {
DimensionExtItem,
ChartComponentS2,
CompareEdit,
SplitSelectorAntV,
@ -1044,6 +1089,7 @@ export default {
quotaData: [],
view: {
xaxis: [],
xaxisExt: [],
yaxis: [],
yaxisExt: [],
extStack: [],
@ -1236,6 +1282,25 @@ export default {
ele.filter = []
}
})
if (view.type === 'table-pivot') {
view.xaxisExt.forEach(function(ele) {
// if (!ele.summary || ele.summary === '') {
// ele.summary = 'sum'
// }
if (!ele.dateStyle || ele.dateStyle === '') {
ele.dateStyle = 'y_M_d'
}
if (!ele.datePattern || ele.datePattern === '') {
ele.datePattern = 'date_sub'
}
if (!ele.sort || ele.sort === '') {
ele.sort = 'none'
}
if (!ele.filter) {
ele.filter = []
}
})
}
if (view.type === 'map' && view.yaxis.length > 1) {
view.yaxis = [view.yaxis[0]]
}
@ -1327,7 +1392,8 @@ export default {
if (view.type === 'liquid' ||
(view.type.includes('table') && view.render === 'echarts') ||
view.type.includes('text') ||
view.type.includes('gauge')) {
view.type.includes('gauge') ||
view.type === 'table-pivot') {
view.drillFields = []
}
view.customFilter.forEach(function(ele) {
@ -1336,6 +1402,7 @@ export default {
}
})
view.xaxis = JSON.stringify(view.xaxis)
view.xaxisExt = JSON.stringify(view.xaxisExt)
view.yaxis = JSON.stringify(view.yaxis)
view.yaxisExt = JSON.stringify(view.yaxisExt)
view.customAttr = JSON.stringify(view.customAttr)
@ -1360,6 +1427,7 @@ export default {
}).then(response => {
const view = JSON.parse(JSON.stringify(response.data))
this.view.xaxis = view.xaxis ? JSON.parse(view.xaxis) : []
this.view.xaxisExt = view.xaxisExt ? JSON.parse(view.xaxisExt) : []
this.view.yaxis = view.yaxis ? JSON.parse(view.yaxis) : []
this.view.yaxisExt = view.yaxisExt ? JSON.parse(view.yaxisExt) : []
this.view.extStack = view.extStack ? JSON.parse(view.extStack) : []
@ -1393,6 +1461,7 @@ export default {
// echart...
const view = JSON.parse(JSON.stringify(this.view))
view.xaxis = JSON.stringify(this.view.xaxis)
view.xaxisExt = JSON.stringify(this.view.xaxisExt)
view.yaxis = JSON.stringify(this.view.yaxis)
view.yaxisExt = JSON.stringify(this.view.yaxisExt)
view.extStack = JSON.stringify(this.view.extStack)
@ -1434,6 +1503,7 @@ export default {
this.initTableData(response.data.tableId)
this.view = JSON.parse(JSON.stringify(response.data))
this.view.xaxis = this.view.xaxis ? JSON.parse(this.view.xaxis) : []
this.view.xaxisExt = this.view.xaxisExt ? JSON.parse(this.view.xaxisExt) : []
this.view.yaxis = this.view.yaxis ? JSON.parse(this.view.yaxis) : []
this.view.yaxisExt = this.view.yaxisExt ? JSON.parse(this.view.yaxisExt) : []
this.view.extStack = this.view.extStack ? JSON.parse(this.view.extStack) : []
@ -1477,6 +1547,7 @@ export default {
this.initTableData(response.data.tableId)
this.view = JSON.parse(JSON.stringify(response.data))
this.view.xaxis = this.view.xaxis ? JSON.parse(this.view.xaxis) : []
this.view.xaxisExt = this.view.xaxisExt ? JSON.parse(this.view.xaxisExt) : []
this.view.yaxis = this.view.yaxis ? JSON.parse(this.view.yaxis) : []
this.view.yaxisExt = this.view.yaxisExt ? JSON.parse(this.view.yaxisExt) : []
this.view.extStack = this.view.extStack ? JSON.parse(this.view.extStack) : []
@ -1507,7 +1578,11 @@ export default {
},
dimensionItemRemove(item) {
this.view.xaxis.splice(item.index, 1)
if (item.removeType === 'dimension') {
this.view.xaxis.splice(item.index, 1)
} else if (item.removeType === 'dimensionExt') {
this.view.xaxisExt.splice(item.index, 1)
}
this.calcData(true)
},
@ -1715,6 +1790,8 @@ export default {
this.view.xaxis[this.itemForm.index].name = this.itemForm.name
} else if (this.itemForm.renameType === 'quotaExt') {
this.view.yaxisExt[this.itemForm.index].name = this.itemForm.name
} else if (this.itemForm.renameType === 'dimensionExt') {
this.view.xaxisExt[this.itemForm.index].name = this.itemForm.name
}
this.calcData(true)
this.closeRename()
@ -1856,6 +1933,16 @@ export default {
}
this.calcData(true)
},
addXaxisExt(e) {
if (this.view.type !== 'table-info') {
this.dragCheckType(this.view.xaxis, 'd')
}
this.dragMoveDuplicate(this.view.xaxis, e)
if ((this.view.type === 'map' || this.view.type === 'word-cloud') && this.view.xaxis.length > 1) {
this.view.xaxis = [this.view.xaxis[0]]
}
this.calcData(true)
},
addYaxis(e) {
this.dragCheckType(this.view.yaxis, 'q')
this.dragMoveDuplicate(this.view.yaxis, e)

View File

@ -20,7 +20,16 @@
<p class="radio-label">{{ $t('chart.chart_table_info') }}</p>
</el-radio>
</div>
<el-radio value="" label="" disabled class="disabled-none-cursor"><svg-icon icon-class="" class="chart-icon" /></el-radio>
<div style="position: relative;display: block;">
<el-radio value="table-pivot" label="table-pivot" border class="radio-style">
<span :title="$t('chart.chart_table_pivot')">
<svg-icon icon-class="table-pivot" class="chart-icon" />
</span>
<p class="radio-label">{{ $t('chart.chart_table_pivot') }}</p>
</el-radio>
</div>
<!--如需要以下用于占位-->
<!--<el-radio value="" label="" disabled class="disabled-none-cursor"><svg-icon icon-class="" class="chart-icon" /></el-radio>-->
</div>
</div>