PCM_Report/preview_dialogs.py

75 lines
2.9 KiB
Python
Raw Permalink Normal View History

2025-12-11 14:32:31 +08:00
from typing import List, Optional
import pandas as pd
from PySide6.QtCore import Qt
from PySide6.QtWidgets import QDialog, QVBoxLayout, QLabel, QTableWidget, QTableWidgetItem, QSizePolicy
try:
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as FigureCanvas
except Exception:
# Fallback for older backends
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas # type: ignore
import matplotlib.pyplot as plt
class TablePreviewDialog(QDialog):
def __init__(self, title: str, df: pd.DataFrame, parent=None) -> None:
super().__init__(parent)
self.setWindowTitle(title or "表格预览")
layout = QVBoxLayout()
layout.addWidget(QLabel(title or "表格预览"))
table = QTableWidget()
if df is not None and not df.empty:
columns: List[str] = [str(c) for c in df.columns]
table.setColumnCount(len(columns))
table.setHorizontalHeaderLabels(columns)
table.setRowCount(len(df))
for r in range(len(df)):
for c, col in enumerate(columns):
val = df.iloc[r][col]
table.setItem(r, c, QTableWidgetItem(str(val)))
else:
table.setColumnCount(0)
table.setRowCount(0)
table.resizeColumnsToContents()
layout.addWidget(table)
self.setLayout(layout)
self.resize(900, 600)
class ChartPreviewDialog(QDialog):
def __init__(self, title: str, df: pd.DataFrame, fields: Optional[List[str]] = None, chart_type: str = "line", parent=None) -> None:
super().__init__(parent)
self.setWindowTitle(title or "图表预览")
layout = QVBoxLayout()
layout.addWidget(QLabel(title or "图表预览"))
fig, ax = plt.subplots(figsize=(8, 4))
canvas = FigureCanvas(fig)
canvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
layout.addWidget(canvas)
# Attempt to plot time series by field
if df is not None and not df.empty and "_time" in df.columns and "_value" in df.columns:
plot_fields: List[str] = fields or sorted([str(f) for f in df.get("_field", pd.Series(dtype=str)).unique() if pd.notna(f)])
if not plot_fields:
plot_fields = ["_value"]
for field in plot_fields:
if "_field" in df.columns:
sdf = df[df["_field"] == field]
else:
sdf = df
if not sdf.empty:
ax.plot(pd.to_datetime(sdf["_time"]), pd.to_numeric(sdf["_value"], errors="coerce"), label=str(field))
ax.set_xlabel("Time")
ax.set_ylabel("Value")
ax.grid(True, alpha=0.3)
ax.legend(loc="best")
else:
ax.text(0.5, 0.5, "无可绘制的数据", ha="center", va="center", transform=ax.transAxes)
canvas.draw()
self.setLayout(layout)
self.resize(900, 600)