|
@@ -214,15 +214,27 @@ let brushRightPx = 0
|
|
|
let brushBottomPx = 0
|
|
|
|
|
|
function resetGlobalVars() {
|
|
|
- pxPerUnitLength = 0 // 原始单位长度对应的像素数
|
|
|
+ // 视口尺寸
|
|
|
+ svgWidth = document.documentElement.clientWidth - 200
|
|
|
+ svgHeight = document.documentElement.clientHeight - 280
|
|
|
+ svgRatio = svgWidth / svgHeight
|
|
|
+
|
|
|
+ // 全体点位数据
|
|
|
rawWholeData = []
|
|
|
wholeDataForRender = []
|
|
|
- xCenter = 0
|
|
|
- yCenter = 0
|
|
|
- startPoint = null
|
|
|
- endPoint = null
|
|
|
- pointDistance = 0
|
|
|
- rowSlope = 0
|
|
|
+
|
|
|
+ // 由原始数据算出的几何信息
|
|
|
+ pxPerUnitLength = 0 // 原始数据1单位长度对应的像素数
|
|
|
+ pointDistance = 0 // 最近相邻点间距离(单位:原始数据中长度单位)
|
|
|
+ rowSlope = 0 // 点位构成的排的斜率 [0deg, 90deg)
|
|
|
+ xCenter = 0
|
|
|
+ yCenter = 0
|
|
|
+
|
|
|
+ // d3选择框位置
|
|
|
+ brushLeftPx = 0
|
|
|
+ brushTopPx = 0
|
|
|
+ brushRightPx = 0
|
|
|
+ brushBottomPx = 0
|
|
|
}
|
|
|
|
|
|
function zoomed({transform}) {
|
|
@@ -373,85 +385,95 @@ export default {
|
|
|
gNode.selectAll('circle').remove()
|
|
|
|
|
|
|
|
|
- const that = this
|
|
|
getWholeData(this.sceneNameOrUrl).then((res) => {
|
|
|
rawWholeData = res
|
|
|
+ this.renderWholePoints()
|
|
|
+ }).finally(() => {
|
|
|
+ this.loadingHandler.close()
|
|
|
+ })
|
|
|
+ },
|
|
|
+ renderWholePoints() {
|
|
|
+ const that = this
|
|
|
|
|
|
- // 相邻点位间距离
|
|
|
- const temp = computePointDistanceAndRowSlope(rawWholeData)
|
|
|
- pointDistance = temp[0]
|
|
|
- rowSlope = temp[1]
|
|
|
-
|
|
|
- // 所有点的分布情况
|
|
|
- let xArray = rawWholeData.map((eachPoint) => {
|
|
|
- return eachPoint.x
|
|
|
- })
|
|
|
- let xLength = Math.max(...xArray) - Math.min(...xArray)
|
|
|
- xCenter = (Math.max(...xArray) + Math.min(...xArray)) / 2
|
|
|
+ // 相邻点位间距离
|
|
|
+ const temp = computePointDistanceAndRowSlope(rawWholeData)
|
|
|
+ pointDistance = temp[0]
|
|
|
+ rowSlope = temp[1]
|
|
|
+
|
|
|
+ // 所有点的分布情况
|
|
|
+ let xArray = rawWholeData.map((eachPoint) => {
|
|
|
+ return eachPoint.x
|
|
|
+ })
|
|
|
+ let xLength = Math.max(...xArray) - Math.min(...xArray)
|
|
|
+ xCenter = (Math.max(...xArray) + Math.min(...xArray)) / 2
|
|
|
|
|
|
- let yArray = rawWholeData.map((eachPoint) => {
|
|
|
- return eachPoint.y
|
|
|
- })
|
|
|
- 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
|
|
|
+ let yArray = rawWholeData.map((eachPoint) => {
|
|
|
+ return eachPoint.y
|
|
|
+ })
|
|
|
+ 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 (svgRatio >= areaRatio) { // 分布范围应略小于svg尺寸
|
|
|
- pxPerUnitLength = svgHeight / yLength * 0.9
|
|
|
- } else {
|
|
|
- pxPerUnitLength = svgWidth / xLength * 0.9
|
|
|
- }
|
|
|
- let wholeXArrayInPx = xArray.map((eachX) => {
|
|
|
- return (eachX - xCenter) * pxPerUnitLength + svgWidth / 2
|
|
|
+ // 各个点坐标映射到视口坐标
|
|
|
+ if (svgRatio >= areaRatio) { // 分布范围应略小于svg尺寸
|
|
|
+ pxPerUnitLength = svgHeight / yLength * 0.9
|
|
|
+ } else {
|
|
|
+ pxPerUnitLength = svgWidth / xLength * 0.9
|
|
|
+ }
|
|
|
+ let wholeXArrayInPx = xArray.map((eachX) => {
|
|
|
+ return (eachX - xCenter) * pxPerUnitLength + svgWidth / 2
|
|
|
+ })
|
|
|
+ let wholeYArrayInPx = yArray.map((eachY) => {
|
|
|
+ return (eachY - yCenter) * pxPerUnitLength + svgHeight / 2
|
|
|
+ })
|
|
|
+
|
|
|
+ // 组合成最终数据用来渲染
|
|
|
+ for (let index = 0; index < rawWholeData.length; index++) {
|
|
|
+ console.assert(rawWholeData[index].id === (index + 1), '数据点id和数据点在数组中的位置不相符!')
|
|
|
+ wholeDataForRender.push([
|
|
|
+ wholeXArrayInPx[index],
|
|
|
+ wholeYArrayInPx[index],
|
|
|
+ zArray[index],
|
|
|
+ rawWholeData[index].isManuallyAdded,
|
|
|
+ JSON.stringify(rawWholeData[index]),
|
|
|
+ rawWholeData[index].id
|
|
|
+ ])
|
|
|
+ }
|
|
|
+
|
|
|
+ gNode.selectAll('rect').data(wholeDataForRender).enter().append('rect')
|
|
|
+ .attr('x', (d) => d[0] - pointDistance * pxPerUnitLength / 2)
|
|
|
+ .attr('y', (d) => d[1] - pointDistance * pxPerUnitLength / 2)
|
|
|
+ .attr('width', pointDistance * pxPerUnitLength)
|
|
|
+ .attr('height', pointDistance * pxPerUnitLength)
|
|
|
+ .attr('fill', (d) => {
|
|
|
+ return `rgba(${Math.round((d[2] -zMin) / zLength * 255)}, 0, 0, ${d[3] ? '0.7' : '1'})`
|
|
|
})
|
|
|
- let wholeYArrayInPx = yArray.map((eachY) => {
|
|
|
- return (eachY - yCenter) * pxPerUnitLength + svgHeight / 2
|
|
|
+ .attr('render-data', (d) => {
|
|
|
+ return d
|
|
|
})
|
|
|
|
|
|
- // 组合成最终数据用来渲染
|
|
|
- for (let index = 0; index < rawWholeData.length; index++) {
|
|
|
- console.assert(rawWholeData[index].id === (index + 1), '数据点id和数据点在数组中的位置不相符!')
|
|
|
- wholeDataForRender.push([wholeXArrayInPx[index], wholeYArrayInPx[index], zArray[index], JSON.stringify(rawWholeData[index]), rawWholeData[index].id])
|
|
|
- }
|
|
|
-
|
|
|
- gNode.selectAll('rect').data(wholeDataForRender).enter().append('rect')
|
|
|
- .attr('x', (d) => d[0] - pointDistance * pxPerUnitLength / 2)
|
|
|
- .attr('y', (d) => d[1] - pointDistance * pxPerUnitLength / 2)
|
|
|
- .attr('width', pointDistance * pxPerUnitLength)
|
|
|
- .attr('height', pointDistance * pxPerUnitLength)
|
|
|
- .attr('fill', (d) => {
|
|
|
- return `rgba(${Math.round((d[2] -zMin) / zLength * 255)}, 0, 0, 1)`
|
|
|
- })
|
|
|
- .attr('render-data', (d) => {
|
|
|
- return d
|
|
|
- })
|
|
|
-
|
|
|
- gNode.selectAll('rect').on('mouseover', function(e) {
|
|
|
- d3.select(this).attr('fill', 'orange')
|
|
|
- let renderDataItem = e.target.attributes['render-data'].value
|
|
|
- let renderDataItemArray = renderDataItem.split(',')
|
|
|
- that.infoText = `数据点id: ${renderDataItemArray[renderDataItemArray.length - 1]}, \n具体值: ${renderDataItem.match(/^[^{]+(\{.+\})[^}]+$/)[1]}`
|
|
|
- }).on('mouseleave', function (e) {
|
|
|
- d3.select(this).attr('fill', (d) => {
|
|
|
- return `rgba(${Math.round((d[2] -zMin) / zLength * 255)}, 0, 0, 1)`
|
|
|
- })
|
|
|
- that.infoText = ''
|
|
|
+ gNode.selectAll('rect').on('mouseover', function(e) {
|
|
|
+ d3.select(this).attr('fill', 'orange')
|
|
|
+ let renderDataItem = e.target.attributes['render-data'].value
|
|
|
+ let renderDataItemArray = renderDataItem.split(',')
|
|
|
+ that.infoText = renderDataItem.match(/^[^{]+(\{.+\})[^}]+$/)[1]
|
|
|
+ }).on('mouseleave', function (e) {
|
|
|
+ d3.select(this).attr('fill', (d) => {
|
|
|
+ return `rgba(${Math.round((d[2] -zMin) / zLength * 255)}, 0, 0, ${d[3] ? '0.7' : '1'})`
|
|
|
})
|
|
|
+ that.infoText = ''
|
|
|
+ })
|
|
|
|
|
|
- zoomObj = d3.zoom().on("zoom", zoomed)
|
|
|
- svgNode.call(zoomObj);
|
|
|
+ zoomObj = d3.zoom().on("zoom", zoomed)
|
|
|
+ svgNode.call(zoomObj);
|
|
|
|
|
|
- brushObj = d3.brush().on("end", (e) => {
|
|
|
- brushed(e)
|
|
|
- })
|
|
|
- }).finally(() => {
|
|
|
- this.loadingHandler.close()
|
|
|
+ brushObj = d3.brush().on("end", (e) => {
|
|
|
+ brushed(e)
|
|
|
})
|
|
|
},
|
|
|
renderPath() {
|
|
@@ -743,22 +765,6 @@ export default {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- gNode.selectAll('rect')
|
|
|
- .attr('fill', (d) => {
|
|
|
- if (affectedPointList.find((affectedPoint) => {
|
|
|
- // console.log(affectedPoint.id, d[4]);
|
|
|
- return affectedPoint.id === d[4]
|
|
|
- })) {
|
|
|
- return 'blue'
|
|
|
- } else if (pointInBrushList.find((pointInBrush) => {
|
|
|
- return pointInBrush.id === d[4]
|
|
|
- })) {
|
|
|
- return 'green'
|
|
|
- } else {
|
|
|
- return `black`
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
if (!affectedPointList.length) {
|
|
|
window.alert('请在已有点位附近新增点位。')
|
|
|
return
|
|
@@ -769,7 +775,7 @@ export default {
|
|
|
}
|
|
|
|
|
|
let activePointIdx = 0
|
|
|
- let newPointId = rawWholeData[rawWholeData.length - 1].id + 1
|
|
|
+ let newPointId = rawWholeData[rawWholeData.length - 1].id
|
|
|
// 位于框选区域内的所有点位构成稀疏图模型,用邻接表表示,依次处理其顶点表中各顶点。
|
|
|
while(activePointIdx <= pointInBrushList.length - 1) {
|
|
|
// 拿到当前顶点
|
|
@@ -807,12 +813,14 @@ export default {
|
|
|
})
|
|
|
// 如果找到了匹配点
|
|
|
if (matchedPoint) {
|
|
|
+ console.log(matchedPoint, 'sdfsdf');
|
|
|
// 记录自己与其关系。
|
|
|
if (neighbourType === 1) {
|
|
|
tempIds1.push(String(matchedPoint.id))
|
|
|
} else {
|
|
|
tempIds2.push(String(matchedPoint.id))
|
|
|
}
|
|
|
+
|
|
|
// 酌情修改这个外围点位与自己的关系。
|
|
|
|
|
|
// 相邻点位数组ids中,前4项表示上下左右邻居,后四项表示斜角邻居。
|
|
@@ -827,13 +835,13 @@ export default {
|
|
|
}
|
|
|
|
|
|
if (!matchedPoint.ids.slice(idsStartIdx, idsEndIdx).find((id) => {
|
|
|
- return id === activePoint.id
|
|
|
+ return id === String(activePoint.id)
|
|
|
})) {
|
|
|
const emptyIdx = matchedPoint.ids.slice(idsStartIdx, idsEndIdx).findIndex((id) => {
|
|
|
return id === '-1'
|
|
|
})
|
|
|
console.assert(emptyIdx !== -1, 'emptyIdx居然不存在?!')
|
|
|
- matchedPoint.ids[idsStartIdx + emptyIdx] = activePoint.id
|
|
|
+ matchedPoint.ids[idsStartIdx + emptyIdx] = String(activePoint.id)
|
|
|
}
|
|
|
}
|
|
|
// 如果没找到匹配点
|
|
@@ -850,7 +858,7 @@ export default {
|
|
|
else {
|
|
|
// 在顶点表中找匹配的点
|
|
|
const matchedPoint = pointInBrushList.find((pointInBrush) => {
|
|
|
- return getDistance2D(pointInBrush, neiPos) < pointDistance * 0.1
|
|
|
+ return getDistance2D(pointInBrush, neiPos) < pointDistance * 0.3
|
|
|
})
|
|
|
// 如果找到了匹配点
|
|
|
if (matchedPoint) {
|
|
@@ -863,6 +871,8 @@ export default {
|
|
|
}
|
|
|
// 如果没找到匹配点
|
|
|
else {
|
|
|
+ newPointId++
|
|
|
+
|
|
|
// 创建新点位,加入顶点表
|
|
|
pointInBrushList.push({
|
|
|
id: newPointId,
|
|
@@ -870,7 +880,6 @@ export default {
|
|
|
y: neiPos.y,
|
|
|
z: this.formData.addPointHeight,
|
|
|
})
|
|
|
- newPointId++
|
|
|
|
|
|
// 记录自己与其关系
|
|
|
if (neighbourType === 1) {
|
|
@@ -912,7 +921,16 @@ export default {
|
|
|
activePointIdx++
|
|
|
} // end of 依次处理顶点表中各顶点
|
|
|
|
|
|
-
|
|
|
+ // 新补的点加入rawWholeData
|
|
|
+ const oldIdMax = rawWholeData.length // 旧有的点的id最大值,据此判断哪些点是新增的
|
|
|
+ for (const pointInBrush of pointInBrushList) {
|
|
|
+ if (pointInBrush.id > oldIdMax) {
|
|
|
+ pointInBrush.isManuallyAdded = true
|
|
|
+ rawWholeData.push(pointInBrush)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ this.renderWholePoints()
|
|
|
}, // end of method addPoint
|
|
|
},
|
|
|
}
|