Power BI自定义视觉开发:如何配置矩阵显示字符串值?
Power BI 视觉开发:路线图矩阵的 dataViewMappings 配置方案
核心思路
你遇到的问题是Power BI默认要求矩阵值为数值型度量,但你需要展示文本型的交付物列表。解决方法是用categorical类型的dataViewMappings,将交付物作为分组字段而非度量值,在视觉代码中自行聚合单元格内的文本内容。
1. 配置 capabilities.json
数据角色定义
先在dataRoles里定义三个必需角色,以及可选的格式字段:
"dataRoles": [ { "name": "rowGroup", "displayName": "团队(行)", "kind": "Grouping" }, { "name": "columnGroup", "displayName": "季度(列)", "kind": "Grouping" }, { "name": "deliverables", "displayName": "交付物", "kind": "Grouping" }, { "name": "formattingColumns", "displayName": "格式字段", "kind": "Grouping", "required": false } ]
dataViewMappings 配置
使用categorical类型,将行、列分组映射到categories,交付物作为values的分组项(这样Power BI不会强制要求度量值):
"dataViewMappings": [ { "categorical": { "categories": { "row": { "for": { "in": "rowGroup" } }, "column": { "for": { "in": "columnGroup" } } }, "values": { "group": { "by": "deliverables", "select": [ { "bind": { "to": "formattingColumns" } } ] } } } } ]
这个配置会让Power BI把每个(Team, Date)组合下的所有Deliverable(包括重复项)都传递给视觉对象,由你自行处理展示逻辑。
2. 视觉代码中处理数据渲染
在update方法里,从dataView中提取数据并构建矩阵结构:
public update(options: VisualUpdateOptions) { const dataView = options.dataViews[0]; if (!dataView) return; // 提取行分组(团队)和列分组(季度) const rowGroups = dataView.categorical.categories[0].values; const columnGroups = dataView.categorical.categories[1].values; // 构建单元格数据映射:key为`团队|季度`,值为交付物数组 const cellData: { [key: string]: string[] } = {}; // 遍历所有数据点,收集每个单元格的交付物 dataView.categorical.values.forEach((valueGroup, index) => { const team = rowGroups[dataView.categorical.values[index].values[0].identity[0].value] as string; const quarter = columnGroups[dataView.categorical.values[index].values[0].identity[1].value] as string; const deliverable = valueGroup.source.displayName; // 或从identity中取实际值 const key = `${team}|${quarter}`; if (!cellData[key]) cellData[key] = []; cellData[key].push(deliverable); }); // 以下为渲染逻辑示例(需根据你的DOM结构调整) const table = document.createElement('table'); // 1. 构建表头(季度列) const headerRow = table.insertRow(); headerRow.insertCell().textContent = "Team"; columnGroups.forEach(q => { const cell = headerRow.insertCell(); cell.textContent = q as string; }); // 2. 构建每行(团队行) rowGroups.forEach(team => { const row = table.insertRow(); row.insertCell().textContent = team as string; columnGroups.forEach(q => { const cell = row.insertCell(); const key = `${team}|${q}`; cell.textContent = cellData[key]?.join(', ') || ''; }); }); // 将表格添加到视觉容器 const container = this.element; container.innerHTML = ''; container.appendChild(table); }
关键说明
- 为什么不用measure?因为Power BI的measure只能返回数值,无法直接返回文本列表,所以必须用分组字段的方式获取所有原始数据,再自行聚合。
- 重复交付物的保留:因为直接遍历原始数据点,同一(Team, Date)下的重复交付物会被依次加入数组,渲染时自然保留重复项。
- 格式字段的处理:如果需要用额外列做格式化(比如颜色、样式),可以在遍历数据点时同时提取这些字段的值,和交付物一起存储,渲染时应用对应样式。
内容的提问来源于stack exchange,提问作者Daniel SH
相关产品推荐
相关产品推荐

