transform()

in client/client/modules/render/tracks/wig/wigTransformer.js [147:314]


    transform(data, viewport) {
        const pixelsPerBp = viewport.factor;
        const isDetailed = pixelsPerBp >= this._config.wig.detailedStyleStartingAtPixelsPerBP;

        const allowedStart = viewport.project.pixel2brushBP(-viewport.canvasSize);
        const allowedEnd = viewport.project.pixel2brushBP(2 * viewport.canvasSize);

        const items = {
            aboveBaseAxis: [],
            belowBaseAxis: []
        };
        const thresholdItems = {
            aboveBaseAxis: [],
            belowBaseAxis: []
        };

        const _baseAxis = 0;
        const extremumSupportStructure = [];
        const minExtremumSupportStructure = [];

        const pushItem = function(item) {
            if (item && item.threshold) {
                if (item.value > _baseAxis) {
                    thresholdItems.aboveBaseAxis.push(item);
                } else {
                    thresholdItems.belowBaseAxis.push(item);
                }
            }
            else if (item) {
                if (item.value > _baseAxis) {
                    items.aboveBaseAxis.push(item);
                } else {
                    items.belowBaseAxis.push(item);
                }
            }
        };

        const skipItem = function(item) {
            return item.value === 0 || item.startIndex > allowedEnd || item.endIndex < allowedStart ||
                (viewport.isShortenedIntronsMode && viewport.shortenedIntronsViewport.shouldSkipFeature(item));
        };

        let lastItem = null;

        let prevEndIndexPx = null;

        for (let index = 0; index < data.length; index++) {
            const dataItem = data[index];
            if (skipItem(dataItem)) {
                continue;
            }
            this.transformItem(dataItem);
            dataItem.startIndex = Math.max(allowedStart, dataItem.startIndex);
            dataItem.endIndex = Math.min(allowedEnd, dataItem.endIndex);
            if (dataItem.value === _baseAxis) {
                pushItem(lastItem);
                lastItem = null;
                continue;
            }

            extremumSupportStructure.push({
                value: dataItem.value,
                startIndex: dataItem.startIndex,
                endIndex: dataItem.endIndex
            });
            minExtremumSupportStructure.push({
                value: dataItem.value,
                startIndex: dataItem.startIndex,
                endIndex: dataItem.endIndex
            });

            const dataItemThreshold = this.isThresholdValue(dataItem.value);

            if (lastItem && (lastItem.endIndex + 1 === dataItem.startIndex || lastItem.endIndex === dataItem.startIndex)) {
                if (lastItem.threshold !== dataItemThreshold ||
                    (lastItem.value - _baseAxis) * (dataItem.value - _baseAxis) < 0) {
                    pushItem(lastItem);
                    lastItem = null;
                }
                else {
                    if (!isDetailed && dataItem.startIndex === dataItem.endIndex && prevEndIndexPx !== null && lastItem.points.length > 0) {
                        if (Math.round(viewport.project.brushBP2pixel(dataItem.endIndex + 0.5)) === prevEndIndexPx) {
                            lastItem.endIndex = dataItem.endIndex;
                            const startIndex = lastItem.points[lastItem.points.length - 1].startIndex;
                            const endIndex = dataItem.endIndex;
                            if (!lastItem.points[lastItem.points.length - 1].dataItem.isHighlightedLocus) {
                                lastItem.points[lastItem.points.length - 1].dataItem = dataItem;
                                lastItem.points[lastItem.points.length - 1].dataValue = Math.max(dataItem.value, lastItem.points[lastItem.points.length - 1].dataValue);
                            }
                            lastItem.points[lastItem.points.length - 1].startIndex = startIndex;
                            lastItem.points[lastItem.points.length - 1].endIndex = endIndex;
                            continue;
                        }
                    }
                    prevEndIndexPx = Math.round(viewport.project.brushBP2pixel(dataItem.endIndex + 0.5));
                    lastItem.points.push(
                        {
                            dataItem: dataItem,
                            dataValue: dataItem.value,
                            startIndex: dataItem.startIndex,
                            endIndex: dataItem.endIndex
                        }
                    );
                    lastItem.endIndex = dataItem.endIndex;
                    continue;
                }
            }
            else if (lastItem && lastItem.endIndex + 1 < dataItem.startIndex) {
                pushItem(lastItem);
                lastItem = null;
            }

            prevEndIndexPx = Math.round(viewport.project.brushBP2pixel(dataItem.endIndex + .5));

            lastItem = {
                startIndex: dataItem.startIndex,
                endIndex: dataItem.endIndex,
                points: [],
                threshold: dataItemThreshold,
                value: dataItem.value
            };
            if (isDetailed) {
                for (let i = dataItem.startIndex; i <= dataItem.endIndex; i++) {
                    lastItem.points.push(
                        {
                            dataItem: dataItem,
                            dataValue: dataItem.value,
                            startIndex: i,
                            endIndex: i
                        }
                    );
                }
            }
            else {
                lastItem.points.push(
                    {
                        dataItem: dataItem,
                        dataValue: dataItem.value,
                        startIndex: dataItem.startIndex,
                        endIndex: dataItem.endIndex
                    }
                );
            }
        }
        pushItem(lastItem);
        Sorting.quickSort(extremumSupportStructure, false, x => x.value);
        Sorting.quickSort(minExtremumSupportStructure, true, x => x.value);
        if (this.groupAutoScaleManager) {
            this.groupAutoScaleManager.registerTrackData(
                this.track,
                {
                    extremumSupportStructure,
                    minExtremumSupportStructure,
                }
            );
        }
        return {
            baseAxis: _baseAxis,
            dataItems: data,
            extremumSupportStructure: extremumSupportStructure,
            minExtremumSupportStructure: minExtremumSupportStructure,
            isDetailed: isDetailed,
            items: items,
            pixelsPerBp: pixelsPerBp,
            thresholdItems: thresholdItems,
            viewport: viewport
        };
    }