in powerbi-visual-builder/src_visual/visual.ts [261:586]
protected getDataset(
dataView: DataView
): {
dataset: CharticulatorContainer.Dataset.Dataset;
rowInfo: Map<
CharticulatorContainer.Dataset.Row,
{ highlight: boolean; index: number; granularity: string }
>;
} {
if (
!dataView ||
!dataView.categorical ||
!dataView.categorical.categories ||
!dataView.categorical.categories[0]
) {
return null;
}
const categorical = dataView.categorical;
const categories = categorical.categories;
const valueColumns = categorical.values;
// Match columns
const columnToValues: {
[name: string]: {
values: CharticulatorContainer.Specification.DataValue[];
highlights: boolean[];
};
} = {};
const defaultTable = this.getDefaultTable(this.template);
let columns = defaultTable.columns.filter(
col => !col.metadata.isRaw
) as PowerBIColumn[];
for (const chartColumn of columns) {
let found = false;
if (valueColumns != null) {
for (const powerBIColumn of valueColumns) {
if (powerBIColumn.source.roles[chartColumn.powerBIName]) {
const [converted, raw] = this.mapColumns(
powerBIColumn,
chartColumn.type,
chartColumn.metadata.format
);
columnToValues[
chartColumn.powerBIName || refineColumnName(chartColumn.name)
] = converted;
if (raw && !chartColumn.metadata.isRaw) {
columnToValues[
`${chartColumn.powerBIName ||
refineColumnName(chartColumn.name)}${rawColumnPostFix}`
] = raw;
}
found = true;
}
}
}
for (const powerBIColumn of categories.reverse()) {
// reverse - to take the latest column (if drill down was enabled)
if (
powerBIColumn.source.roles[
chartColumn.powerBIName || chartColumn.name
] &&
!columnToValues[chartColumn.powerBIName || chartColumn.name]
) {
const [converted, raw] = this.mapColumns(
powerBIColumn,
chartColumn.type,
chartColumn.metadata && chartColumn.metadata.format
);
columnToValues[
chartColumn.powerBIName || refineColumnName(chartColumn.name)
] = converted;
if (raw && !chartColumn.metadata.isRaw) {
columnToValues[
`${chartColumn.powerBIName ||
refineColumnName(chartColumn.name)}${rawColumnPostFix}`
] = raw;
}
found = true;
}
}
if (!found) {
return null;
}
}
const defaultTableRawColumns = defaultTable.columns
// add powerBIName to raw columns
.map((column: PowerBIColumn) => {
if (!column.powerBIName) {
column.powerBIName = refineColumnName(column.name);
}
return column;
})
.filter(col => !col.metadata.isRaw)
.filter(rawColumnFilter(defaultTable.columns))
.map(rawColumnMapper);
columns = defaultTable.columns = defaultTable.columns.concat(
defaultTableRawColumns
) as PowerBIColumn[];
const linksTable = this.getLinksTable(this.template);
const powerBILinkColumns = dataView.categorical.categories;
let chartLinks =
linksTable &&
(linksTable.columns.filter(
col => !col.metadata.isRaw
) as PowerBIColumn[]);
if (chartLinks && powerBILinkColumns) {
for (const chartColumn of chartLinks) {
for (const powerBIColumn of powerBILinkColumns) {
if (powerBIColumn.source.roles[chartColumn.powerBIName]) {
const [converted, raw] = this.mapColumns(
powerBIColumn,
chartColumn.type,
chartColumn.metadata && chartColumn.metadata.format
);
columnToValues[
chartColumn.powerBIName || chartColumn.name
] = converted;
if (raw && !chartColumn.metadata.isRaw) {
columnToValues[
`${chartColumn.powerBIName ||
refineColumnName(chartColumn.name)}${rawColumnPostFix}`
] = raw;
}
}
}
}
const linksTableRawColumns = linksTable.columns
.filter(rawColumnFilter(linksTable.columns))
.map(rawColumnMapper);
chartLinks = linksTable.columns = linksTable.columns.concat(
linksTableRawColumns
) as PowerBIColumn[];
}
const tooltipsTable = this.getTooltipsTable(this.template);
const tooltipsTableColumns = [
...categorical.categories.filter(
cat => cat.source.roles.powerBITooltips
),
...(categorical.values
? categorical.values.filter(cat => cat.source.roles.powerBITooltips)
: [])
];
if (tooltipsTable && tooltipsTableColumns) {
const type =
(tooltipsTable.columns.length && tooltipsTable.columns[0].type) ||
CharticulatorContainer.Specification.DataType.String;
const metadata = (tooltipsTable.columns.length &&
tooltipsTable.columns[0].metadata) || {
kind: "categorical"
};
tooltipsTable.columns = [];
tooltipsTableColumns.forEach(powerBIColumn => {
if (!columnToValues[powerBIColumn.source.displayName]) {
const [converted, raw] = this.mapColumns(powerBIColumn, type);
columnToValues[powerBIColumn.source.displayName] = converted;
if (raw) {
columnToValues[
`${refineColumnName(
powerBIColumn.source.displayName
)}${rawColumnPostFix}`
] = raw;
}
}
tooltipsTable.columns.push({
displayName: powerBIColumn.source.displayName,
name: powerBIColumn.source.displayName,
metadata,
type
});
});
}
const tooltips =
tooltipsTable && (tooltipsTable.columns as PowerBIColumn[]);
const rowInfo = new Map<
CharticulatorContainer.Dataset.Row,
{ highlight: boolean; index: number; granularity: string }
>();
const uniqueRows = new Set<string>();
const rowIdentity = categories.filter(
category => category.source.roles.primarykey
);
const rows = categories[0].values
.map((categoryValue, i) => {
const obj: CharticulatorContainer.Dataset.Row = {
_id: /*"ID" +*/ i.toString()
};
let rowHasHighlightedColumn = false;
let rowHash = rowIdentity.length
? rowIdentity.map(idRow => idRow.values[i]).toString()
: "";
for (const column of columns) {
const valueColumn = columnToValues[column.powerBIName];
if (!valueColumn) {
return null;
}
let value = valueColumn.values[i];
if (value == null) {
if (
columns.find(col => col.name === column.name).metadata.kind ===
"numerical"
) {
value = 0;
} else {
return null;
}
}
obj[column.powerBIName] = value;
rowHash += (value || "null").toString();
// if one value column has highlights
if (valueColumn.highlights[i]) {
rowHasHighlightedColumn = true;
}
}
const catDate = categoryValue as Date;
let granularity = categoryValue.valueOf().toString();
// Try to do some extra formatting for dates
if (catDate && typeof catDate.toDateString === "function") {
granularity = catDate.toDateString();
}
if (!uniqueRows.has(rowHash)) {
uniqueRows.add(rowHash);
rowInfo.set(obj, {
highlight: rowHasHighlightedColumn,
index: i,
granularity
});
return obj;
} else {
return null;
}
})
.filter(x => x != null);
const dataset: CharticulatorContainer.Dataset.Dataset = {
name: "Dataset",
tables: [
{
name: defaultTable.name,
columns: columns.map(column => {
return {
displayName: this.getUserColumnName(
dataView,
column.powerBIName
),
name: column.powerBIName,
type: column.type,
metadata: column.metadata
};
}),
rows
},
chartLinks &&
powerBILinkColumns && {
name: linksTable.name,
columns:
powerBILinkColumns.length >= 2
? chartLinks.map(column => {
return {
displayName: this.getUserColumnName(
dataView,
column.powerBIName
),
name: column.powerBIName,
type: column.type,
metadata: column.metadata
};
})
: null,
rows: categories[0].values
.map((source, index) => {
const obj: CharticulatorContainer.Dataset.Row = {
_id: index.toString()
};
for (const column of chartLinks) {
const valueColumn =
columnToValues[column.powerBIName || column.name];
if (valueColumn) {
const value = valueColumn.values[index];
obj[column.powerBIName || column.name] = value;
}
}
if (obj.source_id && obj.target_id) {
return obj;
} else {
return null;
}
})
.filter(row => row)
},
tooltips &&
tooltipsTableColumns && {
name: powerBITooltipsTablename,
columns: tooltipsTable ? tooltipsTable.columns : null,
rows: categories[0].values
.map((source, index) => {
const obj = {
_id: index.toString()
};
for (const column of tooltips) {
const valueColumn =
columnToValues[column.powerBIName || column.name];
if (valueColumn) {
const value = valueColumn.values[index];
obj[column.powerBIName || column.name] = value;
}
}
return obj;
})
.filter(row => row)
}
].filter(table => table && table.columns)
};
return { dataset, rowInfo };
}