Commit dfd5cc55 by jiang'yun

修改

parent fa53ed97
<template>
<div>
<el-tooltip content="设置" placement="bottom" effect="light">
<el-button @click="editProperties" :class="{ 'active': showLineStylePanel }">
<i class="el-icon-setting"></i>
</el-button>
</el-tooltip>
<el-tooltip content="上传文件" placement="bottom" effect="light">
<el-button @click="triggerFileUpload">
<i class="el-icon-upload"></i>
</el-button>
</el-tooltip>
<el-dialog title="设置" :visible.sync="showPropertiesDialog" width="100%">
<el-form ref="form" label-width="130px">
<el-row>
<el-col :span="5">
<el-form-item label="颜色集合">
<el-select v-model="colorMapSelect" placeholder="请选择颜色集合" @change="changeColor">
<el-option v-for="item in listNameColorMaps" :label="item" :value="item"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="归一化类型">
<el-select v-model="NormalizationType" @change="changeNor" placeholder="请选择归一化类型">
<el-option v-for="item in NormalizationTypeData" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="归一化比例">
<el-slider @change="changeNor" style="width: 180px;" v-model="NormalizationBl" :min="0.1" :max="5"
:step="0.1" show-stops>
</el-slider>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="每英寸道数">
<el-input v-model="mycds" @blur="changeMycds"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="5">
<el-form-item label="每秒英寸数">
<el-input v-model="msycs" @blur="changeMycds"></el-input>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="采样插值类型">
<el-select v-model="samplesType" @change="changeInt" placeholder="请选择采样插值类型">
<el-option v-for="item in InterpolationType" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="采样插值边缘">
<el-select v-model="samplesEdge" @change="changeInt" placeholder="请选择采样插值边缘">
<el-option v-for="item in InterpolationEdge" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="道插值类型">
<el-select v-model="tracesEdge" @change="changeInt" placeholder="请选择道插值类型">
<el-option v-for="item in InterpolationType" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="5">
<el-form-item label="道插值边缘">
<el-select v-model="tracesType" @change="changeInt" placeholder="请选择道插值边缘">
<el-option v-for="item in InterpolationEdge" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="绘图类型">
<el-checkbox v-model="Wiggle" @change="changePlotType">Wiggle</el-checkbox>
<el-checkbox v-model="Reversed" @change="changePlotType">Reversed</el-checkbox>
<el-checkbox v-model="PositiveFill" @change="changePlotType">Positive fill</el-checkbox>
<el-checkbox v-model="NegativeFill" @change="changePlotType">Negative fill</el-checkbox>
<el-checkbox v-model="PositiveColorFill" @change="changePlotType">Positive color fill</el-checkbox>
<el-checkbox v-model="NegativeColorFill" @change="changePlotType">Negative color fill</el-checkbox>
<el-checkbox v-model="SimpleDensity" @change="changePlotType">Simple density</el-checkbox>
<el-checkbox v-model="InterpolatedDensity" @change="changePlotType">Interpolated density</el-checkbox>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="Wiggle-裁剪因子">
<el-input v-model="ClippingFactor" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="5">
<el-form-item label="Wiggle-抽取间距">
<el-input v-model="DecimationSpacing" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="Wiggle-密度抽取">
<el-checkbox v-model="densityDecimation" @change="changePlotType">Density decimation(密度抽取)</el-checkbox>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="Clipping mode(裁剪模式)">
<el-select v-model="ClippingMode" @change="changePlotType" placeholder="请选择裁剪模式">
<el-option v-for="item in ClippingModeData" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="3">
<el-form-item label="TaperFilter(滤波)">
<el-checkbox v-model="TaperFilterEnbled" @change="changePlotType">启用滤波</el-checkbox>
</el-form-item>
</el-col>
<el-col :span="2">
<el-form-item label="f1">
<el-input v-model="f1" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="2">
<el-form-item label="f2">
<el-input v-model="f2" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="2">
<el-form-item label="f3">
<el-input v-model="f3" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="2">
<el-form-item label="f4">
<el-input v-model="f4" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="采样率">
<el-input v-model="sampleRate" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="带通模式">
<el-checkbox v-model="passFlag" @change="changePlotType">带通模式</el-checkbox>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="3">
<el-form-item label="AGC">
<el-checkbox v-model="AGCEnbled" @change="changePlotType">启用AGC</el-checkbox>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="AGC length">
<el-input v-model="AGCLength" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="Desired average">
<el-input v-model="DesiredAverage" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="Noise reduction">
<el-select v-model="NoiseReduction" @change="changePlotType" placeholder="请选择降噪">
<el-option v-for="item in NoiseReductionData" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="Noise reduction percentage">
<el-input v-model="NoiseReductionPercentage" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="Start sample">
<el-input v-model="StartSample" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="Step">
<el-input v-model="Step" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="4">
<el-form-item label="Units">
<el-select v-model="Units" @change="changePlotType" placeholder="请选择单位">
<el-option v-for="item in UnitsData" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="Window length">
<el-input v-model="WindowLength" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="3">
<el-form-item label="Reverse">
<el-checkbox v-model="ReverseEnbled" @change="changePlotType">启用Reverse</el-checkbox>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="inverted">
<el-checkbox v-model="inverted" @change="changePlotType">启用inverted</el-checkbox>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="reversed">
<el-checkbox v-model="reversed" @change="changePlotType">启用reversed</el-checkbox>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="showPropertiesDialog = false">取 消</el-button>
<el-button type="primary" @click="showPropertiesDialog = false">确 定</el-button>
</div>
</el-dialog>
<canvas ref="plot" id="canvas" />
<!-- <PropertiesDialog-->
<!-- :show-dialog="showPropertiesDialog"-->
<!-- :node-props="nodeProps"-->
<!-- :ajv="ajv"-->
<!-- :schema="schema"-->
<!-- @close="applyProps"-->
<!-- />-->
</div>
</template>
<script>
import { SeismicPlot } from './App.js';
import PropertiesDialog from './ui/PropertiesDialog.vue';
import { getAjv, setNodeProps, getNodeProps } from './ui/DialogPropertyUtils';
import { getToken } from "@/utils/auth";
import { SegyReader } from '@int/geotoolkit/seismic/data/SegyReader';
import { LocalFile } from '@int/geotoolkit/seismic/data/LocalFile';
import { Reverse } from '@int/geotoolkit/seismic/pipeline/processor/Reverse';
import { AGC } from '@int/geotoolkit/seismic/pipeline/processor/AGC';
import { TaperFilterProcess } from '@int/geotoolkit/seismic/analysis/filters/TaperFilterProcess';
import { NormalizationType } from '@int/geotoolkit/seismic/pipeline/NormalizationType';
import { SeismicPipeline } from '@int/geotoolkit/seismic/pipeline/SeismicPipeline';
import { SeismicColors } from '@int/geotoolkit/seismic/util/SeismicColors';
let seismicPlot = null;
export default {
name: "index",
components: {
PropertiesDialog
},
data() {
return {
showLineStylePanel: false,
showPropertiesDialog: false,
nodeProps: null,
ajv: null,
schema: null,
chartIsActive: false,
tableIsActive: false,
listNameColorMaps: [
"WhiteBlack",
"RedWhiteBlack",
"RedWhiteBlue",
"Saddleback",
"Angles5color",
"BlackRedYellowWhite",
"GreyOrange",
"IntervalVelocity",
"IntervalVelocity16",
"IntervalVelocity32",
"Rainbow",
"RedGreenBlue",
"RedWhiteBlueExtremes",
"RedWhiteBlueHot",
"RedYellowBlue",
"SaddlebackHot",
"Spectrum"
],
colorMapSelect: "",
_colorMap: "",
pipeline: null,
_seismicWidget: null,
NormalizationType: null,
NormalizationBl: 0.1,
NormalizationTypeData: [
{
"label": "None",
"value": 0,
},
{
"label": "Maximum",
"value": 1,
},
{
"label": "TraceMaximum",
"value": 2,
},
{
"label": "Average",
"value": 3,
},
{
"label": "TraceAverage",
"value": 4,
}, {
"label": "RMS",
"value": 5,
}, {
"label": "TraceRMS",
"value": 6,
}, {
"label": "Limits",
"value": 7,
}
],
mycds: null,
msycs: null,
samplesType: null,
samplesEdge: null,
tracesType: null,
tracesEdge: null,
InterpolationType: [
{
"label": "Linear",
"value": 1,
}, {
"label": "Quadratic",
"value": 2,
}, {
"label": "Step",
"value": 3,
}, {
"label": "CenteredStep",
"value": 4,
}, {
"label": "Cubic",
"value": 5,
}, {
"label": "Logarithmic",
"value": 6,
},
],
InterpolationEdge: [
{
"label": "Zero",
"value": 0,
}, {
"label": "Duplicate",
"value": 1,
}
],
Wiggle: false,
Reversed: false,
PositiveFill: false,
NegativeFill: false,
PositiveColorFill: false,
NegativeColorFill: false,
SimpleDensity: false,
InterpolatedDensity: true,
ClippingFactor: 4,
DecimationSpacing: 5,
densityDecimation: false,
ClippingMode: null,
ClippingModeData: [
{
"label": "Connected",
"value": "Connected"
}, {
"label": "Disconnected",
"value": "Disconnected"
},
],
TaperFilterEnbled: false,
f1: 10,
f2: 20,
f3: 60,
f4: 70,
sampleRate: 0,
passFlag: false,
AGCEnbled: false,
AGCLength: 0,
DesiredAverage: 1,
NoiseReductionPercentage: 3,
NoiseReduction: null,
StartSample: 0,
Step: 1,
Units: "",
WindowLength: 250,
UnitsData: [
{
"label": "Sample",
"value": 0
}, {
"label": "Time",
"value": 1
},
],
NoiseReductionData: [
{
"label": "disable",
"value": "disable"
}, {
"label": "enable",
"value": "enable"
}, {
"label": "auto",
"value": "auto"
},
],
ReverseEnbled: false,
inverted: false,
reversed: false,
// 文件上传相关
uploadUrl: process.env.VUE_APP_BASE_API + '/ndy/dz/upload',
uploadHeaders: {
Authorization: "Bearer " + getToken()
},
fileList: []
}
},
mounted() {
// this.init()
},
methods: {
init() {
//创建
seismicPlot = new SeismicPlot({
'canvas': this.$refs.plot,
'errorCallback': this.onCreateWidgetError,
'fileOpenedCallback': this.onFileOpen
});
// 不再自动加载默认文件,等待用户上传文件
},
handleFileSelect() {
let url = process.env.VUE_APP_BASE_API + "/ndy/dz/getSegyDataFile3?fileName=density.segy";
let fileName = 'density.segy';
return fetch(url, {
headers: {
Authorization: "Bearer " + getToken()
}
}).then((response) => {
if (!response.ok) {
throw new Error(`网络请求失败: ${response.status} ${response.statusText}`);
}
return response.blob();
}).then((blob) => {
if (!blob || blob.size === 0) {
throw new Error('获取到的文件数据为空');
}
let fileInput = new File([blob], fileName, { type: blob.type, lastModified: Date.now() });
// seismicPlot.createWidgetFromFile(filesObj)
const file = new LocalFile(fileInput);
this._fileSize = file.fileSize;
const segyReader = new SegyReader(file);
segyReader.loadMetaData((reader) => {
if (reader instanceof Error && this.errorCallback != null) {
this.errorCallback(reader.message);
return;
}
// this.createRemotePipeline(reader)
reader.readDataSetStatistics((reader, statistics) => {
if (reader.getModelLimits().getHeight() === 0 && this.warningCallback != null) {
return this.$message.error("加载失败");
}
// return this.createPipelineFromFile(file.getFileName(), reader, statistics);
this.pipeline = new SeismicPipeline(file.getFileName(), reader, statistics)
seismicPlot.createPipelineFromFile2(this.pipeline, file.getFileName(), reader, statistics);
console.log(this.pipeline)
});
});
})
},
onCreateWidgetError(errorMsg) {
this.$message.error(errorMsg);
},
editProperties() {
// console.log(seismicPlot)
// this.ajv = getAjv({chartNames: seismicPlot.getChartNames()});
// console.log(this.ajv)
// this.schema = this.ajv.getSchema(`/${seismicPlot.getWidget().getClassName()}`).schema;
// console.log(this.schema)
// this.nodeProps = getNodeProps(seismicPlot);
// console.log(this.nodeProps)
this.showPropertiesDialog = true;
},
applyProps(props) {
if (props) {
setNodeProps(seismicPlot, props);
}
this.showPropertiesDialog = false;
},
onFileOpen() {
},
changeColor(val) {
var colorMap = SeismicColors.getDefault().createNamedColorMap(val, 256)
this.pipeline.setColorMap(colorMap);
if (seismicPlot._seismicWidget) {
seismicPlot._seismicWidget.invalidate(); // 使组件重新渲染
seismicPlot._seismicWidget.fitToBounds(); // 调整视图以适应数据
} else {
console.error('Widget不可用,无法更新视图');
}
// 如果plots对象存在redraw方法,使用它来触发重绘
if (seismicPlot.plots && typeof seismicPlot.plots.redraw === 'function') {
seismicPlot.plots.redraw();
}
},
//归一化
changeNor(val) {
if (this.NormalizationType == 7) {
this.pipeline.setOptions({
'normalization': {
'type': this.NormalizationType,
'scale': this.NormalizationBl
}
})
} else {
this.pipeline.setOptions({
'normalization': {
'type': this.NormalizationType,
'scale': this.NormalizationBl
}
})
}
},
changeMycds() {
seismicPlot.openPipeline(this.pipeline, {
'tracescale': this.mycds,
'samplescale': this.msycs,
'deviceunit': 'in',
'sampleunit': 's',
});
},
changeInt() {
console.log(this.pipeline.getOptions())
this.pipeline.setOptions({
'interpolation': {
'samples': {
"type": this.samplesType,//采样插值类型,
"edge": this.samplesEdge,//采样插值边缘,
},
'traces': {
"type": this.tracesType,//道插值类型
"edge": this.tracesEdge,//道插值边缘
},
}
})
},
changePlotType() {
this.pipeline.setOptions({
'plot': {
'type': {
"Wiggle": this.Wiggle,
"Reversed": this.Reversed,
"PositiveFill": this.PositiveFill,
"NegativeFill": this.NegativeFill,
"PositiveColorFill": this.PositiveColorFill,
"NegativeColorFill": this.NegativeColorFill,
"SimpleDensity": this.SimpleDensity,
"InterpolatedDensity": this.InterpolatedDensity,
},
"clippingFactor": this.ClippingFactor,
"decimationSpacing": this.DecimationSpacing,
"densityDecimation": this.densityDecimation,
},
"clippingmode": this.ClippingMode,
"dataProcessors": {
"TaperFilter": {
"apply": this.TaperFilterEnbled,
"f1": Number(this.f1),
"f2": Number(this.f2),
"f3": Number(this.f3),
"f4": Number(this.f4),
"sampleRate": Number(this.sampleRate),
"passFlag": this.passFlag,
},
"AGC": {
"agcLength": this.AGCLength,
"apply": this.AGCEnbled,
"desiredAverage": this.DesiredAverage,
"noiseReduction": this.NoiseReduction,
"noiseReductionPercentage": this.NoiseReductionPercentage,
"startSample": this.StartSample,
"step": this.Step,
"units": this.Units,
"windowLength": this.WindowLength,
},
"Reverse": {
"apply": this.ReverseEnbled,
"inverted": this.inverted,
"reversed": this.reversed,
}
}
})
console.log(this.pipeline.getOptions())
},
// 文件上传相关方法
triggerFileUpload() {
// 创建隐藏的文件输入元素
const input = document.createElement('input');
input.type = 'file';
input.accept = '.segy,.sgy';
input.style.display = 'none';
input.onchange = (event) => {
const file = event.target.files[0];
if (file) {
this.handleFileUpload(file);
}
};
document.body.appendChild(input);
input.click();
document.body.removeChild(input);
},
handleFileUpload(file) {
// 检查文件类型
const allowedTypes = ['.segy', '.sgy'];
const fileName = file.name.toLowerCase();
const isValidType = allowedTypes.some(type => fileName.endsWith(type));
if (!isValidType) {
this.$message.error('只能上传segy、sgy文件');
return;
}
// 检查文件大小 (例如限制为100MB)
const maxSize = 100 * 1024 * 1024; // 100MB
if (file.size > maxSize) {
this.$message.error('文件大小不能超过100MB');
return;
}
// 创建FormData
const formData = new FormData();
formData.append('file', file);
// 上传文件
this.$message.info('正在上传文件...');
fetch(this.uploadUrl, {
method: 'POST',
headers: this.uploadHeaders,
body: formData
})
.then(response => {
if (!response.ok) {
throw new Error(`上传失败: ${response.status} ${response.statusText}`);
}
return response.json();
})
.then(data => {
this.$message.success('文件上传成功');
console.log('上传成功:', data);
// 这里可以处理上传成功后的逻辑,比如重新加载数据
this.loadNewFile(data.fileName);
this.init()
})
.catch(error => {
console.error('上传失败:', error);
this.$message.error('文件上传失败: ' + error.message);
});
},
loadNewFile(fileName) {
// 加载新文件的逻辑
let url = process.env.VUE_APP_BASE_API + "/ndy/dz/getSegyDataFile3?fileName=" + fileName;
return fetch(url, {
headers: {
Authorization: "Bearer " + getToken()
}
}).then((response) => {
if (!response.ok) {
throw new Error(`网络请求失败: ${response.status} ${response.statusText}`);
}
return response.blob();
}).then((blob) => {
if (!blob || blob.size === 0) {
throw new Error('获取到的文件数据为空');
}
let fileInput = new File([blob], fileName, { type: blob.type, lastModified: Date.now() });
const file = new LocalFile(fileInput);
this._fileSize = file.fileSize;
const segyReader = new SegyReader(file);
segyReader.loadMetaData((reader) => {
if (reader instanceof Error && this.errorCallback != null) {
this.errorCallback(reader.message);
return;
}
reader.readDataSetStatistics((reader, statistics) => {
if (reader.getModelLimits().getHeight() === 0 && this.warningCallback != null) {
return this.$message.error("加载失败");
}
this.pipeline = new SeismicPipeline(fileName, reader, statistics)
seismicPlot.createPipelineFromFile2(this.pipeline, fileName, reader, statistics);
console.log(this.pipeline)
});
});
}).catch(error => {
console.error('加载文件失败:', error);
this.$message.error('加载文件失败: ' + error.message);
});
}
}
}
</script>
<style scoped>
#canvas {
width: 100% !important;
height: calc(85vh - 35px) !important;
margin-top: 20px;
}
</style>
......@@ -188,7 +188,7 @@
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">
支持 doc、docx、pdf、xls、xlsx、ppt、pptx、txt、jpg、jpeg、png、gif 格式文件,单个文件不超过50MB<br/>
支持 doc、docx、pdf、xls、xlsx、ppt、pptx、txt、jpg、jpeg、png、gif 格式文件<br/>
<span style="color: #409EFF;">上传新文件将自动替换已有文件</span>
</div>
</el-upload>
......@@ -617,11 +617,11 @@ export default {
}
// 校验文件大小
const isLt50M = file.size / 1024 / 1024 < 50
if (!isLt50M) {
this.$modal.msgError('上传文件大小不能超过 50MB!')
return false
}
// const isLt50M = file.size / 1024 / 1024 < 50
// if (!isLt50M) {
// this.$modal.msgError('上传文件大小不能超过 50MB!')
// return false
// }
return true
},
......
......@@ -68,7 +68,6 @@
</div>
<!-- 缩略图 end-->
<!-- 缩略图弹窗 start -->
<!-- 缩略图弹窗 start -->
<el-dialog v-if="shouldShowThumb" title="缩略图预览" :visible.sync="showThumbDialog" width="80%" append-to-body
:z-index="9999999" :modal="true" :close-on-click-modal="true" :close-on-press-escape="true"
custom-class="thumbnail-dialog">
......@@ -78,7 +77,6 @@
</div>
</el-dialog>
<!-- 缩略图弹窗 end -->
<!-- 缩略图弹窗 end -->
</div>
<!-- 添加加载状态和错误提示 -->
......@@ -813,6 +811,14 @@ export default {
// height: 0.1452145214521452
// }
// }],
// 添加鼠标悬停相关的数据
cursorInfo: {
depth: null,
trace: null,
value: null
},
showCursorInfo: true,
isHovering: false,
// 添加画笔工具相关属性
pencilTool: null,
selectedShape: null,
......@@ -881,6 +887,9 @@ export default {
'DashDot': [20, 4, 2, 4],
'DashDotDot': [20, 4, 2, 4, 2, 4]
},
isWidgetReady: false,
loadingError: null,
pipeline: null,
colorProvider: null,
// 右键菜单相关数据
contextMenu: {
......@@ -1154,7 +1163,7 @@ export default {
},
// 监听routeId变化
routeId(newId, oldId) {
// console.log('[index2] routeId变化:', newId, oldId);
//console.log('[index2] routeId变化:', newId, oldId);
if (newId !== oldId) {
this.handleRouteChange();
// 强制刷新缩略图
......@@ -1162,69 +1171,66 @@ export default {
}
}
},
// mounted() {
//
// console.log(1111)
// // 初始化时强制设置为初始状态
// this.resetToInitialState();
//
// // 立即禁用滚动条工具
// this.disableScrollbarTools();
//
// // 添加强制隐藏滚动条的CSS
// this.addForceHideScrollbarCSS();
//
// // 关闭强力滚动条监控,避免影响全局布局
// // this.startAggressiveScrollbarMonitor();
//
// this.$nextTick(async () => {
// ['thumb-test-container', 'thumb-chart-container', 'super-visible-thumb'].forEach(id => {
// const el = document.getElementById(id);
// if (el) try { el.remove(); } catch (e) { }
// });
// // 保持缩略图容器在组件内部,避免在DOM树中难以定位
// // 初始化场景时不自动加载演示数据,等待接口结果决定
// this.shouldLoadDemo = false;
// this.createScene(this.$refs.plot, { autoloadDemo: false });
// // 等DOM稳定后再渲染缩略图组件
// setTimeout(() => {
// this.thumbReady = true;
// // 再兜底:确保右上角出现内容,并直接绘制缩略图
// setTimeout(() => {
// this.ensureThumbRendered();
// this.drawThumbDirect();
// }, 200);
// }, 100);
// // 已改为内嵌 YsgcIndex 缩略图,不再走旧的 ECharts 缩略图初始化
//
// // 自动拉取接口数据并加载第一组上/下部 SEGY(jbsegy -> 顶部,xbsegy -> 底部)
// try {
// await this.loadThumbData();
// if (Array.isArray(this.segyList) && this.segyList.length > 0) {
// await this.loadCurrentSegy();
// } else {
// // 无接口数据:若没有路由id,允许加载演示数据;若有id但无数据,保持空白
// const hasId = !!this.routeId;
// if (!hasId) {
// this.shouldLoadDemo = true;
// try { await this.handleFileSelect(this.plots); } catch (e) { }
// } else {
// this.clearCurrentPlots();
// console.info('[index2] 该项目无可用SEGY数据');
// }
// }
// } catch (e) {
// console.warn('[index2] 自动加载数据失败:', e);
// // 加载失败时,如果没有路由ID,尝试加载演示数据
// if (!this.routeId) {
// this.shouldLoadDemo = true;
// try { await this.handleFileSelect(this.plots); } catch (e) { }
// }
// }
// });
// },
mounted() {
console.log(2222)
// 初始化时强制设置为初始状态
this.resetToInitialState();
// 立即禁用滚动条工具
this.disableScrollbarTools();
// 添加强制隐藏滚动条的CSS
this.addForceHideScrollbarCSS();
// 关闭强力滚动条监控,避免影响全局布局
// this.startAggressiveScrollbarMonitor();
this.$nextTick(async () => {
['thumb-test-container', 'thumb-chart-container', 'super-visible-thumb'].forEach(id => {
const el = document.getElementById(id);
if (el) try { el.remove(); } catch (e) { }
});
// 保持缩略图容器在组件内部,避免在DOM树中难以定位
// 初始化场景时不自动加载演示数据,等待接口结果决定
this.shouldLoadDemo = false;
this.createScene(this.$refs.plot, { autoloadDemo: false });
// 等DOM稳定后再渲染缩略图组件
setTimeout(() => {
this.thumbReady = true;
// 再兜底:确保右上角出现内容,并直接绘制缩略图
setTimeout(() => {
this.ensureThumbRendered();
this.drawThumbDirect();
}, 200);
}, 100);
// 已改为内嵌 YsgcIndex 缩略图,不再走旧的 ECharts 缩略图初始化
// 自动拉取接口数据并加载第一组上/下部 SEGY(jbsegy -> 顶部,xbsegy -> 底部)
try {
await this.loadThumbData();
if (Array.isArray(this.segyList) && this.segyList.length > 0) {
await this.loadCurrentSegy();
} else {
// 无接口数据:若没有路由id,允许加载演示数据;若有id但无数据,保持空白
const hasId = !!this.routeId;
if (!hasId) {
this.shouldLoadDemo = true;
try { await this.handleFileSelect(this.plots); } catch (e) { }
} else {
this.clearCurrentPlots();
console.info('[index2] 该项目无可用SEGY数据');
}
}
} catch (e) {
console.warn('[index2] 自动加载数据失败:', e);
// 加载失败时,如果没有路由ID,尝试加载演示数据
if (!this.routeId) {
this.shouldLoadDemo = true;
try { await this.handleFileSelect(this.plots); } catch (e) { }
}
}
});
},
mounted() {
// 将缩略图容器移动到body,确保fixed基于视口
if (this.$refs.thumbContainer && this.$refs.thumbContainer.parentNode !== document.body) {
document.body.appendChild(this.$refs.thumbContainer);
......@@ -2180,8 +2186,6 @@ export default {
//console.log('[index2] 加载segy文件 Top/Bottom:', (currentSegy.jbsegyName || currentSegy.jbsegy), (currentSegy.xbsegyName || currentSegy.xbsegy));
//console.log('[index2] segy文件路径 Top/Bottom:', currentSegy.jbsegy, currentSegy.xbsegy);
//
try {
// 双图加载:jbsegy -> 顶部;xbsegy -> 底部
// 根据后台返回的 ysqqXmxxSegy 数据,jbsegy 顶部展示,xbsegy 底部展示
......@@ -2205,9 +2209,6 @@ export default {
try { this._seismicWidget && this._seismicWidget.invalidate && this._seismicWidget.invalidate(); } catch (e) { }
// 关键修复:切换下一道后,强制将底部 widget 绑定为当前 pipeline,并重新插入绘制工具,防止短暂显示上一道
try {
// 确保 pipeline/路径键为当前
// await this.assertBottomPipelineCurrent();
this.refreshBottomDisplay();
// 确保 pipeline/路径键为当前(只在必要时调用,避免频繁刷新)
await this.assertBottomPipelineCurrent();
// 移除重复的 refreshBottomDisplay 调用,避免闪烁
......@@ -2467,7 +2468,7 @@ export default {
}
console.log('[renderAnnotationsFromXbbznr] 开始解析标注数据,数量:', annotationList.length);
// console.log('[renderAnnotationsFromXbbznr] annotationList 详细内容:', JSON.stringify(annotationList, null, 2));
console.log('[renderAnnotationsFromXbbznr] annotationList 详细内容:', JSON.stringify(annotationList, null, 2));
// 清空现有的底部 savedAnnotations 和 savedLineAnnotations
this.savedAnnotationsBottom = [];
......@@ -2878,143 +2879,116 @@ export default {
this.isHovering = false;
// 打开双图布局
// this.showDualChart();
this.showDualChart();
// 不再隐藏容器,避免首次绘制依赖鼠标事件触发
const topScroll = this.$refs.topScroll;
const bottomScroll = this.$refs.bottomScroll;
// if (this.annotationTool){
// // if (this.annotationTool.isEnabled() && this.annotationTool.getMode() === PaintMode.Edit && this.annotationTool.getShape() != null) {
// if (Array.isArray(this.annotationTool.getShape())) {
// this.annotationTool.getShape().forEach((shape) => shape.dispose());
// } else {
// this.annotationTool.getShape().dispose();
// }
// this.annotationTool.editNode(null);
// // }
// }
var theCanvas = document.getElementById("canvasTop");
var w = theCanvas.width;
var h = theCanvas.height;
var context = theCanvas.getContext("2d");
context.clearRect(0, 0, w, h);
if(this.plots){
this.plots.dispose();
}
if(this.plotsBottom){
this.plotsBottom.dispose();
}
// 清空现有图表
this.clearCurrentPlots();
//
// 清空 pipeline 引用,确保旧数据被清除
this.pipeline = null;
this.pipelineBottom = null;
this.plots = null;
this.plotsBottom = null;
// // 确保两个画布已初始化(如果widget不存在,才创建新的)
// if (this.$refs.plot && !this._seismicWidget) {
// this.createScene(this.$refs.plot, { autoloadDemo: false });
// }
// if (this.$refs.plot2 && !this._seismicWidgetBottom) {
// this.initSecondWidget(this.$refs.plot2);
// }
// // 重新绑定事件监听器
// this.$nextTick(() => {
// this.bindContextMenuListeners();
// });
//
// // 等待一小段时间,确保清空操作完成
// await new Promise(resolve => setTimeout(resolve, 50));
//
// // 顺序加载,分别统计成功与失败,但不立即刷新
// let topOk = false;
// let bottomOk = false;
// try {
// if (jbPath) {
// const topTitle = jbName || this.extractFileName(jbPath) || 'jbsegy';
// await this.loadSegyIntoWidget('top', jbPath, topTitle, false); // 不立即刷新
// topOk = true;
// }
// } catch (e) {
// console.warn('加载上部SEGY失败:', e);
// }
//
// try {
// if (xbPath) {
// const bottomTitle = xbName || this.extractFileName(xbPath) || 'xbsegy';
// await this.loadSegyIntoWidget('bottom', xbPath, bottomTitle, false); // 不立即刷新
// bottomOk = true;
// }
// } catch (e) {
// console.warn('加载下部SEGY失败:', e);
// }
//
// // 等待所有数据加载完成后再统一刷新
// if (topOk || bottomOk) {
// // 使用 requestAnimationFrame 确保在下一帧统一刷新
// await this.$nextTick();
// requestAnimationFrame(() => {
// try {
// if (topOk && this._seismicWidget) {
// if (this._seismicWidget.invalidate) {
// this._seismicWidget.invalidate();
// }
// this.setScrollbarCSS(this._seismicWidget);
// this.forceDisableInternalScrollbars();
// setTimeout(() => {
// try {
// if (this._seismicWidget && this._seismicWidget.fitToBounds) {
// this._seismicWidget.fitToBounds();
// }
// } catch (e) { }
// }, 100);
// }
// if (bottomOk && this._seismicWidgetBottom) {
// if (this._seismicWidgetBottom.invalidate) {
// this._seismicWidgetBottom.invalidate();
// }
// this.setScrollbarCSS(this._seismicWidgetBottom);
// this.forceDisableInternalScrollbars();
// setTimeout(() => {
// try {
// if (this._seismicWidgetBottom && this._seismicWidgetBottom.fitToBounds) {
// this._seismicWidgetBottom.fitToBounds();
// }
// // 额外在显示前进行一次尺寸同步与重绘
// try { this.updateBaseCanvasSize(); } catch (e) { }
// try { this.plotsBottom && typeof this.plotsBottom.redraw === 'function' && this.plotsBottom.redraw(); } catch (e) { }
// } catch (e) { }
// }, 100);
// }
// } catch (e) {
// console.warn('最终刷新widget时出错:', e);
// }
// });
//
// // 刷新完成后,额外进行一次尺寸同步与重绘,确保无悬浮也正确
// setTimeout(() => {
// try { this.updateBaseCanvasSize(); } catch (e) { }
// try { this._seismicWidget && this._seismicWidget.invalidate && this._seismicWidget.invalidate(); } catch (e) { }
// try { this._seismicWidgetBottom && this._seismicWidgetBottom.invalidate && this._seismicWidgetBottom.invalidate(); } catch (e) { }
// requestAnimationFrame(() => {
// try { this._seismicWidget && this._seismicWidget.invalidate && this._seismicWidget.invalidate(); } catch (e) { }
// try { this._seismicWidgetBottom && this._seismicWidgetBottom.invalidate && this._seismicWidgetBottom.invalidate(); } catch (e) { }
// });
// }, 200);
// } else {
// // 加载失败也做一次重绘尝试
// try { this._seismicWidget && this._seismicWidget.invalidate && this._seismicWidget.invalidate(); } catch (e) { }
// try { this._seismicWidgetBottom && this._seismicWidgetBottom.invalidate && this._seismicWidgetBottom.invalidate(); } catch (e) { }
// }
// 确保两个画布已初始化(如果widget不存在,才创建新的)
if (this.$refs.plot && !this._seismicWidget) {
this.createScene(this.$refs.plot, { autoloadDemo: false });
}
if (this.$refs.plot2 && !this._seismicWidgetBottom) {
this.initSecondWidget(this.$refs.plot2);
}
// 重新绑定事件监听器
this.$nextTick(() => {
this.bindContextMenuListeners();
});
// 等待一小段时间,确保清空操作完成
await new Promise(resolve => setTimeout(resolve, 50));
// 顺序加载,分别统计成功与失败,但不立即刷新
let topOk = false;
let bottomOk = false;
try {
if (jbPath) {
const topTitle = jbName || this.extractFileName(jbPath) || 'jbsegy';
await this.loadSegyIntoWidget('top', jbPath, topTitle, false); // 不立即刷新
topOk = true;
}
} catch (e) {
console.warn('加载上部SEGY失败:', e);
}
try {
if (xbPath) {
const bottomTitle = xbName || this.extractFileName(xbPath) || 'xbsegy';
await this.loadSegyIntoWidget('bottom', xbPath, bottomTitle, false); // 不立即刷新
bottomOk = true;
}
} catch (e) {
console.warn('加载下部SEGY失败:', e);
}
// 等待所有数据加载完成后再统一刷新
if (topOk || bottomOk) {
// 使用 requestAnimationFrame 确保在下一帧统一刷新
await this.$nextTick();
requestAnimationFrame(() => {
try {
if (topOk && this._seismicWidget) {
if (this._seismicWidget.invalidate) {
this._seismicWidget.invalidate();
}
this.setScrollbarCSS(this._seismicWidget);
this.forceDisableInternalScrollbars();
setTimeout(() => {
try {
if (this._seismicWidget && this._seismicWidget.fitToBounds) {
this._seismicWidget.fitToBounds();
}
} catch (e) { }
}, 100);
}
if (bottomOk && this._seismicWidgetBottom) {
if (this._seismicWidgetBottom.invalidate) {
this._seismicWidgetBottom.invalidate();
}
this.setScrollbarCSS(this._seismicWidgetBottom);
this.forceDisableInternalScrollbars();
setTimeout(() => {
try {
if (this._seismicWidgetBottom && this._seismicWidgetBottom.fitToBounds) {
this._seismicWidgetBottom.fitToBounds();
}
// 额外在显示前进行一次尺寸同步与重绘
try { this.updateBaseCanvasSize(); } catch (e) { }
try { this.plotsBottom && typeof this.plotsBottom.redraw === 'function' && this.plotsBottom.redraw(); } catch (e) { }
} catch (e) { }
}, 100);
}
} catch (e) {
console.warn('最终刷新widget时出错:', e);
}
});
// 刷新完成后,额外进行一次尺寸同步与重绘,确保无悬浮也正确
setTimeout(() => {
try { this.updateBaseCanvasSize(); } catch (e) { }
try { this._seismicWidget && this._seismicWidget.invalidate && this._seismicWidget.invalidate(); } catch (e) { }
try { this._seismicWidgetBottom && this._seismicWidgetBottom.invalidate && this._seismicWidgetBottom.invalidate(); } catch (e) { }
requestAnimationFrame(() => {
try { this._seismicWidget && this._seismicWidget.invalidate && this._seismicWidget.invalidate(); } catch (e) { }
try { this._seismicWidgetBottom && this._seismicWidgetBottom.invalidate && this._seismicWidgetBottom.invalidate(); } catch (e) { }
});
}, 200);
} else {
// 加载失败也做一次重绘尝试
try { this._seismicWidget && this._seismicWidget.invalidate && this._seismicWidget.invalidate(); } catch (e) { }
try { this._seismicWidgetBottom && this._seismicWidgetBottom.invalidate && this._seismicWidgetBottom.invalidate(); } catch (e) { }
}
},
// 将指定segy加载到顶部/底部widget
// skipRefresh: 如果为 true,则不立即刷新,等待统一刷新
......@@ -6286,9 +6260,6 @@ export default {
}
},
async handleFileSelect(plot) {
let segys = [];
......@@ -6411,7 +6382,7 @@ export default {
});
// Set the pipeline first
this.pipeline= pipeline;
this.pipeline = pipeline;
this._seismicWidget.setPipeline(pipeline);
// Then set widget options
......@@ -6517,11 +6488,11 @@ export default {
});
},
// handleMouseMove(event) {
// if (!this._seismicWidget || !this.isHovering) return;
//
// // 使用内置状态栏,不需要额外的处理逻辑
// },
handleMouseMove(event) {
if (!this._seismicWidget || !this.isHovering) return;
// 使用内置状态栏,不需要额外的处理逻辑
},
onFileOpen(evt, plot, fileInfo) {
evt.stopPropagation();
......@@ -7947,7 +7918,8 @@ export default {
if (!this.checkWidgetStatus() || !this.isWidgetReady) return;
const widget = this.plots.getRoot();
// 修复:如果 plots 为 null,直接使用 _seismicWidget
const widget = (this.plots && this.plots.getRoot) ? this.plots.getRoot() : this._seismicWidget;
if (!widget) return;
// 确保注释层存在
......@@ -8014,9 +7986,42 @@ export default {
if (node && this.annotations.indexOfChild(node) === -1) {
this.annotations.addChild(node);
}
tool.setEditMode(EditMode.EditNode);
tool.editNode(node);
// 关键修复:绘制完成后,确保节点保持可编辑属性
try {
const props = typeof node.getProperties === 'function' ? node.getProperties() : {};
if (!props.selectable || !props.movable || !props.editable) {
// 如果属性丢失,重新设置
const currentLineStyle = props.linestyle || new LineStyle({
color: this.lineStyle?.color || '#0351ad',
width: this.lineStyle?.width || 2,
pattern: this.getProcessedLinePattern ? this.getProcessedLinePattern(this.lineStyle?.pattern) : []
});
node.setProperties({
...props,
linestyle: currentLineStyle,
selectable: true,
movable: true,
editable: true
});
}
} catch (e) {
console.warn('设置线条节点编辑属性失败:', e);
}
// 修复:绘制完成后,保持编辑模式,让用户可以立即编辑刚绘制的线条
// 用户可以通过点击空白区域或按 ESC 来取消编辑,然后继续绘制新线条
try {
if (this.pencilTool && this.pencilTool.isEnabled() && this.showLineStylePanel) {
// 设置编辑模式,让用户可以选择和编辑刚绘制的线条
this.pencilTool.setEditMode(EditMode.EditNode);
this.pencilTool.editNode(node);
this.selectedShape = node;
}
} catch (e) {
console.warn('设置线条编辑模式失败:', e);
}
this.requestRepaint();
});
}
......@@ -10041,7 +10046,7 @@ export default {
.scrollbar-track,
.gt-scrollbar-thumb,
.gt-scrollbar-track,
/* 仅在地震图可滚动区域内隐藏内部滚动条相关"thumb/track",避免误伤缩略图 */
/* 仅在地震图可滚动区域内隐藏内部滚动条相关"thumb/track",避免误伤缩略图 */
.sync-section [class*="thumb"]:not(.thumb-holder):not(.thumb-title):not(.right-thumb),
.sync-section [class*="track"] {
display: none !important;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment