in src/converterStrategy/baseConverterStrategy.ts [84:304]
public getLegend(colorPalette: IColorPalette, defaultLabelLegendColor?: string, defaultColor?: string, colorGradient?: boolean, colorGradientEndColor?: string): LegendSeriesInfo {
const legend: MekkoLegendDataPoint[] = [];
const seriesSources: DataViewMetadataColumn[] = [];
const seriesObjects: DataViewObjects[][] = [];
let grouped: boolean = false;
let legendTitle: string = undefined;
const colorHelper: ColorHelper = new ColorHelper(
colorPalette,
MekkoChart.Properties["dataPoint"]["fill"],
defaultLabelLegendColor
);
const categoryFieldIndex: number = 0;
let categoryMaxValues: ICategotyValuesStatsCollection = {};
this.dataView.categories[categoryFieldIndex].values.forEach((category, index) => {
categoryMaxValues[index] = {
category: category,
maxValueOfCategory: max(this.dataView.values.map(v => <number>v.values[index])),
maxItemOfCategory: sum(this.dataView.values.map(v => <number>v.values[index] !== undefined ? 1 : 0)),
minValueOfCategory: min(this.dataView.values.map(v => <number>v.values[index]))
};
});
// find base color identity
// todo handle color change of
let valueGroups: DataViewValueColumnGroup[] = this.dataView.values.grouped();
let categoryGradientBaseColorIdentities: BaseColorIdentity[] = [];
let categoryGradientEndBaseColorIdentities: BaseColorIdentity[] = [];
let categoryItemsCount: Array<IFilteredValueGroups[]> = [];
let restoredColors: any;
this.dataView.categories[categoryFieldIndex].values.forEach((category: PrimitiveValue, index: number) => {
const categorySelectionId: ISelectionId = this.visualHost.createSelectionIdBuilder()
.withCategory(this.dataView.categories[categoryFieldIndex], index)
.createSelectionId();
// gradiend start color
let mappedItems: IFilteredValueGroups[] = [];
valueGroups.forEach(group => {
if (group.values[0].values[index] !== null) {
mappedItems.push(<IFilteredValueGroups>{
gr: group,
categoryValue: group.values[0].values[index],
categoryIndex: index,
category: category || "",
identity: group.identity
});
}
});
categoryItemsCount[index] = mappedItems;
if (colorGradient) {
categoryItemsCount[index] = categoryItemsCount[index].sort((a, b) => {
return a[BaseConverterStrategy.SortField] > b[BaseConverterStrategy.SortField] ? 1 : -1;
});
}
let baseStartColorIdentity: IFilteredValueGroups = mappedItems.sort((a, b) => a[BaseConverterStrategy.SortField] > b[BaseConverterStrategy.SortField] ? 1 : -1)[0];
if (baseStartColorIdentity === undefined) {
return;
}
let colorStart: string = defaultLabelLegendColor;
if (baseStartColorIdentity.gr.objects !== undefined && (<Fill>(<any>baseStartColorIdentity.gr.objects).dataPoint.fill).solid !== undefined) {
colorStart = (<Fill>(<any>baseStartColorIdentity.gr.objects).dataPoint.fill).solid.color;
}
if (colorStart === undefined) {
colorStart = colorHelper.getColorForSeriesValue(baseStartColorIdentity.gr.objects, baseStartColorIdentity.categoryValue);
}
// gradiend end color
let baseEndColorIdentity: IFilteredValueGroups = mappedItems.sort((a, b) => a[BaseConverterStrategy.SortField] < b[BaseConverterStrategy.SortField] ? 1 : -1)[0];
if (baseEndColorIdentity === undefined) {
return;
}
let colorEnd: string = defaultLabelLegendColor;
if (baseEndColorIdentity.gr.objects !== undefined && (<Fill>(<any>baseEndColorIdentity.gr.objects).dataPoint.fill).solid !== undefined) {
colorEnd = (<Fill>(<any>baseEndColorIdentity.gr.objects).dataPoint.fill).solid.color;
}
if (colorEnd === undefined) {
colorEnd = colorHelper.getColorForSeriesValue(baseEndColorIdentity.gr.objects, baseEndColorIdentity.categoryValue);
}
let categoryStartColor: string = ((
this.dataView.categories[categoryFieldIndex].objects &&
this.dataView.categories[categoryFieldIndex].objects[index] &&
this.dataView.categories[categoryFieldIndex].objects[index]["categoryColorStart"] ||
<MekkoGradientSettings>{
categoryGradient: {
solid: {
color: colorStart
}
}
}) as MekkoGradientSettings).categoryGradient.solid.color;
let categoryEndColor: string = ((
this.dataView.categories[categoryFieldIndex].objects &&
this.dataView.categories[categoryFieldIndex].objects[index] &&
this.dataView.categories[categoryFieldIndex].objects[index]["categoryColorEnd"] ||
<MekkoGradientSettings>{
categoryGradient: {
solid: {
color: colorEnd
}
}
}) as MekkoGradientSettings).categoryGradient.solid.color;
categoryGradientBaseColorIdentities[index] = {
category: (baseStartColorIdentity.category || "").toString(),
color: colorStart,
identity: baseStartColorIdentity.gr.identity,
group: baseStartColorIdentity.gr,
categorySelectionId: categorySelectionId,
categoryStartColor: categoryStartColor,
categoryEndColor: categoryEndColor
};
});
if (this.dataView && this.dataView.values) {
const allValues: DataViewValueColumns = this.dataView.values;
const valueGroups: DataViewValueColumnGroup[] = allValues.grouped();
const hasDynamicSeries: boolean = !!(allValues && allValues.source);
for (let valueGroupsIndex: number = 0; valueGroupsIndex < valueGroups.length; valueGroupsIndex++) {
const valueGroup: DataViewValueColumnGroup = valueGroups[valueGroupsIndex];
const valueGroupObjects: DataViewObjects = valueGroup.objects;
const values: DataViewValueColumn[] = valueGroup.values;
for (let valueIndex: number = 0; valueIndex < values.length; valueIndex++) {
const series: DataViewValueColumn = values[valueIndex];
const source: DataViewMetadataColumn = series.source;
// Gradient measures do not create series.
if (BaseConverterStrategy.hasRole(source, BaseConverterStrategy.WidthColumnName)
&& !BaseConverterStrategy.hasRole(source, BaseConverterStrategy.YColumnName)) {
continue;
}
seriesSources.push(source);
seriesObjects.push(series.objects);
const categoryColumn: DataViewCategoryColumn = {
source: series.source,
identity: [series.identity],
values: undefined
};
const selectionId: ISelectionId = this.visualHost.createSelectionIdBuilder()
.withCategory(categoryColumn, 0)
.withMeasure(this.getMeasureNameByIndex(valueIndex))
.createSelectionId();
const label: string = getFormattedLegendLabel(source, allValues);
let category: string;
let color: string;
let categoryIndex: number = series.values.findIndex(value => typeof value !== undefined && value !== null);
if (!colorGradient) {
color = hasDynamicSeries ? colorHelper.getColorForSeriesValue(valueGroupObjects || source.objects, source.groupName)
: colorHelper.getColorForMeasure(valueGroupObjects || source.objects, source.queryName);
}
else {
let positionIndex: number = (<IFilteredValueGroups[]>categoryItemsCount[categoryIndex]).findIndex(ser => isEqual(ser.identity, series.identity));
category = (categoryMaxValues[categoryIndex].category || "").toString();
let gradientBaseColorStart: string = categoryGradientBaseColorIdentities[categoryIndex].categoryStartColor;
let gradientBaseColorEnd: string = categoryGradientBaseColorIdentities[categoryIndex].categoryEndColor;
color = createLinearColorScale(
[0, categoryItemsCount[categoryIndex].length],
[gradientBaseColorEnd, gradientBaseColorStart], true)
(positionIndex);
}
legend.push({
color,
label,
markerShape: LegendIcon.circle,
identity: selectionId,
selected: false,
valueSum: sum(<number[]>series.values),
categoryValues: series.values,
category: category,
categoryStartColor: categoryGradientBaseColorIdentities[categoryIndex].categoryStartColor,
categoryEndColor: categoryGradientBaseColorIdentities[categoryIndex].categoryEndColor,
categoryIdentity: categoryGradientBaseColorIdentities[categoryIndex].categorySelectionId,
categorySort: this.dataView.categories[categoryFieldIndex].values[categoryIndex]
});
if (series.identity && source.groupName !== undefined) {
grouped = true;
}
}
}
legendTitle = allValues && allValues.source
? allValues.source.displayName
: "";
}
const legendData: ILegendData = {
title: legendTitle,
dataPoints: legend,
grouped: grouped,
};
return {
seriesSources,
seriesObjects,
legend: legendData
};
}