in src/globemap.ts [243:465]
public static converter(dataView: DataView, colors: IColorPalette, visualHost: IVisualHost): GlobeMapData {
const categorical: GlobeMapColumns<GlobeMapCategoricalColumns> = GlobeMapColumns.getCategoricalColumns(dataView);
if (!categorical
|| !categorical.Location
|| _.isEmpty(categorical.Location.values) && !(categorical.X && categorical.Y)) {
return null;
}
const settings: GlobeMapSettings = GlobeMap.parseSettings(dataView);
const groupedColumns: GlobeMapColumns<DataViewValueColumn>[] = GlobeMapColumns.getGroupedValueColumns(dataView);
const dataPoints: GlobeMapDataPoint[] = [];
let seriesDataPoints: GlobeMapSeriesDataPoint[] = [];
let locations: PrimitiveValue[] = [];
const colorHelper: ColorHelper = new ColorHelper(colors, GlobeMap.DataPointFillProperty);
let locationType: string;
let heights: number[];
let heightsBySeries: number[] | number[][];
let toolTipDataBySeries: {}[];
let heats: number[];
if (categorical.Location
&& categorical.Location.values
&& categorical.Location.source
) {
locations = categorical.Location.values;
const sourceType: IGlobeMapValueTypeDescriptor = <IGlobeMapValueTypeDescriptor>categorical.Location.source.type;
locationType = sourceType.category
? `${sourceType.category}`.toLowerCase()
: "";
} else {
locations = [];
if (categorical.X && categorical.Y && categorical.X.values && categorical.Y.values) {
locations = new Array(categorical.X.values.length);
}
}
if (!_.isEmpty(categorical.Height)) {
if (groupedColumns.length > 1) {
heights = [];
heightsBySeries = [];
toolTipDataBySeries = [];
seriesDataPoints = [];
// creating a matrix for drawing values by series later.
for (let i: number = 0; i < groupedColumns.length; i++) {
const values: number[] = <number[]>groupedColumns[i].Height.values;
let dataPointsParams = {
dataView: dataView,
source: groupedColumns[i].Height.source,
seriesIndex: i,
metaData: null,
colorHelper: colorHelper,
colors: colors,
visualHost: visualHost,
catIndex: null
};
seriesDataPoints[i] = GlobeMap.createDataPointForEnumeration(dataPointsParams);
for (let j: number = 0; j < values.length; j++) {
if (!heights[j]) {
heights[j] = 0;
}
heights[j] += values[j] ? values[j] : 0;
if (!heightsBySeries[j]) {
heightsBySeries[j] = <number[]>[];
}
heightsBySeries[j][i] = values[j];
if (!toolTipDataBySeries[j]) {
toolTipDataBySeries[j] = [];
}
toolTipDataBySeries[j][i] = {
displayName: categorical.Series && categorical.Series.source && categorical.Series.source.displayName,
value: dataView.categorical.values.grouped()[i].name,
dataPointValue: values[j]
};
}
}
for (let i: number = 0; i < groupedColumns.length; i++) {
const values: number[] = <number[]>groupedColumns[i].Height.values;
for (let j: number = 0; j < values.length; j++) {
// calculating relative size of series
heightsBySeries[j][i] = <number>values[j] / <number>heights[j];
}
}
} else {
heights = <number[]>categorical.Height[0].values;
heightsBySeries = [];
heights.forEach((element, index) => {
let displayName: PrimitiveValue;
if (categorical.X && categorical.Y && categorical.X.values && categorical.Y.values) {
displayName = groupedColumns[0].Height.source.displayName + index;
} else if (categorical.Location) {
displayName = categorical.Location.values[index];
}
let dataPointsParams = {
dataView: dataView,
source: { ...groupedColumns[0].Height.source, displayName: displayName },
seriesIndex: 0,
metaData: dataView.metadata,
colorHelper: colorHelper,
colors: colors,
visualHost: visualHost,
catIndex: index
};
seriesDataPoints[index] = GlobeMap.createDataPointForEnumeration(dataPointsParams);
});
}
} else {
heightsBySeries = [];
heights = [];
if (categorical.Location && categorical.Location.values || categorical.X && categorical.Y && categorical.X.values && categorical.Y.values) {
let heightsLenght: number = 0;
if (categorical.Location && categorical.Location.values) {
heightsLenght = categorical.Location.values.length;
} else if (categorical.X && categorical.X.values) {
heightsLenght = categorical.X.values.length;
}
for (let i = 0; i < heightsLenght; i++) {
heights.push(1);
}
const color: string = colorHelper.getColorForMeasure(dataView.metadata.objects, "");
seriesDataPoints[0] = {
label: "label",
identity: "identity",
category: "category",
color: color,
selected: null
};
}
}
if (!_.isEmpty(categorical.Heat)) {
if (groupedColumns.length > 1) {
heats = [];
for (let i: number = 0; i < groupedColumns.length; i++) {
const values: number[] = <number[]>groupedColumns[i].Heat.values;
for (let j = 0; j < values.length; j++) {
if (!heats[j]) {
heats[j] = 0;
}
heats[j] += values[j] ? values[j] : 0;
}
}
} else {
heats = <number[]>categorical.Heat[0].values;
}
} else {
heats = [];
}
const maxHeight: number = Math.max.apply(null, heights) || 1;
const maxHeat: number = Math.max.apply(null, heats) || 1;
const heatFormatter: IValueFormatter = valueFormatter.create({
format: !_.isEmpty(categorical.Heat) && categorical.Heat[0].source.format,
value: heats[0],
value2: heats[1]
});
const heightFormatter = valueFormatter.create({
format: !_.isEmpty(categorical.Height) && categorical.Height[0].source.format,
value: heights[0],
value2: heights[1]
});
const len: number = locations.length;
for (let i: number = 0; i < len; ++i) {
if (typeof (locations[i]) === "string" || (categorical.X && categorical.Y && categorical.X.values && categorical.Y.values)) {
const height: number = <number>heights[i] / maxHeight;
const heat: number = <number>heats[i] / maxHeat;
let place: string;
let placeKey: string;
let toolTipDataLocationName: string;
let toolTipDataLongName: string;
let toolTipDataLatName: string;
let location: ILocation;
let locationValue: string;
if (typeof (locations[i]) === "string") {
place = `${locations[i]}`.toLowerCase();
placeKey = `${place} / ${locationType}`;
location = (!_.isEmpty(categorical.X) && !_.isEmpty(categorical.Y))
? { longitude: <number>categorical.X[0].values[i] || 0, latitude: <number>categorical.Y[0].values[i] || 0 }
: undefined;
toolTipDataLocationName = categorical.Location && categorical.Location.source.displayName;
locationValue = `${locations[i]}`;
} else {
place = `${categorical.X.values[i]} ${categorical.Y.values[i]}`;
placeKey = categorical.X.values[i] + " " + categorical.Y.values[i];
location = (!_.isEmpty(categorical.X) && !_.isEmpty(categorical.Y))
? { longitude: <number>categorical.X.values[i] || 0, latitude: <number>categorical.Y.values[i] || 0 }
: undefined;
toolTipDataLongName = categorical.X && categorical.X.source && categorical.X.source.displayName;
toolTipDataLatName = categorical.Y && categorical.Y.source && categorical.Y.source.displayName;
locationValue = "";
}
const longitudeValue: string = GlobeMap.getCategoricalValueByIndex(categorical.X, i);
const latitudeValue: string = GlobeMap.getCategoricalValueByIndex(categorical.Y, i);
let renderDatum: GlobeMapDataPoint = {
location: location,
placeKey: placeKey,
place: place,
locationType: locationType,
height: height ? height || GlobeMap.datapointShiftPoint : undefined,
heightBySeries: <number[]>heightsBySeries[i],
seriesToolTipData: toolTipDataBySeries ? toolTipDataBySeries[i] : undefined,
heat: heat || 0,
toolTipData: {
location: { displayName: !_.isEmpty(toolTipDataLocationName) && toolTipDataLocationName, value: locationValue },
longitude: { displayName: !_.isEmpty(toolTipDataLongName) && toolTipDataLongName, value: longitudeValue },
latitude: { displayName: !_.isEmpty(toolTipDataLatName) && toolTipDataLatName, value: latitudeValue },
height: { displayName: !_.isEmpty(categorical.Height) && categorical.Height[0].source.displayName, value: heightFormatter.format(heights[i]) },
heat: { displayName: !_.isEmpty(categorical.Heat) && categorical.Heat[0].source.displayName, value: heatFormatter.format(heats[i]) }
}
};
dataPoints.push(renderDatum);
}
}
return {
dataView: dataView,
dataPoints: dataPoints,
seriesDataPoints: seriesDataPoints,
settings: settings
};
}