Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
pdczt_qd
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
zhaopanyu
pdczt_qd
Commits
344e397f
Commit
344e397f
authored
Mar 04, 2026
by
zhaopanyu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
zpy
parent
8b364239
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
1880 additions
and
1 deletions
+1880
-1
src/views/wellDesign/components/BitDesigns.vue
+1874
-0
src/views/wellDesign/index.vue
+6
-1
No files found.
src/views/wellDesign/components/BitDesigns.vue
0 → 100644
View file @
344e397f
<
template
>
<div
class=
"app-container"
v-loading=
"loading"
element-loading-text=
"正在加载钻头设计数据..."
>
<div>
<div
style=
"position: relative"
>
<canvas
ref=
"plot"
style=
"height: 700px; width: 100%; position: relative"
/>
<!-- 合并表头 -->
<div
style=
"position: absolute; top: 5px; left: 770px; display: flex; margin-top: -4px; z-index: 1;"
>
<div
style=
"width: 85px; border-bottom: 1px solid #000000; border-right: 1px solid #000000; border-left: 0; display: flex; align-items: center; justify-content: center; font-size: 10px; font-weight: bold; background-color: #f3f8ff;"
>
布齿密度
</div>
<div
style=
"display: flex; flex-direction: column;"
>
<div
style=
"width: 270px;border-right: 1px solid #000000; border-bottom: 1px solid #000000; display: flex; align-items: center; justify-content: center; font-size: 10px; font-weight: bold; background-color: #f3f8ff;"
>
刀翼设计
</div>
<div
style=
"display: flex;"
>
<div
style=
"width: 150px; border-bottom: 1px solid #000000; display: flex; align-items: center; justify-content: center; font-size: 10px; font-weight: bold; background-color: #f3f8ff;"
>
刀翼数
</div>
<div
style=
"width: 119px;border-right: 1px solid #000000; border-bottom: 1px solid #000000; display: flex; align-items: center; justify-content: center; font-size: 10px; font-weight: bold; background-color: #f3f8ff;"
>
冠部轮廓
</div>
</div>
</div>
<div
style=
"display: flex; flex-direction: column;"
>
<div
style=
"width: 300px;border-right: 1px solid #000000; border-bottom: 1px solid #000000; display: flex; align-items: center; justify-content: center; font-size: 10px; font-weight: bold; background-color: #f3f8ff;"
>
切削齿
</div>
<div
style=
"display: flex;"
>
<div
style=
"width: 120px; border-right: 1px solid #000000;border-bottom: 1px solid #000000; display: flex; align-items: center; justify-content: center; font-size: 10px; font-weight: bold; background-color: #f3f8ff;"
>
尺寸(mm)
</div>
<div
style=
"width: 180px;border-right: 1px solid #000000; border-bottom: 1px solid #000000; display: flex; align-items: center; justify-content: center; font-size: 10px; font-weight: bold; background-color: #f3f8ff;"
>
后倾角(°)
</div>
</div>
</div>
</div>
<!-- 添加伽马和纵波时差表头 -->
<div
style=
"position: absolute; top: 5px; left: 50px; display: flex; margin-top: -4px; z-index: 2;"
>
<div
style=
"display: flex; width: 100px;"
>
<div
style=
"width: 98px; height: 20px; display: flex; align-items: center; justify-content: center; font-size: 10px; font-weight: bold; background-color: #f3f8ff;"
>
伽马/纵波时差
</div>
</div>
</div>
<!-- 添加层位表头 -->
<div
style=
"position: absolute; top: 20px; left: 345px; display: flex;margin-top: -4px;"
>
<div
style=
"display: flex; width: 100px;"
>
<div
style=
"width: 70px; align-items: center; justify-content: center; font-size: 10px; font-weight: bold; "
>
层位
</div>
</div>
</div>
<!-- 添加单轴线压强度表头 -->
<div
style=
"position: absolute; top: 5px; left: 385px; display: flex; margin-top: -4px; z-index: 2;"
>
<div
style=
"display: flex; width: 100px;"
>
<div
style=
"width: 98px; height: 20px; display: flex; align-items: center; justify-content: center; font-size: 10px; font-weight: bold; background-color: #f3f8ff;"
>
单轴线压强度
</div>
</div>
</div>
<!-- 添加岩石可钻性级值表头 -->
<div
style=
"position: absolute; top: 5px; left: 485px; display: flex; margin-top: -4px; z-index: 2;"
>
<div
style=
"display: flex; width: 100px;"
>
<div
style=
"width: 98px; height: 20px; display: flex; align-items: center; justify-content: center; font-size: 10px; font-weight: bold; background-color: #f3f8ff;"
>
岩石可钻性级值
</div>
</div>
</div>
<!-- 添加研磨性系数表头 -->
<div
style=
"position: absolute; top: 5px; left: 585px; display: flex; margin-top: -4px; z-index: 2;"
>
<div
style=
"display: flex; width: 100px;"
>
<div
style=
"width: 98px; height: 20px; display: flex; align-items: center; justify-content: center; font-size: 10px; font-weight: bold; background-color: #f3f8ff;"
>
研磨性系数
</div>
</div>
</div>
<!-- 添加均质性系数表头 -->
<div
style=
"position: absolute; top: 5px; left: 685px; display: flex; margin-top: -4px; z-index: 2;"
>
<div
style=
"display: flex; width: 80px;"
>
<div
style=
"width: 78px; height: 20px; display: flex; align-items: center; justify-content: center; font-size: 10px; font-weight: bold; background-color: #f3f8ff;"
>
均质性系数
</div>
</div>
</div>
<!-- 添加钻头尺寸表头 -->
<!--
<div
style=
"position: absolute; top: 10px; left: 150px; display: flex; margin-top: -4px; z-index: 2;"
>
<div
style=
"display: flex; width: 173px;"
>
<div
style=
"width: 180px; height: 73px; display: flex; flex-direction: column; align-items: center; justify-content: center; font-size: 10px; font-weight: bold; background-color: #f3f8ff;"
>
<div>
钻头尺寸(mm)
</div>
<div
style=
"width: 100%; height: 1px; background-color: #000; margin-top: 5px;"
></div>
<div
style=
"display: flex; justify-content: space-between; width: 100%; padding: 0 10px; margin-top: 5px;"
>
<span>
{{
this
.
curveData
[
'ztccmax'
]
!==
undefined
?
this
.
curveData
[
'ztccmax'
]
:
'-'
}}
</span>
<span>
{{
this
.
curveData
[
'ztccmin'
]
!==
undefined
?
this
.
curveData
[
'ztccmin'
]
:
'-'
}}
</span>
</div>
</div>
</div>
</div>
-->
<!-- 原有的列结构 -->
<div
style=
"position: absolute; top: 50px; left: 775px; font-size: 10px; writing-mode: vertical-rl; font-weight: bold;"
>
低
</div>
<div
style=
"position: absolute; top: 50px; left: 805px; font-size: 10px; writing-mode: vertical-rl; font-weight: bold;"
>
中
</div>
<div
style=
"position: absolute; top: 50px; left: 835px; font-size: 10px; writing-mode: vertical-rl; font-weight: bold;"
>
高
</div>
<div
style=
"position: absolute; top: 50px; left:865px; font-size: 10px; font-weight: bold; display: flex; flex-direction: column; align-items: center; justify-content: center;"
>
4
</div>
<div
style=
"position: absolute; top: 50px; left:895px; font-size: 10px; font-weight: bold; display: flex; flex-direction: column; align-items: center; justify-content: center;"
>
5
</div>
<div
style=
"position: absolute; top: 50px; left: 925px; font-size: 10px; font-weight: bold; display: flex; flex-direction: column; align-items: center; justify-content: center;"
>
6
</div>
<div
style=
"position: absolute; top: 50px; left: 955px; font-size: 10px; font-weight: bold; display: flex; flex-direction: column; align-items: center; justify-content: center;"
>
7
</div>
<div
style=
"position: absolute; top: 50px; left: 985px; font-size: 10px; font-weight: bold; display: flex; flex-direction: column; align-items: center; justify-content: center;"
>
8
</div>
<div
style=
"position: absolute; top: 40px; left: 1015px; font-size: 10px; writing-mode: vertical-rl; font-weight: bold;"
>
长抛物线
</div>
<div
style=
"position: absolute; top: 30px; left: 1045px; font-size: 10px; writing-mode: vertical-rl; font-weight: bold;"
>
中等抛物线
</div>
<div
style=
"position: absolute; top: 40px; left: 1075px; font-size: 10px; writing-mode: vertical-rl; font-weight: bold;"
>
短抛物线
</div>
<div
style=
"position: absolute; top: 50px; left: 1100px; font-size: 10px; writing-mode: vertical-rl; font-weight: bold;"
>
鱼尾型
</div>
<div
style=
"position: absolute; top: 50px; left: 1135px; font-size: 10px; writing-mode: vertical-rl; font-weight: bold;"
>
13
</div>
<div
style=
"position: absolute; top: 50px; left: 1165px; font-size: 10px; writing-mode: vertical-rl; font-weight: bold;"
>
16
</div>
<div
style=
"position: absolute; top: 50px; left: 1195px; font-size: 10px; writing-mode: vertical-rl; font-weight: bold;"
>
19
</div>
<div
style=
"position: absolute; top: 50px; left: 1225px; font-size: 10px; writing-mode: vertical-rl; font-weight: bold;"
>
24
</div>
<div
style=
"position: absolute; top: 50px; left: 1255px; font-size: 10px; writing-mode: vertical-rl; font-weight: bold;"
>
15
</div>
<div
style=
"position: absolute; top: 50px; left: 1285px; font-size: 10px; writing-mode: vertical-rl; font-weight: bold;"
>
18
</div>
<div
style=
"position: absolute; top: 50px; left:1315px; font-size: 10px; writing-mode: vertical-rl; font-weight: bold;"
>
20
</div>
<div
style=
"position: absolute; top: 50px; left: 1345px; font-size: 10px; writing-mode: vertical-rl; font-weight: bold;"
>
25
</div>
<div
style=
"position: absolute; top: 50px; left: 1375px; font-size: 10px; writing-mode: vertical-rl; font-weight: bold;"
>
30
</div>
<div
style=
"position: absolute; top: 50px; left: 1405px; font-size: 10px; writing-mode: vertical-rl; font-weight: bold;"
>
35
</div>
<div
class=
"well1Title"
v-if=
"jjgTrue"
style=
"position: absolute;top: 30px;left: 112px;font-size: 14px"
>
井身结构
</div>
<!-- 开次表头 -->
<div
style=
"position: absolute; top: 3px; left: 1425px; width: 80px; height: 100px; z-index: 11;"
>
<div
style=
"width: 80px; height: 80px; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: bold; background-color: #f3f8ff; border: 1px solid #000000;"
>
开次
</div>
</div>
<!-- 开次信息显示区域 -->
<div
ref=
"kcListContainer"
style=
"position: absolute; top: 90px; left: 1425px; width: 80px; height: 560px; overflow: visible; z-index: 10; border: 1px solid #000000; border-top: 0;"
>
</div>
</div>
<div
id=
"tooltip-container"
style=
"display: none;position: absolute"
></div>
</div>
</div>
</
template
>
<
script
>
import
{
ComponentNodeFactoryRegistry
}
from
'@int/geotoolkit/schematics/factory/ComponentNodeFactoryRegistry'
;
import
{
v3
as
WellLogWidget
}
from
'@int/impl/geotoolkit.welllog.widgets.js'
;
import
{
WellBoreData
}
from
'@int/geotoolkit/schematics/data/WellBoreData'
;
import
{
LogAbstractVisual
}
from
'@int/geotoolkit/welllog/LogAbstractVisual'
;
import
{
WellBoreNode
,
ViewMode
}
from
'@int/geotoolkit/schematics/scene/WellBoreNode'
;
import
{
TrackType
}
from
'@int/geotoolkit/welllog/TrackType'
;
import
{
HeaderType
}
from
'@int/geotoolkit/welllog/header/LogAxisVisualHeader'
;
import
{
Rect
}
from
'@int/geotoolkit/util/Rect'
;
import
{
LogData
}
from
'@int/geotoolkit/welllog/data/LogData'
;
import
{
LogCurve
}
from
'@int/geotoolkit/welllog/LogCurve'
;
import
{
Group
}
from
'@int/geotoolkit/scene/Group'
;
import
{
CssLayout
}
from
'@int/geotoolkit/layout/CssLayout'
;
import
{
Plot
}
from
'@int/geotoolkit/plot/Plot'
;
import
{
MathUtil
}
from
'@int/geotoolkit/util/MathUtil'
;
import
{
NodeTubingBW
}
from
'@/views/wellTest/wellComData/NodeTubingBW'
;
import
{
NodeCementBW
}
from
'@/views/wellTest/wellComData/NodeCementBW'
;
import
{
NodeCasingBW
}
from
'@/views/wellTest/wellComData/NodeCasingBW'
;
//曲线数据
import
curveData
from
'@/views/wellTest/wellComData/MutiWells.json'
;
//井结构数据
import
mixin
from
"@/views/wellTest/wellComData/mixin.json"
import
cjsj
from
"@/views/wellTest/wellComData/cjsj.json"
import
wellLogCurve
from
"@/views/wellTest/wellComData/wellLogCurve.json"
import
{
TooltipTool
}
from
'@/views/wellTest/wellCurveData/tooltipTool'
;
import
{
CssStyle
}
from
'@int/geotoolkit/css/CssStyle'
;
import
{
getCjqxDataztyx
,
ztTj
}
from
"@/api/system/cjsjLas"
;
//地层
import
{
LogMudLogSection
}
from
'@int/geotoolkit/welllog/LogMudLogSection'
;
import
{
Text
}
from
'@int/geotoolkit/scene/shapes/Text'
;
import
{
AnchorType
}
from
'@int/geotoolkit/util/AnchorType'
;
export
default
{
name
:
"cjqx"
,
data
()
{
return
{
// 加载状态
loading
:
false
,
//井号
jhSelection
:
[],
qkSelection
:
[],
jh
:
''
,
qk
:
''
,
formInline
:
{
dcljList
:
[],
jhList
:
[],
qk
:
''
},
options
:
[{
value
:
'录井曲线'
,
label
:
'录井曲线'
}],
curveData
:
{},
curve
:
{},
jjg
:
[],
//井最大深度
scale
:
''
,
//井最小深度
scale1
:
''
,
jjgTrue
:
false
,
//对数曲线集合
logCurveList
:
[],
// 添加层位相关数据
layerColors
:
{},
// 存储层位和颜色的映射
uniqueLayers
:
[],
// 存储唯一的层位列表
// 预定义的颜色数组
predefinedColors
:
[
'#fbd860'
,
'#f3a43a'
,
'#5fc0de'
,
'#d74f4a'
,
'#c6e679'
,
'#fce913'
,
],
// 开次数据
kcList
:
[],
// 图表实例
widgetInstance
:
null
}
},
mounted
()
{
this
.
onSearch
()
},
methods
:
{
getQk
()
{
const
jsjg
=
{
jh
:
''
}
getQkNumber
(
jsjg
).
then
(
res
=>
{
this
.
qkSelection
=
res
.
map
(
item
=>
{
return
{
value
:
item
.
qk
,
label
:
item
.
qk
}
})
})
},
//查询按钮
onSearch
()
{
console
.
log
(
'this.formInline'
,
this
.
formInline
)
const
canvas
=
this
.
$refs
.
plot
;
const
parent
=
canvas
.
parentElement
;
// 获取父元素
if
(
canvas
&&
parent
)
{
parent
.
removeChild
(
canvas
);
// 从父元素中移除 canvas 元素
// 创建一个新的 canvas 元素
this
.
newCanvas
=
document
.
createElement
(
'canvas'
);
this
.
newCanvas
.
style
.
height
=
'650px'
;
this
.
newCanvas
.
style
.
width
=
'100%'
;
this
.
newCanvas
.
style
.
position
=
'relative'
;
this
.
newCanvas
.
setAttribute
(
'ref'
,
'plot'
);
// 添加 ref 属性
parent
.
appendChild
(
this
.
newCanvas
);
// 将新的 canvas 元素添加到父元素中
}
this
.
$refs
.
plot
=
this
.
newCanvas
;
this
.
getWelllogData
()
},
//重置按钮
resetForm
()
{
this
.
qk
=
'孤东'
this
.
jh
=
''
this
.
formInline
.
dcljList
=
[]
this
.
onSearch
()
},
// 添加 processData 方法
processData
(
data
,
key
)
{
if
(
!
data
)
{
console
.
warn
(
`
${
key
}
数据为空`
);
return
[];
}
if
(
Array
.
isArray
(
data
))
{
console
.
log
(
`
${
key
}
数据长度:`
,
data
.
length
);
return
data
;
}
console
.
warn
(
`
${
key
}
数据格式不正确:`
,
data
);
return
[];
},
//获取数据
getWelllogData
()
{
this
.
loading
=
true
;
// 开始加载
this
.
formInline
.
jhList
=
[]
this
.
formInline
.
jhList
.
push
(
this
.
jh
)
this
.
formInline
.
qk
=
this
.
qk
console
.
log
(
'this.formInline'
,
this
.
formInline
)
getCjqxDataztyx
({
jh
:
this
.
$route
.
query
.
jh
}).
then
(
res
=>
{
console
.
log
(
'获取到的原始数据:'
,
res
)
this
.
scale
=
res
.
scale
this
.
scale1
=
res
.
scale1
console
.
log
(
'深度显示范围 - 起始(scale1):'
,
this
.
scale1
,
'结束(scale):'
,
this
.
scale
);
// 初始化 curveData 对象
this
.
curveData
=
{}
// 处理钻头尺寸和层位数据
console
.
log
(
'开始处理关键数据...'
);
// 特殊处理钻头尺寸数据
console
.
log
(
'处理钻头尺寸数据'
);
// 检查是否有 ztccLeftList2 和 ztccRigntList2 数据
if
(
res
.
ztccLeftList2
&&
res
.
ztccRigntList2
&&
Array
.
isArray
(
res
.
ztccLeftList2
)
&&
res
.
ztccLeftList2
.
length
>
0
)
{
console
.
log
(
'使用 ztccLeftList2 和 ztccRigntList2 数据'
);
// 检查数据格式:如果是对象数组格式 [{ztcc: 33.76, dept: 3660.15}, ...]
if
(
typeof
res
.
ztccLeftList2
[
0
]
===
'object'
&&
res
.
ztccLeftList2
[
0
].
hasOwnProperty
(
'dept'
)
&&
res
.
ztccLeftList2
[
0
].
hasOwnProperty
(
'ztcc'
))
{
console
.
log
(
'数据是对象数组格式,直接使用'
);
this
.
curveData
[
'钻头尺寸左'
]
=
res
.
ztccLeftList2
;
this
.
curveData
[
'钻头尺寸右'
]
=
res
.
ztccRigntList2
;
}
else
{
console
.
log
(
'数据是普通数组格式,进行处理'
);
this
.
curveData
[
'钻头尺寸左'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
ztccLeftList2
,
'钻头尺寸左'
),
'钻头尺寸左'
);
this
.
curveData
[
'钻头尺寸右'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
ztccRigntList2
,
'钻头尺寸右'
),
'钻头尺寸右'
);
}
// 显示前两个值用于头部展示
if
(
res
.
ztccmax
!==
undefined
)
{
this
.
curveData
[
'ztccmax'
]
=
res
.
ztccmax
;
}
if
(
res
.
ztccmin
!==
undefined
)
{
this
.
curveData
[
'ztccmin'
]
=
res
.
ztccmin
;
}
// 检查数据点的深度范围(仅对对象数组格式)
if
(
this
.
curveData
[
'钻头尺寸左'
].
length
>
0
&&
typeof
this
.
curveData
[
'钻头尺寸左'
][
0
]
===
'object'
&&
this
.
curveData
[
'钻头尺寸左'
][
0
].
hasOwnProperty
(
'dept'
))
{
const
deptValues
=
this
.
curveData
[
'钻头尺寸左'
].
map
(
item
=>
item
.
dept
);
const
minDept
=
Math
.
min
(...
deptValues
);
const
maxDept
=
Math
.
max
(...
deptValues
);
console
.
log
(
'钻头尺寸数据深度范围:'
,
minDept
,
'-'
,
maxDept
);
// 如果数据深度范围与widget显示范围不匹配,更新scale1和scale
if
(
minDept
<
this
.
scale1
||
maxDept
>
this
.
scale
)
{
console
.
log
(
'数据深度范围超出显示范围,调整显示范围'
);
this
.
scale1
=
Math
.
min
(
this
.
scale1
,
minDept
);
this
.
scale
=
Math
.
max
(
this
.
scale
,
maxDept
);
console
.
log
(
'调整后的深度显示范围:'
,
this
.
scale1
,
'-'
,
this
.
scale
);
}
}
console
.
log
(
'钻头尺寸左数据(ztccLeftList2):'
,
this
.
curveData
[
'钻头尺寸左'
]);
console
.
log
(
'钻头尺寸右数据(ztccRigntList2):'
,
this
.
curveData
[
'钻头尺寸右'
]);
}
else
{
console
.
warn
(
'钻头尺寸数据无效或为空'
);
this
.
curveData
[
'钻头尺寸左'
]
=
[];
this
.
curveData
[
'钻头尺寸右'
]
=
[];
}
// 处理层位数据
this
.
curveData
[
'层位'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
cwList
,
'层位'
),
'层位'
);
// 处理层位颜色映射
this
.
processLayerData
(
this
.
curveData
[
'层位'
]);
// 处理开次数据
this
.
kcList
=
res
.
kcList
||
[];
console
.
log
(
'开次数据:'
,
this
.
kcList
);
// 处理其他数据...
this
.
curveData
[
'伽马'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
grList
,
'伽马'
),
'伽马'
);
this
.
curveData
[
'纵波时差'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
zbList
,
'纵波时差'
),
'纵波时差'
);
this
.
curveData
[
'单轴线压强度'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
dzkyList
,
'单轴线压强度'
),
'单轴线压强度'
);
this
.
curveData
[
'岩石可钻性级值'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
yskzxjzList
,
'岩石可钻性级值'
),
'岩石可钻性级值'
);
this
.
curveData
[
'研磨性系数'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
ymzsList
,
'研磨性系数'
),
'研磨性系数'
);
this
.
curveData
[
'均质性系数'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
cjzsList
,
'均质性系数'
),
'均质性系数'
);
this
.
curveData
[
'布齿密度(低)'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
bcmdXList
,
'布齿密度(低)'
),
'布齿密度(低)'
);
this
.
curveData
[
'布齿密度(中)'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
bcmdZList
,
'布齿密度(中)'
),
'布齿密度(中)'
);
this
.
curveData
[
'布齿密度(高)'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
bcmdMList
,
'布齿密度(高)'
),
'布齿密度(高)'
);
console
.
log
(
'布齿密度(高)原始数据:'
,
res
.
bcmdMList
);
console
.
log
(
'布齿密度(高)处理后数据:'
,
this
.
curveData
[
'布齿密度(高)'
]);
this
.
curveData
[
'刀翼数4'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
dysList4
,
'刀翼数4'
),
'刀翼数4'
);
this
.
curveData
[
'刀翼数5'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
dysList5
,
'刀翼数5'
),
'刀翼数5'
);
this
.
curveData
[
'刀翼数6'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
dysList6
,
'刀翼数6'
),
'刀翼数6'
);
this
.
curveData
[
'刀翼数7'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
dysList7
,
'刀翼数7'
),
'刀翼数7'
);
this
.
curveData
[
'刀翼数8'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
dysList8
,
'刀翼数8'
),
'刀翼数8'
);
this
.
curveData
[
'冠部轮廓(长抛物线)'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
gblkYwList
,
'冠部轮廓(长抛物线)'
),
'冠部轮廓(长抛物线)'
);
this
.
curveData
[
'冠部轮廓(中等抛物线)'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
gblkDList
,
'冠部轮廓(中等抛物线)'
),
'冠部轮廓(中等抛物线)'
);
this
.
curveData
[
'冠部轮廓(短抛物线)'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
gblkZList
,
'冠部轮廓(短抛物线)'
),
'冠部轮廓(短抛物线)'
);
this
.
curveData
[
'冠部轮廓(圆形)'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
gblkCList
,
'冠部轮廓(圆形)'
),
'冠部轮廓(圆形)'
);
this
.
curveData
[
'尺寸(13)'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
qxcccList13
,
'尺寸(13)'
),
'尺寸(13)'
);
this
.
curveData
[
'尺寸(16)'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
qxcccList16
,
'尺寸(16)'
),
'尺寸(16)'
);
this
.
curveData
[
'尺寸(19)'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
qxcccList19
,
'尺寸(19)'
),
'尺寸(19)'
);
this
.
curveData
[
'尺寸(24)'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
qxcccList22
,
'尺寸(24)'
),
'尺寸(24)'
);
this
.
curveData
[
'后倾角(°)(15)'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
qxcfqj15List
,
'后倾角(15)'
),
'后倾角(15)'
);
this
.
curveData
[
'后倾角(°)(18)'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
qxcfqj18List
,
'后倾角(18)'
),
'后倾角(18)'
);
this
.
curveData
[
'后倾角(°)(20)'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
qxcfqj20List
,
'后倾角(20)'
),
'后倾角(20)'
);
this
.
curveData
[
'后倾角(°)(25)'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
qxcfqj25List
,
'后倾角(25)'
),
'后倾角(25)'
);
this
.
curveData
[
'后倾角(°)(30)'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
qxcfqj30List
,
'后倾角(30)'
),
'后倾角(30)'
);
this
.
curveData
[
'后倾角(°)(35)'
]
=
this
.
filterValidData
(
this
.
processData
(
res
.
qxcfqj35List
,
'后倾角(35)'
),
'后倾角(35)'
);
this
.
curveData
[
'mc'
]
=
Array
(
200
).
fill
(
' '
);
console
.
log
(
'数据处理完成'
);
console
.
log
(
'处理后的曲线数据:'
,
this
.
curveData
);
// 创建图表
this
.
createScene
(
this
.
$refs
.
plot
);
}).
catch
(
error
=>
{
console
.
error
(
'获取数据失败:'
,
error
);
this
.
$message
.
error
(
'获取钻头设计数据失败,请重试'
);
}).
finally
(()
=>
{
this
.
loading
=
false
;
// 结束加载
})
},
createScene
(
canvas
)
{
//网格结构
const
widget
=
new
WellLogWidget
({
'header'
:
{
'visible'
:
true
},
'footer'
:
{
'visible'
:
false
},
'border'
:
{
'visible'
:
true
},
'horizontalscrollable'
:
false
,
'verticalscrollable'
:
false
,
'nodefilter'
:
(
node
)
=>
node
instanceof
LogAbstractVisual
||
node
instanceof
WellBoreNode
})
.
setAxisHeaderType
(
HeaderType
.
Simple
)
.
setHeaderHeight
(
90
)
.
setIndexUnit
(
'm'
);
// 保存图表实例,用于后续交互
this
.
widgetInstance
=
widget
;
// 设置深度范围
console
.
log
(
'设置widget深度范围:'
,
this
.
scale1
,
'-'
,
this
.
scale
);
// 检查钻头尺寸数据深度范围
let
dataMinDepth
=
this
.
scale1
;
let
dataMaxDepth
=
this
.
scale
;
if
(
this
.
curveData
[
'钻头尺寸左'
]
&&
this
.
curveData
[
'钻头尺寸左'
].
length
>
0
&&
typeof
this
.
curveData
[
'钻头尺寸左'
][
0
]
===
'object'
&&
this
.
curveData
[
'钻头尺寸左'
][
0
].
hasOwnProperty
(
'dept'
))
{
const
deptValues
=
this
.
curveData
[
'钻头尺寸左'
].
map
(
item
=>
item
.
dept
);
const
minDept
=
Math
.
min
(...
deptValues
);
const
maxDept
=
Math
.
max
(...
deptValues
);
console
.
log
(
'钻头尺寸数据深度范围:'
,
minDept
,
'-'
,
maxDept
);
// 调整深度范围以适应数据
dataMinDepth
=
Math
.
min
(
dataMinDepth
,
minDept
);
dataMaxDepth
=
Math
.
max
(
dataMaxDepth
,
maxDept
);
}
console
.
log
(
'最终使用的深度范围:'
,
dataMinDepth
,
'-'
,
dataMaxDepth
);
widget
.
setDepthLimits
(
dataMinDepth
,
dataMaxDepth
);
//样式
this
.
applyModernThemeCSS
(
widget
);
//曲线提示框
widget
.
connectTool
(
new
TooltipTool
(
widget
));
//添加坐标
widget
.
addTrack
(
TrackType
.
IndexTrack
);
//曲线
widget
.
addTrack
(
TrackType
.
LinearTrack
)
.
setWidth
(
100
)
.
addChild
([
this
.
createCurve
(
0
,
30
,
'伽马'
,
'orange'
),
this
.
createCurve
(
0
,
30
,
'纵波时差'
,
'#b3428a'
),
].
filter
(
curve
=>
curve
!==
null
));
// 添加钻头尺寸左右线
console
.
log
(
'钻头尺寸左数据:'
,
this
.
curveData
[
'钻头尺寸左'
]);
console
.
log
(
'钻头尺寸右数据:'
,
this
.
curveData
[
'钻头尺寸右'
]);
const
ztccTrack
=
widget
.
addTrack
(
TrackType
.
LinearTrack
)
.
setWidth
(
175
)
.
addChild
(
new
Group
()
.
setLayout
(
new
CssLayout
())
.
setLayoutStyle
({
'left'
:
'0%'
,
'right'
:
'0%'
,
'top'
:
'-45px'
,
// 将表头放在 track 上方
'height'
:
'45px'
})
);
// 只有当钻头尺寸数据有效时才添加曲线
if
(
this
.
curveData
[
'钻头尺寸左'
]
&&
this
.
curveData
[
'钻头尺寸左'
].
length
>
0
)
{
console
.
log
(
'添加钻头尺寸左曲线'
);
console
.
log
(
'原始数据点数量:'
,
this
.
curveData
[
'钻头尺寸左'
].
length
);
// 创建深度数组和值数组
let
depths
=
[];
let
values
=
[];
// 检查是否为对象数组格式
if
(
typeof
this
.
curveData
[
'钻头尺寸左'
][
0
]
===
'object'
&&
this
.
curveData
[
'钻头尺寸左'
][
0
].
hasOwnProperty
(
'dept'
)
&&
this
.
curveData
[
'钻头尺寸左'
][
0
].
hasOwnProperty
(
'ztcc'
))
{
console
.
log
(
'钻头尺寸左数据是对象数组格式,提取dept和ztcc值'
);
let
dataToProcess
=
this
.
curveData
[
'钻头尺寸左'
];
// 对于大数据集进行采样
if
(
dataToProcess
.
length
>
1000
)
{
console
.
log
(
'数据量过大,进行采样处理'
);
const
sampleRate
=
Math
.
max
(
1
,
Math
.
floor
(
dataToProcess
.
length
/
500
));
// 确保不超过500个点
const
sampledData
=
[];
// 确保包含第一个点
sampledData
.
push
(
dataToProcess
[
0
]);
// 采样中间点
for
(
let
i
=
sampleRate
;
i
<
dataToProcess
.
length
-
sampleRate
;
i
+=
sampleRate
)
{
sampledData
.
push
(
dataToProcess
[
i
]);
}
// 确保包含最后一个点
if
(
dataToProcess
.
length
>
1
)
{
sampledData
.
push
(
dataToProcess
[
dataToProcess
.
length
-
1
]);
}
dataToProcess
=
sampledData
;
console
.
log
(
'采样后数据点数量:'
,
dataToProcess
.
length
);
}
// 从对象中提取dept和ztcc值
depths
=
dataToProcess
.
map
(
item
=>
item
.
dept
);
values
=
dataToProcess
.
map
(
item
=>
item
.
ztcc
);
console
.
log
(
'钻头尺寸左 - 深度数组长度:'
,
depths
.
length
);
console
.
log
(
'钻头尺寸左 - 值数组长度:'
,
values
.
length
);
console
.
log
(
'钻头尺寸左 - 深度范围:'
,
Math
.
min
(...
depths
),
'-'
,
Math
.
max
(...
depths
));
console
.
log
(
'钻头尺寸左 - 值范围:'
,
Math
.
min
(...
values
),
'-'
,
Math
.
max
(...
values
));
console
.
log
(
'钻头尺寸左 - 前5个深度值:'
,
depths
.
slice
(
0
,
5
));
console
.
log
(
'钻头尺寸左 - 前5个ztcc值:'
,
values
.
slice
(
0
,
5
));
}
else
{
// 使用常规方法创建深度数组
depths
=
Array
.
from
({
length
:
this
.
curveData
[
'钻头尺寸左'
].
length
},
(
_
,
i
)
=>
this
.
scale1
+
i
*
0.5
);
values
=
this
.
curveData
[
'钻头尺寸左'
];
console
.
log
(
'钻头尺寸左 - 使用常规方法,深度数组长度:'
,
depths
.
length
);
console
.
log
(
'钻头尺寸左 - 使用常规方法,值数组长度:'
,
values
.
length
);
}
// 创建LogData
console
.
log
(
'创建钻头尺寸左LogData,参数:'
,
{
depths
:
depths
.
slice
(
0
,
3
),
values
:
values
.
slice
(
0
,
3
),
indexunit
:
'm'
});
const
logData
=
new
LogData
({
depths
:
depths
,
values
:
values
,
indexunit
:
'm'
});
console
.
log
(
'LogData创建成功,最小值:'
,
logData
.
getMinValue
(),
'最大值:'
,
logData
.
getMaxValue
());
// 创建曲线
const
leftCurve
=
new
LogCurve
(
logData
)
.
setLineStyle
({
'color'
:
'#00dae4'
,
// 蓝色
'width'
:
2
,
'pattern'
:
[
1
]
})
.
setName
(
'钻头尺寸左'
);
console
.
log
(
'钻头尺寸左曲线创建成功'
);
// 设置归一化范围
if
(
this
.
curveData
[
'ztccmin'
]
!==
undefined
&&
this
.
curveData
[
'ztccmax'
]
!==
undefined
)
{
console
.
log
(
'使用ztccmin和ztccmax设置归一化范围:'
,
this
.
curveData
[
'ztccmin'
],
'-'
,
this
.
curveData
[
'ztccmax'
]);
leftCurve
.
setNormalizationLimits
(
this
.
curveData
[
'ztccmin'
],
this
.
curveData
[
'ztccmax'
]);
}
else
{
// 检查是否为固定值数据
const
isConstantValue
=
values
.
every
(
v
=>
v
===
values
[
0
]);
if
(
isConstantValue
)
{
console
.
log
(
'钻头尺寸左为固定值:'
,
values
[
0
]);
// 对于固定值,手动设置归一化范围以确保曲线显示
const
range
=
Math
.
abs
(
values
[
0
])
*
0.1
||
10
;
// 使用10%的范围或默认10
leftCurve
.
setNormalizationLimits
([
values
[
0
]
-
range
,
values
[
0
]
+
range
]);
console
.
log
(
'设置固定值归一化范围:'
,
values
[
0
]
-
range
,
'-'
,
values
[
0
]
+
range
);
}
}
ztccTrack
.
addChild
(
leftCurve
);
console
.
log
(
'钻头尺寸左曲线已添加到轨道'
);
}
if
(
this
.
curveData
[
'钻头尺寸右'
]
&&
this
.
curveData
[
'钻头尺寸右'
].
length
>
0
)
{
console
.
log
(
'添加钻头尺寸右曲线'
);
console
.
log
(
'原始数据点数量:'
,
this
.
curveData
[
'钻头尺寸右'
].
length
);
// 创建深度数组和值数组
let
depths
=
[];
let
values
=
[];
// 检查是否为对象数组格式
if
(
typeof
this
.
curveData
[
'钻头尺寸右'
][
0
]
===
'object'
&&
this
.
curveData
[
'钻头尺寸右'
][
0
].
hasOwnProperty
(
'dept'
)
&&
this
.
curveData
[
'钻头尺寸右'
][
0
].
hasOwnProperty
(
'ztcc'
))
{
console
.
log
(
'钻头尺寸右数据是对象数组格式,提取dept和ztcc值'
);
let
dataToProcess
=
this
.
curveData
[
'钻头尺寸右'
];
// 对于大数据集进行采样
if
(
dataToProcess
.
length
>
1000
)
{
console
.
log
(
'数据量过大,进行采样处理'
);
const
sampleRate
=
Math
.
max
(
1
,
Math
.
floor
(
dataToProcess
.
length
/
500
));
// 确保不超过500个点
const
sampledData
=
[];
// 确保包含第一个点
sampledData
.
push
(
dataToProcess
[
0
]);
// 采样中间点
for
(
let
i
=
sampleRate
;
i
<
dataToProcess
.
length
-
sampleRate
;
i
+=
sampleRate
)
{
sampledData
.
push
(
dataToProcess
[
i
]);
}
// 确保包含最后一个点
if
(
dataToProcess
.
length
>
1
)
{
sampledData
.
push
(
dataToProcess
[
dataToProcess
.
length
-
1
]);
}
dataToProcess
=
sampledData
;
console
.
log
(
'采样后数据点数量:'
,
dataToProcess
.
length
);
}
// 从对象中提取dept和ztcc值
depths
=
dataToProcess
.
map
(
item
=>
item
.
dept
);
values
=
dataToProcess
.
map
(
item
=>
item
.
ztcc
);
console
.
log
(
'钻头尺寸右 - 深度数组长度:'
,
depths
.
length
);
console
.
log
(
'钻头尺寸右 - 值数组长度:'
,
values
.
length
);
console
.
log
(
'钻头尺寸右 - 深度范围:'
,
Math
.
min
(...
depths
),
'-'
,
Math
.
max
(...
depths
));
console
.
log
(
'钻头尺寸右 - 值范围:'
,
Math
.
min
(...
values
),
'-'
,
Math
.
max
(...
values
));
console
.
log
(
'钻头尺寸右 - 前5个深度值:'
,
depths
.
slice
(
0
,
5
));
console
.
log
(
'钻头尺寸右 - 前5个ztcc值:'
,
values
.
slice
(
0
,
5
));
}
else
{
// 使用常规方法创建深度数组
depths
=
Array
.
from
({
length
:
this
.
curveData
[
'钻头尺寸右'
].
length
},
(
_
,
i
)
=>
this
.
scale1
+
i
*
0.5
);
values
=
this
.
curveData
[
'钻头尺寸右'
];
console
.
log
(
'钻头尺寸右 - 使用常规方法,深度数组长度:'
,
depths
.
length
);
console
.
log
(
'钻头尺寸右 - 使用常规方法,值数组长度:'
,
values
.
length
);
}
// 创建LogData
console
.
log
(
'创建钻头尺寸右LogData,参数:'
,
{
depths
:
depths
.
slice
(
0
,
3
),
values
:
values
.
slice
(
0
,
3
),
indexunit
:
'm'
});
const
logDataRight
=
new
LogData
({
depths
:
depths
,
values
:
values
,
indexunit
:
'm'
});
console
.
log
(
'LogData创建成功,最小值:'
,
logDataRight
.
getMinValue
(),
'最大值:'
,
logDataRight
.
getMaxValue
());
// 创建曲线
const
rightCurve
=
new
LogCurve
(
logDataRight
)
.
setLineStyle
({
'color'
:
'#0000FF'
,
// 蓝色
'width'
:
2
,
'pattern'
:
[
1
]
})
.
setName
(
'钻头尺寸右'
);
console
.
log
(
'钻头尺寸右曲线创建成功'
);
// 设置归一化范围
if
(
this
.
curveData
[
'ztccmin'
]
!==
undefined
&&
this
.
curveData
[
'ztccmax'
]
!==
undefined
)
{
console
.
log
(
'使用ztccmin和ztccmax设置归一化范围:'
,
this
.
curveData
[
'ztccmin'
],
'-'
,
this
.
curveData
[
'ztccmax'
]);
rightCurve
.
setNormalizationLimits
(
this
.
curveData
[
'ztccmin'
],
this
.
curveData
[
'ztccmax'
]);
}
else
{
// 检查是否为固定值数据
const
isConstantValue
=
values
.
every
(
v
=>
v
===
values
[
0
]);
if
(
isConstantValue
)
{
console
.
log
(
'钻头尺寸右为固定值:'
,
values
[
0
]);
// 对于固定值,手动设置归一化范围以确保曲线显示
const
range
=
Math
.
abs
(
values
[
0
])
*
0.1
||
10
;
// 使用10%的范围或默认10
rightCurve
.
setNormalizationLimits
([
values
[
0
]
-
range
,
values
[
0
]
+
range
]);
console
.
log
(
'设置固定值归一化范围:'
,
values
[
0
]
-
range
,
'-'
,
values
[
0
]
+
range
);
}
}
ztccTrack
.
addChild
(
rightCurve
);
console
.
log
(
'钻头尺寸右曲线已添加到轨道'
);
}
// 层位轨道 - 无论是否有数据都创建轨道和表头
const
layerTrack
=
widget
.
addTrack
(
TrackType
.
LinearTrack
)
.
setWidth
(
60
)
.
addChild
(
new
Group
()
.
setLayout
(
new
CssLayout
())
.
setLayoutStyle
({
'left'
:
'0%'
,
'right'
:
'0%'
,
'top'
:
'-45px'
,
'height'
:
'45px'
})
);
// 添加层位数据(如果有数据)
if
(
this
.
curveData
[
'层位'
]
&&
Array
.
isArray
(
this
.
curveData
[
'层位'
])
&&
this
.
curveData
[
'层位'
].
length
>
0
)
{
// 过滤出在当前显示范围内的层位
const
visibleLayers
=
this
.
curveData
[
'层位'
].
filter
(
layer
=>
{
// 检查层位是否与显示范围有交集
return
!
(
layer
.
endDepth
<
dataMinDepth
||
layer
.
startDepth
>
dataMaxDepth
);
});
console
.
log
(
'层位数据总数:'
,
this
.
curveData
[
'层位'
].
length
);
console
.
log
(
'可见层位数量:'
,
visibleLayers
.
length
);
console
.
log
(
'可见层位详情:'
,
visibleLayers
.
map
(
l
=>
({
layer
:
l
.
layer
,
start
:
l
.
startDepth
,
end
:
l
.
endDepth
})));
console
.
log
(
'显示深度范围:'
,
dataMinDepth
,
'-'
,
dataMaxDepth
);
if
(
visibleLayers
.
length
>
0
)
{
// 构建深度数组和值数组
// LogMudLogSection 的 setDepthsAndValues 方法工作原理:
// 深度数组和值数组长度必须相同,每个深度点对应一个值
// 对于层位显示,我们需要为每个层位区间创建深度边界点
const
allDepths
=
[];
const
allValues
=
[];
visibleLayers
.
forEach
((
layer
,
index
)
=>
{
// 确保深度在显示范围内
const
startDepth
=
Math
.
max
(
layer
.
startDepth
,
dataMinDepth
);
const
endDepth
=
Math
.
min
(
layer
.
endDepth
,
dataMaxDepth
);
// 如果是第一个层位,添加起始深度
if
(
index
===
0
)
{
allDepths
.
push
(
startDepth
);
allValues
.
push
(
layer
.
layer
);
}
else
{
// 检查是否与前一个层位连续
const
prevLayer
=
visibleLayers
[
index
-
1
];
const
prevEndDepth
=
Math
.
min
(
prevLayer
.
endDepth
,
dataMaxDepth
);
if
(
startDepth
!==
prevEndDepth
)
{
// 不连续,添加前一个层位的结束深度和当前层位的起始深度
allDepths
.
push
(
prevEndDepth
);
allValues
.
push
(
prevLayer
.
layer
);
allDepths
.
push
(
startDepth
);
allValues
.
push
(
layer
.
layer
);
}
else
{
// 连续,只添加当前层位的起始深度(边界点)
allDepths
.
push
(
startDepth
);
allValues
.
push
(
layer
.
layer
);
}
}
// 添加当前层位的结束深度(最后一个层位必须添加)
if
(
index
===
visibleLayers
.
length
-
1
||
endDepth
!==
visibleLayers
[
index
+
1
].
startDepth
)
{
allDepths
.
push
(
endDepth
);
allValues
.
push
(
layer
.
layer
);
}
});
console
.
log
(
'构建的深度数组长度:'
,
allDepths
.
length
);
console
.
log
(
'构建的值数组长度:'
,
allValues
.
length
);
console
.
log
(
'深度数组前10个:'
,
allDepths
.
slice
(
0
,
10
));
console
.
log
(
'值数组前10个:'
,
allValues
.
slice
(
0
,
10
));
console
.
log
(
'层位范围详情:'
,
visibleLayers
.
map
(
l
=>
({
layer
:
l
.
layer
,
start
:
l
.
startDepth
,
end
:
l
.
endDepth
,
inRange
:
l
.
startDepth
>=
dataMinDepth
&&
l
.
endDepth
<=
dataMaxDepth
})));
layerTrack
.
addChild
(
new
Group
()
.
setLayout
(
new
CssLayout
())
.
addChild
(
new
LogMudLogSection
({
'fillstyles'
:
(
depth
,
text
,
i
)
=>
{
const
layerInfo
=
visibleLayers
.
find
(
range
=>
depth
>=
range
.
startDepth
&&
depth
<
range
.
endDepth
);
const
color
=
layerInfo
?
this
.
layerColors
[
layerInfo
.
layer
]
:
'#FFFFFF'
;
return
color
;
},
'textstyles'
:
{
'color'
:
'#FFFFFF !important'
,
'font'
:
'bold 14px Arial'
,
'alignment'
:
'center'
,
'baseline'
:
'middle'
,
'angle'
:
0
,
'fillstyle'
:
{
'color'
:
'#FFFFFF !important'
},
'css'
:
{
'writing-mode'
:
'vertical-rl'
,
'text-orientation'
:
'upright'
,
'white-space'
:
'nowrap'
,
'text-shadow'
:
'1px 1px 2px rgba(0,0,0,0.8)'
,
'color'
:
'#FFFFFF !important'
}
},
'displaytext'
:
(
depth
,
text
)
=>
{
const
layerInfo
=
visibleLayers
.
find
(
range
=>
depth
>=
range
.
startDepth
&&
depth
<
range
.
endDepth
);
if
(
!
layerInfo
)
return
''
;
return
`<div style="color: white !important; font-weight: bold; font-size: 14px; writing-mode: vertical-rl; text-orientation: upright; text-shadow: 1px 1px 3px black; width: 100%; text-align: center;">
${
layerInfo
.
layer
}
</div>`
;
},
'textposition'
:
'center'
,
'textoptions'
:
{
'horizontaloffset'
:
0
,
'sectionheight'
:
20
,
'verticaloffset'
:
0
,
'wordwrap'
:
false
,
'useHTML'
:
true
}
})
.
setDepthsAndValues
(
allDepths
,
allValues
)
.
setEllipsisString
(
''
)
)
);
}
else
{
console
.
warn
(
'没有可见的层位数据'
);
}
}
// 单轴线压强度轨道 - 无论是否有数据都创建轨道和表头
const
dzkTrack
=
widget
.
addTrack
(
TrackType
.
LinearTrack
)
.
setWidth
(
100
)
.
addChild
(
new
Group
()
.
setLayout
(
new
CssLayout
())
.
setLayoutStyle
({
'left'
:
'0%'
,
'right'
:
'0%'
,
'top'
:
'-45px'
,
'height'
:
'45px'
})
);
// 添加单轴线压强度曲线(如果有数据)
const
dzkCurve
=
this
.
createCurve
(
0
,
20
,
'单轴线压强度'
,
'orange'
);
if
(
dzkCurve
!==
null
)
{
dzkTrack
.
addChild
(
dzkCurve
);
}
// 岩石可钻性级值轨道 - 无论是否有数据都创建轨道和表头
const
yskzTrack
=
widget
.
addTrack
(
TrackType
.
LinearTrack
)
.
setWidth
(
100
)
.
addChild
(
new
Group
()
.
setLayout
(
new
CssLayout
())
.
setLayoutStyle
({
'left'
:
'0%'
,
'right'
:
'0%'
,
'top'
:
'-45px'
,
'height'
:
'45px'
})
);
// 添加岩石可钻性级值曲线(如果有数据)
const
yskzCurve
=
this
.
createCurve
(
0
,
20
,
'岩石可钻性级值'
,
'orange'
);
if
(
yskzCurve
!==
null
)
{
yskzTrack
.
addChild
(
yskzCurve
);
}
// 研磨性系数轨道 - 无论是否有数据都创建轨道和表头
const
ymzsTrack
=
widget
.
addTrack
(
TrackType
.
LinearTrack
)
.
setWidth
(
100
)
.
addChild
(
new
Group
()
.
setLayout
(
new
CssLayout
())
.
setLayoutStyle
({
'left'
:
'0%'
,
'right'
:
'0%'
,
'top'
:
'-45px'
,
'height'
:
'45px'
})
);
// 添加研磨性系数曲线(如果有数据)
const
ymzsCurve
=
this
.
createCurve
(
0
,
20
,
'研磨性系数'
,
'#7cb342'
);
if
(
ymzsCurve
!==
null
)
{
ymzsTrack
.
addChild
(
ymzsCurve
);
}
// 均质性系数轨道 - 无论是否有数据都创建轨道和表头
const
cjzsTrack
=
widget
.
addTrack
(
TrackType
.
LinearTrack
)
.
setWidth
(
80
)
.
addChild
(
new
Group
()
.
setLayout
(
new
CssLayout
())
.
setLayoutStyle
({
'left'
:
'0%'
,
'right'
:
'0%'
,
'top'
:
'-45px'
,
'height'
:
'45px'
})
);
// 添加均质性系数曲线(如果有数据)
const
cjzsCurve
=
this
.
createCurve
(
0
,
20
,
'均质性系数'
,
'orange'
);
if
(
cjzsCurve
!==
null
)
{
cjzsTrack
.
addChild
(
cjzsCurve
);
}
// 添加钻头体和布齿密度相关列
const
styles
=
[
'#A1FE44'
,
'#fafafa'
];
const
styles2
=
[
'#FDFC3E'
,
'#fafafa'
];
const
styles3
=
[
'#FFA616'
,
'#fafafa'
];
const
styles5
=
[
'#48FEFE'
,
'#fafafa'
];
const
styles6
=
[
'#1212FE'
,
'#fafafa'
];
// 通用函数来添加带检查的track
const
addTrackWithCheck
=
(
widget
,
dataKey
,
stylePair
,
width
=
30
)
=>
{
if
(
!
this
.
curveData
[
dataKey
]
||
!
Array
.
isArray
(
this
.
curveData
[
dataKey
]))
{
console
.
warn
(
`
${
dataKey
}
数据无效,跳过创建`
);
widget
.
addTrack
(
TrackType
.
LinearTrack
).
setWidth
(
width
);
return
;
}
// 检查mc数据
if
(
!
this
.
curveData
[
'mc'
]
||
!
Array
.
isArray
(
this
.
curveData
[
'mc'
]))
{
console
.
warn
(
`mc 数据无效,使用空数组`
);
this
.
curveData
[
'mc'
]
=
Array
(
this
.
curveData
[
dataKey
].
length
).
fill
(
' '
);
}
// 确保mc数据长度足够
while
(
this
.
curveData
[
'mc'
].
length
<
this
.
curveData
[
dataKey
].
length
)
{
this
.
curveData
[
'mc'
].
push
(
' '
);
}
console
.
log
(
`添加
${
dataKey
}
轨道:`
,
{
dataLength
:
this
.
curveData
[
dataKey
].
length
,
mcLength
:
this
.
curveData
[
'mc'
].
length
,
sampleData
:
this
.
curveData
[
dataKey
].
slice
(
0
,
5
),
sampleMc
:
this
.
curveData
[
'mc'
].
slice
(
0
,
5
)
});
widget
.
addTrack
(
TrackType
.
LinearTrack
)
.
setName
(
" "
)
.
setWidth
(
width
)
.
addChild
(
new
LogMudLogSection
({
'fillstyles'
:
(
depth
,
text
,
i
)
=>
{
const
style
=
i
===
2
?
'#fdd835'
:
stylePair
[
i
%
2
];
return
style
;
}
})
.
setDepthsAndValues
(
this
.
curveData
[
dataKey
],
this
.
curveData
[
'mc'
])
.
setEllipsisString
(
' '
)
);
};
// 布齿密度
if
(
this
.
curveData
[
'布齿密度(低)'
])
{
addTrackWithCheck
(
widget
,
'布齿密度(低)'
,
styles
);
}
if
(
this
.
curveData
[
'布齿密度(中)'
])
{
addTrackWithCheck
(
widget
,
'布齿密度(中)'
,
styles2
);
}
console
.
log
(
'准备添加布齿密度(高):'
,
this
.
curveData
[
'布齿密度(高)'
]);
if
(
this
.
curveData
[
'布齿密度(高)'
]
&&
Array
.
isArray
(
this
.
curveData
[
'布齿密度(高)'
])
&&
this
.
curveData
[
'布齿密度(高)'
].
length
>
0
)
{
console
.
log
(
'添加布齿密度(高)轨道'
);
addTrackWithCheck
(
widget
,
'布齿密度(高)'
,
styles3
);
}
else
{
console
.
warn
(
'布齿密度(高)数据无效,跳过创建轨道'
);
widget
.
addTrack
(
TrackType
.
LinearTrack
).
setWidth
(
30
);
}
// 刀翼数4-8
[
'4'
,
'5'
,
'6'
,
'7'
,
'8'
].
forEach
((
num
,
index
)
=>
{
const
key
=
`刀翼数
${
num
}
`
;
if
(
this
.
curveData
[
key
])
{
addTrackWithCheck
(
widget
,
key
,
[
styles
,
styles2
,
styles5
,
styles3
,
styles
][
index
]);
}
});
// 冠部轮廓
[
'长抛物线'
,
'中等抛物线'
,
'短抛物线'
,
'圆形'
].
forEach
((
type
,
index
)
=>
{
const
key
=
`冠部轮廓(
${
type
}
)`
;
if
(
this
.
curveData
[
key
])
{
addTrackWithCheck
(
widget
,
key
,
[
styles
,
styles2
,
styles3
,
styles
][
index
]);
}
});
// 尺寸
[
'13'
,
'16'
,
'19'
,
'24'
].
forEach
((
size
,
index
)
=>
{
const
key
=
`尺寸(
${
size
}
)`
;
if
(
this
.
curveData
[
key
])
{
addTrackWithCheck
(
widget
,
key
,
[
styles
,
styles5
,
styles6
,
styles3
][
index
]);
}
});
// 后倾角
[
'15'
,
'18'
,
'20'
,
'25'
,
'30'
,
'35'
].
forEach
((
angle
,
index
)
=>
{
console
.
log
(
`正在添加后倾角(
${
angle
}
)轨道`
);
console
.
log
(
`数据:`
,
this
.
curveData
[
`后倾角(°)(
${
angle
}
)`
]);
const
styleArray
=
[
styles
,
styles3
,
styles2
,
styles5
,
styles6
,
styles3
];
addTrackWithCheck
(
widget
,
`后倾角(°)(
${
angle
}
)`
,
styleArray
[
index
],
30
);
});
// 添加层位图例
const
legendGroup
=
new
Group
()
.
setLayout
(
new
CssLayout
())
.
setLayoutStyle
({
'position'
:
'absolute'
,
'top'
:
'10px'
,
'right'
:
'100px'
,
// 调整图例位置,避免与开次信息重叠
'background'
:
'rgba(255, 255, 255, 0.9)'
,
'padding'
:
'10px'
,
'border'
:
'1px solid #ccc'
,
'borderRadius'
:
'4px'
,
'width'
:
'120px'
});
// 添加图例标题
const
legendTitle
=
new
Text
({
text
:
'层位图例'
,
textbaseline
:
'top'
,
textalign
:
'left'
})
.
setTextStyle
({
'color'
:
'#000000'
,
'font'
:
'bold 12px Roboto'
})
.
setLayoutStyle
({
'position'
:
'absolute'
,
'left'
:
'5px'
,
'top'
:
'5px'
});
legendGroup
.
addChild
(
legendTitle
);
// 添加图例项
this
.
uniqueLayers
.
forEach
((
layer
,
index
)
=>
{
const
legendItemGroup
=
new
Group
()
.
setLayout
(
new
CssLayout
())
.
setLayoutStyle
({
'position'
:
'absolute'
,
'left'
:
'5px'
,
'top'
:
`
${
index
*
25
+
30
}
px`
,
'width'
:
'110px'
,
'height'
:
'20px'
});
// 创建颜色块
const
colorBox
=
new
Group
()
.
setLayout
(
new
CssLayout
())
.
setLayoutStyle
({
'position'
:
'absolute'
,
'left'
:
'0px'
,
'top'
:
'2px'
,
'width'
:
'15px'
,
'height'
:
'15px'
,
'background'
:
this
.
layerColors
[
layer
],
'border'
:
'1px solid #ccc'
});
// 创建文本标签
const
legendText
=
new
Text
({
text
:
layer
,
textbaseline
:
'top'
,
textalign
:
'left'
})
.
setTextStyle
({
'color'
:
'#000000'
,
'font'
:
'10px Roboto'
})
.
setLayoutStyle
({
'position'
:
'absolute'
,
'left'
:
'25px'
,
'top'
:
'2px'
});
legendItemGroup
.
addChild
(
colorBox
);
legendItemGroup
.
addChild
(
legendText
);
legendGroup
.
addChild
(
legendItemGroup
);
});
widget
.
addChild
(
legendGroup
);
widget
.
setLayoutStyle
({
'top'
:
0
,
'left'
:
0
,
'bottom'
:
0
,
'width'
:
1280
});
const
plot
=
new
Plot
({
'canvasElement'
:
canvas
,
'autosize'
:
false
,
'root'
:
widget
});
//适应大小
widget
.
fitToHeight
();
// 完全禁用 widget 的工具,防止拖动
try
{
const
widgetTool
=
widget
.
getTool
();
if
(
widgetTool
)
{
// 禁用所有工具
if
(
widgetTool
.
setEnabled
)
{
widgetTool
.
setEnabled
(
false
);
}
}
}
catch
(
e
)
{
console
.
warn
(
'无法禁用 widget 工具:'
,
e
);
}
// 不添加 widget 的工具到 plot,避免拖动功能
// plot.getTool().add(widget.getTool());
// 通过事件监听完全阻止 header 区域的所有鼠标交互(防止拖动)
const
canvasElement
=
canvas
;
const
headerHeight
=
120
;
// header 高度,稍微大一点确保覆盖
// 完全阻止 header 区域的所有鼠标事件
const
blockAllHeaderEvents
=
(
e
)
=>
{
const
rect
=
canvasElement
.
getBoundingClientRect
();
const
y
=
e
.
clientY
-
rect
.
top
;
// 如果在 header 区域,完全阻止所有事件
if
(
y
<
headerHeight
)
{
e
.
preventDefault
();
e
.
stopPropagation
();
e
.
stopImmediatePropagation
();
return
false
;
}
};
// 使用捕获阶段,设置为非 passive,确保可以阻止默认行为
const
eventOptions
=
{
capture
:
true
,
passive
:
false
};
// 阻止 header 区域的所有鼠标事件
canvasElement
.
addEventListener
(
'mousedown'
,
blockAllHeaderEvents
,
eventOptions
);
canvasElement
.
addEventListener
(
'mousemove'
,
blockAllHeaderEvents
,
eventOptions
);
canvasElement
.
addEventListener
(
'mouseup'
,
blockAllHeaderEvents
,
eventOptions
);
canvasElement
.
addEventListener
(
'click'
,
blockAllHeaderEvents
,
eventOptions
);
canvasElement
.
addEventListener
(
'dblclick'
,
blockAllHeaderEvents
,
eventOptions
);
canvasElement
.
addEventListener
(
'contextmenu'
,
blockAllHeaderEvents
,
eventOptions
);
// 阻止所有拖动事件
canvasElement
.
addEventListener
(
'dragstart'
,
blockAllHeaderEvents
,
eventOptions
);
canvasElement
.
addEventListener
(
'drag'
,
blockAllHeaderEvents
,
eventOptions
);
canvasElement
.
addEventListener
(
'dragend'
,
blockAllHeaderEvents
,
eventOptions
);
canvasElement
.
addEventListener
(
'dragover'
,
blockAllHeaderEvents
,
eventOptions
);
canvasElement
.
addEventListener
(
'drop'
,
blockAllHeaderEvents
,
eventOptions
);
// 通过 CSS 禁用用户选择
canvasElement
.
style
.
userSelect
=
'none'
;
canvasElement
.
style
.
webkitUserSelect
=
'none'
;
canvasElement
.
style
.
mozUserSelect
=
'none'
;
canvasElement
.
style
.
msUserSelect
=
'none'
;
canvasElement
.
style
.
pointerEvents
=
'auto'
;
// 确保事件可以捕获
// 图表初始化完成后渲染开次信息
this
.
renderGroupedKcList
();
return
plot
;
},
//自定义css样式
applyModernThemeCSS
(
widget
)
{
widget
.
setCss
(
new
CssStyle
(
{
'css'
:
[
'* {'
,
//字体颜色
' textstyle-font : 10px Roboto;'
,
' textstyle-color : #000;'
,
'}'
,
'.geotoolkit.welllog.header.AdaptiveLogCurveVisualHeader {'
,
' element-tracking-textstyle-font : bold 10px Roboto;'
,
//头部数字颜色
' element-tracking-textstyle-color : #000;'
,
'}'
,
//头部样式
'.geotoolkit.welllog.header.LogTrackHeader {'
,
//线性渐变
' borderfillstyle-style: lineargradient;'
,
//绝对坐标
' borderfillstyle-unittype: absoluteCoordinates;'
,
' borderfillstyle-startpoint-x: 0;'
,
' borderfillstyle-startpoint-y: 0;'
,
//头部背景色
' borderfillstyle-startcolor: rgba(255, 255, 255, 0);'
,
' borderfillstyle-endpoint-x: 0;'
,
' borderfillstyle-endpoint-y: 500;'
,
//头部背景色-渐变色
' borderfillstyle-endcolor: rgba(255, 255, 255, 0);'
,
//头部边框色
' borderlinestyle: null;'
,
// if it is null then we use track border line style
' isbordervisible: true;'
,
' borders-left: true;'
,
' borders-top: true;'
,
' borders-right: true;'
,
' borders-bottom: true;'
,
'}'
,
//网格样式
'.geotoolkit.welllog.LogTrack {'
,
//线性渐变
' backgroundcolor-style: lineargradient;'
,
//绝对坐标
' backgroundcolor-unittype: absoluteCoordinates;'
,
' backgroundcolor-startpoint-x: 0;'
,
' backgroundcolor-startpoint-y: 0;'
,
//网格背景色
' backgroundcolor-startcolor: rgba(255, 255, 255, 0);'
,
' backgroundcolor-endpoint-x: 0;'
,
' backgroundcolor-endpoint-y: 500;'
,
' backgroundcolor-endcolor: rgba(255, 255, 255, 0);'
,
' clipping : true;'
,
' borderstrategy: top;'
,
' border-visible : true;'
,
' border-borderstyle: visible-bounds;'
,
' border-linestyle-color: #000;'
,
' border-linestyle-weight: blod;'
,
' border-linestyle-pixelsnapmode-x: true;'
,
' border-linestyle-pixelsnapmode-y: true;'
,
' border-borders-left : true;'
,
' border-borders-right : true;'
,
' border-borders-top : true;'
,
' border-borders-bottom : true;'
,
'}'
,
'.geotoolkit.welllog.LogAxis {'
,
//坐标字体颜色
' tickgenerator-major-labelstyle-color: red;'
,
' tickgenerator-major-labelstyle-font: 10px Roboto;'
,
//坐标字体颜色
' tickgenerator-major-tickstyle-color: #C8C8C8;'
,
//坐标横线粗细
' tickgenerator-major-tickstyle-width: 1;'
,
' tickgenerator-major-tickstyle-pixelsnapmode-x: true;'
,
' tickgenerator-major-tickstyle-pixelsnapmode-y: true;'
,
' tickgenerator-minor-tickstyle-color: #646464;'
,
' tickgenerator-edge-labelstyle-color: red;'
,
' tickgenerator-edge-tickstyle-color: #EFFFFF;'
,
' tickgenerator-edge-labelstyle-font: 10px Roboto;'
,
'}'
,
'.geotoolkit.welllog.LogCurve:highlight {'
,
' linestyle-width: 2;'
,
' linestyle-shadow-enable: true;'
,
' linestyle-shadow-blur: 2;'
,
' linestyle-shadow-offsetx: 0;'
,
' linestyle-shadow-offsety: 0;'
,
'}'
,
'.geotoolkit.welllog.LogTrack:highlight {'
,
' borderstrategy: top;'
,
// 高亮的边框颜色
' linestyle-color: grey;'
,
' linestyle-width: 2;'
,
' linestyle-shadow-enable: true;'
,
' linestyle-shadow-blur: 2;'
,
' linestyle-shadow-offsetx: 0;'
,
' linestyle-shadow-offsety: 0;'
,
'}'
].
join
(
''
)
}))
},
//井结构数据
registerSchematicComponents
(
arr
,
data
)
{
const
components
=
arr
.
map
((
component
)
=>
{
const
{
name
,
from
,
to
,
outer
,
inner
}
=
component
;
data
.
addComponent
(
name
,
{
geometry
:
{
depth
:
{
from
,
to
},
diameter
:
{
outer
,
inner
}
}
});
return
JSON
.
parse
(
JSON
.
stringify
(
data
.
getComponents
().
slice
(
-
1
)[
0
]));
});
return
components
;
},
//井结构
createSchematicRegistry
()
{
const
factoryRegistry
=
new
ComponentNodeFactoryRegistry
(
false
);
factoryRegistry
.
setFactory
(
'tubing'
,
(
data
)
=>
new
NodeTubingBW
(
data
));
factoryRegistry
.
setFactory
(
'cement'
,
(
data
)
=>
new
NodeCementBW
(
data
));
factoryRegistry
.
setFactory
(
'casing'
,
(
data
)
=>
new
NodeCasingBW
(
data
));
return
factoryRegistry
;
},
//曲线
createCurve
(
from
,
step
,
curveMnemonic
,
color
)
{
try
{
// 数据验证
if
(
!
this
.
curveData
)
{
console
.
warn
(
'curveData 对象不存在'
);
return
null
;
}
const
values
=
this
.
curveData
[
curveMnemonic
];
if
(
!
values
||
!
Array
.
isArray
(
values
)
||
values
.
length
===
0
)
{
console
.
warn
(
`
${
curveMnemonic
}
的数据无效:`
,
values
);
return
null
;
}
// 创建深度数组
const
depths
=
Array
.
from
({
length
:
values
.
length
},
(
_
,
i
)
=>
from
+
i
*
step
);
// 创建数据对象
const
data
=
new
LogData
(
depths
,
values
);
// 计算限制
let
limits
;
try
{
limits
=
MathUtil
.
calculateNeatLimits
(
data
.
getMinValue
(),
data
.
getMaxValue
(),
false
,
false
);
}
catch
(
e
)
{
console
.
warn
(
`计算
${
curveMnemonic
}
的限制时出错:`
,
e
);
limits
=
[
0
,
1
];
// 默认限制
}
// 创建曲线
return
new
LogCurve
(
data
)
.
setName
(
curveMnemonic
)
.
setNormalizationLimits
(
limits
)
.
setLineStyle
({
'color'
:
color
,
'width'
:
1
});
}
catch
(
e
)
{
console
.
error
(
`创建曲线
${
curveMnemonic
}
时出错:`
,
e
);
return
null
;
}
},
//对数曲线
createLogCurve
(
name
,
depths
,
values
,
color
)
{
const
data
=
new
LogData
({
'name'
:
name
,
'depths'
:
depths
,
'values'
:
values
,
'indexunit'
:
'ft'
});
return
new
LogCurve
(
data
)
.
setLineStyle
({
'color'
:
color
,
'width'
:
2
});
},
// 添加数据过滤函数
filterValidData
(
data
,
name
)
{
if
(
!
data
||
!
Array
.
isArray
(
data
))
{
console
.
warn
(
`
${
name
}
数据无效或为空`
);
return
[];
// 始终返回空数组而不是 null
}
// 对于所有数据类型,确保返回的是数组
if
(
data
.
length
===
0
)
{
console
.
warn
(
`
${
name
}
数据长度为0`
);
return
[];
}
// 如果是mc数据,确保它有足够的长度
if
(
name
===
'mc'
&&
(
!
Array
.
isArray
(
data
)
||
data
.
length
===
0
))
{
// 返回一个足够长的空字符串数组
return
Array
(
200
).
fill
(
' '
);
}
// 对于尺寸相关的数据特殊处理
if
(
name
.
startsWith
(
'尺寸('
))
{
console
.
log
(
`处理
${
name
}
数据开始`
);
console
.
log
(
`原始数据长度:
${
data
.
length
}
`
);
// 确保数据是数值类型且有效
const
validData
=
data
.
filter
(
value
=>
value
!==
null
&&
value
!==
undefined
&&
!
isNaN
(
value
)
&&
value
!==
0
);
if
(
validData
.
length
===
0
)
{
console
.
warn
(
`
${
name
}
没有有效数据点`
);
return
[];
}
console
.
log
(
`
${
name
}
有效数据点数量:
${
validData
.
length
}
`
);
return
validData
;
}
// 特殊处理层位数据
if
(
name
===
'层位'
)
{
if
(
!
data
||
!
Array
.
isArray
(
data
))
{
console
.
warn
(
'层位数据无效或为空'
);
return
[];
// 返回空数组而不是null
}
const
layerRanges
=
[];
let
currentLayer
=
null
;
let
startDepth
=
null
;
data
.
forEach
((
value
,
index
)
=>
{
const
depth
=
this
.
scale1
+
index
*
0.5
;
if
(
value
&&
value
!==
currentLayer
)
{
if
(
currentLayer
)
{
layerRanges
.
push
({
layer
:
currentLayer
,
startDepth
:
startDepth
,
endDepth
:
depth
});
}
currentLayer
=
value
;
startDepth
=
depth
;
}
});
if
(
currentLayer
)
{
layerRanges
.
push
({
layer
:
currentLayer
,
startDepth
:
startDepth
,
endDepth
:
this
.
scale
});
}
return
layerRanges
.
length
>
0
?
layerRanges
:
[];
}
// 特殊处理钻头尺寸数据
if
(
name
.
includes
(
'钻头尺寸'
))
{
console
.
log
(
`处理
${
name
}
数据,数据长度:
${
data
.
length
}
`
);
// 如果是对象数组格式,直接返回,不进行过滤
if
(
data
.
length
>
0
&&
typeof
data
[
0
]
===
'object'
&&
data
[
0
].
hasOwnProperty
(
'dept'
)
&&
data
[
0
].
hasOwnProperty
(
'ztcc'
))
{
console
.
log
(
`
${
name
}
是对象数组格式,直接返回`
);
return
data
;
}
// 对于普通数组格式的处理
// 检查是否所有值都相同
const
isAllSameValue
=
data
.
every
(
val
=>
val
===
data
[
0
]);
console
.
log
(
`
${
name
}
数据是否全部相同:
${
isAllSameValue
}
, 第一个值:
${
data
[
0
]}
`
);
// 如果数据量太大,进行采样
if
(
data
.
length
>
1000
)
{
const
sampledData
=
[];
// 每100个点取一个,确保至少有20个点
const
sampleRate
=
Math
.
max
(
1
,
Math
.
floor
(
data
.
length
/
20
));
// 确保至少包含第一个和最后一个点
sampledData
.
push
(
data
[
0
]);
for
(
let
i
=
sampleRate
;
i
<
data
.
length
-
sampleRate
;
i
+=
sampleRate
)
{
sampledData
.
push
(
data
[
i
]);
}
// 添加最后一个点
if
(
data
.
length
>
1
)
{
sampledData
.
push
(
data
[
data
.
length
-
1
]);
}
console
.
log
(
`
${
name
}
数据采样后长度:
${
sampledData
.
length
}
`
);
return
sampledData
;
}
// 数据量不大,直接返回
return
data
;
}
// 其他数据的处理保持不变
const
validData
=
[];
let
totalPoints
=
0
;
let
validPoints
=
0
;
data
.
forEach
((
value
,
index
)
=>
{
totalPoints
++
;
if
(
value
!==
0
)
{
validPoints
++
;
validData
.
push
({
depth
:
this
.
scale1
+
index
*
0.5
,
value
:
value
});
}
});
if
(
validData
.
length
>
0
)
{
console
.
log
(
`[
${
name
}
] 数据统计:`
);
console
.
log
(
`- 总数据点:
${
totalPoints
}
`
);
console
.
log
(
`- 有效数据点:
${
validPoints
}
`
);
console
.
log
(
`- 有效率:
${((
validPoints
/
totalPoints
)
*
100
).
toFixed
(
2
)}
%`
);
console
.
log
(
`- 数据范围:
${
Math
.
min
(...
validData
.
map
(
d
=>
d
.
value
))}
~
${
Math
.
max
(...
validData
.
map
(
d
=>
d
.
value
))}
`
);
}
else
{
console
.
warn
(
`[
${
name
}
] 未找到有效数据点`
);
}
return
validData
.
map
(
item
=>
item
.
value
);
},
// 生成随机颜色
generateRandomColor
(
index
)
{
// 使用预定义的颜色
if
(
index
<
this
.
predefinedColors
.
length
)
{
console
.
log
(
`为层位分配预定义颜色:
${
this
.
predefinedColors
[
index
]}
`
);
return
this
.
predefinedColors
[
index
];
}
// 如果预定义颜色用完,生成随机颜色
const
letters
=
'0123456789ABCDEF'
;
let
color
=
'#'
;
for
(
let
i
=
0
;
i
<
6
;
i
++
)
{
color
+=
letters
[
Math
.
floor
(
Math
.
random
()
*
16
)];
}
console
.
log
(
`生成随机颜色:
${
color
}
`
);
return
color
;
},
// 处理层位数据
processLayerData
(
layerRanges
)
{
if
(
!
layerRanges
||
!
Array
.
isArray
(
layerRanges
)
||
layerRanges
.
length
===
0
)
{
console
.
warn
(
'层位数据无效,使用默认值'
);
this
.
uniqueLayers
=
[];
this
.
layerColors
=
{};
return
{
uniqueLayers
:
[],
layerColors
:
{},
layerRanges
:
[]
};
}
// 获取唯一的层位值
const
uniqueLayers
=
[...
new
Set
(
layerRanges
.
map
(
item
=>
item
.
layer
))];
console
.
log
(
'唯一层位列表:'
,
uniqueLayers
);
// 为每个层位生成颜色
const
layerColors
=
{};
uniqueLayers
.
forEach
((
layer
,
index
)
=>
{
const
color
=
this
.
generateRandomColor
(
index
);
console
.
log
(
`为层位
${
layer
}
分配颜色:
${
color
}
`
);
this
.
$set
(
layerColors
,
layer
,
color
);
});
this
.
uniqueLayers
=
uniqueLayers
;
this
.
layerColors
=
layerColors
;
return
{
uniqueLayers
,
layerColors
,
layerRanges
};
},
// 解析开次数据,提取每个开次的完整深度区间(处理连续深度点)
parseKcDepthRanges
()
{
if
(
!
this
.
kcList
.
length
||
!
this
.
kcList
[
0
].
hasOwnProperty
(
'kc'
)
||
!
this
.
kcList
[
0
].
hasOwnProperty
(
'dept'
))
{
console
.
warn
(
'开次数据格式错误,需包含 kc(开次名称)和 dept(深度)'
);
return
[];
}
// 1. 先按深度排序(确保深度从浅到深)
const
sortedKcList
=
[...
this
.
kcList
].
sort
((
a
,
b
)
=>
a
.
dept
-
b
.
dept
);
const
kcRanges
=
[];
let
currentKc
=
null
;
let
currentRange
=
null
;
// 2. 遍历排序后的深度点,提取连续的开次区间
sortedKcList
.
forEach
((
item
)
=>
{
const
{
kc
,
dept
}
=
item
;
// 如果是新的开次,或当前开次的深度不连续(间隔超过0.5m,可根据你的数据精度调整)
if
(
kc
!==
currentKc
||
(
currentRange
&&
dept
-
currentRange
.
endDepth
>
0.5
))
{
// 保存上一个开次的区间
if
(
currentRange
)
{
kcRanges
.
push
(
currentRange
);
}
// 初始化新的开次区间
currentKc
=
kc
;
currentRange
=
{
kc
:
kc
,
startDepth
:
dept
,
// 区间起始深度
endDepth
:
dept
,
// 区间结束深度(初始等于起始深度)
depthPoints
:
[
dept
]
// 存储该区间的所有深度点(用于校验)
};
}
else
{
// 同一开次且深度连续,更新区间结束深度
currentRange
.
endDepth
=
dept
;
currentRange
.
depthPoints
.
push
(
dept
);
}
});
// 3. 保存最后一个开次的区间
if
(
currentRange
)
{
kcRanges
.
push
(
currentRange
);
}
console
.
log
(
'解析后的开次深度区间:'
,
kcRanges
);
return
kcRanges
;
},
// 渲染开次信息
renderGroupedKcList
()
{
console
.
log
(
'开始渲染开次信息...'
);
const
container
=
this
.
$refs
.
kcListContainer
;
if
(
!
container
)
{
console
.
error
(
'开次容器未找到'
);
return
;
}
// 检查开次数据
if
(
!
this
.
kcList
||
this
.
kcList
.
length
===
0
)
{
console
.
warn
(
'没有开次数据'
);
container
.
innerHTML
=
'<div style="text-align:center; padding:10px; color:#999; font-size:12px;">无开次数据</div>'
;
return
;
}
console
.
log
(
'开次数据:'
,
this
.
kcList
);
// 按开次分组
const
kcGroups
=
{};
this
.
kcList
.
forEach
(
item
=>
{
if
(
!
kcGroups
[
item
.
kc
])
{
kcGroups
[
item
.
kc
]
=
[];
}
kcGroups
[
item
.
kc
].
push
(
item
.
dept
);
});
console
.
log
(
'开次分组:'
,
kcGroups
);
// 计算每个开次的深度范围
const
kcRanges
=
[];
Object
.
keys
(
kcGroups
).
forEach
(
kcName
=>
{
const
depths
=
kcGroups
[
kcName
].
sort
((
a
,
b
)
=>
a
-
b
);
kcRanges
.
push
({
kc
:
kcName
,
startDepth
:
Math
.
min
(...
depths
),
endDepth
:
Math
.
max
(...
depths
),
pointCount
:
depths
.
length
});
});
// 按起始深度排序
kcRanges
.
sort
((
a
,
b
)
=>
a
.
startDepth
-
b
.
startDepth
);
console
.
log
(
'开次范围:'
,
kcRanges
);
// 获取图表参数
const
chartStartDepth
=
this
.
scale1
;
const
chartEndDepth
=
this
.
scale
;
const
chartTotalDepth
=
chartEndDepth
-
chartStartDepth
;
// 获取widget的实际绘制区域高度
let
actualChartHeight
=
600
;
if
(
this
.
widgetInstance
)
{
try
{
const
bounds
=
this
.
widgetInstance
.
getBounds
();
actualChartHeight
=
bounds
.
getHeight
()
-
90
;
// 减去头部高度
console
.
log
(
'Widget实际高度:'
,
actualChartHeight
);
}
catch
(
e
)
{
console
.
warn
(
'无法获取widget高度,使用默认值'
);
}
}
console
.
log
(
'图表深度范围:'
,
chartStartDepth
,
'-'
,
chartEndDepth
,
'总深度:'
,
chartTotalDepth
,
'图表高度:'
,
actualChartHeight
);
// 清空容器
container
.
innerHTML
=
""
;
// 颜色配置
const
colors
=
[
{
bg
:
'rgba(76, 175, 80, 0.3)'
,
border
:
'#4caf50'
,
text
:
'#2e7d32'
},
{
bg
:
'rgba(33, 150, 243, 0.3)'
,
border
:
'#2196f3'
,
text
:
'#1565c0'
},
{
bg
:
'rgba(255, 152, 0, 0.3)'
,
border
:
'#ff9800'
,
text
:
'#e65100'
},
{
bg
:
'rgba(156, 39, 176, 0.3)'
,
border
:
'#9c27b0'
,
text
:
'#4a148c'
},
{
bg
:
'rgba(244, 67, 54, 0.3)'
,
border
:
'#f44336'
,
text
:
'#b71c1c'
},
{
bg
:
'rgba(0, 150, 136, 0.3)'
,
border
:
'#009688'
,
text
:
'#004d40'
}
];
// 渲染每个开次
kcRanges
.
forEach
((
range
,
index
)
=>
{
const
{
kc
,
startDepth
,
endDepth
,
pointCount
}
=
range
;
console
.
log
(
`处理开次
${
kc
}
:
${
startDepth
}
-
${
endDepth
}
m, 图表范围:
${
chartStartDepth
}
-
${
chartEndDepth
}
m`
);
const
color
=
colors
[
index
%
colors
.
length
];
// 严格按照深度比例计算位置,使用实际图表高度
const
topPos
=
((
startDepth
-
chartStartDepth
)
/
chartTotalDepth
)
*
actualChartHeight
;
const
bottomPos
=
((
endDepth
-
chartStartDepth
)
/
chartTotalDepth
)
*
actualChartHeight
;
const
height
=
Math
.
max
(
bottomPos
-
topPos
,
25
);
// 最小高度25px
console
.
log
(
`开次
${
kc
}
: 起始深度
${
startDepth
}
m ->
${
topPos
.
toFixed
(
1
)}
px, 结束深度
${
endDepth
}
m ->
${
bottomPos
.
toFixed
(
1
)}
px, 高度
${
height
.
toFixed
(
1
)}
px`
);
// 检查开次是否与当前图表显示范围有交集
const
hasOverlap
=
!
(
endDepth
<
chartStartDepth
||
startDepth
>
chartEndDepth
);
if
(
!
hasOverlap
)
{
console
.
log
(
`开次
${
kc
}
与当前显示范围无交集,但仍然显示`
);
}
// 创建背景条
const
bgDiv
=
document
.
createElement
(
'div'
);
bgDiv
.
style
.
cssText
=
`
position: absolute;
top:
${
topPos
}
px;
left: 0;
width: 100%;
height:
${
height
}
px;
background-color:
${
color
.
bg
}
;
border-left: 3px solid
${
color
.
border
}
;
border-radius: 0 4px 4px 0;
`
;
container
.
appendChild
(
bgDiv
);
// 创建标签
const
labelDiv
=
document
.
createElement
(
'div'
);
labelDiv
.
style
.
cssText
=
`
position: absolute;
top:
${
topPos
+
height
/
2
}
px;
left: 2px;
width: 76px;
transform: translateY(-50%);
text-align: center;
font-size: 10px;
font-weight: bold;
color:
${
color
.
text
}
;
background-color: rgba(255,255,255,0.9);
border: 1px solid
${
color
.
border
}
;
border-radius: 3px;
padding: 2px;
cursor: pointer;
`
;
labelDiv
.
innerHTML
=
`
<div style="font-size: 12px; font-weight: bold; color:
${
color
.
text
}
;">
${
kc
}
</div>
`
;
// 点击事件
labelDiv
.
addEventListener
(
'click'
,
()
=>
{
console
.
log
(
`点击开次
${
kc
}
,跳转到推荐方案页面`
);
// 收集该开次的ztcc数据
const
kcZtccData
=
this
.
kcList
.
filter
(
item
=>
item
.
kc
===
kc
);
const
ztccValues
=
kcZtccData
.
map
(
item
=>
item
.
ztcc
);
const
uniqueZtccValues
=
[...
new
Set
(
ztccValues
)];
// 去重
console
.
log
(
`开次
${
kc
}
的ztcc数据:`
,
kcZtccData
);
console
.
log
(
`开次
${
kc
}
的ztcc值:`
,
uniqueZtccValues
);
// 查找该开次的ksjs和jsjs值
const
kcData
=
this
.
kcList
.
find
(
item
=>
item
.
kc
===
kc
);
const
startDepth
=
kcData
?
kcData
.
ksjs
:
0
;
const
endDepth
=
kcData
?
kcData
.
jsjs
:
0
;
console
.
log
(
startDepth
,
'startDepth'
);
console
.
log
(
endDepth
,
'endDepth'
);
// 跳转到钻头设计参数推荐页面,传递开次信息
this
.
$router
.
push
({
name
:
'BitDesignRecommendation'
,
query
:
{
from
:
'main'
,
jh
:
this
.
jh
||
this
.
$route
.
query
.
jh
,
qk
:
this
.
qk
,
openingTimes
:
kc
,
startDepth
:
startDepth
.
toString
(),
// 确保转换为字符串
endDepth
:
endDepth
.
toString
(),
// 确保转换为字符串
pointCount
:
pointCount
,
ztccValues
:
JSON
.
stringify
(
uniqueZtccValues
),
// 将ztcc值数组转为JSON字符串传递
ztccData
:
JSON
.
stringify
(
kcZtccData
)
// 传递完整的ztcc数据
}
});
});
container
.
appendChild
(
labelDiv
);
});
console
.
log
(
'开次信息渲染完成'
);
},
// 跳转到钻头设计参数推荐页面
goToRecommendation
()
{
console
.
log
(
'跳转到钻头设计参数推荐页面'
)
// 使用路由跳转到推荐方案页面
this
.
$router
.
push
({
name
:
'BitDesignRecommendation'
,
query
:
{
from
:
'main'
,
jh
:
this
.
jh
,
qk
:
this
.
qk
}
})
},
// 跳转到钻头匹配页面
goToMatching
()
{
console
.
log
(
'跳转到钻头匹配页面'
)
// 使用路由跳转到匹配页面
this
.
$router
.
push
({
name
:
'BitMatching'
,
query
:
{
from
:
'main'
,
jh
:
this
.
jh
,
qk
:
this
.
qk
}
})
},
// 跳转到查看选型信息页面
goToSelectionInfo
()
{
console
.
log
(
'跳转到查看选型信息页面'
)
// 使用路由跳转到选型信息页面
this
.
$router
.
push
({
name
:
'BitSelectionInfo'
,
query
:
{
from
:
'main'
,
jh
:
this
.
jh
,
qk
:
this
.
qk
}
})
}
}
};
</
script
>
<
style
lang=
"scss"
scoped
>
.image
{
width
:
100%
;
height
:
450px
;
}
@media
screen
and
(
min-width
:
1400px
),
screen
and
(
min-height
:
800px
)
{
.image
{
height
:
650px
;
}
}
.box
{
margin
:
0
5px
;
min-height
:
600px
;
overflow-y
:
auto
;
}
.action-buttons
{
display
:
flex
;
gap
:
15px
;
margin-bottom
:
10px
;
padding
:
10px
;
background-color
:
#f5f7fa
;
border-radius
:
4px
;
}
div
#tooltip-container
{
z-index
:
100
;
margin-left
:
5px
;
opacity
:
1
;
text-align
:
left
;
color
:
rgb
(
73
,
73
,
73
);
padding-left
:
5px
;
padding-right
:
5px
;
background
:
rgba
(
255
,
255
,
204
,
0.5
);
border-radius
:
4px
;
border-width
:
1px
;
border-style
:
solid
;
border-color
:
grey
;
border-image
:
initial
;
width
:
150px
;
}
</
style
>
src/views/wellDesign/index.vue
View file @
344e397f
...
@@ -13,9 +13,12 @@
...
@@ -13,9 +13,12 @@
<el-tab-pane
label=
"地层岩石数据强度分析"
name=
"formationAnalysis"
>
<el-tab-pane
label=
"地层岩石数据强度分析"
name=
"formationAnalysis"
>
<formation-analysis
v-if=
"activeTab === 'formationAnalysis'"
:jh=
"wellInfo.jh"
/>
<formation-analysis
v-if=
"activeTab === 'formationAnalysis'"
:jh=
"wellInfo.jh"
/>
</el-tab-pane>
</el-tab-pane>
<el-tab-pane
label=
"
钻头设计参
数推荐"
name=
"bitDesign"
>
<el-tab-pane
label=
"
指
数推荐"
name=
"bitDesign"
>
<bit-design
v-if=
"activeTab === 'bitDesign'"
:well-info=
"wellInfo"
/>
<bit-design
v-if=
"activeTab === 'bitDesign'"
:well-info=
"wellInfo"
/>
</el-tab-pane>
</el-tab-pane>
<el-tab-pane
label=
"智能推荐"
name=
"bitDesigns"
>
<BitDesigns
v-if=
"activeTab === 'bitDesigns'"
:well-info=
"wellInfo"
/>
</el-tab-pane>
</el-tabs>
</el-tabs>
</div>
</div>
</
template
>
</
template
>
...
@@ -25,6 +28,7 @@ import WellStructure from './components/WellStructure.vue'
...
@@ -25,6 +28,7 @@ import WellStructure from './components/WellStructure.vue'
import
AdjacentWell
from
'./components/AdjacentWell.vue'
import
AdjacentWell
from
'./components/AdjacentWell.vue'
import
FormationAnalysis
from
'./components/FormationAnalysis.vue'
import
FormationAnalysis
from
'./components/FormationAnalysis.vue'
import
BitDesign
from
'./components/BitDesign.vue'
import
BitDesign
from
'./components/BitDesign.vue'
import
BitDesigns
from
'./components/BitDesign.vue'
import
FormationMaintenance
from
'./components/FormationMaintenance.vue'
import
FormationMaintenance
from
'./components/FormationMaintenance.vue'
export
default
{
export
default
{
name
:
'WellDesign'
,
name
:
'WellDesign'
,
...
@@ -33,6 +37,7 @@ export default {
...
@@ -33,6 +37,7 @@ export default {
AdjacentWell
,
AdjacentWell
,
FormationAnalysis
,
FormationAnalysis
,
BitDesign
,
BitDesign
,
BitDesigns
,
FormationMaintenance
FormationMaintenance
},
},
data
()
{
data
()
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment