function setMinMaxSpan(axisProxy) {
    var minMaxSpan = axisProxy._minMaxSpan = {};
    var dataZoomModel = axisProxy._dataZoomModel;
    var dataExtent = axisProxy._dataExtent;

    each$13(['min', 'max'], function (minMax) {
        var percentSpan = dataZoomModel.get(minMax + 'Span');
        var valueSpan = dataZoomModel.get(minMax + 'ValueSpan');
        valueSpan != null && (valueSpan = axisProxy.getAxisModel().axis.scale.parse(valueSpan));

        // minValueSpan and maxValueSpan has higher priority than minSpan and maxSpan
        if (valueSpan != null) {
            percentSpan = linearMap(
                dataExtent[0] + valueSpan, dataExtent, [0, 100], true
            );
        }
        else if (percentSpan != null) {
            valueSpan = linearMap(
                percentSpan, [0, 100], dataExtent, true
            ) - dataExtent[0];
        }

        minMaxSpan[minMax + 'Span'] = percentSpan;
        minMaxSpan[minMax + 'ValueSpan'] = valueSpan;
    });
}
Suppose a "main process" start at the point that model prepared (that is,
model initialized or merged or method called in `action`).
We should keep the `main process` idempotent, that is, given a set of values
on `option`, we get the same result.

But sometimes, values on `option` will be updated for providing users
a "final calculated value" (`dataZoomProcessor` will do that). Those value
should not be the base/input of the `main process`.

So in that case we should save and keep the input of the `main process`
separately, called `settledOption`.

For example, consider the case:
(Step_1) brush zoom the grid by `toolbox.dataZoom`,
    where the original input `option.startValue`, `option.endValue` are earsed by
    calculated value.
(Step)2) click the legend to hide and show a series,
    where the new range is calculated by the earsed `startValue` and `endValue`,
    which brings incorrect result.

@readOnly