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
};
}