class TimelineChartImpl implements TimelineChart {

    private final String column;
    private final Number[] x;
    private final Number[] y;
    private final Number minY;
    private final Number maxY;
    private final Number minX;
    private final Number maxX;

    public TimelineChartImpl(String column, Number[] x, Number[] y) {
        this.column = column;
        this.x = x;
        this.y = y;
        this.minY = calculateMin(y);
        this.maxY = calculateMax(y);
        this.minX = calculateMin(x);
        this.maxX = calculateMax(x);
    }

    public static TimelineChartImpl of(Graph graph, String column) {
        if (graph != null && column != null) {
            Object dynamicValue = graph.getAttribute(column);
            if (dynamicValue instanceof IntervalMap) {
                return TimelineChartImpl.of(column, (IntervalMap) dynamicValue);
            } else if (dynamicValue instanceof TimestampMap) {
                return TimelineChartImpl.of(column, (TimestampMap) dynamicValue);
            }
        }

        return null;
    }

    public static TimelineChartImpl of(String column, IntervalMap dynamicValue) {
        double[] lowsAndHighs = dynamicValue.getIntervals();
        Object[] values = dynamicValue.toValuesArray();

        final Number[] xs = new Number[lowsAndHighs.length];
        final Number[] ys = new Number[lowsAndHighs.length];

        for (int i = 0; i < lowsAndHighs.length; i += 2) {
            xs[i] = lowsAndHighs[i];
            xs[i + 1] = lowsAndHighs[i + 1];

            Number numValue = (Number) values[i];
            if (numValue == null) {
                numValue = 0.0;
            }

            ys[i] = numValue;
            ys[i + 1] = numValue;
        }

        if (xs.length > 0) {
            return new TimelineChartImpl(column, xs, ys);
        } else {
            return null;
        }
    }

    public static TimelineChartImpl of(String column, TimestampMap dynamicValue) {
        double[] timestamps = dynamicValue.getTimestamps();
        Object[] values = dynamicValue.toValuesArray();

        final Number[] xs = new Number[timestamps.length];
        final Number[] ys = new Number[timestamps.length];

        for (int i = 0; i < timestamps.length; i++) {
            xs[i] = timestamps[i];
            Number numValue = (Number) values[i];
            if (numValue == null) {
                numValue = 0.0;
            }

            ys[i] = numValue;
        }

        if (xs.length > 0) {
            return new TimelineChartImpl(column, xs, ys);
        } else {
            return null;
        }
    }

    @Override
    public Number[] getX() {
        return x;
    }

    @Override
    public Number[] getY() {
        return y;
    }

    @Override
    public Number getY(Number posX) {<FILL_FUNCTION_BODY>}

    @Override
    public Number getMinY() {
        return minY;
    }

    @Override
    public Number getMaxY() {
        return maxY;
    }

    @Override
    public Number getMinX() {
        return minX;
    }

    @Override
    public Number getMaxX() {
        return maxX;
    }

    @Override
    public String getColumn() {
        return column;
    }

    private Number calculateMin(Number[] yValues) {
        double min = yValues[0].doubleValue();
        for (Number d : yValues) {
            min = Math.min(min, d.doubleValue());
        }
        Number t = yValues[0];
        if (t instanceof Double) {
            return min;
        } else if (t instanceof Float) {
            return new Float(min);
        } else if (t instanceof Short) {
            return (short) min;
        } else if (t instanceof Long) {
            return (long) min;
        } else if (t instanceof BigInteger) {
            return new BigDecimal(min);
        }
        return min;
    }

    private Number calculateMax(Number[] yValues) {
        double max = yValues[0].doubleValue();
        for (Number d : yValues) {
            max = Math.max(max, d.doubleValue());
        }
        Number t = yValues[0];
        if (t instanceof Double) {
            return max;
        } else if (t instanceof Float) {
            return new Float(max);
        } else if (t instanceof Short) {
            return (short) max;
        } else if (t instanceof Long) {
            return (long) max;
        } else if (t instanceof BigInteger) {
            return new BigDecimal(max);
        }
        return max;
    }
}

        double pos = posX.doubleValue();
        Double value = null;
        if (pos <= maxX.doubleValue()) {
            for (int i = 0; i < x.length; i++) {
                if (pos < x[i].doubleValue()) {
                    return value;
                }
                value = y[i].doubleValue();
            }
        }

        return value;
    
<no_super_class>