diff --git a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java index a3d7cc0500..6c65c75c77 100644 --- a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java +++ b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java @@ -327,7 +327,7 @@ public class ChartViewService { QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType()); if (StringUtils.equalsIgnoreCase(table.getType(), "db")) { datasourceRequest.setTable(dataTableInfoDTO.getTable()); - if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType())) { + if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType()) || StringUtils.equalsIgnoreCase("liquid", view.getType())) { datasourceRequest.setQuery(qp.getSQLSummary(dataTableInfoDTO.getTable(), yAxis, customFilter, extFilterList)); } else if (StringUtils.containsIgnoreCase(view.getType(), "stack")) { datasourceRequest.setQuery(qp.getSQLStack(dataTableInfoDTO.getTable(), xAxis, yAxis, customFilter, extFilterList, extStack, ds)); @@ -339,7 +339,7 @@ public class ChartViewService { datasourceRequest.setQuery(qp.getSQL(dataTableInfoDTO.getTable(), xAxis, yAxis, customFilter, extFilterList, ds)); } } else if (StringUtils.equalsIgnoreCase(table.getType(), "sql")) { - if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType())) { + if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType()) || StringUtils.equalsIgnoreCase("liquid", view.getType())) { datasourceRequest.setQuery(qp.getSQLSummaryAsTmp(dataTableInfoDTO.getSql(), yAxis, customFilter, extFilterList)); } else if (StringUtils.containsIgnoreCase(view.getType(), "stack")) { datasourceRequest.setQuery(qp.getSQLAsTmpStack(dataTableInfoDTO.getSql(), xAxis, yAxis, customFilter, extFilterList, extStack)); @@ -354,7 +354,7 @@ public class ChartViewService { DataTableInfoDTO dt = new Gson().fromJson(table.getInfo(), DataTableInfoDTO.class); List list = dataSetTableUnionService.listByTableId(dt.getList().get(0).getTableId()); String sql = dataSetTableService.getCustomSQLDatasource(dt, list, ds); - if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType())) { + if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType()) || StringUtils.equalsIgnoreCase("liquid", view.getType())) { datasourceRequest.setQuery(qp.getSQLSummaryAsTmp(sql, yAxis, customFilter, extFilterList)); } else if (StringUtils.containsIgnoreCase(view.getType(), "stack")) { datasourceRequest.setQuery(qp.getSQLAsTmpStack(sql, xAxis, yAxis, customFilter, extFilterList, extStack)); @@ -386,7 +386,7 @@ public class ChartViewService { String tableName = "ds_" + table.getId().replaceAll("-", "_"); datasourceRequest.setTable(tableName); QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType()); - if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType())) { + if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType()) || StringUtils.equalsIgnoreCase("liquid", view.getType())) { datasourceRequest.setQuery(qp.getSQLSummary(tableName, yAxis, customFilter, extFilterList)); } else if (StringUtils.containsIgnoreCase(view.getType(), "stack")) { datasourceRequest.setQuery(qp.getSQLStack(tableName, xAxis, yAxis, customFilter, extFilterList, extStack, ds)); diff --git a/frontend/package.json b/frontend/package.json index 2e3cd54833..42f7c9c21f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -15,6 +15,7 @@ "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml" }, "dependencies": { + "@antv/g2plot": "^2.3.32", "@riophae/vue-treeselect": "0.4.0", "@tinymce/tinymce-vue": "^3.2.8", "axios": "^0.21.1", diff --git a/frontend/src/components/canvas/custom-component/UserView.vue b/frontend/src/components/canvas/custom-component/UserView.vue index ce19cc8b54..ef55f4673e 100644 --- a/frontend/src/components/canvas/custom-component/UserView.vue +++ b/frontend/src/components/canvas/custom-component/UserView.vue @@ -16,7 +16,8 @@ {{ $t('chart.chart_error_tips') }} - + + @@ -43,9 +44,10 @@ import { deepCopy } from '@/components/canvas/utils/utils' import { getToken, getLinkToken } from '@/utils/auth' import DrillPath from '@/views/chart/view/DrillPath' import { areaMapping } from '@/api/map/map' +import ChartComponentG2 from '@/views/chart/components/ChartComponentG2' export default { name: 'UserView', - components: { ChartComponent, TableNormal, LabelNormal, DrillPath }, + components: { ChartComponent, TableNormal, LabelNormal, DrillPath, ChartComponentG2 }, props: { element: { type: Object, @@ -434,6 +436,14 @@ export default { this.destroyTimeMachine() }, 200) } + }, + + renderComponent() { + if (this.chart.type === 'liquid') { + return 'g2' + } else { + return 'echarts' + } } } } diff --git a/frontend/src/icons/svg/liquid.svg b/frontend/src/icons/svg/liquid.svg new file mode 100644 index 0000000000..6cdd202223 --- /dev/null +++ b/frontend/src/icons/svg/liquid.svg @@ -0,0 +1 @@ + diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js index 55c74c162f..85d59e48c7 100644 --- a/frontend/src/lang/en.js +++ b/frontend/src/lang/en.js @@ -862,7 +862,20 @@ export default { yAxis_main: 'Main Vertical Axis', yAxis_ext: 'Ext Vertical Axis', total: 'Total', - items: 'Items' + items: 'Items', + chart_liquid: 'Liquid', + drag_block_progress: 'Progress', + liquid_max: 'End Value', + liquid_outline_border: 'Border Width', + liquid_outline_distance: 'Border Distance', + liquid_wave_length: 'Wave Length', + liquid_wave_count: 'Wave Count', + liquid_shape: 'Shape', + liquid_shape_circle: 'Circle', + liquid_shape_diamond: 'Diamond', + liquid_shape_triangle: 'Triangle', + liquid_shape_pin: 'Pin', + liquid_shape_rect: 'Rect' }, 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 8a2b821c3e..c1cf4ab1a8 100644 --- a/frontend/src/lang/tw.js +++ b/frontend/src/lang/tw.js @@ -861,7 +861,20 @@ export default { yAxis_main: '主縱軸', yAxis_ext: '副縱軸', total: '共', - items: '條數據' + items: '條數據', + chart_liquid: '水波圖', + drag_block_progress: '進度指示', + liquid_max: '目標值', + liquid_outline_border: '邊框粗細', + liquid_outline_distance: '邊框間隔', + liquid_wave_length: '水波長度', + liquid_wave_count: '水波數量', + liquid_shape: '形狀', + liquid_shape_circle: '圓形', + liquid_shape_diamond: '菱形', + liquid_shape_triangle: '三角形', + liquid_shape_pin: '氣球', + liquid_shape_rect: '矩形' }, dataset: { sheet_warn: '有多個sheet頁面,默認抽取第一個', diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index 203ddc33ba..b20ce1c6e7 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -893,7 +893,20 @@ export default { yAxis_main: '主纵轴', yAxis_ext: '副纵轴', total: '共', - items: '条数据' + items: '条数据', + chart_liquid: '水波图', + drag_block_progress: '进度指示', + liquid_max: '目标值', + liquid_outline_border: '边框粗细', + liquid_outline_distance: '边框间隔', + liquid_wave_length: '水波长度', + liquid_wave_count: '水波数量', + liquid_shape: '形状', + liquid_shape_circle: '圆形', + liquid_shape_diamond: '菱形', + liquid_shape_triangle: '三角形', + liquid_shape_pin: '气球', + liquid_shape_rect: '矩形' }, dataset: { sheet_warn: '有多个 Sheet 页,默认抽取第一个', diff --git a/frontend/src/views/chart/chart/chart.js b/frontend/src/views/chart/chart/chart.js index 707bfbb606..77fad0baed 100644 --- a/frontend/src/views/chart/chart/chart.js +++ b/frontend/src/views/chart/chart/chart.js @@ -42,7 +42,14 @@ export const DEFAULT_SIZE = { scatterSymbol: 'circle', scatterSymbolSize: 20, treemapWidth: 80, - treemapHeight: 80 + treemapHeight: 80, + liquidMax: 100, + liquidSize: 80, + liquidOutlineBorder: 4, + liquidOutlineDistance: 8, + liquidWaveLength: 128, + liquidWaveCount: 3, + liquidShape: 'circle' } export const DEFAULT_LABEL = { show: false, diff --git a/frontend/src/views/chart/chart/liquid/liquid.js b/frontend/src/views/chart/chart/liquid/liquid.js new file mode 100644 index 0000000000..25a1561fdd --- /dev/null +++ b/frontend/src/views/chart/chart/liquid/liquid.js @@ -0,0 +1,95 @@ +import { Liquid } from '@antv/g2plot' +import { digToHex } from '@/views/chart/chart/util' +import { DEFAULT_SIZE } from '@/views/chart/chart/chart' + +export function baseLiquid(plot, container, chart) { + let value = 0 + const colors = [] + let max + let radius + let outlineBorder + let outlineDistance + let waveLength + let waveCount + let bgColor + let shape + let labelContent + if (chart.data) { + if (chart.data.series.length > 0) { + value = chart.data.series[0].data[0].value + } + } + let customAttr = {} + if (chart.customAttr) { + customAttr = JSON.parse(chart.customAttr) + // color + if (customAttr.color) { + const c = JSON.parse(JSON.stringify(customAttr.color)) + const alpha = digToHex(parseInt(c.alpha)) + c.colors.forEach(ele => { + colors.push(ele.concat(alpha)) + }) + } + // size + if (customAttr.size) { + const size = JSON.parse(JSON.stringify(customAttr.size)) + max = size.liquidMax ? size.liquidMax : DEFAULT_SIZE.liquidMax + radius = parseFloat((size.liquidSize ? size.liquidSize : DEFAULT_SIZE.liquidSize) / 100) + outlineBorder = parseInt(size.liquidOutlineBorder ? size.liquidOutlineBorder : DEFAULT_SIZE.liquidOutlineBorder) + outlineDistance = parseInt(size.liquidOutlineDistance ? size.liquidOutlineDistance : DEFAULT_SIZE.liquidOutlineDistance) + waveLength = parseInt(size.liquidWaveLength ? size.liquidWaveLength : DEFAULT_SIZE.liquidWaveLength) + waveCount = parseInt(size.liquidWaveCount ? size.liquidWaveCount : DEFAULT_SIZE.liquidWaveCount) + shape = size.liquidShape ? size.liquidShape : DEFAULT_SIZE.liquidShape + } + // label + if (customAttr.label) { + const label = JSON.parse(JSON.stringify(customAttr.label)) + if (label.show) { + labelContent = { + style: ({ percent }) => ({ + fontSize: parseInt(label.fontSize), + color: label.color + }) + } + } else { + labelContent = false + } + } + } + let customStyle + if (chart.customStyle) { + customStyle = JSON.parse(chart.customStyle) + if (customStyle.background) { + bgColor = customStyle.background.color.concat(digToHex(parseInt(customStyle.background.alpha))) + } + } + // 开始渲染 + if (plot) { + plot.destroy() + } + plot = new Liquid(container, { + theme: { + styleSheet: { + brandColor: colors[0], + paletteQualitative10: colors, + backgroundColor: bgColor + } + }, + percent: (parseFloat(value) / parseFloat(max)), + radius: radius, + shape: shape, + outline: { + border: outlineBorder, + distance: outlineDistance + }, + wave: { + length: waveLength, + count: waveCount + }, + statistic: { + content: labelContent + } + }) + plot.render() + return plot +} diff --git a/frontend/src/views/chart/chart/util.js b/frontend/src/views/chart/chart/util.js index a075480b99..1bec7413d9 100644 --- a/frontend/src/views/chart/chart/util.js +++ b/frontend/src/views/chart/chart/util.js @@ -17,3 +17,12 @@ export function hexColorToRGBA(hex, alpha) { return 'rgb(0,0,0)' } } + +export function digToHex(dig) { + let prefix = '' + const num = parseInt(dig * 2.55) + if (num < 16) { + prefix = '0' + } + return prefix.concat(num.toString(16).toUpperCase()) +} diff --git a/frontend/src/views/chart/components/ChartComponentG2.vue b/frontend/src/views/chart/components/ChartComponentG2.vue new file mode 100644 index 0000000000..089b33a618 --- /dev/null +++ b/frontend/src/views/chart/components/ChartComponentG2.vue @@ -0,0 +1,162 @@ + + + + + diff --git a/frontend/src/views/chart/components/shape-attr/LabelSelector.vue b/frontend/src/views/chart/components/shape-attr/LabelSelector.vue index 2ee0a55909..4801f322cc 100644 --- a/frontend/src/views/chart/components/shape-attr/LabelSelector.vue +++ b/frontend/src/views/chart/components/shape-attr/LabelSelector.vue @@ -17,12 +17,12 @@ - + - + {{ $t('chart.content_formatter') }} @@ -126,7 +126,7 @@ export default { }, init() { const arr = [] - for (let i = 10; i <= 20; i = i + 2) { + for (let i = 10; i <= 40; i = i + 2) { arr.push({ name: i + '', value: i + '' diff --git a/frontend/src/views/chart/components/shape-attr/SizeSelector.vue b/frontend/src/views/chart/components/shape-attr/SizeSelector.vue index 63fdd1565f..b17076a604 100644 --- a/frontend/src/views/chart/components/shape-attr/SizeSelector.vue +++ b/frontend/src/views/chart/components/shape-attr/SizeSelector.vue @@ -218,6 +218,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -250,6 +281,13 @@ export default { { name: this.$t('chart.line_symbol_pin'), value: 'pin' }, { name: this.$t('chart.line_symbol_arrow'), value: 'arrow' } ], + liquidShapeOptions: [ + { name: this.$t('chart.liquid_shape_circle'), value: 'circle' }, + { name: this.$t('chart.liquid_shape_diamond'), value: 'diamond' }, + { name: this.$t('chart.liquid_shape_triangle'), value: 'triangle' }, + { name: this.$t('chart.liquid_shape_pin'), value: 'pin' }, + { name: this.$t('chart.liquid_shape_rect'), value: 'rect' } + ], fontSize: [] } }, @@ -279,6 +317,14 @@ export default { this.sizeForm.treemapWidth = this.sizeForm.treemapWidth ? this.sizeForm.treemapWidth : 80 this.sizeForm.treemapHeight = this.sizeForm.treemapHeight ? this.sizeForm.treemapHeight : 80 this.sizeForm.radarSize = this.sizeForm.radarSize ? this.sizeForm.radarSize : 80 + + this.sizeForm.liquidShape = this.sizeForm.liquidShape ? this.sizeForm.liquidShape : DEFAULT_SIZE.liquidShape + this.sizeForm.liquidMax = this.sizeForm.liquidMax ? this.sizeForm.liquidMax : DEFAULT_SIZE.liquidMax + this.sizeForm.liquidSize = this.sizeForm.liquidSize ? this.sizeForm.liquidSize : DEFAULT_SIZE.liquidSize + this.sizeForm.liquidOutlineBorder = this.sizeForm.liquidOutlineBorder ? this.sizeForm.liquidOutlineBorder : DEFAULT_SIZE.liquidOutlineBorder + this.sizeForm.liquidOutlineDistance = this.sizeForm.liquidOutlineDistance ? 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 } } }, diff --git a/frontend/src/views/chart/components/table/TableNormal.vue b/frontend/src/views/chart/components/table/TableNormal.vue index 06e6f690fa..4297eaa7fa 100644 --- a/frontend/src/views/chart/components/table/TableNormal.vue +++ b/frontend/src/views/chart/components/table/TableNormal.vue @@ -33,7 +33,7 @@ {{ $t('chart.total') }} - {{ chart.data.tableRow.length }} + {{ (chart.data && chart.data.tableRow)?chart.data.tableRow.length:0 }} {{ $t('chart.items') }} + + + + + + +
-
-
@@ -217,8 +222,14 @@ -
+ + + + + + +
@@ -254,7 +265,7 @@ /> - + {{ $t('chart.drag_block_table_data_column') }} {{ $t('chart.drag_block_type_axis') }} @@ -296,6 +307,7 @@ {{ $t('chart.chart_data') }} {{ $t('chart.drag_block_treemap_size') }} {{ $t('chart.drag_block_value_axis_main') }} + {{ $t('chart.drag_block_progress') }} / {{ $t('chart.quota') }} @@ -418,7 +430,7 @@ {{ $t('chart.placeholder_field') }} - + {{ $t('chart.drill') }} / @@ -471,7 +483,7 @@ - + @@ -491,10 +503,10 @@ - + - + @@ -510,7 +522,8 @@
- + +
@@ -670,9 +683,11 @@ import FieldEdit from '../../dataset/data/FieldEdit' import { areaMapping } from '@/api/map/map' import QuotaExtItem from '@/views/chart/components/drag-item/QuotaExtItem' import YAxisExtSelector from '@/views/chart/components/component-style/YAxisExtSelector' +import ChartComponentG2 from '@/views/chart/components/ChartComponentG2' export default { name: 'ChartEdit', components: { + ChartComponentG2, YAxisExtSelector, QuotaExtItem, FilterItem, @@ -1593,6 +1608,14 @@ export default { if (temp) return temp } } + }, + + renderComponent() { + if (this.chart.type === 'liquid') { + return 'g2' + } else { + return 'echarts' + } } }