feat(视图-水波图): 水波图目标值支持动态值

水波图目标值支持动态值 https://www.tapd.cn/55578866/prong/stories/view/1155578866001009735
This commit is contained in:
wisonic-s 2022-10-20 18:12:52 +08:00
parent 87f3fd9586
commit e5b59e409a
9 changed files with 243 additions and 86 deletions

View File

@ -580,7 +580,7 @@ public class ChartViewService {
List<ChartViewFieldDTO> yAxisExt = gson.fromJson(view.getYAxisExt(), tokenType);
yAxis.addAll(yAxisExt);
}
if (StringUtils.equalsIgnoreCase(view.getRender(), "antv") && StringUtils.equalsIgnoreCase(view.getType(), "gauge")) {
if (StringUtils.equalsIgnoreCase(view.getRender(), "antv") && StringUtils.equalsAnyIgnoreCase(view.getType(), "gauge","liquid")) {
List<ChartViewFieldDTO> sizeField = getSizeField(view);
yAxis.addAll(sizeField);
}
@ -1656,49 +1656,46 @@ public class ChartViewService {
JSONObject jsonObject = JSONObject.parseObject(customAttr);
JSONObject size = jsonObject.getJSONObject("size");
String gaugeMinType = size.getString("gaugeMinType");
if (StringUtils.equalsIgnoreCase("dynamic", gaugeMinType)) {
JSONObject gaugeMinField = size.getJSONObject("gaugeMinField");
String id = gaugeMinField.getString("id");
String summary = gaugeMinField.getString("summary");
DatasetTableField datasetTableField = dataSetTableFieldsService.get(id);
if (ObjectUtils.isNotEmpty(datasetTableField)) {
if (datasetTableField.getDeType() == 0 || datasetTableField.getDeType() == 1 || datasetTableField.getDeType() == 5) {
if (!StringUtils.containsIgnoreCase(summary, "count")) {
DEException.throwException(Translator.get("i18n_gauge_field_change"));
}
}
ChartViewFieldDTO dto = new ChartViewFieldDTO();
BeanUtils.copyBean(dto, datasetTableField);
dto.setSummary(summary);
list.add(dto);
} else {
DEException.throwException(Translator.get("i18n_gauge_field_delete"));
}
ChartViewFieldDTO gaugeMinViewField = getDynamicField(size, "gaugeMinType", "gaugeMinField");
if (gaugeMinViewField != null) {
list.add(gaugeMinViewField);
}
String gaugeMaxType = size.getString("gaugeMaxType");
if (StringUtils.equalsIgnoreCase("dynamic", gaugeMaxType)) {
JSONObject gaugeMaxField = size.getJSONObject("gaugeMaxField");
String id = gaugeMaxField.getString("id");
String summary = gaugeMaxField.getString("summary");
DatasetTableField datasetTableField = dataSetTableFieldsService.get(id);
if (ObjectUtils.isNotEmpty(datasetTableField)) {
if (datasetTableField.getDeType() == 0 || datasetTableField.getDeType() == 1 || datasetTableField.getDeType() == 5) {
if (!StringUtils.containsIgnoreCase(summary, "count")) {
DEException.throwException(Translator.get("i18n_gauge_field_change"));
}
}
ChartViewFieldDTO dto = new ChartViewFieldDTO();
BeanUtils.copyBean(dto, datasetTableField);
dto.setSummary(summary);
list.add(dto);
} else {
DEException.throwException(Translator.get("i18n_gauge_field_delete"));
}
ChartViewFieldDTO gaugeMaxViewField = getDynamicField(size, "gaugeMaxType", "gaugeMaxField");
if (gaugeMaxViewField != null) {
list.add(gaugeMaxViewField);
}
ChartViewFieldDTO liquidMaxViewField = getDynamicField(size, "liquidMaxType", "liquidMaxField");
if (liquidMaxViewField != null) {
list.add(liquidMaxViewField);
}
return list;
}
private ChartViewFieldDTO getDynamicField(JSONObject sizeObj, String type, String field) {
String maxType = sizeObj.getString(type);
if (StringUtils.equalsIgnoreCase("dynamic", maxType)) {
JSONObject maxField = sizeObj.getJSONObject(field);
String id = maxField.getString("id");
String summary = maxField.getString("summary");
DatasetTableField datasetTableField = dataSetTableFieldsService.get(id);
if (ObjectUtils.isNotEmpty(datasetTableField)) {
if (datasetTableField.getDeType() == 0 || datasetTableField.getDeType() == 1 || datasetTableField.getDeType() == 5) {
if (!StringUtils.containsIgnoreCase(summary, "count")) {
DEException.throwException(Translator.get("i18n_gauge_field_change"));
}
}
ChartViewFieldDTO dto = new ChartViewFieldDTO();
BeanUtils.copyBean(dto, datasetTableField);
dto.setSummary(summary);
return dto;
} else {
DEException.throwException(Translator.get("i18n_gauge_field_delete"));
}
}
return null;
}
private List<ChartSeniorAssistDTO> getDynamicAssistFields(ChartViewDTO view) {
String senior = view.getSenior();
JSONObject jsonObject = JSONObject.parseObject(senior);

View File

@ -103,6 +103,11 @@ export const DEFAULT_SIZE = {
treemapWidth: 80,
treemapHeight: 80,
liquidMax: 100,
liquidMaxType: 'fix', // fix or dynamic
liquidMaxField: {
id: '',
summary: ''
},
liquidSize: 80,
liquidOutlineBorder: 4,
liquidOutlineDistance: 8,
@ -132,8 +137,8 @@ export const DEFAULT_LABEL = {
decimalCount: 2, // 小数位数
thousandSeparator: true// 千分符
},
reserveDecimalCount: 2, // 百分比堆叠柱状图,饼图,环形图保留小数位数
labelContent: ['dimension', 'proportion'] // 饼图,环形图指标展示项
reserveDecimalCount: 2,
labelContent: ['dimension', 'proportion']
}
export const DEFAULT_TOOLTIP = {
show: true,

View File

@ -126,6 +126,9 @@ export function getLabel(chart) {
type: l.position,
autoRotate: false
}
if (l.position === 'outer') {
label.type = 'spider'
}
} else if (chart.type.includes('line') || chart.type.includes('area')) {
label = {
position: l.position,

View File

@ -21,7 +21,7 @@ export function getCustomTheme(chart) {
backgroundColor: headerColor,
horizontalBorderColor: borderColor,
verticalBorderColor: borderColor,
verticalBorderWidth: 0 // 左上角顶点单元格左右边缘宽度要设置为 0不然序号列的数字部分会比表头多几个像素视觉上会突出去
verticalBorderWidth: 0
},
text: {
fill: DEFAULT_COLOR_CASE.tableHeaderFontColor,
@ -130,9 +130,9 @@ export function getCustomTheme(chart) {
theme.rowCell.cell.backgroundColor = i_c // 这个参数其实只对开启序号列的行头生效
theme.rowCell.cell.horizontalBorderColor = i_c
theme.rowCell.cell.verticalBorderColor = i_c
theme.rowCell.bolderText.fill = c.tableHeaderFontColor ? c.tableHeaderFontColor : c.tableFontColor
theme.rowCell.text.fill = c.tableHeaderFontColor ? c.tableHeaderFontColor : c.tableFontColor
theme.rowCell.measureText.fill = c.tableHeaderFontColor ? c.tableHeaderFontColor : c.tableFontColor
theme.rowCell.bolderText.fill = c.tableFontColor
theme.rowCell.text.fill = c.tableFontColor
theme.rowCell.measureText.fill = c.tableFontColor
theme.colCell.cell.backgroundColor = h_c
theme.colCell.cell.horizontalBorderColor = b_c
@ -162,11 +162,11 @@ export function getCustomTheme(chart) {
theme.cornerCell.measureText.textAlign = h_a
// 序号列的数字单元格内容样式使用指标的内容样式而不是表头的内容样式
theme.rowCell.bolderText.fontSize = parseInt(s.tableTitleFontSize)
theme.rowCell.bolderText.fontSize = parseInt(s.tableItemFontSize)
theme.rowCell.bolderText.textAlign = i_a
theme.rowCell.text.fontSize = parseInt(s.tableTitleFontSize)
theme.rowCell.text.fontSize = parseInt(s.tableItemFontSize)
theme.rowCell.text.textAlign = i_a
theme.rowCell.measureText.fontSize = parseInt(s.tableTitleFontSize)
theme.rowCell.measureText.fontSize = parseInt(s.tableItemFontSize)
theme.rowCell.measureText.textAlign = i_a
theme.colCell.bolderText.fontSize = parseInt(s.tableTitleFontSize)

View File

@ -9,10 +9,8 @@ export function baseLiquid(plot, container, chart) {
let value = 0
const colors = []
let max, radius, bgColor, shape, labelContent
if (chart.data) {
if (chart.data.series.length > 0) {
value = chart.data.series[0].data[0]
}
if (chart.data?.series.length > 0) {
value = chart.data.series[0].data[0]
}
let customAttr = {}
if (chart.customAttr) {
@ -27,7 +25,11 @@ export function baseLiquid(plot, container, chart) {
// size
if (customAttr.size) {
const size = JSON.parse(JSON.stringify(customAttr.size))
max = size.liquidMax ? size.liquidMax : DEFAULT_SIZE.liquidMax
if (size.liquidMaxType === 'dynamic') {
max = chart.data?.series[chart.data?.series.length - 1]?.data[0]
} else {
max = size.liquidMax ? size.liquidMax : DEFAULT_SIZE.liquidMax
}
radius = parseFloat((size.liquidSize ? size.liquidSize : DEFAULT_SIZE.liquidSize) / 100)
shape = size.liquidShape ? size.liquidShape : DEFAULT_SIZE.liquidShape
}

View File

@ -592,37 +592,37 @@
@change="changeQuotaField('min')"
>
<el-option
v-if="minField.id !== 'count' && minField.deType !== 0 && minField.deType !== 1 && minField.deType !== 5"
v-if="validMinField"
key="sum"
value="sum"
:label="$t('chart.sum')"
/>
<el-option
v-if="minField.id !== 'count' && minField.deType !== 0 && minField.deType !== 1 && minField.deType !== 5"
v-if="validMinField"
key="avg"
value="avg"
:label="$t('chart.avg')"
/>
<el-option
v-if="minField.id !== 'count' && minField.deType !== 0 && minField.deType !== 1 && minField.deType !== 5"
v-if="validMinField"
key="max"
value="max"
:label="$t('chart.max')"
/>
<el-option
v-if="minField.id !== 'count' && minField.deType !== 0 && minField.deType !== 1 && minField.deType !== 5"
v-if="validMinField"
key="min"
value="min"
:label="$t('chart.min')"
/>
<el-option
v-if="minField.id !== 'count' && minField.deType !== 0 && minField.deType !== 1 && minField.deType !== 5"
v-if="validMinField"
key="stddev_pop"
value="stddev_pop"
:label="$t('chart.stddev_pop')"
/>
<el-option
v-if="minField.id !== 'count' && minField.deType !== 0 && minField.deType !== 1 && minField.deType !== 5"
v-if="validMinField"
key="var_pop"
value="var_pop"
:label="$t('chart.var_pop')"
@ -711,37 +711,37 @@
@change="changeQuotaField('max')"
>
<el-option
v-if="maxField.id !== 'count' && maxField.deType !== 0 && maxField.deType !== 1 && maxField.deType !== 5"
v-if="validMaxField"
key="sum"
value="sum"
:label="$t('chart.sum')"
/>
<el-option
v-if="maxField.id !== 'count' && maxField.deType !== 0 && maxField.deType !== 1 && maxField.deType !== 5"
v-if="validMaxField"
key="avg"
value="avg"
:label="$t('chart.avg')"
/>
<el-option
v-if="maxField.id !== 'count' && maxField.deType !== 0 && maxField.deType !== 1 && maxField.deType !== 5"
v-if="validMaxField"
key="max"
value="max"
:label="$t('chart.max')"
/>
<el-option
v-if="maxField.id !== 'count' && maxField.deType !== 0 && maxField.deType !== 1 && maxField.deType !== 5"
v-if="validMaxField"
key="min"
value="min"
:label="$t('chart.min')"
/>
<el-option
v-if="maxField.id !== 'count' && maxField.deType !== 0 && maxField.deType !== 1 && maxField.deType !== 5"
v-if="validMaxField"
key="stddev_pop"
value="stddev_pop"
:label="$t('chart.stddev_pop')"
/>
<el-option
v-if="maxField.id !== 'count' && maxField.deType !== 0 && maxField.deType !== 1 && maxField.deType !== 5"
v-if="validMaxField"
key="var_pop"
value="var_pop"
:label="$t('chart.var_pop')"
@ -1041,6 +1041,19 @@
<el-form-item
v-show="showProperty('liquidMax')"
:label="$t('chart.liquid_max')"
class="form-item"
>
<el-radio-group
v-model="sizeForm.liquidMaxType"
size="mini"
@change="changeQuotaField('max')"
>
<el-radio-button label="fix">{{ $t('chart.fix') }}</el-radio-button>
<el-radio-button label="dynamic">{{ $t('chart.dynamic') }}</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item
v-if="showProperty('liquidMax') && sizeForm.liquidMaxType === 'fix'"
class="form-item form-item-slider"
>
<el-input-number
@ -1050,6 +1063,101 @@
@change="changeBarSizeCase('liquidMax')"
/>
</el-form-item>
<el-form-item
v-if="showProperty('liquidMax') && sizeForm.liquidMaxType === 'dynamic'"
class="form-item form-flex"
>
<el-select
v-model="sizeForm.liquidMaxField.id"
:placeholder="$t('chart.field')"
@change="changeQuotaField('max',true)"
>
<el-option
v-for="item in quotaData"
:key="item.id"
:label="item.name"
:value="item.id"
>
<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"
/>
</span>
<span style="float: left; color: #8492a6; font-size: 12px">{{ item.name }}</span>
</el-option>
</el-select>
<el-select
v-model="sizeForm.liquidMaxField.summary"
:placeholder="$t('chart.summary')"
@change="changeQuotaField('max')"
>
<el-option
v-if="validLiquidMaxField"
key="sum"
value="sum"
:label="$t('chart.sum')"
/>
<el-option
v-if="validLiquidMaxField"
key="avg"
value="avg"
:label="$t('chart.avg')"
/>
<el-option
v-if="validLiquidMaxField"
key="max"
value="max"
:label="$t('chart.max')"
/>
<el-option
v-if="validLiquidMaxField"
key="min"
value="min"
:label="$t('chart.min')"
/>
<el-option
v-if="validLiquidMaxField"
key="stddev_pop"
value="stddev_pop"
:label="$t('chart.stddev_pop')"
/>
<el-option
v-if="validLiquidMaxField"
key="var_pop"
value="var_pop"
:label="$t('chart.var_pop')"
/>
<el-option
key="count"
value="count"
:label="$t('chart.count')"
/>
<el-option
v-if="liquidMaxField.id !== 'count'"
key="count_distinct"
value="count_distinct"
:label="$t('chart.count_distinct')"
/>
</el-select>
</el-form-item>
<el-form-item
v-show="showProperty('liquidSize')"
:label="$t('chart.radar_size')"
@ -1162,9 +1270,21 @@ export default {
fontLetterSpace: CHART_FONT_LETTER_SPACE,
minField: {},
maxField: {},
liquidMaxField: {},
quotaData: []
}
},
computed: {
validLiquidMaxField() {
return this.isValidField(this.liquidMaxField)
},
validMinField() {
return this.isValidField(this.minField)
},
validMaxField() {
return this.isValidField(this.maxField)
}
},
watch: {
'chart': {
handler: function() {
@ -1190,6 +1310,9 @@ export default {
if (this.sizeForm.gaugeMaxField.id) {
this.maxField = this.getQuotaField(this.sizeForm.gaugeMaxField.id)
}
if (this.sizeForm.liquidMaxField.id) {
this.liquidMaxField = this.getQuotaField(this.sizeForm.liquidMaxField.id)
}
},
initData() {
const chart = JSON.parse(JSON.stringify(this.chart))
@ -1213,6 +1336,12 @@ export default {
this.sizeForm.liquidOutlineDistance = (this.sizeForm.liquidOutlineDistance || this.sizeForm.liquidOutlineDistance === 0) ? this.sizeForm.liquidOutlineDistance : DEFAULT_SIZE.liquidOutlineDistance
this.sizeForm.liquidWaveLength = this.sizeForm.liquidWaveLength ? this.sizeForm.liquidWaveLength : DEFAULT_SIZE.liquidWaveLength
this.sizeForm.liquidWaveCount = this.sizeForm.liquidWaveCount ? this.sizeForm.liquidWaveCount : DEFAULT_SIZE.liquidWaveCount
this.sizeForm.liquidMaxType = this.sizeForm.liquidMaxType ? this.sizeForm.liquidMaxType : DEFAULT_SIZE.liquidMaxType
if (!this.sizeForm.liquidMaxField) {
this.sizeForm.liquidMaxField = DEFAULT_SIZE.liquidMaxField
this.sizeForm.liquidMaxField.id = this.quotaData[0]?.id
this.sizeForm.liquidMaxField.summary = 'count'
}
this.sizeForm.tablePageMode = this.sizeForm.tablePageMode ? this.sizeForm.tablePageMode : DEFAULT_SIZE.tablePageMode
this.sizeForm.tablePageSize = this.sizeForm.tablePageSize ? this.sizeForm.tablePageSize : DEFAULT_SIZE.tablePageSize
@ -1302,27 +1431,43 @@ export default {
}
}
} else if (type === 'max') {
if (this.sizeForm.gaugeMaxType === 'dynamic') {
if (!this.sizeForm.gaugeMaxField.id) {
this.sizeForm.gaugeMaxField.id = this.quotaData[0]?.id
if (this.chart.type === 'liquid') {
if (!this.sizeForm.liquidMaxField.id) {
this.sizeForm.liquidMaxField.id = this.quotaData[0]?.id
}
if (!this.sizeForm.gaugeMaxField.summary) {
this.sizeForm.gaugeMaxField.summary = 'count'
if (!this.sizeForm.liquidMaxField.summary) {
this.sizeForm.liquidMaxField.summary = 'count'
}
if (resetSummary) {
this.sizeForm.gaugeMaxField.summary = 'count'
this.sizeForm.liquidMaxField.summary = 'count'
}
if (this.sizeForm.gaugeMaxField.id && this.sizeForm.gaugeMaxField.summary) {
this.maxField = this.getQuotaField(this.sizeForm.gaugeMaxField.id)
this.changeBarSizeCase('gaugeMaxField')
if (this.sizeForm.liquidMaxField.id && this.sizeForm.liquidMaxField.summary) {
this.maxField = this.getQuotaField(this.sizeForm.liquidMaxField.id)
this.changeBarSizeCase('liquidMaxField')
}
} else {
if (this.sizeForm.gaugeMinType === 'dynamic') {
if (this.sizeForm.gaugeMinField.id && this.sizeForm.gaugeMinField.summary) {
if (this.sizeForm.gaugeMaxType === 'dynamic') {
if (!this.sizeForm.gaugeMaxField.id) {
this.sizeForm.gaugeMaxField.id = this.quotaData[0]?.id
}
if (!this.sizeForm.gaugeMaxField.summary) {
this.sizeForm.gaugeMaxField.summary = 'count'
}
if (resetSummary) {
this.sizeForm.gaugeMaxField.summary = 'count'
}
if (this.sizeForm.gaugeMaxField.id && this.sizeForm.gaugeMaxField.summary) {
this.maxField = this.getQuotaField(this.sizeForm.gaugeMaxField.id)
this.changeBarSizeCase('gaugeMaxField')
}
} else {
this.changeBarSizeCase('gaugeMaxField')
if (this.sizeForm.gaugeMinType === 'dynamic') {
if (this.sizeForm.gaugeMinField.id && this.sizeForm.gaugeMinField.summary) {
this.changeBarSizeCase('gaugeMaxField')
}
} else {
this.changeBarSizeCase('gaugeMaxField')
}
}
}
}
@ -1339,6 +1484,12 @@ export default {
} else {
return fields[0]
}
},
isValidField(field) {
return field.id !== 'count' &&
field.deType !== 0 &&
field.deType !== 1 &&
field.deType !== 5
}
}
}

View File

@ -1042,7 +1042,6 @@ export default {
attr.label.show = true
attr.label.position = 'outer'
}
// * 0.5 * 0.7
if (type === 'pie-donut') {
attr.size.pieInnerRadius = Math.round(attr.size.pieOuterRadius * 0.7)
}

View File

@ -1637,7 +1637,7 @@ export default {
required: false,
default: 'view'
},
editStatue: {
editStatus: {
type: Boolean,
required: false,
default: false
@ -1792,7 +1792,7 @@ export default {
} */
},
watch: {
'editStatue': function(val) {
'editStatus': function(val) {
if (val && this.param.id !== this.preChartId) {
this.preChartId = this.param.id
this.chartInit()
@ -1801,7 +1801,7 @@ export default {
'param': function(val) {
if (this.param.optType === 'new') {
//
} else if (this.param.id !== this.preChartId && this.editStatue) {
} else if (this.param.id !== this.preChartId && this.editStatus) {
this.preChartId = this.param.id
this.chartInit()
}
@ -1881,9 +1881,7 @@ export default {
initFromPanel() {
this.hasEdit = (this.panelViewEditInfo[this.param.id] || false)
},
// v1.16.0
convertChart(chart) {
// v1.16.0
if (equalsAny(chart.type, 'pie', 'pie-rose')) {
let customAttr = chart.customAttr
if (typeof chart.customAttr === 'string') {
@ -2359,7 +2357,7 @@ export default {
return true
}).then(() => {
//
if (this.editStatue) {
if (this.editStatus) {
this.convertChart(this.chart)
this.convertChart(this.view)
}
@ -3088,13 +3086,15 @@ export default {
customAttr.label.show = true
customAttr.label.position = 'outer'
}
// * 0.5 * 0.7
if (type === 'pie-donut') {
customAttr.size.pieInnerRadius = Math.round(customAttr.size.pieOuterRadius * 0.7)
}
if (type === 'pie-donut-rose') {
customAttr.size.pieInnerRadius = Math.round(customAttr.size.pieOuterRadius * 0.5)
}
if (equalsAny(type, 'pie', 'pie-rose')) {
customAttr.size.pieInnerRadius = 0
}
} else if (type.includes('line')) {
this.view.customAttr.label.position = 'top'
} else if (type.includes('treemap')) {

View File

@ -272,7 +272,7 @@
<div v-if="showViewToolsAside">
<chart-edit
ref="chartEditRef"
:edit-statue="showViewToolsAside&&!mobileLayoutStatus&&rightDrawOpen"
:edit-status="showViewToolsAside&&!mobileLayoutStatus&&rightDrawOpen"
:edit-from="'panel'"
:param="chartEditParam"
/>