|
@@ -5,7 +5,10 @@
|
|
|
label-position="left"
|
|
|
>
|
|
|
<el-form-item label="场景名或完整url">
|
|
|
- <el-input v-model="sceneNameOrUrl" />
|
|
|
+ <el-input
|
|
|
+ v-model="sceneNameOrUrl"
|
|
|
+ autofocus
|
|
|
+ />
|
|
|
</el-form-item>
|
|
|
<el-button
|
|
|
type="primary"
|
|
@@ -35,17 +38,17 @@
|
|
|
显示路径
|
|
|
</el-button>
|
|
|
<el-button @click="onResetPath">
|
|
|
- Reset
|
|
|
+ 清空
|
|
|
</el-button>
|
|
|
</el-form>
|
|
|
<el-form
|
|
|
class="form3"
|
|
|
label-position="top"
|
|
|
>
|
|
|
- <el-form-item label="起点坐标(以英文逗号分隔)(红色小圆圈表示)">
|
|
|
+ <el-form-item label="起点坐标(以英文逗号分隔)(浅绿色小圆圈表示)">
|
|
|
<el-input v-model="formData.startPoint" />
|
|
|
</el-form-item>
|
|
|
- <el-form-item label="终点坐标(以英文逗号分隔)(绿色小圆圈表示)">
|
|
|
+ <el-form-item label="终点坐标(以英文逗号分隔)(深绿色小圆圈表示)">
|
|
|
<el-input v-model="formData.endPoint" />
|
|
|
</el-form-item>
|
|
|
<el-button
|
|
@@ -55,7 +58,7 @@
|
|
|
显示起点终点
|
|
|
</el-button>
|
|
|
<el-button @click="onResetStartEndPoint">
|
|
|
- Reset
|
|
|
+ 清空
|
|
|
</el-button>
|
|
|
</el-form>
|
|
|
</div>
|
|
@@ -65,27 +68,63 @@
|
|
|
</div>
|
|
|
<div class="map">
|
|
|
<div class="svgWrapper" />
|
|
|
- <div class="button-group">
|
|
|
- <el-button
|
|
|
- class="btn"
|
|
|
- type="primary"
|
|
|
- @click="zoomInToStartPoint"
|
|
|
+ <div class="map-control-area">
|
|
|
+ <div class="zoom-control panel">
|
|
|
+ 聚焦操作
|
|
|
+ <el-button
|
|
|
+ class="btn"
|
|
|
+ type="primary"
|
|
|
+ @click="zoomInToStartPoint"
|
|
|
+ >
|
|
|
+ 聚焦到起点
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ class="btn"
|
|
|
+ type="primary"
|
|
|
+ @click="zoomInToEndPoint"
|
|
|
+ >
|
|
|
+ 聚焦到终点
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ class="btn"
|
|
|
+ @click="resetZoom"
|
|
|
+ >
|
|
|
+ 取消聚焦
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ <el-form
|
|
|
+ class="height-filter panel"
|
|
|
+ label-position="top"
|
|
|
>
|
|
|
- zoom in到起点
|
|
|
- </el-button>
|
|
|
- <el-button
|
|
|
- class="btn"
|
|
|
- type="primary"
|
|
|
- @click="zoomInToEndPoint"
|
|
|
- >
|
|
|
- zoom in到终点
|
|
|
- </el-button>
|
|
|
- <el-button
|
|
|
- clas="btn"
|
|
|
- @click="resetZoom"
|
|
|
- >
|
|
|
- reset zoom
|
|
|
- </el-button>
|
|
|
+ 高度筛选
|
|
|
+ <el-form-item
|
|
|
+ :label="`高度上限`"
|
|
|
+ >
|
|
|
+ <el-input
|
|
|
+ v-model="formData.maxHeight"
|
|
|
+ type="number"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item
|
|
|
+ :label="`高度下限`"
|
|
|
+ >
|
|
|
+ <el-input
|
|
|
+ v-model="formData.minHeight"
|
|
|
+ type="number"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <div class="btn-group">
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ @click="onSetHeightFilter"
|
|
|
+ >
|
|
|
+ 确定
|
|
|
+ </el-button>
|
|
|
+ <el-button @click="onResetHeightFilter">
|
|
|
+ 清空
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </el-form>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
@@ -100,7 +139,7 @@ const LENGTH_PER_POINT = 0.36
|
|
|
// 视口尺寸
|
|
|
let svgWidth = document.documentElement.clientWidth - 200
|
|
|
let svgHeight = document.documentElement.clientHeight - 280
|
|
|
-let viewportRatio = svgWidth / svgHeight
|
|
|
+let svgRatio = svgWidth / svgHeight
|
|
|
|
|
|
let pxPerUnitLength = 0 // 原始单位长度对应的像素数
|
|
|
let rawWholeData = []
|
|
@@ -130,7 +169,7 @@ export default {
|
|
|
name: 'App',
|
|
|
data() {
|
|
|
return {
|
|
|
- sceneNameOrUrl: 'SS-t-XkquhxxurM',
|
|
|
+ sceneNameOrUrl: 'SS-t-NZUICC2fRLi',
|
|
|
infoText: '',
|
|
|
loadingHandler: null,
|
|
|
formData: {
|
|
@@ -138,6 +177,8 @@ export default {
|
|
|
path2: '',
|
|
|
startPoint: '-38.5, 10.8',
|
|
|
endPoint: '-28.4, 12.2',
|
|
|
+ maxHeight: '',
|
|
|
+ minHeight: '',
|
|
|
}
|
|
|
}
|
|
|
},
|
|
@@ -252,11 +293,16 @@ export default {
|
|
|
})
|
|
|
let yLength = Math.max(...yArray) - Math.min(...yArray)
|
|
|
yCenter = (Math.max(...yArray) + Math.min(...yArray)) / 2
|
|
|
+ let zArray = rawWholeData.map((eachPoint) => {
|
|
|
+ return eachPoint.z
|
|
|
+ })
|
|
|
+ let zLength = Math.max(...zArray) - Math.min(...zArray)
|
|
|
+ let zMin = Math.min(...zArray)
|
|
|
|
|
|
let areaRatio = xLength / yLength
|
|
|
|
|
|
// 各个点坐标映射到视口坐标
|
|
|
- if (viewportRatio >= areaRatio) { // 分布范围应略小于svg尺寸
|
|
|
+ if (svgRatio >= areaRatio) { // 分布范围应略小于svg尺寸
|
|
|
pxPerUnitLength = svgHeight / yLength * 0.9
|
|
|
} else {
|
|
|
pxPerUnitLength = svgWidth / xLength * 0.9
|
|
@@ -271,7 +317,7 @@ export default {
|
|
|
// 组合成最终数据用来渲染
|
|
|
for (let index = 0; index < rawWholeData.length; index++) {
|
|
|
console.assert(rawWholeData[index].id === (index + 1), '数据点id和数据点在数组中的位置不相符!')
|
|
|
- wholeDataForRender.push([wholeXArrayInPx[index], wholeYArrayInPx[index], JSON.stringify(rawWholeData[index]), rawWholeData[index].id])
|
|
|
+ wholeDataForRender.push([wholeXArrayInPx[index], wholeYArrayInPx[index], zArray[index], JSON.stringify(rawWholeData[index]), rawWholeData[index].id])
|
|
|
}
|
|
|
|
|
|
gNode.selectAll('rect').data(wholeDataForRender).enter().append('rect')
|
|
@@ -279,7 +325,9 @@ export default {
|
|
|
.attr('y', (d) => d[1] - LENGTH_PER_POINT * pxPerUnitLength / 2)
|
|
|
.attr('width', LENGTH_PER_POINT * pxPerUnitLength)
|
|
|
.attr('height', LENGTH_PER_POINT * pxPerUnitLength)
|
|
|
- .attr('fill', 'black')
|
|
|
+ .attr('fill', (d) => {
|
|
|
+ return `rgba(${Math.round((d[2] -zMin) / zLength * 255)}, 0, 0, 1)`
|
|
|
+ })
|
|
|
.attr('render-data', (d) => {
|
|
|
return d
|
|
|
})
|
|
@@ -290,7 +338,9 @@ export default {
|
|
|
let renderDataItemArray = renderDataItem.split(',')
|
|
|
that.infoText = `数据点id: ${renderDataItemArray[renderDataItemArray.length - 1]}, \n具体值: ${renderDataItem.match(/^[^{]+(\{.+\})[^}]+$/)[1]}`
|
|
|
}).on('mouseleave', function (e) {
|
|
|
- d3.select(this).attr('fill', 'black')
|
|
|
+ d3.select(this).attr('fill', (d) => {
|
|
|
+ return `rgba(${Math.round((d[2] -zMin) / zLength * 255)}, 0, 0, 1)`
|
|
|
+ })
|
|
|
that.infoText = ''
|
|
|
})
|
|
|
|
|
@@ -446,7 +496,7 @@ export default {
|
|
|
.attr('cx', (d) => d[0])
|
|
|
.attr('cy', (d) => d[1])
|
|
|
.attr('r', LENGTH_PER_POINT * pxPerUnitLength / 3.5)
|
|
|
- .attr('fill', 'red')
|
|
|
+ .attr('fill', 'rgba(50, 255, 50, 1)')
|
|
|
.attr('pointer-events', 'none')
|
|
|
}
|
|
|
|
|
@@ -490,6 +540,24 @@ export default {
|
|
|
zoomObj.transform,
|
|
|
d3.zoomIdentity.scale(1)
|
|
|
)
|
|
|
+ },
|
|
|
+ onSetHeightFilter() {
|
|
|
+ gNode.selectAll('rect').attr('visibility', (d) => {
|
|
|
+ if ((this.formData.maxHeight !== '') && (this.formData.maxHeight < d[2])) {
|
|
|
+ return 'hidden'
|
|
|
+ } else if ((this.formData.minHeight !== '') && (this.formData.minHeight > d[2])) {
|
|
|
+ return 'hidden'
|
|
|
+ } else {
|
|
|
+ return 'visible'
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ onResetHeightFilter() {
|
|
|
+ this.formData.maxHeight = ''
|
|
|
+ this.formData.minHeight = ''
|
|
|
+ gNode.selectAll('rect').attr('visibility', (d) => {
|
|
|
+ return 'visible'
|
|
|
+ })
|
|
|
}
|
|
|
},
|
|
|
}
|
|
@@ -523,15 +591,30 @@ export default {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
}
|
|
|
-.map .button-group {
|
|
|
+.map > .map-control-area {
|
|
|
+ margin-left: 20px;
|
|
|
+}
|
|
|
+.map > .map-control-area > .panel {
|
|
|
+ border: 1px solid black;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
justify-content: center;
|
|
|
align-items: center;
|
|
|
+ margin-bottom: 15px;
|
|
|
}
|
|
|
-.map .button-group .btn {
|
|
|
+.map > .map-control-area > .panel > .btn {
|
|
|
margin: 10px;
|
|
|
}
|
|
|
+.map > .map-control-area > .panel.height-filter {
|
|
|
+ padding-left: 10px;
|
|
|
+ padding-right: 10px;
|
|
|
+}
|
|
|
+.map > .map-control-area > .panel.height-filter > .btn-group {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin-bottom: 10px;
|
|
|
+}
|
|
|
+
|
|
|
.svgWrapper {
|
|
|
display: inline-block;
|
|
|
overflow: hidden;
|