forked from github/dataease
feat:瀑布图
This commit is contained in:
parent
9ce5192386
commit
1abfbef7b6
1
frontend/src/icons/svg/waterfall.svg
Normal file
1
frontend/src/icons/svg/waterfall.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg t="1631170441004" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="826" width="200" height="200"><path d="M64 104.1c0-1.3 0.5-2.6 1.5-3.6s2.3-1.5 3.6-1.5H101c1.3 0 2.6 0.5 3.6 1.5s1.5 2.3 1.5 3.6V883H955c1.3 0 2.6 0.5 3.6 1.5s1.5 2.3 1.5 3.6V920c0 1.3-0.5 2.6-1.5 3.6s-2.3 1.5-3.6 1.5H64v-821z" p-id="827"></path><path d="M524.9 640.7H387c-8.3 0-15-6.7-15-15V300.3c0-8.3 6.7-15 15-15h137.9c8.3 0 15 6.7 15 15v325.3c0 8.3-6.7 15.1-15 15.1zM314.9 827H177c-8.3 0-15-6.7-15-15V300.3c0-8.3 6.7-15 15-15h137.9c8.3 0 15 6.7 15 15V812c0 8.3-6.7 15-15 15zM734.9 640.7H597c-8.3 0-15-6.7-15-15V114c0-8.3 6.7-15 15-15h137.9c8.3 0 15 6.7 15 15v511.7c0 8.2-6.7 15-15 15zM944.9 463H807c-8.3 0-15-6.7-15-15V104.2c0-8.3 6.7-15 15-15h137.9c8.3 0 15 6.7 15 15V448c0 8.3-6.7 15-15 15z" p-id="828"></path></svg>
|
After Width: | Height: | Size: 839 B |
@ -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',
|
||||
|
@ -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 頁,默認抽取第一個',
|
||||
|
@ -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 页,默认抽取第一个',
|
||||
|
100
frontend/src/views/chart/chart/waterfall/waterfall.js
Normal file
100
frontend/src/views/chart/chart/waterfall/waterfall.js
Normal file
@ -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
|
||||
}
|
@ -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
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div style="width: 100%">
|
||||
<el-col>
|
||||
<el-form v-show="chart.type && chart.type.includes('bar')" ref="sizeFormBar" :disabled="param && !hasDataPermission('manage',param.privileges)" :model="sizeForm" label-width="80px" size="mini">
|
||||
<el-form v-show="chart.type && (chart.type.includes('bar') || chart.type === 'waterfall')" ref="sizeFormBar" :disabled="param && !hasDataPermission('manage',param.privileges)" :model="sizeForm" label-width="80px" size="mini">
|
||||
<el-form-item :label="$t('chart.adapt')" class="form-item">
|
||||
<el-checkbox v-model="sizeForm.barDefault" @change="changeBarSizeCase">{{ $t('chart.adapt') }}</el-checkbox>
|
||||
</el-form-item>
|
||||
|
@ -157,7 +157,7 @@
|
||||
<el-row v-if="view.type !=='text' && view.type !== 'gauge' && view.type !== 'liquid'" class="padding-lr">
|
||||
<span style="width: 80px;text-align: right;">
|
||||
<span v-if="view.type && view.type.includes('table')">{{ $t('chart.drag_block_table_data_column') }}</span>
|
||||
<span v-else-if="view.type && (view.type.includes('bar') || view.type.includes('line') || view.type.includes('scatter') || view.type === 'chart-mix')">{{ $t('chart.drag_block_type_axis') }}</span>
|
||||
<span v-else-if="view.type && (view.type.includes('bar') || view.type.includes('line') || view.type.includes('scatter') || view.type === 'chart-mix' || view.type === 'waterfall')">{{ $t('chart.drag_block_type_axis') }}</span>
|
||||
<span v-else-if="view.type && view.type.includes('pie')">{{ $t('chart.drag_block_pie_label') }}</span>
|
||||
<span v-else-if="view.type && view.type.includes('funnel')">{{ $t('chart.drag_block_funnel_split') }}</span>
|
||||
<span v-else-if="view.type && view.type.includes('radar')">{{ $t('chart.drag_block_radar_label') }}</span>
|
||||
@ -188,7 +188,7 @@
|
||||
<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>
|
||||
<span v-else-if="view.type && (view.type.includes('bar') || view.type.includes('line') || view.type.includes('scatter'))">{{ $t('chart.drag_block_value_axis') }}</span>
|
||||
<span v-else-if="view.type && (view.type.includes('bar') || view.type.includes('line') || view.type.includes('scatter') || view.type === 'waterfall')">{{ $t('chart.drag_block_value_axis') }}</span>
|
||||
<span v-else-if="view.type && view.type.includes('pie')">{{ $t('chart.drag_block_pie_angel') }}</span>
|
||||
<span v-else-if="view.type && view.type.includes('funnel')">{{ $t('chart.drag_block_funnel_width') }}</span>
|
||||
<span v-else-if="view.type && view.type.includes('radar')">{{ $t('chart.drag_block_radar_length') }}</span>
|
||||
@ -321,7 +321,7 @@
|
||||
<span class="drag-placeholder-style-span">{{ $t('chart.placeholder_field') }}</span>
|
||||
</div>
|
||||
</el-row>
|
||||
<el-row v-if="view.type && !view.type.includes('table') && !view.type.includes('text') && !view.type.includes('gauge') && view.type !== 'liquid'" class="padding-lr" style="margin-top: 6px;">
|
||||
<el-row v-if="view.type && !view.type.includes('table') && !view.type.includes('text') && !view.type.includes('gauge') && view.type !== 'liquid' && view.type !== 'waterfall'" class="padding-lr" style="margin-top: 6px;">
|
||||
<span style="width: 80px;text-align: right;">
|
||||
<span>{{ $t('chart.drill') }}</span>
|
||||
/
|
||||
@ -405,7 +405,7 @@
|
||||
<title-selector v-if="view.render && view.render === 'echarts'" :param="param" class="attr-selector" :chart="chart" @onTextChange="onTextChange" />
|
||||
<title-selector-ant-v v-else-if="view.render && view.render === 'antv'" :param="param" class="attr-selector" :chart="chart" @onTextChange="onTextChange" />
|
||||
</el-collapse-item>
|
||||
<el-collapse-item v-show="view.type && view.type !== 'map' && !view.type.includes('table') && !view.type.includes('text') && (chart.type !== 'treemap' || chart.render === 'antv') && view.type !== 'liquid'" name="legend" :title="$t('chart.legend')">
|
||||
<el-collapse-item v-show="view.type && view.type !== 'map' && !view.type.includes('table') && !view.type.includes('text') && (chart.type !== 'treemap' || chart.render === 'antv') && view.type !== 'liquid' && view.type !== 'waterfall'" name="legend" :title="$t('chart.legend')">
|
||||
<legend-selector v-if="view.render && view.render === 'echarts'" :param="param" class="attr-selector" :chart="chart" @onLegendChange="onLegendChange" />
|
||||
<legend-selector-ant-v v-else-if="view.render && view.render === 'antv'" :param="param" class="attr-selector" :chart="chart" @onLegendChange="onLegendChange" />
|
||||
</el-collapse-item>
|
||||
@ -1339,7 +1339,7 @@ export default {
|
||||
this.save(true)
|
||||
},
|
||||
addYaxis(e) {
|
||||
if (this.view.type === 'map' && this.view.yaxis.length > 1) {
|
||||
if ((this.view.type === 'map' || this.view.type === 'waterfall') && this.view.yaxis.length > 1) {
|
||||
this.view.yaxis = [this.view.yaxis[0]]
|
||||
}
|
||||
this.dragCheckType(this.view.yaxis, 'q')
|
||||
|
@ -66,6 +66,11 @@
|
||||
<!-- <svg-icon icon-class="map" class="chart-icon" />-->
|
||||
<!-- </span>-->
|
||||
<!-- </el-radio>-->
|
||||
<el-radio value="waterfall" label="waterfall">
|
||||
<span :title="$t('chart.chart_waterfall')">
|
||||
<svg-icon icon-class="waterfall" class="chart-icon" />
|
||||
</span>
|
||||
</el-radio>
|
||||
<el-radio value="radar" label="radar">
|
||||
<span :title="$t('chart.chart_radar')">
|
||||
<svg-icon icon-class="radar" class="chart-icon" />
|
||||
@ -86,13 +91,13 @@
|
||||
<svg-icon icon-class="pie-rose" class="chart-icon" />
|
||||
</span>
|
||||
</el-radio>
|
||||
</div>
|
||||
<div style="width: 100%;display: flex;display: -webkit-flex;justify-content: space-between;flex-direction: row;flex-wrap: wrap;">
|
||||
<el-radio value="funnel" label="funnel">
|
||||
<span :title="$t('chart.chart_funnel')">
|
||||
<svg-icon icon-class="funnel" class="chart-icon" />
|
||||
</span>
|
||||
</el-radio>
|
||||
</div>
|
||||
<div style="width: 100%;display: flex;display: -webkit-flex;justify-content: space-between;flex-direction: row;flex-wrap: wrap;">
|
||||
<el-radio value="treemap" label="treemap">
|
||||
<span :title="$t('chart.chart_treemap')">
|
||||
<svg-icon icon-class="treemap" class="chart-icon" />
|
||||
@ -105,7 +110,6 @@
|
||||
</el-radio>
|
||||
<el-radio value="" label="" disabled class="disabled-none-cursor"><svg-icon icon-class="" class="chart-icon" /></el-radio>
|
||||
<el-radio value="" label="" disabled class="disabled-none-cursor"><svg-icon icon-class="" class="chart-icon" /></el-radio>
|
||||
<el-radio value="" label="" disabled class="disabled-none-cursor"><svg-icon icon-class="" class="chart-icon" /></el-radio>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="chart.render && chart.render === 'echarts'">
|
||||
|
@ -310,7 +310,7 @@ export default {
|
||||
const that = this
|
||||
setTimeout(function() {
|
||||
const currentHeight = document.documentElement.clientHeight
|
||||
that.maxHeight = (currentHeight - 56 - 30 - 35 - 26 - 10) + 'px'
|
||||
that.maxHeight = (currentHeight - 56 - 30 - 35 - 26 - 10 - 10) + 'px'
|
||||
}, 10)
|
||||
},
|
||||
initField() {
|
||||
|
Loading…
Reference in New Issue
Block a user