function getLineRenderer(xyIndex) {
    return {
        createCover: function (controller, brushOption) {
            return createBaseRectCover(
                curry$5(
                    driftRect,
                    function (range) {
                        var rectRange = [range, [0, 100]];
                        xyIndex && rectRange.reverse();
                        return rectRange;
                    },
                    function (rectRange) {
                        return rectRange[xyIndex];
                    }
                ),
                controller,
                brushOption,
                [['w', 'e'], ['n', 's']][xyIndex]
            );
        },
        getCreatingRange: function (localTrack) {
            var ends = getTrackEnds(localTrack);
            var min = mathMin$5(ends[0][xyIndex], ends[1][xyIndex]);
            var max = mathMax$5(ends[0][xyIndex], ends[1][xyIndex]);

            return [min, max];
        },
        updateCoverShape: function (controller, cover, localRange, brushOption) {
            var otherExtent;
            // If brushWidth not specified, fit the panel.
            var panel = getPanelByCover(controller, cover);
            if (panel !== true && panel.getLinearBrushOtherExtent) {
                otherExtent = panel.getLinearBrushOtherExtent(
                    xyIndex, controller._transform
                );
            }
            else {
                var zr = controller._zr;
                otherExtent = [0, [zr.getWidth(), zr.getHeight()][1 - xyIndex]];
            }
            var rectRange = [localRange, otherExtent];
            xyIndex && rectRange.reverse();

            updateBaseRect(controller, cover, rectRange, brushOption);
        },
        updateCommon: updateCommon,
        contain: mainShapeContain
    };
}
[option in constructor]:
{
    Index/Id/Name of geo, xAxis, yAxis, grid: See util/model#parseFinder.
}


[targetInfo]:

There can be multiple axes in a single targetInfo. Consider the case
of `grid` component, a targetInfo represents a grid which contains one or more
cartesian and one or more axes. And consider the case of parallel system,
which has multiple axes in a coordinate system.
Can be {
    panelId: ...,
    coordSys: <a representitive cartesian in grid (first cartesian by default)>,
    coordSyses: all cartesians.
    gridModel: <grid component>
    xAxes: correspond to coordSyses on index
    yAxes: correspond to coordSyses on index
}
or {
    panelId: ...,
    coordSys: <geo coord sys>
    coordSyses: [<geo coord sys>]
    geoModel: <geo component>
}


[panelOpt]:

Make from targetInfo. Input to BrushController.
{
    panelId: ...,
    rect: ...
}


[area]:

Generated by BrushController or user input.
{
    panelId: Used to locate coordInfo directly. If user inpput, no panelId.
    brushType: determine how to convert to/from coord('rect' or 'polygon' or 'lineX/Y').
    Index/Id/Name of geo, xAxis, yAxis, grid: See util/model#parseFinder.
    range: pixel range.
    coordRange: representitive coord range (the first one of coordRanges).
    coordRanges: <Array> coord ranges, used in multiple cartesian in one grid.
}