<template>
<div class="layout-container">
<div class="main-content">
<!-- 投影图和曲折度的两图表布局 -->
<div v-if="activeTab !== 'rate'" class="chart-container">
<!-- 第一个图表 -->
<div class="chart">
<div style="text-align: center; margin-top: 5px; font-size: 12px;">
{{ configForm.Xname }}
</div>
<ChartDialog
:Obj="obj"
:configVisible="configVisible"
@onConfigVisible="onConfigVisible"
@applyConfig="applyConfig"
/>
<EchartsAnime
:key="chartKey1"
:chartType="activeTab === 'projection' ? 'horizontal' : 'vertical'"
:width="configForm.width"
:height="configForm.height"
:Obj="currentChartData"
:Fixed="configForm.Fixed"
:Xname="''"
:Yname="configForm.Yname"
:nameGapNearX="configForm.nameGapNearX"
:nameGapNearY="configForm.nameGapNearY"
:inverseTrue="activeTab === 'projection' ? false : true"
:axisLabelRotate="configForm.axisLabelRotate"
:intervalSizeX="configForm.intervalSizeX"
:intervalSizeY="configForm.intervalSizeY"
:Xmax="configForm.Xmax"
:Xmim="configForm.Xmim"
:Ymax="configForm.Ymax"
:Ymim="configForm.Ymim"
:gridLeft="configForm.gridLeft"
:gridRight="configForm.gridRight"
:gridTop="configForm.gridTop"
:gridBottom="configForm.gridBottom"
:tooltipData="tooltipData"
:legendData="configForm.legendData"
:titlePosition="{ left: 'center', top: 10, bottom: 'auto' }"
xAxisPosition="top"
@initEcharts="(val) => initEcharts(val, 'first')"
/>
</div>
<!-- 第二个图表 -->
<div class="chart">
<div style="text-align: center; margin-top: 5px; font-size: 12px;">
{{ secondConfigForm.Xname }}
</div>
<EchartsAnime
:key="chartKey2"
chartType="vertical"
:width="secondConfigForm.width"
:height="secondConfigForm.height"
:Obj="secondChartData"
:Xname="''"
:Fixed="secondConfigForm.Fixed"
:Yname="secondConfigForm.Yname"
:nameGapNearX="45"
:nameGapNearY="58"
:inverseTrue="true"
:axisLabelRotate="secondConfigForm.axisLabelRotate"
:intervalSizeX="secondConfigForm.intervalSizeX"
:intervalSizeY="secondConfigForm.intervalSizeY"
:Xmax="secondConfigForm.Xmax"
:Ymax="secondConfigForm.Ymax"
:Xmim="secondConfigForm.Xmim"
:Ymim="secondConfigForm.Ymim"
:gridLeft="secondConfigForm.gridLeft"
:gridRight="secondConfigForm.gridRight"
:gridTop="secondConfigForm.gridTop"
:gridBottom="secondConfigForm.gridBottom"
:tooltipData="tooltipData"
:legendData="secondConfigForm.legendData"
:titlePosition="{ left: 'center', top: 10, bottom: 'auto' }"
xAxisPosition="top"
@initEcharts="(val) => initEcharts(val, 'second')"
/>
</div>
</div>
<!-- 变化率的三图表布局 -->
<div v-if="activeTab === 'rate'" class="chart-container three-charts">
<!-- 第一个图表 -->
<div class="chart">
<div style="text-align: center; margin-top: 5px; font-size: 12px;">
{{ configForm.Xname }}
</div>
<EchartsAnime
:key="chartKey1"
chartType="rate-vertical"
:width="configForm.width"
:height="configForm.height"
:Obj="currentChartData"
:Fixed="configForm.Fixed"
:Xname="''"
:Yname="configForm.Yname"
:nameGapNearX="configForm.nameGapNearX"
:nameGapNearY="configForm.nameGapNearY"
:inverseTrue="true"
:axisLabelRotate="configForm.axisLabelRotate"
:intervalSizeX="configForm.intervalSizeX"
:intervalSizeY="configForm.intervalSizeY"
:Xmax="configForm.Xmax"
:Xmim="configForm.Xmim"
:Ymax="configForm.Ymax"
:Ymim="configForm.Ymim"
:gridLeft="configForm.gridLeft"
:gridRight="configForm.gridRight"
:gridTop="configForm.gridTop"
:gridBottom="configForm.gridBottom"
:tooltipData="tooltipData"
:legendData="configForm.legendData"
:titlePosition="{ left: 'center', top: 10, bottom: 'auto' }"
@initEcharts="(val) => initEcharts(val, 'first')"
/>
</div>
<!-- 第二个图表 -->
<div class="chart">
<div style="text-align: center; margin-top: 5px; font-size: 12px;">
{{ secondConfigForm.Xname }}
</div>
<EchartsAnime
:key="chartKey2"
chartType="rate-vertical"
:width="secondConfigForm.width"
:height="secondConfigForm.height"
:Obj="secondChartData"
:Xname="''"
:Fixed="secondConfigForm.Fixed"
:Yname="secondConfigForm.Yname"
:nameGapNearX="45"
:nameGapNearY="58"
:inverseTrue="true"
:axisLabelRotate="secondConfigForm.axisLabelRotate"
:intervalSizeX="secondConfigForm.intervalSizeX"
:intervalSizeY="secondConfigForm.intervalSizeY"
:Xmax="secondConfigForm.Xmax"
:Ymax="secondConfigForm.Ymax"
:Xmim="secondConfigForm.Xmim"
:Ymim="secondConfigForm.Ymim"
:gridLeft="secondConfigForm.gridLeft"
:gridRight="secondConfigForm.gridRight"
:gridTop="secondConfigForm.gridTop"
:gridBottom="secondConfigForm.gridBottom"
:tooltipData="tooltipData"
:legendData="secondConfigForm.legendData"
:titlePosition="{ left: 'center', top: 10, bottom: 'auto' }"
@initEcharts="(val) => initEcharts(val, 'second')"
/>
</div>
<!-- 第三个图表 -->
<div class="chart">
<div style="text-align: center; margin-top: 5px; font-size: 12px;">
{{ thirdConfigForm.Xname }}
</div>
<EchartsAnime
:key="chartKey3"
chartType="rate-vertical"
:width="thirdConfigForm.width"
:height="thirdConfigForm.height"
:Obj="thirdChartData"
:Fixed="thirdConfigForm.Fixed"
:Xname="''"
:Yname="thirdConfigForm.Yname"
:nameGapNearX="thirdConfigForm.nameGapNearX"
:nameGapNearY="thirdConfigForm.nameGapNearY"
:inverseTrue="true"
:axisLabelRotate="thirdConfigForm.axisLabelRotate"
:intervalSizeX="thirdConfigForm.intervalSizeX"
:intervalSizeY="thirdConfigForm.intervalSizeY"
:Xmax="thirdConfigForm.Xmax"
:Xmim="thirdConfigForm.Xmim"
:Ymax="thirdConfigForm.Ymax"
:Ymim="thirdConfigForm.Ymim"
:gridLeft="thirdConfigForm.gridLeft"
:gridRight="thirdConfigForm.gridRight"
:gridTop="thirdConfigForm.gridTop"
:gridBottom="thirdConfigForm.gridBottom"
:tooltipData="tooltipData"
:legendData="thirdConfigForm.legendData"
:titlePosition="{ left: 'center', top: 10, bottom: 'auto' }"
@initEcharts="(val) => initEcharts(val, 'third')"
/>
</div>
</div>
<div class="bottom-tabs">
<el-tabs v-model="activeTab" @tab-click="handleTabClick">
<el-tab-pane label="投影图" name="projection"></el-tab-pane>
<el-tab-pane label="曲折度" name="curvature"></el-tab-pane>
<el-tab-pane label="变化率" name="rate"></el-tab-pane>
</el-tabs>
</div>
</div>
</div>
</template>
<script>
import * as echarts from "echarts";
import "echarts-gl";
import EchartsAnime from "@/components/hc-echartseAnime/index.vue";
import ChartDialog from "@/components/hc-echartseAnime/dialog.vue";
import {
getHorizontalProjectionApi,
getVerticalProjectionApi,
getWellSlopeApi,
getBuildRateApi,
getAzimuthApi,
getWellCurvatureApi,
getVerticalSectionApi,
} from "@/service/api/jygj/newjygj";
export default {
name: "Well2DView",
components: {
EchartsAnime,
ChartDialog,
},
data() {
return {
activeViewTab: "2D",
activeTab: "projection",
configVisible: false,
loading: false,
ModifyItem: null,
echartsInstances: [],
currentChartData: [],
secondChartData: [],
obj: [
// 添加 obj 属性
{
itemStyle: "#e22222",
dataList: [],
},
{
itemStyle: "#f777ff",
dataList: [],
},
],
configForm: {
width: this.activeTab === "rate" ? "100%" : "100%",
height: "100%",
Fixed: 2,
Xname: "",
Yname: "South(-)/North(+)(m)",
axisLabelRotate: 0,
inverseTrue: false,
intervalSizeX: 200,
intervalSizeY: 30,
Xmax: "0",
Xmim: "-800",
Ymax: "0",
Ymim: "-150",
gridLeft: 30, // 使用数字,不需要带px
gridRight: 20,
gridTop: 20,
gridBottom: 20,
},
secondConfigForm: {
width: this.activeTab === "rate" ? "100%" : "100%",
height: "100%",
Fixed: 2,
Xname: "",
Yname: "TVD(m)",
axisLabelRotate: 0,
inverseTrue: false,
intervalSizeX: 200,
intervalSizeY: 30,
Xmax: "0",
Xmim: "-800",
Ymax: "0",
Ymim: "-150",
gridLeft: 40, // 使用数字,不需要带px
gridRight: 20,
gridTop: 20,
gridBottom: 20,
},
tooltipData: {
title: "",
distance: "时间",
unit: "",
names: [], // 初始化为一个空数组
},
thirdChartData: [],
thirdConfigForm: {
width: this.activeTab === "rate" ? "100%" : "100%",
height: "100%",
Fixed: 2,
Xname: "",
Yname: "Turn Rate(°/30m)",
axisLabelRotate: 0,
inverseTrue: false,
intervalSizeX: 200,
intervalSizeY: 1,
nameGapNearX: 30,
nameGapNearY: 45,
gridLeft: 40,
gridRight: 20,
gridTop: 20,
gridBottom: 20,
}, // 添加预定义的颜色数组
lineColors: [
"#e22222", // 红色
"#2278ff", // 蓝色
"#22bb33", // 绿色
"#f4a460", // 沙褐色
"#9370db", // 紫色
"#20b2aa", // 青色
"#ff6347", // 橙红色
"#4682b4", // 钢青色
],
isFirstChartVertical: false,
isSecondChartVertical: false,
isThirdChartVertical: false,
chartKey1: 0,
chartKey2: 0,
chartKey3: 0,
};
},
watch: {
// 监听 activeTab 变化,更新宽度
activeTab: {
handler(newVal) {
const width = newVal === "rate" ? "100%" : "100%";
this.configForm.width = width;
this.secondConfigForm.width = width;
this.thirdConfigForm.width = width;
},
immediate: true,
},
},
mounted() {},
beforeDestroy() {
this.echartsInstances.forEach((chart) => {
if (chart) {
chart.dispose();
}
});
},
methods: {
// 添加计算动态间隔的辅助方法
calculateDynamicInterval(min, max, maxTickCount) {
const range = max - min;
return Math.max(1, Math.ceil(range / maxTickCount)); // 确保至少为1,避免间隔为0
},
updateWellParams(params) {
// 处理接收到的参数
this.ModifyItem = params;
// 重置图表配置
this.resetChartConfigurations();
// 根据当前激活的 tab 调用对应的数据加载方法
switch (this.activeTab) {
case "projection":
this.loadProjectionData();
break;
case "curvature":
this.loadCurvatureData();
break;
case "rate":
this.loadRateData();
break;
}
},
handleClick() {
this.configVisible = !this.configVisible;
},
onConfigVisible(val) {
this.configVisible = val;
},
applyConfig(val) {
this.configForm = val;
},
initEcharts(instance, type) {
if (type === "first") {
this.firstChartInstance = instance;
} else if (type === "second") {
this.secondChartInstance = instance;
} else if (type === "third") {
this.thirdChartInstance = instance;
}
},
async handleTabClick(tab) {
if (this.loading) return;
this.loading = true;
try {
// 销毁现有图表实例
if (this.firstChartInstance) {
this.firstChartInstance.dispose();
this.firstChartInstance = null;
}
if (this.secondChartInstance) {
this.secondChartInstance.dispose();
this.secondChartInstance = null;
}
if (this.thirdChartInstance) {
this.thirdChartInstance.dispose();
this.thirdChartInstance = null;
}
// 重置所有图表配置
this.resetChartConfigurations();
switch (tab.name) {
case "projection":
await this.loadProjectionData();
break;
case "curvature":
await this.loadCurvatureData();
break;
case "rate":
await this.loadRateData();
break;
}
} catch (error) {
console.error("Error loading data:", error);
this.$message.error("加载数据失败");
} finally {
this.loading = false;
}
},
async loadProjectionData() {
// 打开loading
const loading = this.$loading({
lock: true,
text: "加载中...",
background: "rgba(0, 0, 0, 0.7)",
});
try {
// 先销毁现有图表实例
if (this.firstChartInstance) {
this.firstChartInstance.dispose();
this.firstChartInstance = null;
}
if (this.secondChartInstance) {
this.secondChartInstance.dispose();
this.secondChartInstance = null;
}
// 清空数据
this.currentChartData = [];
this.secondChartData = [];
// 然后获取新数据
const [horizontalRes, verticalRes] = await Promise.all([
getHorizontalProjectionApi(this.ModifyItem),
getVerticalSectionApi(this.ModifyItem),
]);
if (horizontalRes.code === 200 && verticalRes.code === 200) {
// 处理水平投影数据
let formattedDataSets = [];
if (horizontalRes.data && horizontalRes.data.length > 0) {
formattedDataSets = horizontalRes.data.map((dataset, index) => ({
itemStyle: this.lineColors[index % this.lineColors.length],
dataList: dataset.chartCmstVoList.map((point) => [
point.z,
point.x,
]),
name: dataset.name,
}));
}
// 确保设置为新数组,而不是修改原数组
this.currentChartData = [...formattedDataSets];
// 处理垂直剖面数据
const verticalDataSets = verticalRes.data.map((dataset, index) => ({
itemStyle: this.lineColors[index % this.lineColors.length], // 循环使用颜色
dataList: dataset.chartCmstVoList.map((point) => [
point.x,
point.z,
]),
name: dataset.name, // 添加井的名称
}));
this.secondChartData = verticalDataSets;
// 提取所有数据点用于分析
const allHorizontalPoints = formattedDataSets.flatMap(
(dataset) => dataset.dataList
);
const allVerticalPoints = verticalDataSets.flatMap(
(dataset) => dataset.dataList
);
// 设置配置并进行动态调整
this.configForm = this.adjustConfigForVerticalData(
allHorizontalPoints,
{
width: "100%",
height: "100%",
Fixed: 2,
Xname: "West(-)/East(+)(m)",
Yname: "South(-)/North(+)(m)",
axisLabelRotate: 0,
inverseTrue: false,
intervalSizeX: this.calculateDynamicInterval(
Math.min(...allHorizontalPoints.map((point) => point[0])),
Math.max(...allHorizontalPoints.map((point) => point[0])),
7
),
intervalSizeY: this.calculateDynamicInterval(
Math.min(...allHorizontalPoints.map((point) => point[1])),
Math.max(...allHorizontalPoints.map((point) => point[1])),
15
),
Xmax: String(
Math.max(...allHorizontalPoints.map((point) => point[0]))
),
Xmim: String(
Math.min(...allHorizontalPoints.map((point) => point[0]))
),
Ymax: String(
Math.max(...allHorizontalPoints.map((point) => point[1]))
),
Ymim: String(
Math.min(...allHorizontalPoints.map((point) => point[1]))
),
nameGapNearX: 30,
nameGapNearY: 45,
gridLeft: 30,
gridRight: 20,
gridTop: 40,
gridBottom: 20,
legendData: {
show: true,
data: formattedDataSets.map((item) => item.name),
},
},
0 // 检查X轴
);
this.secondConfigForm = this.adjustConfigForVerticalData(
allVerticalPoints,
{
width: "100%",
height: "100%",
Fixed: 2,
Xname: "Vertical Section(m)",
Yname: "TVD(m)",
axisLabelRotate: 0,
inverseTrue: true,
intervalSizeX: this.calculateDynamicInterval(
Math.min(...allVerticalPoints.map((point) => point[0])),
Math.max(...allVerticalPoints.map((point) => point[0])),
7
),
intervalSizeY: this.calculateDynamicInterval(
Math.min(...allVerticalPoints.map((point) => point[1])),
Math.max(...allVerticalPoints.map((point) => point[1])),
15
),
Xmax: String(
Math.max(...allVerticalPoints.map((point) => point[0]))
),
Xmim: String(
Math.min(...allVerticalPoints.map((point) => point[0]))
),
Ymax: String(
Math.max(...allVerticalPoints.map((point) => point[1]))
),
Ymim: String(
Math.min(...allVerticalPoints.map((point) => point[1]))
),
nameGapNearX: 30,
nameGapNearY: 45,
gridLeft: 30,
gridRight: 20,
gridTop: 40,
gridBottom: 20,
legendData: {
show: true,
data: verticalDataSets.map((item) => item.name),
},
},
0 // 检查X轴
);
// 设置垂直井标志以便组件内部处理
this.isFirstChartVertical = this.isVerticalOrSingleValueData(
allHorizontalPoints,
0
);
this.isSecondChartVertical = this.isVerticalOrSingleValueData(
allVerticalPoints,
0
);
// 关闭loading
loading.close();
}
} catch (error) {
// 关闭loading
loading.close();
console.error("加载投影图数据失败:", error);
this.$message.warning("加载投影图数据失败");
}
},
async loadCurvatureData() {
// 打开loading
const loading = this.$loading({
lock: true,
text: "加载中...",
background: "rgba(0, 0, 0, 0.7)",
});
try {
const [slopeRes, directionRes] = await Promise.all([
getWellSlopeApi(this.ModifyItem),
getAzimuthApi(this.ModifyItem),
]);
if (slopeRes.code === 200 && directionRes.code === 200) {
// 处理井斜角数据
const slopeDataSets = slopeRes.data.map((dataset, index) => ({
itemStyle: this.lineColors[index % this.lineColors.length], // 循环使用颜色
dataList: dataset.chartCmstVoList.map((point) => [
point.z, // 测量深度作为X轴
point.x, // 井斜角作为Y轴
]),
name: dataset.name, // 添加井的名称
}));
this.currentChartData = slopeDataSets;
// 处理方位角数据
const directionDataSets = directionRes.data.map((dataset, index) => ({
itemStyle: this.lineColors[index % this.lineColors.length], // 循环使用颜色
dataList: dataset.chartCmstVoList.map((point) => [
point.z, // 测量深度作为X轴
point.x, // 方位角作为Y轴
]),
name: dataset.name, // 添加井的名称
}));
this.secondChartData = directionDataSets;
// 提取所有数据点
const allSlopePoints = slopeDataSets.flatMap(
(dataset) => dataset.dataList
);
const allDirectionPoints = directionDataSets.flatMap(
(dataset) => dataset.dataList
);
// 应用动态调整
this.configForm = this.adjustConfigForVerticalData(
allSlopePoints,
{
width: "100%",
height: "100%",
Fixed: 2,
Xname: "INC(°)",
Yname: "MD(m)",
axisLabelRotate: 0,
inverseTrue: true,
intervalSizeX: this.calculateDynamicInterval(
Math.min(...allSlopePoints.map((point) => point[0])),
Math.max(...allSlopePoints.map((point) => point[0])),
7
),
intervalSizeY: this.calculateDynamicInterval(
Math.max(
0,
Math.min(...allSlopePoints.map((point) => point[1])) - 5
),
Math.max(...allSlopePoints.map((point) => point[1])) + 5,
15
),
Xmax: String(
Math.max(...allSlopePoints.map((point) => point[0]))
),
Xmim: String(
Math.min(...allSlopePoints.map((point) => point[0]))
),
Ymax: String(
Math.max(...allSlopePoints.map((point) => point[1])) + 5
),
Ymim: String(
Math.max(
0,
Math.min(...allSlopePoints.map((point) => point[1])) - 5
)
),
nameGapNearX: 30,
nameGapNearY: 45,
gridLeft: 40,
gridRight: 20,
gridTop: 20,
gridBottom: 20,
legendData: {
show: true,
data: slopeDataSets.map((item) => item.name),
},
},
0 // 检查X轴
);
this.secondConfigForm = this.adjustConfigForVerticalData(
allDirectionPoints,
{
width: "100%",
height: "100%",
Fixed: 2,
Xname: "AZI(°)",
Yname: "MD(m)",
axisLabelRotate: 0,
inverseTrue: true,
intervalSizeX: this.calculateDynamicInterval(
Math.min(...allDirectionPoints.map((point) => point[0])),
Math.max(...allDirectionPoints.map((point) => point[0])),
7
),
intervalSizeY: this.calculateDynamicInterval(0, 360, 15),
Xmax: String(
Math.max(...allDirectionPoints.map((point) => point[0]))
),
Xmim: String(
Math.min(...allDirectionPoints.map((point) => point[0]))
),
Ymax: String(360),
Ymim: String(0),
nameGapNearX: 30,
nameGapNearY: 45,
gridLeft: 40,
gridRight: 20,
gridTop: 20,
gridBottom: 20,
legendData: {
show: true,
data: directionDataSets.map((item) => item.name),
},
},
0 // 检查X轴
);
// 设置垂直井标志
this.isFirstChartVertical = this.isVerticalOrSingleValueData(
allSlopePoints,
0
);
this.isSecondChartVertical = this.isVerticalOrSingleValueData(
allDirectionPoints,
0
);
// 关闭loading
loading.close();
}
} catch (error) {
// 关闭loading
loading.close();
console.error("数据处理错误:", error);
this.$message.warning("加载变化率数据失败");
}
},
async loadRateData() {
// 打开loading
const loading = this.$loading({
lock: true,
text: "加载中...",
background: "rgba(0, 0, 0, 0.7)",
});
try {
const [curvatureRes, buildRes, deviationRes] = await Promise.all([
getWellCurvatureApi(this.ModifyItem),
getBuildRateApi(this.ModifyItem),
getVerticalProjectionApi(this.ModifyItem),
]);
if (
curvatureRes.code === 200 &&
buildRes.code === 200 &&
deviationRes.code === 200
) {
// 处理三组数据
const curvatureDataSets = curvatureRes.data.map((dataset, index) => ({
itemStyle: this.lineColors[index % this.lineColors.length], // 循环使用颜色
dataList: dataset.chartCmstVoList.map((point) => [
point.z,
point.x,
]),
name: dataset.name, // 添加井的名称
}));
const buildDataSets = buildRes.data.map((dataset, index) => ({
itemStyle: this.lineColors[index % this.lineColors.length], // 循环使用颜色
dataList: dataset.chartCmstVoList.map((point) => [
point.z,
point.x,
]),
name: dataset.name, // 添加井的名称
}));
const deviationDataSets = deviationRes.data.map((dataset, index) => ({
itemStyle: this.lineColors[index % this.lineColors.length], // 循环使用颜色
dataList: dataset.chartCmstVoList.map((point) => [
point.z,
point.x,
]),
name: dataset.name, // 添加井的名称
}));
this.currentChartData = curvatureDataSets;
this.secondChartData = buildDataSets;
this.thirdChartData = deviationDataSets;
// 提取所有数据点
const allCurvaturePoints = curvatureDataSets.flatMap(
(dataset) => dataset.dataList
);
const allBuildPoints = buildDataSets.flatMap(
(dataset) => dataset.dataList
);
const allDeviationPoints = deviationDataSets.flatMap(
(dataset) => dataset.dataList
);
// 应用动态调整
this.configForm = this.adjustConfigForVerticalData(
allCurvaturePoints,
{
width: "100%",
height: "100%",
Fixed: 2,
Xname: "Dogleg(°/30m)",
Yname: "MD(m)",
axisLabelRotate: 0,
inverseTrue: true,
intervalSizeX: this.calculateDynamicInterval(
Math.min(...allCurvaturePoints.map((point) => point[0])),
Math.max(...allCurvaturePoints.map((point) => point[0])),
7
),
intervalSizeY: this.calculateDynamicInterval(
Math.min(...allCurvaturePoints.map((point) => point[1])),
Math.max(...allCurvaturePoints.map((point) => point[1])),
15
),
Xmax: String(
Math.max(...allCurvaturePoints.map((point) => point[0]))
),
Xmim: String(
Math.min(...allCurvaturePoints.map((point) => point[0]))
),
Ymax: String(
Math.max(...allCurvaturePoints.map((point) => point[1]))
),
Ymim: String(
Math.min(...allCurvaturePoints.map((point) => point[1]))
),
nameGapNearX: 45,
nameGapNearY: 45,
gridLeft: 60,
gridRight: 20,
gridTop: 10,
gridBottom: 40,
legendData: {
show: true,
data: curvatureDataSets.map((item) => item.name),
},
},
0 // 检查X轴
);
this.secondConfigForm = this.adjustConfigForVerticalData(
allBuildPoints,
{
width: "100%",
height: "100%",
Fixed: 2,
Xname: "Build Rate(°/30m)",
Yname: "MD(m)",
axisLabelRotate: 0,
inverseTrue: true,
intervalSizeX: this.calculateDynamicInterval(
Math.min(...allBuildPoints.map((point) => point[0])),
Math.max(...allBuildPoints.map((point) => point[0])),
7
),
intervalSizeY: this.calculateDynamicInterval(
Math.min(...allBuildPoints.map((point) => point[1])),
Math.max(...allBuildPoints.map((point) => point[1])),
15
),
Xmax: String(
Math.max(...allBuildPoints.map((point) => point[0]))
),
Xmim: String(
Math.min(...allBuildPoints.map((point) => point[0]))
),
Ymax: String(
Math.max(...allBuildPoints.map((point) => point[1]))
),
Ymim: String(
Math.min(...allBuildPoints.map((point) => point[1]))
),
nameGapNearX: 45,
nameGapNearY: 45,
gridLeft: 60,
gridRight: 20,
gridTop: 10,
gridBottom: 40,
legendData: {
show: true,
data: buildDataSets.map((item) => item.name),
},
},
0 // 检查X轴
);
this.thirdConfigForm = this.adjustConfigForVerticalData(
allDeviationPoints,
{
width: "100%",
height: "100%",
Fixed: 2,
Xname: "Turn Rate(°/30m)",
Yname: "MD(m)",
axisLabelRotate: 0,
inverseTrue: true,
intervalSizeX: this.calculateDynamicInterval(
Math.min(...allDeviationPoints.map((point) => point[0])),
Math.max(...allDeviationPoints.map((point) => point[0])),
7
),
intervalSizeY: this.calculateDynamicInterval(
Math.min(...allDeviationPoints.map((point) => point[1])),
Math.max(...allDeviationPoints.map((point) => point[1])),
15
),
Xmax: String(
Math.max(...allDeviationPoints.map((point) => point[0]))
),
Xmim: String(
Math.min(...allDeviationPoints.map((point) => point[0]))
),
Ymax: String(
Math.max(...allDeviationPoints.map((point) => point[1]))
),
Ymim: String(
Math.min(...allDeviationPoints.map((point) => point[1]))
),
nameGapNearX: 45,
nameGapNearY: 45,
gridLeft: 60,
gridRight: 20,
gridTop: 10,
gridBottom: 40,
legendData: {
show: true,
data: deviationDataSets.map((item) => item.name),
},
},
0 // 检查X轴
);
// 设置垂直井标志
this.isFirstChartVertical = this.isVerticalOrSingleValueData(
allCurvaturePoints,
0
);
this.isSecondChartVertical = this.isVerticalOrSingleValueData(
allBuildPoints,
0
);
this.isThirdChartVertical = this.isVerticalOrSingleValueData(
allDeviationPoints,
0
);
// 关闭loading
loading.close();
}
} catch (error) {
// 关闭loading
loading.close();
console.error("数据处理错误:", error);
throw new Error("加载变化率数据失败");
}
},
// 添加新方法用于重置图表配置
resetChartConfigurations() {
// 重置第一个图表的配置
this.configForm = {
width: this.activeTab === "rate" ? "100%" : "100%",
height: "100%",
Fixed: 2,
Xname: "",
Yname: "",
axisLabelRotate: 0,
inverseTrue: true,
intervalSizeX: 200,
intervalSizeY: 30,
Xmax: "0",
Xmim: "-800",
Ymax: "0",
Ymim: "-150",
gridLeft: 30,
gridRight: 20,
gridTop: 20,
gridBottom: 20,
nameGapNearX: 30,
nameGapNearY: 45,
};
// 重置第二个图表的配置
this.secondConfigForm = {
width: this.activeTab === "rate" ? "100%" : "100%",
height: "100%",
Fixed: 2,
Xname: "",
Yname: "",
axisLabelRotate: 0,
inverseTrue: true,
intervalSizeX: 200,
intervalSizeY: 30,
Xmax: "0",
Xmim: "-800",
Ymax: "0",
Ymim: "-150",
gridLeft: 40,
gridRight: 20,
gridTop: 20,
gridBottom: 20,
nameGapNearX: 30,
nameGapNearY: 45,
};
// 重置第三个图表的配置
this.thirdConfigForm = {
width: this.activeTab === "rate" ? "100%" : "100%",
height: "100%",
Fixed: 2,
Xname: "",
Yname: "",
axisLabelRotate: 0,
inverseTrue: true,
intervalSizeX: 200,
intervalSizeY: 1,
nameGapNearX: 30,
nameGapNearY: 45,
gridLeft: 40,
gridRight: 20,
gridTop: 20,
gridBottom: 20,
Xmax: "0",
Xmim: "-800",
Ymax: "0",
Ymim: "-150",
};
// 增加key值,强制重新渲染
this.chartKey1++;
this.chartKey2++;
this.chartKey3++;
// 清空数据
this.currentChartData = [];
this.secondChartData = [];
this.thirdChartData = [];
},
isVerticalOrSingleValueData(dataPoints, axis = 0) {
if (!dataPoints || dataPoints.length === 0) return false;
// 检查指定轴上的所有值是否相同
const firstValue = dataPoints[0][axis];
return dataPoints.every((point) => point[axis] === firstValue);
},
adjustConfigForVerticalData(dataPoints, configObj, axis = 0) {
if (!this.isVerticalOrSingleValueData(dataPoints, axis)) return configObj;
const value = dataPoints[0][axis];
const range = 10; // 设置一个合理的范围
// 创建新的配置对象
const newConfig = { ...configObj };
// 根据轴设置适当的属性
if (axis === 0) {
// X轴
newConfig.Xmax = String(value + range);
newConfig.Xmim = String(value - range);
} else {
// Y轴
newConfig.Ymax = String(value + range);
newConfig.Ymim = String(value - range);
}
// 增加网格边距
newConfig.gridLeft = 60;
newConfig.gridRight = 60;
return newConfig;
},
},
};
</script>
<style scoped lang="scss">
.layout-container {
height: 100%;
width: 100%;
background-color: #fff;
border-radius: 4px;
overflow: hidden;
display: flex;
flex-direction: column;
}
.view-header {
padding: 0 20px;
border-bottom: 1px solid #ebeef5;
.tab-group {
display: flex;
gap: 20px;
.tab {
padding: 12px 20px;
cursor: pointer;
position: relative;
color: #606266;
&.active {
color: #409eff;
&::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 2px;
background-color: #409eff;
}
}
}
}
}
.main-content {
width: 100%;
height: 100%;
box-sizing: border-box;
overflow: hidden;
display: flex;
flex-direction: column;
position: relative;
}
.chart-container {
display: grid;
gap: 10px;
width: 100%;
height: calc(100% - 50px);
box-sizing: border-box;
grid-template-columns: 1fr 1fr; /* 默认两列 */
}
.chart-container.three-charts {
grid-template-columns: 1fr 1fr 1fr; /* 变化率时三列 */
}
.chart {
height: 100%;
border: 1px solid #ebeef5;
border-radius: 4px;
padding: 10px;
position: relative;
box-sizing: border-box;
overflow: hidden;
}
.chart {
height: 100%;
border: 1px solid #ebeef5;
border-radius: 4px;
padding: 10px;
position: relative;
}
.bottom-tabs {
margin-top: 10px;
border-top: 1px solid #ebeef5;
position: absolute;
bottom: 0;
left: 0;
right: 0;
::v-deep .el-tabs__header {
margin: 0;
}
::v-deep .el-tabs__nav-wrap::after {
height: 0;
}
::v-deep .el-tabs__item {
height: 40px;
line-height: 40px;
font-size: 15px;
color: #252627;
&.is-active {
color: #409eff;
}
}
}
::v-deep .el-button--primary {
background-color: transparent;
border-color: #0790d6;
&:hover,
&:focus {
background-color: #0790d6;
border-color: #0790d6;
color: white;
}
}
</style>
为什么切换时 第二个和第二个tab里面的图表会随机有的渲染不出来呢