Commit d7d8a15a by cat

曲线图形改id

parent d7e75ada
<template> <template>
<div class="drilling-chart-container" v-loading="loading"> <div class="drilling-chart-container" v-loading="loading">
<div id="drillingEfficiencyChart" class="chart"></div> <div id="drillingEfficiencyChartDJ" class="chart"></div>
</div> </div>
</template> </template>
...@@ -73,14 +73,14 @@ export default { ...@@ -73,14 +73,14 @@ export default {
initChart() { initChart() {
if (!this.chartData) { if (!this.chartData) {
const chartDom = document.getElementById('drillingEfficiencyChart'); const chartDom = document.getElementById('drillingEfficiencyChartDJ');
if (chartDom && this.myChart) { if (chartDom && this.myChart) {
this.myChart.clear(); this.myChart.clear();
} }
return; return;
} }
const chartDom = document.getElementById('drillingEfficiencyChart'); const chartDom = document.getElementById('drillingEfficiencyChartDJ');
if (!chartDom) { if (!chartDom) {
console.error('未找到图表容器'); console.error('未找到图表容器');
return; return;
......
<template>
<div class="chart-container" v-loading="loading">
<div id="mainzft" class="chart" ></div>
</div>
</template>
<script>
import * as echarts from "echarts";
import { getdjZft } from "@/api/optimization/initialization";
export default {
name: "HistogramGraph",
props: {
jh: {
type: String,
default: "",
},
jhs: {
type: String,
default: ''
}
},
data() {
return {
mockData: {},
myChart: null,
initRetryCount: 0,
maxRetryCount: 5,
resizeObserver: null,
loading: false // 新增loading状态
};
},
mounted() {
// this.$nextTick(() => {
// setTimeout(() => {
// this.initChart();
// this.observeParentResize();
// }, 800);
// });
// window.addEventListener("resize", this.handleResize);
},
beforeDestroy() {
window.removeEventListener("resize", this.handleResize);
if (this.myChart) {
this.myChart.dispose();
}
if (this.resizeObserver) {
this.resizeObserver.disconnect();
}
},
methods: {
/**
* 外部调用:加载数据并渲染
*/
loadData() {
this.loading = true;
this.$nextTick(() => {
setTimeout(() => {
this.initChart();
this.observeParentResize();
}, 800);
});
window.addEventListener("resize", this.handleResize);
},
observeParentResize() {
const parentDom = document.getElementById("mainzft")?.parentElement;
if (parentDom && window.ResizeObserver) {
this.resizeObserver = new ResizeObserver(() => {
if (this.myChart) {
this.myChart.resize();
}
});
this.resizeObserver.observe(parentDom);
}
},
async getList() {
try {
const res = await getdjZft({ jhs: this.jhs });
this.mockData = res?.mockData || {};
return this.mockData;
} catch (error) {
console.error("获取数据失败:", error);
return {};
}
},
async initChart() {
this.loading = true;
const chartDom = document.getElementById("mainzft");
if (!chartDom) {
console.error("未找到图表容器 DOM");
this.loading = false;
return;
}
// 获取视口尺寸
const viewportWidth = window.innerWidth;
const viewportHeight = window.innerHeight;
// 计算可用空间(减去导航栏等固定元素的高度)
const availableHeight = viewportHeight - 120; // 减去导航栏等高度
const availableWidth = viewportWidth - 80; // 减去左右边距,增加边距
// 设置图表容器尺寸
chartDom.style.width = `${availableWidth}px`;
chartDom.style.height = `${availableHeight}px`;
// 强制重排
chartDom.offsetHeight;
// 重试机制
if ((availableWidth <= 0 || availableHeight <= 0) && this.initRetryCount < this.maxRetryCount) {
this.initRetryCount++;
setTimeout(() => this.initChart(), 500);
return;
}
this.initRetryCount = 0;
if (this.myChart) {
this.myChart.dispose();
}
this.myChart = echarts.init(chartDom);
const mockData = await this.getList();
if (!mockData || !mockData.wellData || !mockData.wellData.depthLine.length) {
this.renderEmpty(chartDom);
this.loading = false;
return;
}
await this.renderRealData(chartDom, mockData);
this.loading = false;
},
handleResize() {
this.debounce(() => {
if (this.myChart) {
// 重新计算尺寸
const viewportHeight = window.innerHeight;
const viewportWidth = window.innerWidth;
const availableHeight = viewportHeight - 120;
const availableWidth = viewportWidth - 80;
const chartDom = document.getElementById("mainzft");
if (chartDom) {
chartDom.style.width = `${availableWidth}px`;
chartDom.style.height = `${availableHeight}px`;
}
this.myChart.resize();
}
}, 200)();
},
async renderRealData(chartDom, mockData) {
const { wellData } = mockData;
const xAxisLabels = wellData.depthLine.map((point) => point.x);
const areaSeries = await Promise.all(
wellData.stackedAreas
.filter(area => area.svg !== null)
.map(async (area) => {
let areaStyle = { opacity: 0.8 };
if (area.svg) {
try {
const svgImage = await this.createSvgImage(area.svg);
areaStyle.color = { image: svgImage, repeat: "repeat" };
} catch (error) {
console.error('SVG转换失败:', error);
}
}
return {
name: area.name,
type: "line",
xAxisIndex: 1,
z: -1,
stack: "总量",
symbol: "none",
showSymbol: false,
areaStyle: areaStyle,
lineStyle: { width: 0 },
data: area.points.map((point) => point.y),
};
})
);
const option = {
title: { text: "", subtext: "" },
aria: {
enabled: false,
},
tooltip: {
trigger: "axis",
axisPointer: { type: "cross", label: { backgroundColor: "#6a7985" } },
},
grid: {
top: 80,
left: "8%",
right: "8%",
bottom: "8%",
containLabel: true,
show: false,
},
xAxis: [
{
type: "category",
boundaryGap: true,
position: "top",
data: xAxisLabels,
axisLabel: { interval: 0, rotate: 90, margin: 8, align: "left", fontSize: 12 },
axisTick: { alignWithLabel: true, length: 5 },
splitLine: { show: false },
axisLine: { show: true }
},
{ type: "category", boundaryGap: false, position: "top", show: false, data: xAxisLabels },
],
yAxis: [
{
type: "value",
name: "井深(m)",
min: mockData.chartConfig.yAxis.min,
max: mockData.chartConfig.yAxis.max,
interval: mockData.chartConfig.yAxis.interval,
inverse: true,
axisLabel: { formatter: "{value}", fontSize: 12 },
splitLine: { show: false },
axisLine: { show: true },
axisTick: { show: false }
},
{
type: "value",
name: "深度(m)",
min: mockData.chartConfig.yAxis2.min,
max: mockData.chartConfig.yAxis2.max,
interval: mockData.chartConfig.yAxis2.interval,
position: "right",
axisLabel: { formatter: "{value}", fontSize: 12 },
splitLine: { show: false },
axisLine: { show: true },
axisTick: { show: false }
},
],
series: [
{
name: "井深数据",
type: "line",
yAxisIndex: 1,
symbol: "circle",
symbolSize: 8,
itemStyle: { color: "#ff0000" },
lineStyle: { color: "#00ff00" },
label: {
show: true,
position: "top",
formatter: "{c}",
fontSize: 12,
color: "#ff0000",
backgroundColor: "rgba(255,255,255,0.8)",
padding: [2, 4],
borderRadius: 2
},
data: wellData.depthLine.map((point) => point.y),
},
{
name: "占位",
type: "bar",
stack: "total",
silent: true,
barWidth: "13%",
itemStyle: { borderColor: "transparent", color: "transparent" },
emphasis: { itemStyle: { borderColor: "transparent", color: "transparent" } },
data: wellData.depthIntervals.map((item) => item.placeholder),
},
{
name: "深度区间",
type: "bar",
stack: "total",
barWidth: "20%",
label: {
show: true,
position: (params) => params.data <= 200 ? "top" : "inside",
color: "#03df6d",
backgroundColor: "rgba(255,255,255,0.8)",
padding: [2, 4],
borderRadius: 2
},
itemStyle: { color: "#00aafe" },
data: wellData.depthIntervals.map((item) => item.interval),
},
...areaSeries,
],
};
this.myChart.setOption(option);
// 确保图表完全渲染后再resize
this.$nextTick(() => {
this.myChart.resize();
});
},
renderEmpty(chartDom) {
chartDom.innerHTML = '<div style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;color:#999;">暂无数据</div>';
},
debounce(fn, delay) {
let timer = null;
return function () {
if (timer) clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, arguments), delay);
};
},
createSvgImage(svgString) {
return new Promise((resolve, reject) => {
const svgBlob = new Blob([svgString], { type: 'image/svg+xml;charset=utf-8' });
const svgUrl = URL.createObjectURL(svgBlob);
const img = new Image();
img.onload = () => {
URL.revokeObjectURL(svgUrl);
resolve(img);
};
img.onerror = (e) => {
URL.revokeObjectURL(svgUrl);
reject(e);
};
img.src = svgUrl;
});
}
},
};
</script>
<style scoped>
/* 确保容器占满可用空间 */
.chart-container {
width: 100%;
height: 100vh;
padding: 0 20px;
margin: 0;
box-sizing: border-box;
display: flex;
flex-direction: column;
}
/* 图表容器样式 - 占满整个容器 */
.chart {
flex: 1;
width: 100%;
height: 100%;
min-height: 400px;
display: block;
}
</style>
\ No newline at end of file
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