public static converter()

in src/visual.ts [215:458]


    public static converter(
        dataView: DataView,
        colorPalette: IColorPalette,
        interactivityService: IInteractivityService,
        visualHost: IVisualHost
    ): StreamData {

        if (!dataView
            || !dataView.categorical
            || !dataView.categorical.values
            || !dataView.categorical.categories
            || !colorPalette) {
            return null;
        }

        let xMaxValue: number = -Number.MAX_VALUE;
        let xMinValue: number = Number.MAX_VALUE;
        let yMaxValue: number = -Number.MAX_VALUE;
        let yMinValue: number = Number.MAX_VALUE;

        let categorical: DataViewCategorical = dataView.categorical,
            categories: DataViewCategoryColumn[] = categorical.categories,
            values: DataViewValueColumns = categorical.values,
            series: StreamGraphSeries[] = [],
            legendData: LegendData = {
                dataPoints: [],
                title: values.source
                    ? values.source.displayName
                    : LegendSettings.DefaultTitleText,
            },
            value: number = 0,
            valuesFormatter: IValueFormatter,
            categoryFormatter: IValueFormatter;

        const category: DataViewCategoryColumn = categories && categories.length > 0
            ? categories[0]
            : null;

        const colorHelper: ColorHelper = new ColorHelper(colorPalette);

        const hasHighlights: boolean = !!(values.length > 0 && values[0].highlights);

        const settings: VisualSettings = StreamGraph.parseSettings(dataView, colorHelper);

        const fontSizeInPx: string = PixelConverter.fromPoint(settings.labels.fontSize);

        const stackValues: StackValue[] = [];

        for (let valueIndex: number = 0; valueIndex < values.length; valueIndex++) {
            let label: string = values[valueIndex].source.groupName as string,
                identity: ISelectionId = null;

            if (visualHost) {
                const categoryColumn: DataViewCategoryColumn = {
                    source: values[valueIndex].source,
                    values: null,
                    identity: [values[valueIndex].identity]
                };

                identity = visualHost.createSelectionIdBuilder()
                    .withCategory(categoryColumn, 0)
                    .withMeasure(values[valueIndex].source.queryName)
                    .createSelectionId();
            }

            const tooltipInfo: VisualTooltipDataItem[] = createTooltipInfo(
                dataView,
                { categories: null, values: values },
                visualHost.createLocalizationManager(),
                valueIndex
            );

            if (!label) {
                if (tooltipInfo
                    && tooltipInfo[0]
                    && tooltipInfo[0].value) {
                    label = tooltipInfo[0].value;
                } else {
                    label = values[valueIndex].source.displayName;
                }
            }

            const color: string = colorHelper.getHighContrastColor(
                "foreground",
                colorPalette.getColor(valueIndex.toString()).value,
            );

            if (label) {
                legendData.dataPoints.push({
                    color,
                    label,
                    identity,
                    icon: LegendIcon.Box,
                    selected: false
                });
            }

            series[valueIndex] = {
                color,
                identity,
                tooltipInfo,
                dataPoints: [],
                highlight: hasHighlights,
                selected: false
            };

            const dataPointsValues: PrimitiveValue[] = values[valueIndex].values;

            if (dataPointsValues.length === 0) {
                continue;
            }

            for (let dataPointValueIndex: number = 0; dataPointValueIndex < dataPointsValues.length; dataPointValueIndex++) {
                const y: number = hasHighlights
                    ? values[valueIndex].highlights[dataPointValueIndex] as number
                    : dataPointsValues[dataPointValueIndex] as number;

                if (y > value) {
                    value = y;
                }
                let streamDataPoint: StreamDataPoint = {
                    x: dataPointValueIndex,
                    y: StreamGraph.isNumber(y)
                        ? y
                        : StreamGraph.DefaultValue,
                    text: label,
                    labelFontSize: fontSizeInPx,
                    highlight: hasHighlights && values[valueIndex].highlights && values[valueIndex].highlights[dataPointValueIndex] !== null
                };

                series[valueIndex].dataPoints.push(streamDataPoint);

                /* Adding values for d3.stack V5 */

                if (!stackValues[dataPointValueIndex]) {
                    stackValues[dataPointValueIndex] = {
                        x: streamDataPoint.x
                    };
                }
                stackValues[dataPointValueIndex][label] = streamDataPoint.y;

                if (!stackValues[dataPointValueIndex]["highlight"]) {
                    stackValues[dataPointValueIndex]["highlight"] = streamDataPoint.highlight ? 1 : 0;
                }

                if (streamDataPoint.x > xMaxValue) {
                    xMaxValue = streamDataPoint.x;
                }
                if (streamDataPoint.x < xMinValue) {
                    xMinValue = streamDataPoint.x;
                }
                if (streamDataPoint.y > yMaxValue) {
                    yMaxValue = streamDataPoint.y;
                }
                if (streamDataPoint.y < yMinValue) {
                    yMinValue = streamDataPoint.y;
                }
            }
        }
        if (interactivityService) {
            interactivityService.applySelectionStateToData(series);
        }

        valuesFormatter = valueFormatter.create({
            format: StreamGraph.ValuesFormat,
            value: value
        });

        categoryFormatter = valueFormatter.create({
            format: valueFormatter.getFormatStringByColumn(category.source),
            value: category.values
        });
        const metadata: DataViewMetadataColumn = category.source;

        const categoriesText: PrimitiveValue[] = category.values;
        if (categoriesText.length) {
            if (metadata.type.dateTime && categoriesText[0] instanceof Date) {
                xMinValue = (<Date>categoriesText[0]).getTime();
                xMaxValue = (<Date>categoriesText[categoriesText.length - 1]).getTime();
            } else if (metadata.type.numeric) {
                xMinValue = categoriesText[0] as number;
                xMaxValue = categoriesText[categoriesText.length - 1] as number;
            } else {
                xMinValue = 0;
                xMaxValue = categoriesText.length - 1;
            }
        }

        let textProperties: TextProperties = {
            text: xMaxValue.toString(),
            fontFamily: "sans-serif",
            fontSize: PixelConverter.toString(settings.categoryAxis.fontSize)
        };
        let xAxisValueMaxTextSize: number = textMeasurementService.measureSvgTextWidth(textProperties);
        let xAxisValueMaxTextHalfSize: number = xAxisValueMaxTextSize / 2;
        let textPropertiesY: TextProperties = {
            text: yMaxValue.toString(),
            fontFamily: "sans-serif",
            fontSize: PixelConverter.toString(settings.valueAxis.fontSize)
        };
        let yAxisValueMaxTextSize: number = textMeasurementService.measureSvgTextWidth(textPropertiesY);
        let yAxisValueMaxTextHalfSize: number = yAxisValueMaxTextSize / 2;
        let yAxisFontSize: number = +settings.valueAxis.fontSize;
        let yAxisFontHalfSize: number = yAxisFontSize / 2;
        let xAxisFontSize: number = +settings.categoryAxis.fontSize;
        let xAxisFontHalfSize: number = xAxisFontSize / 2;

        /* Generate stack values for d3.stack V5 */
        const allLabels = legendData.dataPoints.map((dataPoint) => dataPoint.label);

        const stack: d3.Stack<any, any, any> = d3.stack()
            .keys(allLabels)
            .offset(d3.stackOffsetNone);

        if (settings.general.wiggle) {
            stack.offset(d3.stackOffsetWiggle);
        }

        /* Adding values for d3.stack V5 */
        let stackedSeries = stack(stackValues);

        return {
            series,
            stackedSeries,
            metadata,
            settings,
            legendData,
            categoriesText,
            categoryFormatter,
            valueFormatter: valuesFormatter,
            yMaxValue,
            yMinValue,
            xMinValue,
            xMaxValue,
            yAxisValueMaxTextSize,
            yAxisValueMaxTextHalfSize,
            xAxisValueMaxTextSize,
            xAxisValueMaxTextHalfSize,
            yAxisFontSize,
            yAxisFontHalfSize,
            xAxisFontSize,
            xAxisFontHalfSize
        };
    }