diff --git a/frontend/src/icons/svg/waterfall.svg b/frontend/src/icons/svg/waterfall.svg new file mode 100644 index 0000000000..194ae55bd6 --- /dev/null +++ b/frontend/src/icons/svg/waterfall.svg @@ -0,0 +1 @@ + diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js index 8f5e667022..9bedbf929b 100644 --- a/frontend/src/lang/en.js +++ b/frontend/src/lang/en.js @@ -932,7 +932,8 @@ export default { liquid_shape_pin: 'Pin', liquid_shape_rect: 'Rect', dimension_or_quota: 'Dimension Or Quota', - axis_value_split_count: 'Tick Count' + axis_value_split_count: 'Tick Count', + chart_waterfall: 'Waterfall' }, dataset: { sheet_warn: 'There are multiple sheet pages, and the first one is extracted by default', diff --git a/frontend/src/lang/tw.js b/frontend/src/lang/tw.js index 860a748b81..dda1fcb63c 100644 --- a/frontend/src/lang/tw.js +++ b/frontend/src/lang/tw.js @@ -933,7 +933,8 @@ export default { liquid_shape_pin: '氣球', liquid_shape_rect: '矩形', dimension_or_quota: '維度或指標', - axis_value_split_count: '刻度數' + axis_value_split_count: '刻度數', + chart_waterfall: '瀑布圖' }, dataset: { sheet_warn: '有多個 Sheet 頁,默認抽取第一個', diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index 273602a890..8d7d6ad979 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -933,7 +933,8 @@ export default { liquid_shape_pin: '气球', liquid_shape_rect: '矩形', dimension_or_quota: '维度或指标', - axis_value_split_count: '刻度数' + axis_value_split_count: '刻度数', + chart_waterfall: '瀑布图' }, dataset: { sheet_warn: '有多个 Sheet 页,默认抽取第一个', diff --git a/frontend/src/views/chart/chart/waterfall/waterfall.js b/frontend/src/views/chart/chart/waterfall/waterfall.js new file mode 100644 index 0000000000..5150c0462d --- /dev/null +++ b/frontend/src/views/chart/chart/waterfall/waterfall.js @@ -0,0 +1,100 @@ +import { + getLabel, + getLegend, + getPadding, + getTheme, + getTooltip, + getXAxis, + getYAxis +} from '@/views/chart/chart/common/common_antv' +import { Waterfall } from '@antv/g2plot' + +export function baseWaterfallOptionAntV(plot, container, chart, action) { + // theme + const theme = getTheme(chart) + // attr + const label = getLabel(chart) + const tooltip = getTooltip(chart) + // style + const legend = getLegend(chart) + const xAxis = getXAxis(chart) + const yAxis = getYAxis(chart) + // data + const data = chart.data.datas + // total + const total = { + label: '合计', + style: { + fill: theme.styleSheet.paletteQualitative10[2] + } + } + // options + const options = { + theme: theme, + data: data, + xField: 'field', + yField: 'value', + seriesField: 'category', + appendPadding: getPadding(chart), + label: label, + tooltip: tooltip, + legend: false, + xAxis: xAxis, + yAxis: yAxis, + risingFill: theme.styleSheet.paletteQualitative10[0], + fallingFill: theme.styleSheet.paletteQualitative10[1], + total: total, + interactions: [ + { + type: 'element-active', cfg: { + start: [{ trigger: 'element:mouseenter', action: ['element-highlight:highlight', 'element-active:reset', 'cursor:pointer'] }], + end: [{ trigger: 'element:mouseleave', action: ['element-highlight:reset', 'element-active:reset', 'cursor:default'] }] + } + }, + // { + // type: 'legend-active', cfg: { + // start: [{ trigger: 'legend-item:mouseenter', action: ['element-active:reset'] }], + // end: [{ trigger: 'legend-item:mouseleave', action: ['element-active:reset'] }] + // } + // }, + // { + // type: 'legend-filter', cfg: { + // start: [{ trigger: 'legend-item:click', action: ['list-unchecked:toggle', 'data-filter:filter', 'element-active:reset', 'element-highlight:reset'] }] + // } + // }, + { + type: 'tooltip', cfg: { + start: [{ trigger: 'interval:mousemove', action: 'tooltip:show' }], + end: [{ trigger: 'interval:mouseleave', action: 'tooltip:hide' }] + } + }, + // { + // type: 'active-region', cfg: { + // start: [{ trigger: 'interval:mousemove', action: 'active-region:show' }], + // end: [{ trigger: 'interval:mouseleave', action: 'active-region:hide' }] + // } + // } + ] + } + // size + let customAttr = {} + if (chart.customAttr) { + customAttr = JSON.parse(chart.customAttr) + if (customAttr.size) { + const s = JSON.parse(JSON.stringify(customAttr.size)) + if (s.barDefault) { + delete options.marginRatio + } else { + options.marginRatio = s.barGap + } + } + } + + // 开始渲染 + if (plot) { + plot.destroy() + } + plot = new Waterfall(container, options) + + return plot +} diff --git a/frontend/src/views/chart/components/ChartComponentG2.vue b/frontend/src/views/chart/components/ChartComponentG2.vue index 78c14b8e61..0cc6fc4549 100644 --- a/frontend/src/views/chart/components/ChartComponentG2.vue +++ b/frontend/src/views/chart/components/ChartComponentG2.vue @@ -22,6 +22,7 @@ import { baseGaugeOptionAntV } from '@/views/chart/chart/gauge/gauge_antv' import { baseFunnelOptionAntV } from '@/views/chart/chart/funnel/funnel_antv' import { baseTreemapOptionAntV } from '@/views/chart/chart/treemap/treemap_antv' import { baseRadarOptionAntV } from '@/views/chart/chart/radar/radar_antv' +import { baseWaterfallOptionAntV } from '@/views/chart/chart/waterfall/waterfall' export default { name: 'ChartComponentG2', @@ -158,6 +159,8 @@ export default { this.myChart = baseTreemapOptionAntV(this.myChart, this.chartId, chart, this.antVAction) } else if (chart.type === 'liquid') { this.myChart = baseLiquid(this.myChart, this.chartId, chart) + } else if (chart.type === 'waterfall') { + this.myChart = baseWaterfallOptionAntV(this.myChart, this.chartId, chart, this.antVAction) } else { if (this.myChart) { this.antVRenderStatus = false diff --git a/frontend/src/views/chart/components/shape-attr/SizeSelectorAntV.vue b/frontend/src/views/chart/components/shape-attr/SizeSelectorAntV.vue index 047bd8918c..74799dac33 100644 --- a/frontend/src/views/chart/components/shape-attr/SizeSelectorAntV.vue +++ b/frontend/src/views/chart/components/shape-attr/SizeSelectorAntV.vue @@ -1,7 +1,7 @@