Commit 87ad0647 by 付振洋

合并分支 'feat/updata' 到 'master'

Feat/updata

查看合并请求 !38
parents 3cb8a57b 4bcc10a5
{
"name": "dataease",
"version": "1.18.11",
"version": "1.18.12",
"description": "dataease front",
"private": true,
"scripts": {
......@@ -36,7 +36,7 @@
"@antv/l7-source": "2.15.0",
"@antv/l7-three": "2.15.0",
"@antv/l7-utils": "2.15.0",
"@antv/s2": "1.35.0",
"@antv/s2": "1.49.1",
"@antv/util": "^2.0.17",
"@riophae/vue-treeselect": "0.4.0",
"@tinymce/tinymce-vue": "^3.2.8",
......
......@@ -33,7 +33,9 @@
const user = getQueryVariable('user')
const terminal = getQueryVariable('terminal')
const attachParams = getQueryVariable('attachParams')
let url = "/#/delink?link=" + encodeURIComponent(link)
const fromLink = getQueryVariable('fromLink')
const baseUrl = window.location.pathname.replace('link.html', '')
let url = baseUrl + "#/delink?link=" + encodeURIComponent(link)
if (terminal) {
url += '&terminal=' + terminal
}
......@@ -43,6 +45,9 @@
if (attachParams) {
url += '&attachParams=' + encodeURIComponent(attachParams)
}
if (fromLink) {
url += '&fromLink=' + fromLink
}
window.location.href = url
</script>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -42,3 +42,20 @@ export function removeMap(data) {
data
})
}
export function saveMapKey(data) {
return request({
url: '/system/saveMapKey',
method: 'post',
loading: true,
data
})
}
export function queryMapKey() {
return request({
url: '/system/onlineMapKey',
method: 'get',
loading: true
})
}
......@@ -12,7 +12,7 @@
>
<el-button-group size="mini">
<el-button
v-if="!isNewBlank"
v-if="fromLink"
size="mini"
type="button"
@click="back2Last"
......@@ -89,8 +89,8 @@ export default {
isPublicLink() {
return this.$router.currentRoute.path === '/delink'
},
isNewBlank() {
return window.history.length === 1
fromLink() {
return this.$route.query.fromLink === 'true'
},
containerClass() {
return this.isPublicLink ? 'trans-pc' : 'bar-main'
......
......@@ -153,6 +153,7 @@
v-if="chart && showMapLayerController"
:chart="chart"
:series-id-map="seriesIdMap"
:show-edit-position="showEditPosition"
/>
</div>
......
......@@ -145,32 +145,31 @@
</template>
<script>
import {getStyle} from '@/components/canvas/utils/style'
import {mapState} from 'vuex'
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, imgUrlTrans} from '@/components/canvas/utils/utils'
import { changeStyleWithScale } from '@/components/canvas/utils/translate'
import { uuid } from 'vue-uuid'
import { deepCopy, imgUrlTrans } from '@/components/canvas/utils/utils'
import eventBus from '@/components/canvas/utils/eventBus'
import elementResizeDetectorMaker from 'element-resize-detector'
import CanvasOptBar from '@/components/canvas/components/editor/CanvasOptBar'
import bus from '@/utils/bus'
import {buildFilterMap, buildViewKeyMap, formatCondition, valueValid, viewIdMatch} from '@/utils/conditionUtil'
import {hasDataPermission} from '@/utils/permission'
import {activeWatermark} from '@/components/canvas/tools/watermark'
import {proxyUserLoginInfo, userLoginInfo} from '@/api/systemInfo/userLogin'
import { buildFilterMap, buildViewKeyMap, formatCondition, valueValid, viewIdMatch } from '@/utils/conditionUtil'
import { hasDataPermission } from '@/utils/permission'
import { activeWatermark } from '@/components/canvas/tools/watermark'
import { proxyUserLoginInfo, userLoginInfo } from '@/api/systemInfo/userLogin'
import html2canvas from 'html2canvasde'
import {queryAll} from '@/api/panel/pdfTemplate'
import { queryAll } from '@/api/panel/pdfTemplate'
import PDFPreExport from '@/views/panel/export/PDFPreExport'
import {listenGlobalKeyDownPreview} from '@/components/canvas/utils/shortcutKey'
import { listenGlobalKeyDownPreview } from '@/components/canvas/utils/shortcutKey'
import UserViewDialog from '@/components/canvas/customComponent/UserViewDialog'
import {hexColorToRGBA} from "@/views/chart/chart/util";
import {isMobile} from '@/utils/index'
import { hexColorToRGBA } from '@/views/chart/chart/util'
import { isMobile } from '@/utils/index'
const erd = elementResizeDetectorMaker()
export default {
components: {UserViewDialog, ComponentWrapper, CanvasOptBar, PDFPreExport},
components: { UserViewDialog, ComponentWrapper, CanvasOptBar, PDFPreExport },
model: {
prop: 'show',
event: 'change'
......@@ -207,14 +206,14 @@ export default {
componentData: {
type: Array,
required: false,
default: function () {
default: function() {
return []
}
},
canvasStyleData: {
type: Object,
required: false,
default: function () {
default: function() {
return {}
}
},
......@@ -649,7 +648,7 @@ export default {
},
clearAllLinkage() {
this.$store.commit('clearPanelLinkageInfo')
bus.$emit('clear_panel_linkage', {viewId: 'all'})
bus.$emit('clear_panel_linkage', { viewId: 'all' })
},
changeStyleWithScale,
getStyle,
......@@ -714,7 +713,7 @@ export default {
},
deselectCurComponent(e) {
if (!this.isClickComponent) {
this.$store.commit('setCurComponent', {component: null, index: null})
this.$store.commit('setCurComponent', { component: null, index: null })
if (this.$refs?.['canvas-opt-bar']) {
this.$refs['canvas-opt-bar'].setWidgetStatus()
}
......
......@@ -393,10 +393,7 @@ export default {
computed: {
// 首次加载且非编辑状态新复制的视图,使用外部filter
initLoad() {
return (
!(this.isEdit && this.currentCanvasNewId.includes(this.element.id)) &&
this.isFirstLoad
)
return !(this.isEdit && this.currentCanvasNewId.includes(this.element.id)) && this.isFirstLoad && this.canvasId === 'canvas-main'
},
scaleCoefficient() {
if (this.terminal === 'pc' && !this.mobileLayoutStatus) {
......@@ -671,6 +668,9 @@ export default {
},
'chart.yaxis': function(newVal, oldVal) {
this.$emit('fill-chart-2-parent', this.chart)
},
'chart.title': function(newVal, oldVal) {
this.$emit('fill-chart-2-parent', this.chart)
}
},
mounted() {
......@@ -1217,6 +1217,12 @@ export default {
sourceInfo = param.viewId + '#' + dimension.id
jumpInfo = this.nowPanelJumpInfo[sourceInfo]
}
// 没有主维度,子维度相等
if (!jumpInfo && dimensionItem.value === param.category) {
dimension = dimensionItem
sourceInfo = param.viewId + '#' + dimension.id
jumpInfo = this.nowPanelJumpInfo[sourceInfo]
}
})
} else {
for (let i = param.dimensionList.length - 1; i >= 0; i--) {
......@@ -1239,7 +1245,7 @@ export default {
if (this.publicLinkStatus) {
// 判断是否有公共链接ID
if (jumpInfo.publicJumpId) {
const url = '/link/' + jumpInfo.publicJumpId
const url = '/link/' + jumpInfo.publicJumpId + '?fromLink=true'
const currentUrl = window.location.href
localStorage.setItem('beforeJumpUrl', currentUrl)
this.windowsJump(url, jumpInfo.jumpType)
......
......@@ -50,10 +50,32 @@ const unlockMap = {
let isCtrlOrCommandDown = false
// 检查当前页面是否有弹框
const checkDialog = () => {
let haveDialog = false
document.querySelectorAll('.el-dialog__wrapper').forEach(element => {
if (window.getComputedStyle(element).getPropertyValue('display') !== 'none') {
haveDialog = true
}
})
document.querySelectorAll('.el-popover').forEach(element => {
if (window.getComputedStyle(element).getPropertyValue('display') !== 'none') {
haveDialog = true
}
})
// 富文本单框
if (document.querySelector('.tox-dialog-wrap')) {
haveDialog = true
}
return haveDialog
}
// Monitor key operations globally and execute corresponding commands
export function listenGlobalKeyDown() {
window.onkeydown = (e) => {
if (!store.state.isInEditor) return
if (!store.state.isInEditor || checkDialog()) return
const { keyCode } = e
if (keyCode === ctrlKey || keyCode === commandKey) {
isCtrlOrCommandDown = true
......
......@@ -443,7 +443,7 @@ export function exportExcelDownload(chart, snapshot, width, height, loadingWrapp
const excelTypes = fields.map(item => item.deType)
const excelHeaderKeys = fields.map(item => item.dataeaseName)
let excelData = tableRow.map(item => excelHeaderKeys.map(i => item[i]))
const excelName = chart.name
const excelName = chart.title ? chart.title : chart.name
let detailFields = []
if (chart.data.detailFields?.length) {
detailFields = chart.data.detailFields.map(item => {
......
......@@ -341,6 +341,7 @@ export default {
<style lang="scss">
.coustom-date-picker {
right: 0px;
border: 1px solid var(--BrDateColor, #dfe4ed) !important;
background: var(--BgDateColor, #FFFFFF) !important;
......
......@@ -1069,6 +1069,7 @@ export default {
fast_calc: 'Fast Calculation',
sum: 'Sum',
count: 'Count',
value: 'Value',
avg: 'Avg',
max: 'Max',
min: 'Min',
......@@ -1574,8 +1575,8 @@ export default {
reference_field_tip: `Reference fields start with "[" and end with "]". <br/>
Do not modify the reference content, otherwise the reference will fail.<br/>
If you enter content in the same format as the reference field, it will be treated as a reference field.`,
scatter_tip:
'When this indicator is in effect, the bubble size attribute in the style size will be invalid',
scatter_tip: 'When this indicator is in effect, the bubble size attribute in the style size will be invalid',
scatter_group_tip: 'This setting only active when quota value in xAxis',
place_name_mapping: 'Place name mapping',
axis_tip:
'The minimum value, maximum value, and interval are all numeric types; it will be regarded as automatic if left blank.<br/>Please make sure that the filled values can be calculated correctly, otherwise the axis values will not be displayed normally.',
......@@ -2043,8 +2044,7 @@ export default {
req_param: 'Request parameters',
headers: 'Request header',
query_param: 'QUERY param',
query_info:
'Follow in the address bar? The following parameters, such as: updateAPI? id=112',
query_info: 'Follow in the address bar? The following parameters, such as: updateAPI? id=112',
key: 'Key',
value: 'Value',
data_path: 'Extract data',
......
......@@ -1038,7 +1038,8 @@ export default {
fast_calc: '快速計算',
sum: '求和',
count: '計數',
avg: '平均',
value: '字段值',
avg: '平均值',
max: '最大值',
min: '最小值',
stddev_pop: '標準差',
......@@ -1534,6 +1535,7 @@ export default {
reference_field_tip:
'引用字段以 "[" 開始,"]" 結束。請<br/>勿修改引用內容,否則將引用失敗。<br/>若輸入與引用字段相同格式的內容,將被當做引用字段處理。',
scatter_tip: '該指標生效時,樣式大小中的氣泡大小屬性將失效',
scatter_group_tip: '僅當橫軸內為指標時生效',
place_name_mapping: '地名映射',
axis_tip:
'最小值、最大值、間隔均為數值類型;若不填,則該項視為自動。<br/>請確保填寫數值能正確計算,否則將無法正常顯示值軸',
......
......@@ -1038,7 +1038,8 @@ export default {
fast_calc: '快速计算',
sum: '求和',
count: '计数',
avg: '平均',
value: '字段值',
avg: '平均值',
max: '最大值',
min: '最小值',
stddev_pop: '标准差',
......@@ -1535,6 +1536,7 @@ export default {
reference_field_tip:
'引用字段以 "[" 开始, "]" 结束。<br/>请勿修改引用内容,否则将引用失败。<br/>若输入与引用字段相同格式的内容,将被当作引用字段处理。',
scatter_tip: '该指标生效时,样式大小中的气泡大小属性将失效',
scatter_group_tip: '仅当横轴内为指标时生效',
place_name_mapping: '地名映射',
axis_tip:
'最小值、最大值、间隔均为数值类型;若不填,则该项视为自动。<br/>请确保填写数值能正确计算,否则将无法正常显示轴值。',
......
......@@ -481,6 +481,7 @@ export const DEFAULT_FUNCTION_CFG = {
}
export const DEFAULT_THRESHOLD = {
gaugeThreshold: '',
liquidThreshold: '',
labelThreshold: [],
tableThreshold: [],
textLabelThreshold: []
......
......@@ -336,7 +336,7 @@ export function seniorCfg(chart_option, chart) {
}
const fixedLines = senior.assistLine.filter(ele => ele.field === '0')
const dynamicLines = chart.data.dynamicAssistLines
const dynamicLines = chart.data.dynamicAssistData
const lines = fixedLines.concat(dynamicLines)
lines.forEach(ele => {
......
......@@ -158,9 +158,14 @@ export function getLabel(chart) {
// label value formatter
if (chart.type && chart.type !== 'waterfall') {
label.formatter = function(param) {
let yAxis, extStack, xaxisExt
let xAxis, yAxis, extStack, xaxisExt
let res = param.value
try {
xAxis = JSON.parse(chart.xaxis)
} catch (e) {
xAxis = JSON.parse(JSON.stringify(chart.xaxis))
}
try {
yAxis = JSON.parse(chart.yaxis)
} catch (e) {
yAxis = JSON.parse(JSON.stringify(chart.yaxis))
......@@ -244,38 +249,46 @@ export function getLabel(chart) {
} else {
for (let i = 0; i < yAxis.length; i++) {
const f = yAxis[i]
if (f.name === param.category) {
let formatterCfg = formatterItem
if (f.formatterCfg) {
formatterCfg = f.formatterCfg
let formatterCfg = formatterItem
if (f.formatterCfg) {
formatterCfg = f.formatterCfg
}
if (chart.type === 'scatter' && xAxis && xAxis.length > 0 && xAxis[0].groupType === 'q') {
// 针对横轴为指标的散点图
if (f.name === param.group) {
res = valueFormatter(param.value, formatterCfg)
}
} else {
if (f.name === param.category) {
// 饼图和环形图格式优化
if (equalsAny(chart.type, 'pie', 'pie-donut')) {
if (equalsAny(chart.type, 'pie', 'pie-donut')) {
// 这边默认值取指标是为了兼容存量的视图
const labelContent = l.labelContent ?? ['quota']
const contentItems = []
if (labelContent.includes('dimension')) {
contentItems.push(param.field)
}
if (labelContent.includes('quota')) {
contentItems.push(valueFormatter(param.value, formatterCfg))
}
if (labelContent.includes('proportion')) {
const percentage = `${(Math.round(param.percent * 10000) / 100).toFixed(l.reserveDecimalCount)}%`
if (labelContent.length === 3) {
contentItems.push(`(${percentage})`)
} else {
contentItems.push(percentage)
const labelContent = l.labelContent ?? ['quota']
const contentItems = []
if (labelContent.includes('dimension')) {
contentItems.push(param.field)
}
if (labelContent.includes('quota')) {
contentItems.push(valueFormatter(param.value, formatterCfg))
}
if (labelContent.includes('proportion')) {
const percentage = `${(Math.round(param.percent * 10000) / 100).toFixed(l.reserveDecimalCount)}%`
if (labelContent.length === 3) {
contentItems.push(`(${percentage})`)
} else {
contentItems.push(percentage)
}
}
res = contentItems.join(' ')
} else if (equalsAny(chart.type, 'pie-rose', 'pie-donut-rose')) {
const quotaValue = valueFormatter(param.value, formatterCfg)
res = [param.field, quotaValue].join(' ')
} else {
res = valueFormatter(param.value, formatterCfg)
}
res = contentItems.join(' ')
} else if (equalsAny(chart.type, 'pie-rose', 'pie-donut-rose')) {
const quotaValue = valueFormatter(param.value, formatterCfg)
res = [param.field, quotaValue].join(' ')
} else {
res = valueFormatter(param.value, formatterCfg)
break
}
break
}
}
}
......@@ -300,21 +313,28 @@ export function getTooltip(chart) {
const t = JSON.parse(JSON.stringify(customAttr.tooltip))
if (t.show) {
tooltip = {}
let xAxis, yAxis, extStack
try {
xAxis = JSON.parse(chart.xaxis)
} catch (e) {
xAxis = JSON.parse(JSON.stringify(chart.xaxis))
}
try {
yAxis = JSON.parse(chart.yaxis)
} catch (e) {
yAxis = JSON.parse(JSON.stringify(chart.yaxis))
}
try {
extStack = JSON.parse(chart.extStack)
} catch (e) {
extStack = JSON.parse(JSON.stringify(chart.extStack))
}
// tooltip value formatter
if (chart.type && chart.type !== 'waterfall') {
tooltip.formatter = function(param) {
let yAxis, extStack
let res = param.value
try {
yAxis = JSON.parse(chart.yaxis)
} catch (e) {
yAxis = JSON.parse(JSON.stringify(chart.yaxis))
}
try {
extStack = JSON.parse(chart.extStack)
} catch (e) {
extStack = JSON.parse(JSON.stringify(chart.extStack))
}
let obj
if (equalsAny(chart.type, 'bar-stack', 'line-stack',
......@@ -445,6 +465,51 @@ export function getTooltip(chart) {
obj.value = res === null ? '' : res
return obj
}
//
if (chart.type === 'scatter' && xAxis && xAxis.length > 0 && xAxis[0].groupType === 'q') {
tooltip.fields = ['x', 'category', 'value', 'group']
tooltip.customContent = (title, data) => {
const key1 = xAxis[0]?.name
let key2, v1, v2
if (data && data.length > 0) {
title = data[0].data.category
key2 = data[0].data.group
const fx = xAxis[0]
if (fx.formatterCfg) {
v1 = valueFormatter(data[0].data.x, fx.formatterCfg)
} else {
v1 = valueFormatter(data[0].data.x, formatterItem)
}
for (let i = 0; i < yAxis.length; i++) {
const f = yAxis[i]
if (f.name === key2) {
if (f.formatterCfg) {
v2 = valueFormatter(data[0].data.value, f.formatterCfg)
} else {
v2 = valueFormatter(data[0].data.value, formatterItem)
}
break
}
}
}
return `
<div>
<div class="g2-tooltip-title">${title}</div>
<div class="g2-tooltip-item">
<span class="g2-tooltip-name">${key1}:</span><span class="g2-tooltip-value">${v1}</span>
</div>
<div class="g2-tooltip-item">
<span class="g2-tooltip-name">${key2}:</span><span class="g2-tooltip-value">${v2}</span>
</div>
<div class="g2-tooltip-item">&nbsp;</div>
</div>
`
}
}
}
} else {
// 百分比堆叠柱状图隐藏 tooltip 设置 show 为 false 或者直接设置 tooltip 为 false 都无效,会变成分组显示,
......@@ -952,7 +1017,7 @@ export function getAnalyse(chart) {
}
const fixedLines = senior.assistLine.filter(ele => ele.field === '0')
const dynamicLines = chart.data.dynamicAssistLines
const dynamicLines = chart.data.dynamicAssistData
const lines = fixedLines.concat(dynamicLines)
lines.forEach(ele => {
......
......@@ -31,6 +31,11 @@ export function baseLineOptionAntV(plot, container, chart, action) {
const analyse = getAnalyse(chart)
// options
const options = {
meta: {
category: {
type: 'cat'
}
},
point: {},
theme: theme,
data: data,
......
......@@ -8,7 +8,7 @@ let labelFormatter = null
export function baseLiquid(plot, container, chart) {
let value = 0
const colors = []
let max, radius, bgColor, shape, labelContent
let max, radius, bgColor, shape, labelContent, liquidStyle
if (chart.data?.series.length > 0) {
value = chart.data.series[0].data[0]
}
......@@ -53,6 +53,26 @@ export function baseLiquid(plot, container, chart) {
}
}
}
// senior
const senior = JSON.parse(chart.senior)
if (senior?.threshold) {
const { liquidThreshold } = senior?.threshold
if (liquidThreshold) {
liquidStyle = ({ percent }) => {
const thresholdArr = liquidThreshold.split(',')
let index = 0
thresholdArr.forEach((v, i) => {
if (percent > v / 100) {
index = i + 1
}
})
return {
fill: colors[index % colors.length],
stroke: colors[index % colors.length]
}
}
}
}
let customStyle
if (chart.customStyle) {
customStyle = JSON.parse(chart.customStyle)
......@@ -78,7 +98,8 @@ export function baseLiquid(plot, container, chart) {
shape: shape,
statistic: {
content: labelContent
}
},
liquidStyle
})
return plot
}
import { Scene, LineLayer } from '@antv/l7'
import { GaodeMap } from '@antv/l7-maps'
import { getLanguage } from '@/lang'
import { queryMapKey } from '@/api/map/map'
export function baseFlowMapOption(chartDom, chartId, chart, action) {
export async function baseFlowMapOption(chartDom, chartId, chart, action) {
const xAxis = JSON.parse(chart.xaxis)
const xAxisExt = JSON.parse(chart.xaxisExt)
let customAttr
......@@ -20,9 +21,11 @@ export function baseFlowMapOption(chartDom, chartId, chart, action) {
} catch (e) {
// ignore
}
const key = await getMapKey()
chartDom = new Scene({
id: chartId,
map: new GaodeMap({
token: key ?? undefined,
lang: lang,
pitch: size.mapPitch,
style: mapStyle
......@@ -85,3 +88,11 @@ export function baseFlowMapOption(chartDom, chartId, chart, action) {
})
return chartDom
}
const getMapKey = async() => {
const key = 'online-map-key'
if (!localStorage.getItem(key)) {
await queryMapKey().then(res => localStorage.setItem(key, res.data))
}
return localStorage.getItem(key)
}
......@@ -32,7 +32,7 @@ export function baseScatterOptionAntV(plot, container, chart, action) {
const options = {
theme: theme,
data: data,
xField: 'field',
xField: 'x',
yField: 'value',
colorField: 'category',
appendPadding: getPadding(chart),
......
......@@ -551,21 +551,22 @@ function getConditions(chart) {
}
}
let filedValueMap = getFieldValueMap(chart)
for (let i = 0; i < conditions.length; i++) {
const field = conditions[i]
res.text.push({
field: field.field.dataeaseName,
mapping(value) {
mapping(value,rowData) {
return {
fill: mappingColor(value, valueColor, field, 'color')
fill: mappingColor(value, valueColor, field, 'color', filedValueMap, rowData)
}
}
})
res.background.push({
field: field.field.dataeaseName,
mapping(value) {
mapping(value,rowData) {
return {
fill: mappingColor(value, valueBgColor, field, 'backgroundColor')
fill: mappingColor(value, valueBgColor, field, 'backgroundColor', filedValueMap, rowData)
}
}
})
......@@ -574,13 +575,37 @@ function getConditions(chart) {
return res
}
function mappingColor(value, defaultColor, field, type) {
function getValue(field, filedValueMap, rowData){
if (field.summary === 'value') {
return rowData[field.curField.dataeaseName]
} else {
return filedValueMap[field.summary + '-' + field.fieldId]
}
}
function mappingColor(value, defaultColor, field, type, filedValueMap, rowData) {
let color
for (let i = 0; i < field.conditions.length; i++) {
let flag = false
const t = field.conditions[i]
if (field.field.deType === 2 || field.field.deType === 3 || field.field.deType === 4) {
const tv = parseFloat(t.value)
let tv,max,min;
if (t.field === '1') {
if (t.term === 'between') {
max = parseFloat(getValue(t.maxField, filedValueMap, rowData))
min = parseFloat(getValue(t.minField, filedValueMap, rowData))
} else {
tv = parseFloat(getValue(t.targetField, filedValueMap, rowData))
}
} else {
if (t.term === 'between') {
min = parseFloat(t.min)
max = parseFloat(t.max)
} else {
tv = parseFloat(t.value)
}
}
if (t.term === 'eq') {
if (value === tv) {
color = t[type]
......@@ -612,8 +637,6 @@ function mappingColor(value, defaultColor, field, type) {
flag = true
}
} else if (t.term === 'between') {
const min = parseFloat(t.min)
const max = parseFloat(t.max)
if (min <= value && value <= max) {
color = t[type]
flag = true
......@@ -625,7 +648,12 @@ function mappingColor(value, defaultColor, field, type) {
color = defaultColor
}
} else if (field.field.deType === 0 || field.field.deType === 5) {
const tv = t.value
let tv;
if (t.field === '1') {
tv = getValue(t.targetField, filedValueMap, rowData)
} else {
tv = t.value
}
if (t.term === 'eq') {
if (value === tv) {
color = t[type]
......@@ -664,7 +692,16 @@ function mappingColor(value, defaultColor, field, type) {
}
} else {
// time
const tv = new Date(t.value.replace(/-/g, '/') + ' GMT+8').getTime()
let tv;
if (t.field === '1') {
let fieldValue = getValue(t.targetField, filedValueMap, rowData);
if (fieldValue) {
tv = new Date(fieldValue.replace(/-/g, '/') + ' GMT+8').getTime()
}
} else {
tv = new Date(t.value.replace(/-/g, '/') + ' GMT+8').getTime()
}
const v = new Date(value.replace(/-/g, '/') + ' GMT+8').getTime()
if (t.term === 'eq') {
if (v === tv) {
......@@ -722,3 +759,13 @@ function showTooltip(s2Instance, event, fieldMap) {
content
})
}
function getFieldValueMap(view){
let fieldValueMap = {}
if (view.data && view.data.dynamicAssistData && view.data.dynamicAssistData.length > 0) {
view.data.dynamicAssistData.forEach(ele => {
fieldValueMap[ele.summary + '-' + ele.fieldId] = ele.value
});
}
return fieldValueMap;
}
......@@ -251,7 +251,7 @@ export default {
})
window.addEventListener('resize', this.calcHeightDelay)
},
drawView() {
async drawView() {
const chart = JSON.parse(JSON.stringify(this.chart))
// type
// if (chart.data) {
......@@ -307,7 +307,7 @@ export default {
} else if (chart.type === 'chart-mix') {
this.myChart = baseMixOptionAntV(this.myChart, this.chartId, chart, this.antVAction)
} else if (chart.type === 'flow-map') {
this.myChart = baseFlowMapOption(this.myChart, this.chartId, chart, this.antVAction)
this.myChart = await baseFlowMapOption(this.myChart, this.chartId, chart, this.antVAction)
} else if (chart.type === 'bidirectional-bar') {
this.myChart = baseBidirectionalBarOptionAntV(this.myChart, this.chartId, chart, this.antVAction)
} else if (chart.type === 'heat-map') {
......@@ -362,7 +362,6 @@ export default {
}
this.setBackGroundBorder()
},
antVAction(param) {
switch (this.chart.type) {
case 'treemap':
......@@ -379,7 +378,8 @@ export default {
}
this.linkageActiveParam = {
category: this.pointParam.data.category ? this.pointParam.data.category : 'NO_DATA',
name: this.pointParam.data.name ? this.pointParam.data.name : 'NO_DATA'
name: this.pointParam.data.name ? this.pointParam.data.name : 'NO_DATA',
group: this.pointParam.data.group ? this.pointParam.data.group : 'NO_DATA'
}
if (this.trackMenu.length < 2) { // 只有一个事件直接调用
this.trackClick(this.trackMenu[0])
......@@ -416,14 +416,18 @@ export default {
name: this.pointParam.data.name,
viewId: this.chart.id,
dimensionList: this.pointParam.data.dimensionList,
quotaList: quotaList
quotaList: quotaList,
category: this.pointParam.data.category,
group: this.pointParam.data.group
}
const jumpParam = {
option: 'jump',
name: this.pointParam.data.name,
viewId: this.chart.id,
dimensionList: this.pointParam.data.dimensionList,
quotaList: quotaList
quotaList: quotaList,
category: this.pointParam.data.category,
group: this.pointParam.data.group
}
switch (trackAction) {
......
......@@ -275,6 +275,10 @@ export default {
quotaData: {
type: Array,
required: true
},
specialType: {
type: String,
required: false
}
},
data() {
......@@ -436,23 +440,35 @@ export default {
showRename() {
this.item.index = this.index
this.item.renameType = 'quota'
if (this.specialType) {
this.item.renameType = this.specialType
}
this.item.dsFieldName = getOriginFieldName(this.dimensionData, this.quotaData, this.item)
this.$emit('onNameEdit', this.item)
},
removeItem() {
this.item.index = this.index
this.item.removeType = 'quota'
if (this.specialType) {
this.item.removeType = this.specialType
}
this.$emit('onQuotaItemRemove', this.item)
},
editFilter() {
this.item.index = this.index
this.item.filterType = 'quota'
if (this.specialType) {
this.item.filterType = this.specialType
}
this.$emit('editItemFilter', this.item)
},
editCompare() {
this.item.index = this.index
this.item.calcType = 'quota'
if (this.specialType) {
this.item.calcType = this.specialType
}
this.$emit('editItemCompare', this.item)
},
getItemTagType() {
......@@ -462,6 +478,9 @@ export default {
valueFormatter() {
this.item.index = this.index
this.item.formatterType = 'quota'
if (this.specialType) {
this.item.formatterType = this.specialType
}
this.$emit('valueFormatter', this.item)
}
}
......
......@@ -198,6 +198,9 @@ export default {
{
label: '',
options: [{
value: 'null',
label: this.$t('chart.filter_null')
}, {
value: 'not_null',
label: this.$t('chart.filter_not_null')
}]
......@@ -237,6 +240,9 @@ export default {
{
label: '',
options: [{
value: 'null',
label: this.$t('chart.filter_null')
}, {
value: 'not_null',
label: this.$t('chart.filter_not_null')
}]
......
<template>
<el-popover
placement="right"
placement="left-start"
title=""
width="150"
:append-to-body="false"
trigger="click"
:popper-class="showEditPosition === 'bar-main-preview' ? 'map-layer-poper' : ''"
>
<i
slot="reference"
......@@ -50,6 +52,10 @@ export default {
id: ''
}
}
},
showEditPosition: {
type: String,
required: true
}
},
data() {
......@@ -97,9 +103,15 @@ export default {
}
}
</script>
<style lang="scss">
.map-layer-poper {
top: 3px !important;
right: 80px !important;
left: auto !important;
}
</style>
<style scoped lang="scss">
.de-ul li {
margin: 5px 2px;
cursor: pointer;
......
......@@ -40,6 +40,45 @@
</el-form-item>
</el-form>
</el-col>
<el-col v-if="chart.type && chart.type === 'liquid'">
<el-form
ref="thresholdForm"
:model="thresholdForm"
label-width="80px"
size="mini"
>
<el-form-item
:label="$t('chart.threshold_range')+'(%)'"
class="form-item"
>
<span>0,</span>
<el-input
v-model="thresholdForm.liquidThreshold"
style="width: 100px;margin: 0 10px;"
:placeholder="$t('chart.threshold_range')"
size="mini"
clearable
@change="gaugeThresholdChange"
/>
<span>,100</span>
<el-tooltip
class="item"
effect="dark"
placement="bottom"
>
<div slot="content">
阈值设置,决定水波图颜色,为空则不开启阈值,范围(0-100),逐级递增
<br>
例如:输入 30,70;表示:分为3段,分别为[0,30],(30,70],(70,100]
</div>
<i
class="el-icon-info"
style="cursor: pointer;margin-left: 10px;font-size: 12px;"
/>
</el-tooltip>
</el-form-item>
</el-form>
</el-col>
<!--文本卡-->
<el-col v-if="chart.type && chart.type === 'label'">
......@@ -212,7 +251,7 @@
:key="index"
class="line-style"
>
<el-col :span="6">
<el-col :span="4">
<span
v-if="item.term === 'eq'"
:title="$t('chart.filter_eq')"
......@@ -266,7 +305,22 @@
:title="$t('chart.filter_not_empty')"
>{{ $t('chart.filter_not_empty') }}</span>
</el-col>
<el-col :span="10">
<el-col :span="4" v-if="!item.term.includes('null') && !item.term.includes('empty')">
<span
v-if="item.field === '0'"
:title="$t('chart.field_fixed')"
>{{ $t('chart.field_fixed') }}</span>
<span
v-if="item.field === '1'"
:title="$t('chart.field_dynamic')"
>{{ $t('chart.field_dynamic') }}</span>
</el-col>
<el-col :span="4" v-if="item.term.includes('null') || item.term.includes('empty')">
&nbsp;
</el-col>
<el-col :span="10" v-if="item.field === '0'">
<span
v-if="!item.term.includes('null') && !item.term.includes('empty') && item.term !== 'between'"
:title="item.value"
......@@ -276,13 +330,27 @@
</span>
<span v-else>&nbsp;</span>
</el-col>
<el-col :span="4">
<el-col :span="10" v-if="item.field === '1'">
<span v-if="!item.term.includes('null') && !item.term.includes('empty') && item.term !== 'between'"
:title="item.targetField.curField.name + '(' + $t('chart.' + item.targetField.summary) + ')'">{{ item.targetField.curField.name + '(' + $t('chart.' + item.targetField.summary) + ')' }}</span>
<span v-else-if="!item.term.includes('null') && !item.term.includes('empty') && item.term === 'between'"
:title="item.minField.curField.name + '(' + $t('chart.' + item.minField.summary) + ')' + ' ≤' + $t('chart.drag_block_label_value') + '≤ ' + item.maxField.curField.name + '(' + $t('chart.' + item.maxField.summary) + ')'">
{{ item.minField.curField.name + '(' + $t('chart.' + item.minField.summary) + ')' + ' ≤' + $t('chart.drag_block_label_value') + '≤ ' + item.maxField.curField.name + '(' + $t('chart.' + item.maxField.summary) + ')' }}
</span>
<span v-else>&nbsp;</span>
</el-col>
<el-col :span="2">
<span
:title="$t('chart.textColor')"
:style="{width:'14px', height:'14px', backgroundColor: item.color, border: 'solid 1px #e1e4e8'}"
/>
</el-col>
<el-col :span="4">
<el-col :span="2">
<span
:title="$t('chart.backgroundColor')"
:style="{width:'14px', height:'14px', backgroundColor: item.backgroundColor, border: 'solid 1px #e1e4e8'}"
......@@ -363,7 +431,7 @@
:title="$t('chart.threshold')"
:visible="editTableThresholdDialog"
:show-close="false"
width="800px"
width="1050px"
class="dialog-css"
append-to-body
>
......@@ -459,10 +527,10 @@ export default {
changeThreshold() {
this.$emit('onThresholdChange', this.thresholdForm)
},
gaugeThresholdChange() {
gaugeThresholdChange(val) {
// check input
if (this.thresholdForm.gaugeThreshold) {
const arr = this.thresholdForm.gaugeThreshold.split(',')
if (val) {
const arr = val.split(',')
for (let i = 0; i < arr.length; i++) {
const ele = arr[i]
if (parseFloat(ele).toString() === 'NaN' || parseFloat(ele) <= 0 || parseFloat(ele) >= 100) {
......@@ -593,6 +661,10 @@ export default {
closeTableThreshold() {
this.editTableThresholdDialog = false
},
fieldValid(field) {
// 检查字段和聚合方式是否不为空
return field && field.fieldId && field.summary;
},
changeTableThreshold() {
// check line config
for (let i = 0; i < this.tableThresholdArr.length; i++) {
......@@ -624,7 +696,7 @@ export default {
return
}
if (ele.term === 'between') {
if (!ele.term.includes('null') && !ele.term.includes('empty') && (!ele.min || !ele.max)) {
if (!ele.term.includes('null') && !ele.term.includes('empty') && ((ele.field === '0' && (!ele.min || !ele.max)) || (ele.field === '1' && (!this.fieldValid(ele.minField) || !this.fieldValid(ele.maxField))))) {
this.$message({
message: this.$t('chart.value_can_not_empty'),
type: 'error',
......@@ -641,7 +713,7 @@ export default {
return
}
} else {
if (!ele.term.includes('null') && !ele.term.includes('empty') && !ele.value) {
if (!ele.term.includes('null') && !ele.term.includes('empty') && ((ele.field === '0' && !ele.value) || (ele.field === '1' && !this.fieldValid(ele.targetField)))) {
this.$message({
message: this.$t('chart.value_can_not_empty'),
type: 'error',
......@@ -649,7 +721,7 @@ export default {
})
return
}
if ((field.field.deType === 2 || field.field.deType === 3 || field.field.deType === 4) && parseFloat(ele.value).toString() === 'NaN') {
if (ele.field === '0' && (field.field.deType === 2 || field.field.deType === 3 || field.field.deType === 4) && parseFloat(ele.value).toString() === 'NaN') {
this.$message({
message: this.$t('chart.value_error'),
type: 'error',
......
......@@ -18,7 +18,7 @@
<el-select
v-model="fieldItem.fieldId"
size="mini"
@change="addField(fieldItem)"
@change="onFieldChange(fieldItem)"
>
<el-option
v-for="fieldOption in fields"
......@@ -72,11 +72,11 @@
:key="index"
class="line-item"
>
<el-col :span="4">
<el-col :span="3">
<el-select
v-model="item.term"
size="mini"
@change="changeThreshold"
@change="changeThresholdField(item)"
>
<el-option-group
v-for="(group,idx) in fieldItem.options"
......@@ -92,24 +92,41 @@
</el-option-group>
</el-select>
</el-col>
<el-col :span="3">
<el-select
v-show="!item.term.includes('null') && !item.term.includes('empty')"
v-model="item.field"
size="mini"
style="margin-left: 10px;"
@change="changeThresholdField(item)"
>
<el-option
v-for="opt in fieldTypeOptions"
:key="opt.value"
:label="opt.label"
:value="opt.value"
/>
</el-select>
</el-col>
<el-col
:span="10"
style="text-align: center;"
v-if="item.field === '0'"
:span="12"
>
<el-input
v-show="!item.term.includes('null') && !item.term.includes('empty') && item.term !== 'between'"
v-model="item.value"
class="value-item"
style="margin-left: 10px;"
:placeholder="$t('chart.drag_block_label_value')"
size="mini"
clearable
@change="changeThreshold"
/>
<span v-if="item.term === 'between'">
<el-input
v-show="!item.term.includes('null') && !item.term.includes('empty') && item.term !== 'between'"
v-model="item.value"
class="value-item"
style="margin-left: 10px;"
:placeholder="$t('chart.drag_block_label_value')"
size="mini"
clearable
@change="changeThreshold"
/>
<span v-if="item.term === 'between'">
<el-input
v-model="item.min"
class="between-item"
class="item-long-between"
:placeholder="$t('chart.axis_value_min')"
size="mini"
clearable
......@@ -118,7 +135,7 @@
<span style="margin: 0 4px;">{{ $t('chart.drag_block_label_value') }}</span>
<el-input
v-model="item.max"
class="between-item"
class="item-long-between"
:placeholder="$t('chart.axis_value_max')"
size="mini"
clearable
......@@ -127,7 +144,185 @@
</span>
</el-col>
<el-col
:span="4"
v-if="item.field === '1'"
:span="12"
>
<span v-show="!item.term.includes('null') && !item.term.includes('empty') && item.term !== 'between'">
<el-select
v-model="item.targetField.fieldId"
size="mini"
style="margin-left: 10px;"
class="item-long select-item"
@change="changeThresholdField(item)"
@visible-change="$forceUpdate()"
>
<el-option
v-for="fieldOption in fieldItem.fieldOptions"
:key="fieldOption.id"
:label="fieldOption.name"
:value="fieldOption.id"
>
<span style="float: left">
<svg-icon
v-if="fieldOption.deType === 0"
icon-class="field_text"
class="field-icon-text"
/>
<svg-icon
v-if="fieldOption.deType === 1"
icon-class="field_time"
class="field-icon-time"
/>
<svg-icon
v-if="fieldOption.deType === 2 || fieldOption.deType === 3"
icon-class="field_value"
class="field-icon-value"
/>
<svg-icon
v-if="fieldOption.deType === 5"
icon-class="field_location"
class="field-icon-location"
/>
</span>
<span style="float: left; color: #8492a6; font-size: 12px">{{ fieldOption.name }}</span>
</el-option>
</el-select>
<el-select
v-model="item.targetField.summary"
size="mini"
class="item-long select-item"
style="margin-left: 10px;"
:placeholder="$t('chart.aggregation')"
@change="changeThreshold"
@visible-change="$forceUpdate()"
>
<el-option
v-for="opt in getSummaryOptions(fieldItem.field.deType)"
:key="opt.id"
:value="opt.id"
:label="opt.name"
/>
</el-select>
</span>
<span v-if="item.term === 'between'">
<el-select
v-model="item.minField.fieldId"
size="mini"
style="margin-left: 10px;"
class="select-item item-short"
@change="changeThresholdField(item)"
@visible-change="$forceUpdate()"
>
<el-option
v-for="fieldOption in fieldItem.fieldOptions"
:key="fieldOption.id"
:label="fieldOption.name"
:value="fieldOption.id"
>
<span style="float: left">
<svg-icon
v-if="fieldOption.deType === 0"
icon-class="field_text"
class="field-icon-text"
/>
<svg-icon
v-if="fieldOption.deType === 1"
icon-class="field_time"
class="field-icon-time"
/>
<svg-icon
v-if="fieldOption.deType === 2 || fieldOption.deType === 3"
icon-class="field_value"
class="field-icon-value"
/>
<svg-icon
v-if="fieldOption.deType === 5"
icon-class="field_location"
class="field-icon-location"
/>
</span>
<span style="float: left; color: #8492a6; font-size: 12px">{{ fieldOption.name }}</span>
</el-option>
</el-select>
<el-select
v-model="item.minField.summary"
size="mini"
class="select-item item-short"
style="margin-left: 10px;"
:placeholder="$t('chart.aggregation')"
@change="changeThreshold"
@visible-change="$forceUpdate()"
>
<el-option
v-for="opt in getSummaryOptions(fieldItem.field.deType)"
:key="opt.id"
:value="opt.id"
:label="opt.name"
/>
</el-select>
<span style="margin: 0 4px;">{{ $t('chart.drag_block_label_value') }}</span>
<el-select
v-model="item.maxField.fieldId"
size="mini"
class="select-item item-short"
@change="changeThresholdField(item)"
@visible-change="$forceUpdate()"
>
<el-option
v-for="fieldOption in fieldItem.fieldOptions"
:key="fieldOption.id"
:label="fieldOption.name"
:value="fieldOption.id"
>
<span style="float: left">
<svg-icon
v-if="fieldOption.deType === 0"
icon-class="field_text"
class="field-icon-text"
/>
<svg-icon
v-if="fieldOption.deType === 1"
icon-class="field_time"
class="field-icon-time"
/>
<svg-icon
v-if="fieldOption.deType === 2 || fieldOption.deType === 3"
icon-class="field_value"
class="field-icon-value"
/>
<svg-icon
v-if="fieldOption.deType === 5"
icon-class="field_location"
class="field-icon-location"
/>
</span>
<span style="float: left; color: #8492a6; font-size: 12px">{{ fieldOption.name }}</span>
</el-option>
</el-select>
<el-select
v-model="item.maxField.summary"
size="mini"
class="select-item item-short"
style="margin-left: 10px;"
:placeholder="$t('chart.aggregation')"
@change="changeThreshold"
@visible-change="$forceUpdate()"
>
<el-option
v-for="opt in getSummaryOptions(fieldItem.field.deType)"
:key="opt.id"
:value="opt.id"
:label="opt.name"
/>
</el-select>
</span>
</el-col>
<el-col
:span="3"
style="display: flex;align-items: center;justify-content: center;"
>
<span class="color-title">{{ $t('chart.textColor') }}</span>
......@@ -140,7 +335,7 @@
/>
</el-col>
<el-col
:span="4"
:span="3"
style="display: flex;align-items: center;justify-content: center;"
>
<span class="color-title">{{ $t('chart.backgroundColor') }}</span>
......@@ -152,7 +347,7 @@
@change="changeThreshold"
/>
</el-col>
<el-col :span="2">
<el-col :span="1">
<el-button
type="text"
icon="el-icon-delete"
......@@ -187,6 +382,11 @@ export default {
return {
thresholdArr: [],
fields: [],
fieldsByType: {
text: [],
value: [],
date: []
},
thresholdObj: {
fieldId: '',
field: {},
......@@ -199,8 +399,24 @@ export default {
color: '#ff0000ff',
backgroundColor: '#ffffff00',
min: '0',
max: '1'
max: '1',
targetField:{},
minField:{},
maxField:{}
},
summaryOptions: [{
id: 'value',
name: this.$t('chart.value')
}, {
id: 'avg',
name: this.$t('chart.avg')
}, {
id: 'max',
name: this.$t('chart.max')
}, {
id: 'min',
name: this.$t('chart.min')
}],
textOptions: [
{
label: '',
......@@ -304,6 +520,10 @@ export default {
}]
}
],
fieldTypeOptions: [
{ label: this.$t('chart.field_fixed'), value: '0' },
{ label: this.$t('chart.field_dynamic'), value: '1' }
],
predefineColors: COLOR_PANEL
}
},
......@@ -314,6 +534,26 @@ export default {
init() {
this.thresholdArr = JSON.parse(JSON.stringify(this.threshold))
this.initFields()
this.thresholdArr && this.thresholdArr.forEach(ele => {
this.initOptions(ele)
if (ele.conditions) {
for (const item of ele.conditions) {
this.initConditionField(item)
}
}
})
},
initConditionField(item) {
// 兼容旧数据
if (!item.targetField) {
item.targetField = {};
}
if (!item.minField) {
item.minField = {};
}
if (!item.maxField) {
item.maxField = {};
}
},
initOptions(item) {
if (item.field) {
......@@ -324,9 +564,18 @@ export default {
} else {
item.options = JSON.parse(JSON.stringify(this.valueOptions))
}
item.conditions && item.conditions.forEach(ele => {
ele.term = ''
})
this.initFieldOptions(item)
}
},
initFieldOptions(item) {
if (item.field) {
if (item.field.deType === 0 || item.field.deType === 5) {
item.fieldOptions = this.fieldsByType.text
} else if (item.field.deType === 1) {
item.fieldOptions = this.fieldsByType.date
} else {
item.fieldOptions = this.fieldsByType.value
}
}
},
initFields() {
......@@ -355,8 +604,36 @@ export default {
this.fields = this.fields.concat(JSON.parse(this.chart.yaxis))
}
}
// 暂不支持时间
// this.fields = this.fields.filter(ele => ele.deType !== 1)
// 区分文本、数值、日期字段
this.fields.forEach(ele => {
// 视图字段和计数字段不可用
if (ele.chartId || ele.id === 'count') {
return;
}
if (ele.deType === 0 || ele.deType === 5) {
this.fieldsByType.text.push(ele)
} else if (ele.deType === 1) {
this.fieldsByType.date.push(ele)
} else {
this.fieldsByType.value.push(ele)
}
})
},
getSummaryOptions(deType) {
if (deType === 1) {
// 时间
return this.summaryOptions.filter(ele => {
return ele.id !== 'avg'
})
} else if (deType === 0 || deType === 5) {
// 文本、地理位置
return this.summaryOptions.filter(ele => {
return ele.id === 'value'
})
} else {
return this.summaryOptions
}
},
addThreshold() {
this.thresholdArr.push(JSON.parse(JSON.stringify(this.thresholdObj)))
......@@ -366,11 +643,40 @@ export default {
this.thresholdArr.splice(index, 1)
this.changeThreshold()
},
changeThreshold() {
this.$emit('onTableThresholdChange', this.thresholdArr)
},
changeThresholdField(item) {
if (item.field === '1') {
if (item.term === 'between') {
item.minField.curField = this.getQuotaField(item.minField.fieldId)
item.maxField.curField = this.getQuotaField(item.maxField.fieldId)
item.targetField = {};
} else {
item.targetField.curField = this.getQuotaField(item.targetField.fieldId)
item.minField = {};
item.maxField = {};
}
} else {
item.targetField = {};
item.minField = {};
item.maxField = {};
}
this.changeThreshold()
},
getQuotaField(id) {
if (!id) {
return {}
}
const fields = this.fields.filter(ele => {
return ele.id === id
})
if (fields.length === 0) {
return {}
} else {
return fields[0]
}
},
addConditions(item) {
item.conditions.push(JSON.parse(JSON.stringify(this.thresholdCondition)))
this.changeThreshold()
......@@ -379,7 +685,7 @@ export default {
item.conditions.splice(index, 1)
this.changeThreshold()
},
addField(item) {
onFieldChange(item) {
// get field
if (this.fields && this.fields.length > 0) {
this.fields.forEach(ele => {
......@@ -389,6 +695,10 @@ export default {
}
})
}
// 清空 term
item.conditions && item.conditions.forEach(ele => {
ele.term = ''
})
this.changeThreshold()
}
}
......@@ -424,16 +734,32 @@ span {
display: inline-block;
}
.between-item {
.select-item {
position: relative;
display: inline-block;
width: 90px !important;
width: 100px !important;
}
.select-item {
.item-long {
position: relative;
display: inline-block;
width: 100px !important;
width: 220px !important;
}
.item-long-between {
position: relative;
display: inline-block;
width: 200px !important;
}
.item-long:first-child,.item-short:first-child,.item-long-between:first-child {
margin-left: 10px;
}
.item-short {
position: relative;
display: inline-block;
width: 95px !important;
}
.el-select-dropdown__item {
......
......@@ -666,9 +666,14 @@ export default {
panelInfo() {
return this.$store.state.panel.panelInfo
},
isPlugin() {
const plugins = localStorage.getItem('plugin-views') && JSON.parse(localStorage.getItem('plugin-views')) || []
return plugins.some(plugin => plugin.value === this.view.type && plugin.render === this.view.render)
},
watchChartTypeChangeObj() {
const { type, render } = this.view
return { type, render }
const isPlugin = this.isPlugin
return { type, render, isPlugin }
}
},
watch: {
......@@ -691,12 +696,11 @@ export default {
// this.view.isPlugin = val && this.$refs['cu-chart-type'] && this.$refs['cu-chart-type'].currentIsPlugin(val)
// },
watchChartTypeChangeObj(newVal, oldVal) {
if (newVal.type === oldVal.type && newVal.render === oldVal.render) {
return
}
this.view.isPlugin =
this.$refs['cu-chart-type'] &&
this.$refs['cu-chart-type'].currentIsPlugin(newVal.type, newVal.render)
this.view.isPlugin = newVal.isPlugin
// if (newVal.type === oldVal.type && newVal.render === oldVal.render && newVal.isPlugin === oldVal.isPlugin) {
// return
// }
// this.view.isPlugin = this.$refs['cu-chart-type'] && this.$refs['cu-chart-type'].currentIsPlugin(newVal.type, newVal.render)
}
},
created() {
......@@ -726,20 +730,22 @@ export default {
this.getChartGroupTree()
},
methods: {
distinctArray(arr, key) {
const m = new Map()
for (const item of arr) {
if (!m.has(item[key])) {
m.set(item[key], item)
}
}
return [...m.values()]
},
loadPluginType() {
const plugins =
(localStorage.getItem('plugin-views') &&
JSON.parse(localStorage.getItem('plugin-views'))) ||
[]
const pluginOptions = plugins
.filter(
(plugin) =>
!this.renderOptions.some((option) => option.value === plugin.render)
)
.map((plugin) => {
return { name: plugin.render, value: plugin.render }
})
this.pluginRenderOptions = [...this.renderOptions, ...pluginOptions]
const plugins = localStorage.getItem('plugin-views') && JSON.parse(localStorage.getItem('plugin-views')) || []
const pluginOptions = plugins.filter(plugin => !this.renderOptions.some(option => option.value === plugin.render)).map(plugin => {
return { name: plugin.render, value: plugin.render }
})
const tempList = [...this.renderOptions, ...pluginOptions]
this.pluginRenderOptions = this.distinctArray(tempList, 'value')
},
clickAdd(param) {
this.currGroup = param.data
......
......@@ -29,6 +29,7 @@
@hide="hideTab"
>
<dataset-chart-detail
v-if="tabStatus"
type="chart"
:data="view"
:tab-status="tabStatus"
......@@ -640,17 +641,12 @@
$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' ||
view.type === 'waterfall' ||
view.type === 'area')
"
v-else-if="view.type && (view.type.includes('bar') || view.type.includes('line') || (view.type.includes('scatter') && view.render !== 'antv') || view.type === 'chart-mix' || view.type === 'waterfall' || view.type === 'area')"
>{{ $t('chart.drag_block_type_axis') }}</span>
<span
v-else-if="view.type && (view.type.includes('scatter') && view.render === 'antv')"
>{{ $t('chart.x_axis') }}</span>
<span
v-else-if="view.type && view.type.includes('pie')"
>{{ $t('chart.drag_block_pie_label') }}</span>
<span
......@@ -675,7 +671,10 @@
$t('chart.start_point')
}}</span>
<span v-show="view.type !== 'richTextView'"> / </span>
<span v-if="view.type && view.type !== 'table-info'">
<span
v-if="view.type && (view.type.includes('scatter') && view.render === 'antv')"
>{{ $t('chart.dimension_or_quota') }}</span>
<span v-else-if="view.type && view.type !== 'table-info'">
{{ $t('chart.dimension') }}
</span>
<span
......@@ -696,22 +695,41 @@
@update="calcData(true)"
>
<transition-group class="draggable-group">
<dimension-item
v-for="(item, index) in view.xaxis"
:key="item.id"
:param="param"
:index="index"
:item="item"
:dimension-data="dimension"
:quota-data="quota"
:chart="chart"
@onDimensionItemChange="dimensionItemChange"
@onDimensionItemRemove="dimensionItemRemove"
@editItemFilter="showDimensionEditFilter"
@onNameEdit="showRename"
@valueFormatter="valueFormatter"
@onCustomSort="onCustomSort"
/>
<template v-for="(item,index) in view.xaxis">
<quota-item
v-if="view.type === 'scatter' && item.groupType === 'q' && view.render === 'antv'"
:key="item.id"
:param="param"
:index="index"
:item="item"
:chart="chart"
:dimension-data="dimension"
:quota-data="quota"
special-type="dimension"
@onQuotaItemChange="dimensionItemChange"
@onQuotaItemRemove="dimensionItemRemove"
@editItemFilter="showQuotaEditFilter"
@onNameEdit="showRename"
@editItemCompare="showQuotaEditCompare"
@valueFormatter="valueFormatter"
/>
<dimension-item
v-else
:key="item.id"
:param="param"
:index="index"
:item="item"
:dimension-data="dimension"
:quota-data="quota"
:chart="chart"
@onDimensionItemChange="dimensionItemChange"
@onDimensionItemRemove="dimensionItemRemove"
@editItemFilter="showDimensionEditFilter"
@onNameEdit="showRename"
@valueFormatter="valueFormatter"
@onCustomSort="onCustomSort"
/>
</template>
</transition-group>
</draggable>
<div
......@@ -963,14 +981,29 @@
</el-row>
<!--extStack-->
<el-row
v-if="view.type && view.type.includes('stack')"
v-if="view.type && (view.type.includes('stack') || (view.type === 'scatter' && view.render === 'antv'))"
class="padding-lr"
style="margin-top: 6px"
>
<span class="data-area-label">
<span>{{ $t('chart.stack_item') }}</span>
<span v-if="view.type.includes('stack')">{{ $t('chart.stack_item') }}</span>
<span v-else>{{ $t('chart.form_type') }}</span>
/
<span>{{ $t('chart.dimension') }}</span>
<el-tooltip
v-if="view.type === 'scatter'"
class="item"
effect="dark"
placement="bottom"
>
<div slot="content">
{{ $t('chart.scatter_group_tip') }}
</div>
<i
class="el-icon-info"
style="cursor: pointer;color: #606266;"
/>
</el-tooltip>
<i
class="el-icon-arrow-down el-icon-delete data-area-clear"
@click="clearData('extStack')"
......@@ -2172,9 +2205,7 @@ export default {
return this.$store.state.panel.panelInfo
},
showCfg() {
return (
(includesAny(this.view.type, 'bar', 'line', 'area', 'gauge', 'table') &&
this.view.type !== 'race-bar') ||
return includesAny(this.view.type, 'bar', 'line', 'area', 'gauge', 'table', 'liquid') && this.view.type !== 'race-bar' ||
equalsAny(this.view.type, 'text', 'label', 'map', 'buddle-map')
)
},
......@@ -2197,8 +2228,7 @@ export default {
if (this.view.type === 'bidirectional-bar') {
return false
}
return (
includesAny(this.view.type, 'bar', 'line', 'area', 'gauge') ||
return includesAny(this.view.type, 'bar', 'line', 'area', 'gauge', 'liquid') ||
equalsAny(this.view.type, 'text', 'label') ||
(this.view.render === 'antv' && this.view.type.includes('table'))
)
......@@ -2210,8 +2240,7 @@ export default {
if (this.view.type === 'bidirectional-bar') {
return false
}
return (
includesAny(this.view.type, 'gauge') ||
return includesAny(this.view.type, 'gauge', 'liquid') ||
equalsAny(this.view.type, 'text', 'label') ||
(this.view.render === 'antv' && this.view.type.includes('table'))
)
......@@ -2234,9 +2263,15 @@ export default {
)
)
},
isPlugin() {
const plugins = localStorage.getItem('plugin-views') && JSON.parse(localStorage.getItem('plugin-views')) || []
return plugins.some(plugin => plugin.value === this.view.type && plugin.render === this.view.render)
},
watchChartTypeChangeObj() {
const { type, render } = this.view
return { type, render }
const isPlugin = this.isPlugin
const id = this.chart.id
return { type, render, isPlugin, id }
},
...mapState(['curComponent', 'panelViewEditInfo', 'allViewRender'])
},
......@@ -2270,21 +2305,33 @@ export default {
this.$emit('typeChange', newVal)
},
watchChartTypeChangeObj(newVal, oldVal) {
if (newVal.type === oldVal.type && newVal.render === oldVal.render) {
this.view.isPlugin = newVal.isPlugin
if (newVal.id === oldVal.id && newVal.type !== oldVal.type && oldVal.type === 'table-info' && this.view.xaxis.length > 0) {
// 针对明细表切换为其他图表
this.$message({
showClose: true,
message: this.$t('chart.table_info_switch'),
type: 'warning'
})
this.view.xaxis = []
}
if (newVal.id === oldVal.id && newVal.type !== oldVal.type) {
this.view.senior.threshold = {}
}
if (newVal.type === oldVal.type && newVal.render === oldVal.render && newVal.isPlugin === oldVal.isPlugin) {
return
}
this.view.isPlugin =
this.$refs['cu-chart-type'] &&
this.$refs['cu-chart-type'].currentIsPlugin(newVal.type, newVal.render)
this.setChartDefaultOptions()
this.calcData(
true,
'chart',
true,
newVal.type !== oldVal.type,
newVal.render !== oldVal.render
)
if (newVal.render === 'antv' && newVal.type === 'chart-mix') {
// 针对antv组合图,清理自定义排序
this.view.xaxis.forEach(x => {
x.customSort = []
x.sort = 'none'
})
}
if (oldVal.id !== 'echart') {
this.setChartDefaultOptions()
this.calcData(true, 'chart', true, newVal.type !== oldVal.type, newVal.render !== oldVal.render)
}
}
},
created() {
......@@ -2341,19 +2388,21 @@ export default {
this.currentAreaCode = code
},
loadPluginType() {
const plugins =
(localStorage.getItem('plugin-views') &&
JSON.parse(localStorage.getItem('plugin-views'))) ||
[]
const pluginOptions = plugins
.filter(
(plugin) =>
!this.renderOptions.some((option) => option.value === plugin.render)
)
.map((plugin) => {
return { name: plugin.render, value: plugin.render }
})
this.pluginRenderOptions = [...this.renderOptions, ...pluginOptions]
const plugins = localStorage.getItem('plugin-views') && JSON.parse(localStorage.getItem('plugin-views')) || []
const pluginOptions = plugins.filter(plugin => !this.renderOptions.some(option => option.value === plugin.render)).map(plugin => {
return { name: plugin.render, value: plugin.render }
})
const tempList = [...this.renderOptions, ...pluginOptions]
this.pluginRenderOptions = this.distinctArray(tempList, 'value')
},
distinctArray(arr, key) {
const m = new Map()
for (const item of arr) {
if (!m.has(item[key])) {
m.set(item[key], item)
}
}
return [...m.values()]
},
emptyTableData(id) {
this.table = {}
......@@ -2525,21 +2574,7 @@ export default {
) {
this.view.resultCount = '1000'
}
if (switchType) {
this.view.senior.threshold = {}
}
if (
switchType &&
(this.view.type === 'table-info' || this.chart.type === 'table-info') &&
this.view.xaxis.length > 0
) {
this.$message({
showClose: true,
message: this.$t('chart.table_info_switch'),
type: 'warning'
})
this.view.xaxis = []
}
const view = JSON.parse(JSON.stringify(this.view))
view.id = this.view.id
view.sceneId = this.view.sceneId
......@@ -2565,6 +2600,20 @@ export default {
if (!ele.filter) {
ele.filter = []
}
if (view.type === 'scatter') {
if (ele.chartId) {
ele.summary = ''
} else {
if (!ele.summary || ele.summary === '') {
if (ele.id === 'count' || ele.deType === 0 || ele.deType === 1) {
ele.summary = 'count'
} else {
ele.summary = 'sum'
}
}
}
}
})
if (
equalsAny(
......@@ -3108,7 +3157,7 @@ export default {
onThresholdChange(val) {
this.view.senior.threshold = val
this.calcStyle()
this.calcData()
},
onScrollChange(val) {
......@@ -3192,6 +3241,9 @@ export default {
} else if (this.quotaItem.filterType === 'quotaExt') {
this.view.yaxisExt[this.quotaItem.index].filter = this.quotaItem.filter
this.view.yaxisExt[this.quotaItem.index].logic = this.quotaItem.logic
} else if (this.quotaItem.filterType === 'dimension') {
this.view.xaxis[this.quotaItem.index].filter = this.quotaItem.filter
this.view.xaxis[this.quotaItem.index].logic = this.quotaItem.logic
}
this.calcData(true)
this.closeQuotaFilter()
......@@ -3304,8 +3356,9 @@ export default {
this.view.yaxis[this.quotaItemCompare.index].compareCalc =
this.quotaItemCompare.compareCalc
} else if (this.quotaItemCompare.calcType === 'quotaExt') {
this.view.yaxisExt[this.quotaItemCompare.index].compareCalc =
this.quotaItemCompare.compareCalc
this.view.yaxisExt[this.quotaItemCompare.index].compareCalc = this.quotaItemCompare.compareCalc
} else if (this.quotaItemCompare.calcType === 'dimension') {
this.view.xaxis[this.quotaItemCompare.index].compareCalc = this.quotaItemCompare.compareCalc
}
this.calcData(true)
this.closeQuotaEditCompare()
......@@ -3464,16 +3517,18 @@ export default {
}
},
addXaxis(e) {
if (this.view.type !== 'table-info') {
if (this.view.type !== 'table-info' && (this.view.type !== 'scatter' && this.view.render !== 'antv')) {
this.dragCheckType(this.view.xaxis, 'd')
}
this.dragMoveDuplicate(this.view.xaxis, e)
if (
(this.view.type === 'map' ||
this.view.type === 'word-cloud' ||
this.view.type === 'label') &&
this.view.xaxis.length > 1
) {
if (this.view.type === 'scatter' && this.view.render === 'antv') {
if (this.view.xaxis[0] && this.view.xaxis[0].groupType === 'q') {
this.view.xaxis = [this.view.xaxis[0]]
} else {
this.dragCheckType(this.view.xaxis, 'd')
}
}
if ((this.view.type === 'map' || this.view.type === 'word-cloud' || this.view.type === 'label') && this.view.xaxis.length > 1) {
this.view.xaxis = [this.view.xaxis[0]]
}
this.calcData(true)
......@@ -3804,10 +3859,14 @@ export default {
})
},
changeChartRender() {
// Do Nothing
// 调整为监听 watchChartTypeChangeObj
// this.setChartDefaultOptions()
// this.calcData(true, 'chart', true, false, true)
},
changeChartType() {
// Do Nothing
// 调整为监听 watchChartTypeChangeObj
// this.setChartDefaultOptions()
// this.calcData(true, 'chart', true, true)
},
setChartDefaultOptions() {
......
<template>
<de-container
v-loading="$store.getters.loadingMap[$store.getters.currentPath]"
class="de-earth"
>
<div class="de-map-tips">
<el-alert
:title="$t('map_setting.prohibit_prompts')"
type="warning"
description=""
:closable="false"
show-icon
/>
</div>
<de-aside-container
type="mapset"
class="map-setting-aside"
>
<map-setting-left
ref="map_setting_tree"
:tree-data="treeData"
@emit-add="emitAdd"
@refresh-tree="refreshTree"
@show-node-info="loadForm"
/>
</de-aside-container>
<de-main-container
class="map-setting-main"
>
<map-setting-right
ref="map_setting_form"
:tree-data="treeData"
:status="formStatus"
@refresh-tree="refreshTree"
/>
</de-main-container>
</de-container>
</template>
<script>
import DeMainContainer from '@/components/dataease/DeMainContainer'
import DeContainer from '@/components/dataease/DeContainer'
import DeAsideContainer from '@/components/dataease/DeAsideContainer'
import { areaMapping } from '@/api/map/map'
import MapSettingLeft from './MapSettingLeft'
import MapSettingRight from './MapSettingRight'
export default {
name: 'MapSetting',
components: { DeMainContainer, DeContainer, DeAsideContainer, MapSettingLeft, MapSettingRight },
data() {
return {
formStatus: 'empty',
treeData: []
}
},
created() {
this.loadTreeData()
},
methods: {
emitAdd(form) {
this.setStatus(form.status)
this.$refs['map_setting_form']?.emitAdd(form)
},
loadForm(nodeInfo) {
this.setStatus(nodeInfo.status)
this.$refs['map_setting_form']?.loadForm(nodeInfo)
},
setStatus(status) {
this.formStatus = status
},
loadTreeData() {
!Object.keys(this.treeData).length && areaMapping().then(res => {
this.treeData = res.data
})
},
refreshTree(node) {
areaMapping().then(res => {
this.treeData = res.data
if (!node?.code) return
this.$refs['map_setting_tree']?.showNewNode(node.code)
})
}
}
}
</script>
<style lang="scss" scoped>
.de-earth {
width: 100%;
height: 100%;
overflow: auto;
.de-map-tips {
position: absolute;
width: calc(100% - 310px);
}
.map-setting-aside {
top: 50px;
height: calc(100% - 50px) !important;
}
.map-setting-main {
margin-top: 50px;
height: calc(100% - 50px);
}
}
</style>
<template>
<el-container
v-loading="loading"
class="online-map-container"
>
<el-aside class="aside-form">
<div class="form-title">
<span>{{ $t('online_map.onlinemap') }}</span>
</div>
<div class="online-form-item">
<span class="form-label">Key</span>
<el-input
v-model="key"
size="small"
/>
</div>
<el-button
type="primary"
:disabled="!key"
@click="saveHandler"
>{{ $t('commons.save') }}</el-button>
</el-aside>
<el-divider
direction="vertical"
class="online-divider"
/>
<el-main class="main-content">
<div
v-show="mapLoaded"
v-if="!mapReloading"
:id="domId"
class="map-gaode-demo"
/>
<el-empty
v-if="!mapLoaded"
:description="$t('online_map.empty_desc')"
/>
</el-main>
</el-container>
</template>
<script>
import { saveMapKey, queryMapKey } from '@/api/map/map'
export default {
name: 'OnlineMap',
data() {
return {
key: '',
secret: '',
mapLoaded: false,
mapInstance: null,
domId: 'qwertyuiop',
mapReloading: false,
loading: false
}
},
mounted() {
this.initLoad()
},
methods: {
loadMap() {
if (!this.key) {
return
}
const mykey = this.key
const url = `https://webapi.amap.com/maps?v=2.0&key=${mykey}`
this.loadScript(url).then(res => {
if (this.mapInstance) {
this.mapInstance.destroy()
this.mapInstance = null
this.mapReloading = true
setTimeout(() => {
this.domId = this.domId + '-de-'
this.mapReloading = false
this.$nextTick(() => {
this.createMapInstance()
})
}, 1500)
return
}
this.createMapInstance()
}).catch(e => {
if (this.mapInstance) {
this.mapInstance.destroy()
this.mapInstance = null
}
console.error(e)
})
},
createMapInstance() {
this.mapInstance = new window.AMap.Map(this.domId, {
viewMode: '2D',
zoom: 11,
center: [116.397428, 39.90923]
})
this.mapLoaded = true
},
saveHandler() {
this.loading = true
saveMapKey({ key: this.key }).then(() => {
this.$message({
message: this.$t('commons.save_success'),
type: 'success',
showClose: true
})
this.initLoad()
}).catch(e => {
console.error(e)
}).finally(() => {
this.loading = false
})
},
initLoad() {
console.log('map load ...')
queryMapKey().then(res => {
this.key = res.data
this.loadMap()
}).catch(e => {
console.error(e)
})
},
loadScript(url) {
return new Promise(function(resolve, reject) {
const scriptId = 'de-gaode-script-id'
let dom = document.getElementById(scriptId)
if (dom) {
dom.parentElement.removeChild(dom)
dom = null
window.AMap = null
// return resolve()
}
var script = document.createElement('script')
script.id = scriptId
script.onload = function() {
return resolve()
}
script.onerror = function() {
return reject(new Error('Load script from '.concat(url, ' failed')))
}
script.src = url
var head = document.head || document.getElementsByTagName('head')[0];
(document.body || head).appendChild(script)
})
}
}
}
</script>
<style lang="scss" scoped>
.online-map-container {
height: 100%;
.online-divider {
height: calc(100% - 139px);
position: absolute;
top: 112px;
margin: 0 0 0 330px;
}
.aside-form {
width: 320px !important;
padding: 0 10px;
height: 100%;
.form-title {
font-size: 16px;
font-weight: 500;
line-height: 24px;
color: #1F2329;
margin-bottom: 10px;
}
.online-form-item {
font-size: 14px;
.form-title {
font-weight: 400;
color: 1F2329;
line-height: 22px;
}
height: 62px;
margin-bottom: 10px;
}
}
.main-content {
width: 100%;
height: 100%;
margin-left: 13px;
.map-gaode-demo {
width: 100%;
height: 100%;
.de-map-iframe {
width: 100%;
height: 100%;
border: none;
}
}
}
}
</style>
<template>
<de-container
v-loading="$store.getters.loadingMap[$store.getters.currentPath]"
class="de-earth"
style="height: calc(100vh - 200px);"
>
<div class="de-map-tips">
<el-alert
:title="$t('map_setting.prohibit_prompts')"
type="warning"
description=""
:closable="false"
show-icon
/>
</div>
<de-aside-container
type="mapset"
class="map-setting-aside"
>
<map-setting-left
ref="map_setting_tree"
:tree-data="treeData"
@emit-add="emitAdd"
@refresh-tree="refreshTree"
@show-node-info="loadForm"
/>
</de-aside-container>
<el-container class="map-setting-container">
<el-aside class="map-setting-left">
<div class="left-container">
<de-main-container
class="map-setting-main"
>
<map-setting-right
ref="map_setting_form"
:tree-data="treeData"
:status="formStatus"
@refresh-tree="refreshTree"
/>
</de-main-container>
</de-container>
<div
v-for="(item, index) in leftOptions"
:key="item.id"
class="left-menu-item"
:class="{'active': activeIndex === item.id}"
@click="selectHandler(index)"
>
<span>{{ $t(item.name) }}</span>
</div>
</div>
</el-aside>
<el-main class="map-setting-right">
<div class="right-container">
<OnlineMap v-if="activeIndex" />
<geometry v-else />
</div>
</el-main>
</el-container>
</template>
<script>
import DeMainContainer from '@/components/dataease/DeMainContainer'
import DeContainer from '@/components/dataease/DeContainer'
import DeAsideContainer from '@/components/dataease/DeAsideContainer'
import { areaMapping } from '@/api/map/map'
import MapSettingLeft from './MapSettingLeft'
import MapSettingRight from './MapSettingRight'
import Geometry from './Geometry'
import OnlineMap from './OnlineMap'
export default {
name: 'MapSetting',
components: { DeMainContainer, DeContainer, DeAsideContainer, MapSettingLeft, MapSettingRight },
components: { Geometry, OnlineMap },
data() {
return {
formStatus: 'empty',
treeData: []
leftOptions: [
{ id: 0, name: 'online_map.geometry' },
{ id: 1, name: 'online_map.onlinemap' }
],
activeIndex: 0
}
},
created() {
this.loadTreeData()
},
methods: {
emitAdd(form) {
this.setStatus(form.status)
this.$refs['map_setting_form']?.emitAdd(form)
},
loadForm(nodeInfo) {
this.setStatus(nodeInfo.status)
this.$refs['map_setting_form']?.loadForm(nodeInfo)
},
setStatus(status) {
this.formStatus = status
},
loadTreeData() {
!Object.keys(this.treeData).length && areaMapping().then(res => {
this.treeData = res.data
})
},
refreshTree(node) {
areaMapping().then(res => {
this.treeData = res.data
if (!node?.code) return
this.$refs['map_setting_tree']?.showNewNode(node.code)
})
selectHandler(index) {
this.activeIndex = index
}
}
}
</script>
<style lang="scss" scoped>
.de-earth {
padding: 24px;
.map-setting-container {
width: 100%;
overflow: auto;
.de-map-tips {
position: absolute;
width: calc(100% - 135px);
}
.map-setting-aside {
top: 50px;
height: calc(100% - 40px) !important;
height: 100%;
padding-bottom: 0px !important;
.map-setting-left {
width: 200px !important;
height: calc(100% + 20px);
border-right: 1px solid #1f232926;
.left-container {
padding: 16px 16px 16px 16px;
width: 100%;
height: 100%;
.left-menu-item {
width: 168px;
height: 40px;
padding: 9px 8px;
line-height: 22px;
border-radius: 4px;
font-size: 14px;
font-weight: 400;
cursor: pointer;
&:hover {
background: #1f232926;
}
}
.active {
background: #3370FF1A;
color: #3370FF;
font-weight: 500;
}
}
}
.map-setting-main {
margin-top: 50px;
height: calc(100% - 50px);
.map-setting-right {
padding-bottom: 0 !important;
.right-container {
height: 100%;
}
}
}
</style>
......@@ -18,6 +18,7 @@ const port = process.env.port || process.env.npm_config_port || 9528 // dev port
const parallel = process.env.NODE_ENV === 'development'
module.exports = {
productionSourceMap: false,
publicPath: process.env.VUE_CONTEXT_PATH,
parallel,
// 使用mock-server
devServer: {
......@@ -62,7 +63,6 @@ module.exports = {
},
output: process.env.NODE_ENV === 'development' ? {} : {
filename: `js/[name].[contenthash:8].${pkg.version}.js`,
publicPath: '/',
chunkFilename: `js/[name].[contenthash:8].${pkg.version}.js`
},
plugins: [
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论