epezent / implot

Immediate Mode Plotting
MIT License
4.55k stars 503 forks source link

`SetupAxisLimitsConstraints()` doesn't apply constraint for autofit #515

Open smilediver opened 10 months ago

smilediver commented 10 months ago

If you're trying to fit the plot values in say [0, 100] range, and have something like:

ImPlot::SetupAxes(nullptr, nullptr, ImPlotAxisFlags_None, ImPlotAxisFlags_AutoFit | ImPlotAxisFlags_RangeFit);
ImPlot::SetupAxisLimitsConstraints(ImAxis_Y1, 0, 100);

then all the data outside [0, 100] limit is ignored during the fitting. For example, if all the data is in [0, 2] range, but one data value is 200, then this 200 value is ignored and the plot is fitted in the [0, 2] range and not in [0, 100] as it's supposed to.

I think the problem is in ExtendFitWith() function (possibly ExtendFit() has the same problem), as it should be something like this:

    inline void ExtendFitWith(ImPlotAxis& alt, double v, double v_alt) {
        if (ImHasFlag(Flags, ImPlotAxisFlags_RangeFit) && !alt.Range.Contains(v_alt))
            return;

        // Current check
        // if (!ImNanOrInf(v) && v >= ConstraintRange.Min && v <= ConstraintRange.Max) {
        //    FitExtents.Min = v < FitExtents.Min ? v : FitExtents.Min;
        //    FitExtents.Max = v > FitExtents.Max ? v : FitExtents.Max;
        // }

        if (!ImNanOrInf(v)) {
            if (v < ConstraintRange.Min) {
                FitExtents.Min = ConstraintRange.Min;
            } else if (v > ConstraintRange.Max) {
                FitExtents.Max = ConstraintRange.Max;
            } else {
                FitExtents.Min = v < FitExtents.Min ? v : FitExtents.Min;
                FitExtents.Max = v > FitExtents.Max ? v : FitExtents.Max;
            }
        }
    }