private _renderDataShadow()

in src/component/dataZoom/SliderZoomView.ts [349:467]


    private _renderDataShadow() {
        const info = this._dataShadowInfo = this._prepareDataShadowInfo();

        this._displayables.dataShadowSegs = [];

        if (!info) {
            return;
        }

        const size = this._size;
        const oldSize = this._shadowSize || [];
        const seriesModel = info.series;
        const data = seriesModel.getRawData();
        const candlestickDim = seriesModel.getShadowDim && seriesModel.getShadowDim();
        const otherDim: string = candlestickDim && data.getDimensionInfo(candlestickDim)
            ? seriesModel.getShadowDim() // @see candlestick
            : info.otherDim;

        if (otherDim == null) {
            return;
        }

        let polygonPts = this._shadowPolygonPts;
        let polylinePts = this._shadowPolylinePts;
        // Not re-render if data doesn't change.
        if (
            data !== this._shadowData || otherDim !== this._shadowDim
            || size[0] !== oldSize[0] || size[1] !== oldSize[1]
        ) {
            let otherDataExtent = data.getDataExtent(otherDim);
            // Nice extent.
            const otherOffset = (otherDataExtent[1] - otherDataExtent[0]) * 0.3;
            otherDataExtent = [
                otherDataExtent[0] - otherOffset,
                otherDataExtent[1] + otherOffset
            ];
            const otherShadowExtent = [0, size[1]];
            const thisShadowExtent = [0, size[0]];

            const areaPoints = [[size[0], 0], [0, 0]];
            const linePoints: number[][] = [];
            const step = thisShadowExtent[1] / (data.count() - 1);
            let thisCoord = 0;

            // Optimize for large data shadow
            const stride = Math.round(data.count() / size[0]);
            let lastIsEmpty: boolean;
            data.each([otherDim], function (value: ParsedValue, index) {
                if (stride > 0 && (index % stride)) {
                    thisCoord += step;
                    return;
                }

                // FIXME
                // Should consider axis.min/axis.max when drawing dataShadow.

                // FIXME
                // 应该使用统一的空判断?还是在list里进行空判断?
                const isEmpty = value == null || isNaN(value as number) || value === '';
                // See #4235.
                const otherCoord = isEmpty
                    ? 0 : linearMap(value as number, otherDataExtent, otherShadowExtent, true);

                // Attempt to draw data shadow precisely when there are empty value.
                if (isEmpty && !lastIsEmpty && index) {
                    areaPoints.push([areaPoints[areaPoints.length - 1][0], 0]);
                    linePoints.push([linePoints[linePoints.length - 1][0], 0]);
                }
                else if (!isEmpty && lastIsEmpty) {
                    areaPoints.push([thisCoord, 0]);
                    linePoints.push([thisCoord, 0]);
                }

                areaPoints.push([thisCoord, otherCoord]);
                linePoints.push([thisCoord, otherCoord]);

                thisCoord += step;
                lastIsEmpty = isEmpty;
            });

            polygonPts = this._shadowPolygonPts = areaPoints;
            polylinePts = this._shadowPolylinePts = linePoints;

        }
        this._shadowData = data;
        this._shadowDim = otherDim;
        this._shadowSize = [size[0], size[1]];

        const dataZoomModel = this.dataZoomModel;

        function createDataShadowGroup(isSelectedArea?: boolean) {
            const model = dataZoomModel.getModel(isSelectedArea ? 'selectedDataBackground' : 'dataBackground');
            const group = new graphic.Group();
            const polygon = new graphic.Polygon({
                shape: {points: polygonPts},
                segmentIgnoreThreshold: 1,
                style: model.getModel('areaStyle').getAreaStyle(),
                silent: true,
                z2: -20
            });
            const polyline = new graphic.Polyline({
                shape: {points: polylinePts},
                segmentIgnoreThreshold: 1,
                style: model.getModel('lineStyle').getLineStyle(),
                silent: true,
                z2: -19
            });
            group.add(polygon);
            group.add(polyline);
            return group;
        }

        // let dataBackgroundModel = dataZoomModel.getModel('dataBackground');
        for (let i = 0; i < 3; i++) {
            const group = createDataShadowGroup(i === 1);
            this._displayables.sliderGroup.add(group);
            this._displayables.dataShadowSegs.push(group);
        }
    }