jfjoch_viewer: protect against NaN in plotting charts
This commit is contained in:
@@ -28,7 +28,8 @@ void JFJochChartView::setImage(int64_t val) {
|
||||
|
||||
if (val < values.size() && val >= 0) {
|
||||
currentSeries->clear();
|
||||
currentSeries->append(curr_image, values[curr_image]);
|
||||
if (std::isfinite(values[curr_image]))
|
||||
currentSeries->append(curr_image, values[curr_image]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,17 +63,24 @@ void JFJochChartView::updateChart() {
|
||||
|
||||
if (binning == 1) {
|
||||
for (int i = 0; i < values.size(); i++)
|
||||
series->append(i, values[i]);
|
||||
if (std::isfinite(values[i]))
|
||||
series->append(i, values[i]);
|
||||
} else {
|
||||
for (int i = 0; i < values.size() / binning; i++) {
|
||||
float tmp = 0;
|
||||
for (int b = 0; b < binning; b++)
|
||||
tmp += values[i * binning + b];
|
||||
series->append((i + 0.5) * binning, tmp / binning);
|
||||
int64_t count = 0;
|
||||
for (int b = 0; b < binning; b++) {
|
||||
if (std::isfinite(values[i * binning + b])) {
|
||||
tmp += values[i * binning + b];
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count > 0)
|
||||
series->append((i + 0.5) * binning, tmp / count);
|
||||
}
|
||||
}
|
||||
|
||||
if (curr_image < values.size() && curr_image >= 0)
|
||||
if (curr_image < values.size() && curr_image >= 0 && std::isfinite(values[curr_image]))
|
||||
currentSeries->append(curr_image, values[curr_image]);
|
||||
|
||||
chart()->addSeries(series);
|
||||
|
||||
@@ -39,22 +39,34 @@ void JFJochSimpleChartView::UpdateData(const std::vector<float> &in_x, const std
|
||||
if (x.empty() || x.size() != y.size()) return;
|
||||
|
||||
auto *series = new QLineSeries(this);
|
||||
for (size_t i = 0; i < x.size(); ++i) series->append(x[i], y[i]);
|
||||
for (size_t i = 0; i < x.size(); ++i) {
|
||||
if (std::isfinite(y[i]))
|
||||
series->append(x[i], y[i]);
|
||||
}
|
||||
chart()->addSeries(series);
|
||||
m_series = series;
|
||||
|
||||
// Compute Y range
|
||||
double ymin = 0.0, ymax = 0.0;
|
||||
{
|
||||
auto [minYIt, maxYIt] = std::minmax_element(y.begin(), y.end());
|
||||
ymin = static_cast<double>(*minYIt);
|
||||
ymax = static_cast<double>(*maxYIt);
|
||||
if (ymin == ymax) {
|
||||
const double eps = (std::abs(ymax) > 0.0) ? std::abs(ymax) * 1e-6 : 1.0;
|
||||
ymin -= eps;
|
||||
ymax += eps;
|
||||
double ymin = std::numeric_limits<double>::max();
|
||||
double ymax = std::numeric_limits<double>::lowest();
|
||||
bool found_finite = false;
|
||||
|
||||
for (float val : y) {
|
||||
if (std::isfinite(val)) {
|
||||
ymin = std::min(ymin, static_cast<double>(val));
|
||||
ymax = std::max(ymax, static_cast<double>(val));
|
||||
found_finite = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_finite) {
|
||||
ymin = 0.0;
|
||||
ymax = 1.0;
|
||||
} else if (ymin == ymax) {
|
||||
const double eps = (std::abs(ymax) > 0.0) ? std::abs(ymax) * 1e-6 : 1.0;
|
||||
ymin -= eps;
|
||||
ymax += eps;
|
||||
}
|
||||
|
||||
// Hidden value axis (left): range + grid
|
||||
auto *axYvalue = new QValueAxis();
|
||||
@@ -206,10 +218,10 @@ void JFJochSimpleChartView::mouseMoveEvent(QMouseEvent *event) {
|
||||
}
|
||||
|
||||
const float xNearest = x[idx];
|
||||
const float yNearest = y[idx];
|
||||
|
||||
// Map that data point to scene coords to get the x position
|
||||
const QPointF ptOnSeries = chart()->mapToPosition(QPointF(xNearest, yNearest), m_series);
|
||||
// Use 0.0 for Y to ensure mapToPosition works even if yNearest is NaN
|
||||
const QPointF ptOnSeries = chart()->mapToPosition(QPointF(xNearest, 0.0), m_series);
|
||||
const QRectF plotArea = chart()->plotArea();
|
||||
|
||||
if (!m_hoverLine) {
|
||||
|
||||
Reference in New Issue
Block a user