Commit 9f4dc9ef by jiang'yun

Merge remote-tracking branch 'origin/master'

parents 0b8100eb df563069
......@@ -308,6 +308,8 @@ export default {
if (chartDom) {
this.setChartDimensions(chartDom);
}
this.$nextTick(() => {
if (this.myChart) {
this.myChart.resize();
if (this.lastStackedAreas && this.lastChartConfig && this.lastXAxisLabels) {
this.drawStratumLabels(this.lastStackedAreas, this.lastChartConfig, this.lastXAxisLabels);
......@@ -320,6 +322,8 @@ export default {
this.drawTopBandSvg(this.lastXAxisLabels, this.lastChartConfig, this.lastStackedAreas);
}
}
});
}
},
// 刷新图表
......@@ -347,19 +351,46 @@ export default {
this.setChartDimensions(chartDom);
}
this.myChart.setOption(option, true);
// 确保图表完全渲染后再resize
// 确保图表完全渲染后再resize和绘制
this.$nextTick(() => {
// 先resize确保图表尺寸正确
this.myChart.resize();
// 使用 requestAnimationFrame 确保浏览器完成渲染后再绘制
requestAnimationFrame(() => {
requestAnimationFrame(() => {
// 再次确认尺寸,确保图表已完全渲染
const chartDom = this.$refs.chartRef;
if (chartDom && chartDom.offsetWidth > 0 && chartDom.offsetHeight > 0) {
// 再次resize确保尺寸准确
this.myChart.resize();
// 保存数据用于后续resize时重新绘制
this.lastStackedAreas = wellData.stackedAreas;
this.lastChartConfig = mockData.chartConfig;
this.lastXAxisLabels = xAxisLabels;
this.lastDepthIntervals = wellData.depthIntervals || [];
// 绘制所有图形元素
this.drawStratumLabels(this.lastStackedAreas, this.lastChartConfig, this.lastXAxisLabels);
this.drawJhSeparators(this.lastDepthIntervals, this.lastXAxisLabels, this.lastChartConfig);
this.drawCategoryEdgeLines(this.lastXAxisLabels, this.lastChartConfig);
this.drawTopBandSvg(this.lastXAxisLabels, this.lastChartConfig, this.lastStackedAreas);
} else {
// 如果尺寸还未确定,延迟重试
setTimeout(() => {
if (this.myChart) {
this.myChart.resize();
this.lastStackedAreas = wellData.stackedAreas;
this.lastChartConfig = mockData.chartConfig;
this.lastXAxisLabels = xAxisLabels;
this.lastDepthIntervals = wellData.depthIntervals || [];
this.drawStratumLabels(this.lastStackedAreas, this.lastChartConfig, this.lastXAxisLabels);
this.drawJhSeparators(this.lastDepthIntervals, this.lastXAxisLabels, this.lastChartConfig);
// 在顶部为每个类目绘制左右两条短竖线
this.drawCategoryEdgeLines(this.lastXAxisLabels, this.lastChartConfig);
// 顶部段内根据 x 和 y2 渲染 SVG 纹理
this.drawTopBandSvg(this.lastXAxisLabels, this.lastChartConfig, this.lastStackedAreas);
}
}, 150);
}
});
});
});
} catch (error) {
console.error("渲染数据失败:", error);
......@@ -965,7 +996,11 @@ export default {
? this.currentGraphicElements.filter(el => !el.__stratumLabel)
: [];
this.currentGraphicElements = elements;
this.myChart.setOption({ graphic: { elements } });
this.$nextTick(() => {
if (this.myChart) {
this.myChart.setOption({ graphic: { elements } }, { replaceMerge: ['graphic'] });
}
});
},
// 根据 depthIntervals 的顺序按 jh 分段,绘制虚线与顶部井号
......@@ -1004,11 +1039,17 @@ export default {
}
const graphics = [];
// 确保图表已完全渲染,检查容器尺寸
const chartDom = this.$refs.chartRef;
if (!chartDom || chartDom.offsetWidth === 0 || chartDom.offsetHeight === 0) {
console.warn('图表容器尺寸无效,跳过绘制井号分隔符');
return;
}
// 垂直范围(像素)——考虑 y 轴 inverse,取像素最小为顶部、最大为底部
const yMinPx = this.myChart.convertToPixel({ yAxisIndex: 0 }, chartConfig.yAxis.min);
const yMaxPx = this.myChart.convertToPixel({ yAxisIndex: 0 }, chartConfig.yAxis.max);
if (yMinPx === null || yMaxPx === null) {
console.warn('convertToPixel 返回 null 值,跳过绘制井号分隔符');
if (yMinPx === null || yMaxPx === null || isNaN(yMinPx) || isNaN(yMaxPx)) {
console.warn('convertToPixel 返回无效值,跳过绘制井号分隔符');
return;
}
const yTopPx = Math.min(yMinPx, yMaxPx);
......@@ -1118,16 +1159,30 @@ export default {
const prevElements = Array.isArray(this.currentGraphicElements) ? this.currentGraphicElements : [];
const merged = prevElements.concat(graphics);
this.currentGraphicElements = merged;
this.myChart.setOption({ graphic: { elements: merged } });
this.$nextTick(() => {
if (this.myChart) {
this.myChart.setOption({ graphic: { elements: merged } }, { replaceMerge: ['graphic'] });
}
});
},
// 为每个 x 类目在左右各画一条黑色竖线(仅顶部短竖线)
drawCategoryEdgeLines(xAxisLabels, chartConfig) {
if (!this.myChart || !Array.isArray(xAxisLabels) || xAxisLabels.length === 0) return;
// 确保图表已完全渲染,检查容器尺寸
const chartDom = this.$refs.chartRef;
if (!chartDom || chartDom.offsetWidth === 0 || chartDom.offsetHeight === 0) {
console.warn('图表容器尺寸无效,跳过绘制类目边界线');
return;
}
const yMinPx = this.myChart.convertToPixel({ yAxisIndex: 0 }, chartConfig.yAxis.min);
const yMaxPx = this.myChart.convertToPixel({ yAxisIndex: 0 }, chartConfig.yAxis.max);
if (yMinPx === null || yMaxPx === null) return;
if (yMinPx === null || yMaxPx === null || isNaN(yMinPx) || isNaN(yMaxPx)) {
console.warn('convertToPixel 返回无效值,跳过绘制类目边界线');
return;
}
const yTopPx = Math.min(yMinPx, yMaxPx);
const yBottomPx = Math.max(yMinPx, yMaxPx);
// 只在上方画短竖线:长度占绘图区高度的 12%,并限制在 30-120 像素
......@@ -1227,13 +1282,24 @@ export default {
const prev = Array.isArray(this.currentGraphicElements) ? this.currentGraphicElements : [];
const merged = prev.concat(graphics);
this.currentGraphicElements = merged;
this.myChart.setOption({ graphic: { elements: merged } });
this.$nextTick(() => {
if (this.myChart) {
this.myChart.setOption({ graphic: { elements: merged } }, { replaceMerge: ['graphic'] });
}
});
},
// 图内根据 x 和 y2 渲染 SVG 纹理(每段使用该 x 在 stackedAreas 中最浅层 y2 对应的 svg),从顶部填充到 y2 深度
async drawTopBandSvg(xAxisLabels, chartConfig, stackedAreas) {
if (!this.myChart || !Array.isArray(xAxisLabels) || !stackedAreas) return;
// 确保图表已完全渲染,检查容器尺寸
const chartDom = this.$refs.chartRef;
if (!chartDom || chartDom.offsetWidth === 0 || chartDom.offsetHeight === 0) {
console.warn('图表容器尺寸无效,跳过绘制顶部SVG纹理');
return;
}
// 计算每个类目的像素中心
const centers = [];
for (let i = 0; i < xAxisLabels.length; i++) {
......@@ -1340,7 +1406,11 @@ export default {
const kept = prev.filter(el => !el.__band);
const merged = kept.concat(graphics);
this.currentGraphicElements = merged;
this.myChart.setOption({ graphic: { elements: merged } });
this.$nextTick(() => {
if (this.myChart) {
this.myChart.setOption({ graphic: { elements: merged } }, { replaceMerge: ['graphic'] });
}
});
}
},
};
......@@ -1420,6 +1490,7 @@ export default {
border-radius: 6px;
border: 1px solid rgba(15, 23, 42, 0.15);
background-color: #d1d5db;
background-size: cover !important;
}
.legend-label {
......
......@@ -944,6 +944,7 @@ export default {
border-radius: 6px;
border: 1px solid rgba(15, 23, 42, 0.15);
background-color: #d1d5db;
background-size: cover !important;
}
.legend-label {
......
......@@ -302,11 +302,86 @@
<!-- 现代化特征代码卡片区 -->
<div class="feature-code-cards">
<div class="code-card" v-for="(item, i) in featureMap" :key="i">
<div class="code-title">T{{ String(i + 1).padStart(2, '0') }}</div>
<div class="code-title">{{ item.tzdl }}</div>
<div class="code-value">{{ detailData[item.codeField + '_tzdm'] || '--' }}</div>
<!-- <div class="code-value">{{ detailData[item.codeField + '_value'] || (detailData[item.codeField] || '--') }}</div> -->
</div>
</div>
<!-- 设计详细参数 -->
<div class="design-detail-params">
<el-divider class="divider-strong">设计详细参数</el-divider>
<el-form :model="detailData" label-width="120px">
<el-row :gutter="20" class="geometry-row">
<el-col :span="8">
<el-form-item label="冠部轮廓">
<el-input :value="detailData.gblk || '--'" readonly />
</el-form-item>
</el-col>
<el-col v-if="['双圆弧', '单圆弧'].includes(detailData.gblk)" :span="8">
<el-form-item label="R1(mm)">
<el-input :value="detailData.r1 || '--'" readonly />
</el-form-item>
</el-col>
<el-col v-if="detailData.gblk === '双圆弧'" :span="8">
<el-form-item label="R2(mm)">
<el-input :value="detailData.r2 || '--'" readonly />
</el-form-item>
</el-col>
<el-col v-if="detailData.gblk === '其他'" :span="8">
<el-form-item label="其他">
<el-input :value="detailData.qt || '--'" readonly />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="内锥角(°)">
<el-input :value="detailData.nzj || '--'" readonly />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="冠部高度(mm)">
<el-input :value="detailData.gbgd || '--'" readonly />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="冠顶直径(mm)">
<el-input :value="detailData.gdzj || '--'" readonly />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="内锥高度(mm)">
<el-input :value="detailData.nzgd || '--'" readonly />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="后倾角心部(°)">
<el-input :value="detailData.hqjxb || '--'" readonly />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="后倾角冠部(°)">
<el-input :value="detailData.hqjgb || '--'" readonly />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="后倾角保径(°)">
<el-input :value="detailData.hqjbj || '--'" readonly />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="后倾角其他(°)">
<el-input :value="detailData.hqjqt || '--'" readonly />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="后排齿后倾角(°)">
<el-input :value="detailData.hpchqj || '--'" readonly />
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<!-- 特征参数 -->
<div class="feature-params">
<div class="params-header">
......@@ -324,13 +399,10 @@
</div>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="detailVisible = false">关闭</el-button>
</span>
</el-dialog>
<el-dialog :visible.sync="imgPreviewVisible" width="80%" append-to-body class="img-preview-dialog"
:show-close="true" center>
<img :src="imgPreviewUrl" style="max-width:80vw;max-height:80vh;border-radius:18px;" />
......@@ -357,7 +429,6 @@
</div>
</el-dialog>
</div>
</template>
<script>
......@@ -1317,6 +1388,17 @@ export default {
letter-spacing: 2px;
}
.design-detail-params {
background: #f8faff;
border-radius: 12px;
padding: 24px 18px;
box-shadow: 0 2px 8px rgba(64, 158, 255, 0.06);
}
.design-detail-params .geometry-row {
margin-top: 20px;
}
.collapse-area {
background: #fafdff;
border-radius: 12px;
......
......@@ -461,9 +461,9 @@ export default {
.attr("transform", "translate(10,0)")
.call(yAxis);
svg2.selectAll(".tick text").style("fill", "#fff");
svg2.selectAll(".tick line").style("stroke", "#fff");
svg2.selectAll(".domain").style("stroke", "#fff");
svg2.selectAll(".tick text").style("fill", "#000");
svg2.selectAll(".tick line").style("stroke", "#000");
svg2.selectAll(".domain").style("stroke", "#000");
const gradient = svg2.append("defs")
.append("linearGradient")
......@@ -532,14 +532,14 @@ export default {
svg2.append("path")
.attr("transform", `translate(0,0)`)
.attr("fill", "none")
.attr("stroke", "#fff")
.attr("stroke", "#000")
.attr("stroke-width", 2)
.attr("d", line(seg.leftLine));
if (seg.leftLine[1]) {
svg2.append("path")
.datum(seg.leftLine[1])
.attr("class", "triangle-point")
.attr("fill", "rgb(255,255,255)")
.attr("fill", "rgb(0,0,0)")
.attr("d", this.drawTriangle(triangleLeft))
.attr("transform", d => `translate(${x(d.value)},${y(d.depth)})`);
}
......@@ -553,14 +553,14 @@ export default {
svg2.append("path")
.attr("transform", `translate(0,0)`)
.attr("fill", "none")
.attr("stroke", "#fff")
.attr("stroke", "#000")
.attr("stroke-width", 2)
.attr("d", line(seg.rightLine));
if (seg.rightLine[1]) {
svg2.append("path")
.datum(seg.rightLine[1])
.attr("class", "triangle-point")
.attr("fill", "rgb(255,255,255)")
.attr("fill", "rgb(0,0,0)")
.attr("d", this.drawTriangle(triangleRight))
.attr("transform", d => `translate(${x(d.value)},${y(d.depth)})`);
}
......@@ -582,7 +582,7 @@ export default {
// 箭头线
svg2.append("path")
.attr("d", arrowLine(item.point))
.attr("stroke", "#ffffff")
.attr("stroke", "#000")
.attr("fill", "none")
.attr("stroke-width", 1)
.attr("stroke-linecap", "round");
......@@ -594,7 +594,7 @@ export default {
.attr("cx", circleX)
.attr("cy", circleY)
.attr("r", 3)
.attr("fill", "#ffffff")
.attr("fill", "#000")
.attr("stroke", "none");
// 文本位置在箭头起点右侧稍上
......@@ -605,7 +605,7 @@ export default {
const text = group.append("text")
.attr("x", textX + 10)
.attr("y", textY)
.attr("fill", "#ffffff")
.attr("fill", "#000")
.attr("font-size", "12px");
if (item.describe1) {
......@@ -640,7 +640,7 @@ export default {
svg2.append("path")
.attr("d", arrowLine(item.point))
.attr("stroke", "#ffffff")
.attr("stroke", "#000")
.attr("fill", "none")
.attr("stroke-width", 1)
.attr("stroke-linecap", "round");
......@@ -651,7 +651,7 @@ export default {
.attr("cx", circleX)
.attr("cy", circleY)
.attr("r", 3)
.attr("fill", "#ffffff")
.attr("fill", "#000")
.attr("stroke", "none");
const textX = x(item.point[0][0] + 20);
......@@ -661,7 +661,7 @@ export default {
const text = group.append("text")
.attr("x", textX + 10)
.attr("y", textY)
.attr("fill", "#ffffff")
.attr("fill", "#000")
.attr("font-size", "12px");
if (item.describe1) {
......@@ -823,7 +823,7 @@ export default {
border-radius: 4px;
display: flex;
flex-direction: column;
background-color: #262a32;
background-color: #fff;
overflow: hidden;
}
......@@ -831,8 +831,9 @@ export default {
padding: 6px 12px;
font-size: 14px;
font-weight: 600;
color: #ffffff;
border-bottom: 1px solid #3c3f45;
color: #333;
border-bottom: 1px solid #e4e7ed;
background-color: #f5f7fa;
}
.jsjgt-body {
......
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