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 5ec118fd32..04b77b38d0 100644 --- a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java +++ b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java @@ -123,7 +123,7 @@ public class ChartViewService { } else if (table.getMode() == 1) {// 抽取 DataTableInfoDTO dataTableInfoDTO = new Gson().fromJson(table.getInfo(), DataTableInfoDTO.class); String tableName = dataTableInfoDTO.getTable() + "-" + table.getDataSourceId();// todo hBase table name maybe change - data = sparkCalc.getData(tableName, xAxis, yAxis, view.getId().split("-")[0]); + data = sparkCalc.getData(tableName, xAxis, yAxis, "tmp_" + view.getId().split("-")[0]); } // 图表组件可再扩展 @@ -136,7 +136,6 @@ public class ChartViewService { } for (String[] d : data) { StringBuilder a = new StringBuilder(); - BigDecimal b = new BigDecimal("0"); for (int i = 0; i < xAxis.size(); i++) { if (i == xAxis.size() - 1) { a.append(d[i]); @@ -147,7 +146,7 @@ public class ChartViewService { x.add(a.toString()); for (int i = xAxis.size(); i < xAxis.size() + yAxis.size(); i++) { int j = i - xAxis.size(); - series.get(j).getData().add(new BigDecimal(d[i])); + series.get(j).getData().add(new BigDecimal(StringUtils.isEmpty(d[i]) ? "0" : d[i])); } } Map map = new HashMap<>(); diff --git a/frontend/package.json b/frontend/package.json index c003bd0abd..2f53ac8bf3 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -18,6 +18,7 @@ "@riophae/vue-treeselect": "0.4.0", "axios": "^0.21.1", "echarts": "^5.0.2", + "element-resize-detector": "^1.2.2", "element-ui": "2.13.0", "fit2cloud-ui": "^0.1.12", "js-cookie": "2.2.0", diff --git a/frontend/src/components/DragItem/index.vue b/frontend/src/components/DragItem/index.vue new file mode 100644 index 0000000000..752948929a --- /dev/null +++ b/frontend/src/components/DragItem/index.vue @@ -0,0 +1,93 @@ + + + + + diff --git a/frontend/src/components/canvas/components/Editor/Preview.vue b/frontend/src/components/canvas/components/Editor/Preview.vue index 58b8f9e879..fbf015a06c 100644 --- a/frontend/src/components/canvas/components/Editor/Preview.vue +++ b/frontend/src/components/canvas/components/Editor/Preview.vue @@ -1,20 +1,10 @@ @@ -23,6 +13,10 @@ import { getStyle } from '@/components/canvas/utils/style' import { mapState } from 'vuex' import ComponentWrapper from './ComponentWrapper' import { changeStyleWithScale } from '@/components/canvas/utils/translate' +import { uuid } from 'vue-uuid' +import { deepCopy } from '@/components/canvas/utils/utils' +import eventBus from '@/components/canvas/utils/eventBus' +import elementResizeDetectorMaker from 'element-resize-detector' export default { components: { ComponentWrapper }, @@ -36,20 +30,84 @@ export default { default: false } }, - computed: mapState([ - 'componentData', - 'canvasStyleData' - ]), + data() { + return { + isShowPreview: false, + panelId: '', + needToChangeHeight: [ + 'top', + 'height', + 'fontSize', + 'borderWidth' + ], + needToChangeWidth: [ + 'left', + 'width' + ], + scaleWidth: '100', + scaleHeight: '100', + timer: null, + componentDataShow: [] + } + }, + computed: { + // 此处单独计算componentData的值 不放入全局mapState中 + componentDataInfo() { + return this.componentDataShow + }, + ...mapState([ + 'componentData', + 'canvasStyleData' + ]) + }, mounted() { - // 计算组件当前合适宽度 + debugger + const _this = this + const erd = elementResizeDetectorMaker() + // 监听div变动事件 + erd.listenTo(document.getElementById('canvasInfo'), element => { + _this.$nextTick(() => { + _this.restore() + }) + }) + // 监听数据变动事件 + eventBus.$on('componentDataChange', () => { + _this.restore() + }) }, methods: { changeStyleWithScale, - getStyle, - - close() { - this.$emit('change', false) + restore() { + const canvasHeight = document.getElementById('canvasInfo').offsetHeight + const canvasWidth = document.getElementById('canvasInfo').offsetWidth + this.scaleWidth = canvasWidth * 100 / parseInt(this.canvasStyleData.width)// 获取宽度比 + this.scaleHeight = canvasHeight * 100 / parseInt(this.canvasStyleData.height)// 获取高度比 + this.handleScaleChange() + }, + resetID(data) { + data.forEach(item => { + item.id = uuid.v1() + }) + return data + }, + format(value, scale) { + return value * parseInt(scale) / 100 + }, + handleScaleChange() { + const componentData = deepCopy(this.componentData) + componentData.forEach(component => { + Object.keys(component.style).forEach(key => { + if (this.needToChangeHeight.includes(key)) { + component.style[key] = this.format(component.style[key], this.scaleHeight) + } + if (this.needToChangeWidth.includes(key)) { + component.style[key] = this.format(component.style[key], this.scaleWidth) + } + }) + }) + this.componentDataShow = componentData + eventBus.$emit('resizing', '') } } } @@ -57,12 +115,14 @@ export default { diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index df5a380349..f71ea7c723 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -693,7 +693,11 @@ export default { filter_null: '为空', filter_not_null: '不为空', filter_include: '包含', - filter_not_include: '不包含' + filter_not_include: '不包含', + rose_type: '玫瑰图模式', + radius_mode: '半径', + area_mode: '面积', + rose_radius: '圆角' }, dataset: { datalist: '数据集', @@ -770,7 +774,10 @@ export default { current_update_time: '当前更新时间', param: '参数', edit_sql: '编辑SQL', - showRow: '显示行' + showRow: '显示行', + add_excel_table: '添加Excel数据集', + add_custom_table: '添加自助数据集', + upload_file: '上传文件' }, datasource: { create: '新建数据连接', diff --git a/frontend/src/styles/index.scss b/frontend/src/styles/index.scss index 39bb7d023f..bb7a718048 100644 --- a/frontend/src/styles/index.scss +++ b/frontend/src/styles/index.scss @@ -88,7 +88,7 @@ div:focus { .de-filter-dialog { min-width: 500px !important; width: 50% !important; - + .el-dialog__header{ background-color: #f4f4f5; padding: 10px 20px !important; @@ -144,3 +144,30 @@ div:focus { border: none !important; } } + +.de-filter-data-table { + .el-table__body-wrapper >table>{ + tbody { + .el-table__row { + :hover { + cursor: pointer; + } + td { + border: none !important; + } + } + + } + + } +} +.de-filter-data-table::before { + height: 0px !important; +} + +.custom-component-class { + width: 100%; + div { + width: 100% !important; + } +} diff --git a/frontend/src/styles/variables.scss b/frontend/src/styles/variables.scss index 6ab717a6bc..bf4a241e3f 100644 --- a/frontend/src/styles/variables.scss +++ b/frontend/src/styles/variables.scss @@ -42,7 +42,7 @@ $subMenuHover:#1682e6; $sideBarWidth: 210px; $topBarHeight: 56px; -$contentHeight: calc(100vh - 56px); +$contentHeight: 100vh; // the :export directive is the magic sauce for webpack // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass diff --git a/frontend/src/views/chart/chart/chart.js b/frontend/src/views/chart/chart/chart.js index 6c77b1264c..101290218e 100644 --- a/frontend/src/views/chart/chart/chart.js +++ b/frontend/src/views/chart/chart/chart.js @@ -15,6 +15,8 @@ export const DEFAULT_SIZE = { lineArea: false, pieInnerRadius: 0, pieOuterRadius: 60, + pieRoseType: 'radius', + pieRoseRadius: 5, funnelWidth: 80, radarShape: 'polygon' } diff --git a/frontend/src/views/chart/chart/pie/pie.js b/frontend/src/views/chart/chart/pie/pie.js index 7ca1d77d6c..0296a75d5b 100644 --- a/frontend/src/views/chart/chart/pie/pie.js +++ b/frontend/src/views/chart/chart/pie/pie.js @@ -50,3 +50,18 @@ export function basePieOption(chart_option, chart) { return chart_option } +export function rosePieOption(chart_option, chart) { + basePieOption(chart_option, chart) + let customAttr = {} + if (chart.customAttr) { + customAttr = JSON.parse(chart.customAttr) + if (customAttr.size) { + chart_option.series[0].roseType = customAttr.size.pieRoseType + chart_option.series[0].itemStyle = { + borderRadius: customAttr.size.pieRoseRadius + } + } + } + return chart_option +} + diff --git a/frontend/src/views/chart/components/ChartComponent.vue b/frontend/src/views/chart/components/ChartComponent.vue index c5fb5f40d7..aa1256cd5a 100644 --- a/frontend/src/views/chart/components/ChartComponent.vue +++ b/frontend/src/views/chart/components/ChartComponent.vue @@ -8,7 +8,7 @@ import { BASE_BAR, BASE_LINE, HORIZONTAL_BAR, BASE_PIE, BASE_FUNNEL, BASE_RADAR } from '../chart/chart' import { baseBarOption, stackBarOption, horizontalBarOption, horizontalStackBarOption } from '../chart/bar/bar' import { baseLineOption, stackLineOption } from '../chart/line/line' -import { basePieOption } from '../chart/pie/pie' +import { basePieOption, rosePieOption } from '../chart/pie/pie' import { baseFunnelOption } from '../chart/funnel/funnel' import { baseRadarOption } from '../chart/radar/radar' import eventBus from '@/components/canvas/utils/eventBus' @@ -73,6 +73,8 @@ export default { chart_option = stackLineOption(JSON.parse(JSON.stringify(BASE_LINE)), chart) } else if (chart.type === 'pie') { chart_option = basePieOption(JSON.parse(JSON.stringify(BASE_PIE)), chart) + } else if (chart.type === 'pie-rose') { + chart_option = rosePieOption(JSON.parse(JSON.stringify(BASE_PIE)), chart) } else if (chart.type === 'funnel') { chart_option = baseFunnelOption(JSON.parse(JSON.stringify(BASE_FUNNEL)), chart) } else if (chart.type === 'radar') { diff --git a/frontend/src/views/chart/components/shape-attr/SizeSelector.vue b/frontend/src/views/chart/components/shape-attr/SizeSelector.vue index 7603f0373f..d6882247f4 100644 --- a/frontend/src/views/chart/components/shape-attr/SizeSelector.vue +++ b/frontend/src/views/chart/components/shape-attr/SizeSelector.vue @@ -57,6 +57,18 @@ + + + + + {{ $t('chart.radius_mode') }} + {{ $t('chart.area_mode') }} + + + + + + diff --git a/frontend/src/views/chart/view/ChartEdit.vue b/frontend/src/views/chart/view/ChartEdit.vue index 3d281dd1cf..f27727dafc 100644 --- a/frontend/src/views/chart/view/ChartEdit.vue +++ b/frontend/src/views/chart/view/ChartEdit.vue @@ -90,8 +90,15 @@
+ +
+
+ + + +
@@ -321,7 +328,7 @@ export default { const view = JSON.parse(JSON.stringify(this.view)) view.id = this.view.id view.sceneId = this.view.sceneId - view.name = this.table.name + view.name = this.view.name ? this.view.name : this.table.name view.tableId = this.view.tableId // view.xaxis.forEach(function(ele) { // if (!ele.summary || ele.summary === '') { diff --git a/frontend/src/views/dataset/add/AddCustom.vue b/frontend/src/views/dataset/add/AddCustom.vue new file mode 100644 index 0000000000..58e484c05f --- /dev/null +++ b/frontend/src/views/dataset/add/AddCustom.vue @@ -0,0 +1,144 @@ + + + + + diff --git a/frontend/src/views/dataset/add/AddExcel.vue b/frontend/src/views/dataset/add/AddExcel.vue new file mode 100644 index 0000000000..21a6e6e8a6 --- /dev/null +++ b/frontend/src/views/dataset/add/AddExcel.vue @@ -0,0 +1,195 @@ + + + + + diff --git a/frontend/src/views/dataset/group/Group.vue b/frontend/src/views/dataset/group/Group.vue index 5e0227f6e6..f4fbcd97d6 100644 --- a/frontend/src/views/dataset/group/Group.vue +++ b/frontend/src/views/dataset/group/Group.vue @@ -536,10 +536,10 @@ export default { this.addData('AddSQL') break case 'excel': - this.$message(param.type) + this.addData('AddExcel') break case 'custom': - this.$message(param.type) + this.addData('AddCustom') break } }, diff --git a/frontend/src/views/dataset/index.vue b/frontend/src/views/dataset/index.vue index c0acf26d12..db241f20aa 100644 --- a/frontend/src/views/dataset/index.vue +++ b/frontend/src/views/dataset/index.vue @@ -22,10 +22,12 @@ import DataHome from './data/DataHome' import ViewTable from './data/ViewTable' import AddDB from './add/AddDB' import AddSQL from './add/AddSQL' +import AddExcel from './add/AddExcel' +import AddCustom from './add/AddCustom' export default { name: 'DataSet', - components: { DeMainContainer, DeContainer, DeAsideContainer, Group, DataHome, ViewTable, AddDB, AddSQL }, + components: { DeMainContainer, DeContainer, DeAsideContainer, Group, DataHome, ViewTable, AddDB, AddSQL, AddExcel, AddCustom }, data() { return { component: DataHome, @@ -46,6 +48,12 @@ export default { case 'AddSQL': this.component = AddSQL break + case 'AddExcel': + this.component = AddExcel + break + case 'AddCustom': + this.component = AddCustom + break default: this.component = DataHome break diff --git a/frontend/src/views/panel/edit/index.vue b/frontend/src/views/panel/edit/index.vue index b2a381237b..09ea451d50 100644 --- a/frontend/src/views/panel/edit/index.vue +++ b/frontend/src/views/panel/edit/index.vue @@ -69,11 +69,31 @@ - + + + + +
+ + 取 消 + 确 定 + +
@@ -123,7 +143,10 @@ export default { showIndex: -1, activeName: 'attr', reSelectAnimateIndex: undefined, - filterVisible: false + filterVisible: false, + currentWidgetId: null, + currentWidget: null, + currentComponent: null } }, @@ -224,11 +247,12 @@ export default { // 画布 restore() { // 用保存的数据恢复画布 - if (localStorage.getItem('canvasData')) { - this.$store.commit('setComponentData', this.resetID(JSON.parse(localStorage.getItem('canvasData')))) + let canvasData = null + if ((canvasData = localStorage.getItem('canvasData')) !== null && canvasData !== 'null') { + this.$store.commit('setComponentData', this.resetID(JSON.parse(canvasData))) } - if (localStorage.getItem('canvasStyle')) { + if (canvasData && canvasData !== 'null') { this.$store.commit('setCanvasStyle', JSON.parse(localStorage.getItem('canvasStyle'))) } }, @@ -260,13 +284,17 @@ export default { } }) } else { - const wd = ApplicationContext.getService(componentInfo.id) - if (wd.filterDialog) { + this.currentWidget = ApplicationContext.getService(componentInfo.id) + if (this.currentWidget.filterDialog) { this.show = false - this.openFilterDiolog() + this.currentComponent = deepCopy(this.currentWidget) + this.currentComponent.style.top = e.offsetY + this.currentComponent.style.left = e.offsetX + this.currentComponent.id = newComponentId + this.openFilterDiolog(componentInfo.id) return } - component = deepCopy(wd) + component = deepCopy(this.currentWidget) } component.style.top = e.offsetY @@ -277,7 +305,6 @@ export default { }, handleDragOver(e) { - console.log('handleDragOver123') e.preventDefault() e.dataTransfer.dropEffect = 'copy' }, @@ -300,10 +327,22 @@ export default { this.$store.commit('hideContextMenu') } }, - openFilterDiolog() { + openFilterDiolog(widgetId) { + this.currentWidgetId = widgetId this.filterVisible = true + }, + cancelFilter() { + this.filterVisible = false + this.currentWidgetId = null + this.currentWidget = null + this.currentComponent = null + }, + sureFilter() { + const component = deepCopy(this.currentComponent) + this.$store.commit('addComponent', { component }) + this.$store.commit('recordSnapshot') + this.cancelFilter() } - } } @@ -371,7 +410,6 @@ export default { .leftPanel { transform: translate(0); } - } diff --git a/frontend/src/views/panel/filter/filterDialog.vue b/frontend/src/views/panel/filter/filterDialog.vue index bcc734e4c3..3fdb715c38 100644 --- a/frontend/src/views/panel/filter/filterDialog.vue +++ b/frontend/src/views/panel/filter/filterDialog.vue @@ -1,14 +1,77 @@