<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Custom visual with hierarchy table in Developer</title>
    <link>https://community.fabric.microsoft.com/t5/Developer/Custom-visual-with-hierarchy-table/m-p/2146463#M32495</link>
    <description>&lt;P&gt;Hello,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I would like to create hierarchical column like this one below:&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="filipwydra_0-1634753735785.png" style="width: 400px;"&gt;&lt;img src="https://community.fabric.microsoft.com/t5/image/serverpage/image-id/616593i72186D0107980281/image-size/medium?v=v2&amp;amp;px=400" role="button" title="filipwydra_0-1634753735785.png" alt="filipwydra_0-1634753735785.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I already created hierarchy in dataset:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;  private static hierarchyDataset(
    dataView: DataView,
    taskTypes: TaskTypes,
    settings: GanttSettings,
    host: IVisualHost
  &lt;span class="lia-unicode-emoji" title=":disappointed_face:"&gt;😞&lt;/span&gt; Task[] | any[] {
    let tasks: Task[] = [];
    const values: GanttColumns&amp;lt;any&amp;gt; =
      GanttColumns.getCategoricalValues(dataView);

    if (!values.yAxis) {
      return tasks;
    }

    const groupValues: GanttColumns&amp;lt;DataViewValueColumn&amp;gt;[] =
      GanttColumns.getGroupedValueColumns(dataView);

    let endDate: ISegment = { date: null, name: "" };

    for (let j = 0; j &amp;lt; values.yAxis.length; j++) {
      for (let index = 0; index &amp;lt; values.yAxis[0].length; index++) {
        let seriesName: TaskTypeMetadata = null;
        let wasDowngradeDurationUnit: boolean = false;
        let stepDurationTransformation: number = 0;
        let segment: ISegment[] = [];
        const selectionBuilder: ISelectionIdBuilder = host
          .createSelectionIdBuilder()
          .withCategory(dataView.categorical.categories[0], index);

        if (groupValues) {
          groupValues.forEach((group: GanttColumns&amp;lt;any&amp;gt;) =&amp;gt; {
            if (group.endDate &amp;amp;&amp;amp; group.endDate.values[index] !== null) {
              seriesName = find(
                taskTypes.types,
                (typeMeta: TaskTypeMetadata) =&amp;gt;
                  typeMeta.name === group.endDate.source.groupName
              );

              if (seriesName) {
                selectionBuilder.withCategory(seriesName.selectionColumn, 0);
              }
              endDate = {
                date: group.endDate.values[index]
                  ? moment(group.endDate.values[index] as Date)
                  : null,
                name: group.endDate.source.displayName,
                showOnTooltip: !!group.endDate.values[index],
                role: `endDate`,
              };

              if (typeof endDate === "string" || typeof endDate === "number") {
                endDate = endDate;
              }
            }

            group.segment.map((d, i) =&amp;gt; {
              if (d &amp;amp;&amp;amp; d.values[index] !== null) {
                seriesName = find(
                  taskTypes.types,
                  (typeMeta: TaskTypeMetadata) =&amp;gt;
                    typeMeta.name === d.source.groupName
                );

                if (seriesName) {
                  selectionBuilder.withCategory(seriesName.selectionColumn, 0);
                }
                segment[i] = {
                  date:
                    d.values[index] &amp;amp;&amp;amp; Date.parse(d.values[index])
                      ? moment(d.values[index] as Date)
                      : null,
                  name: d.source.displayName || null,
                  showOnTooltip: !!d.values[index],
                  role: `segment${i}`,
                };
              }
            });
          });
        }

        const selectionId: powerbi.extensibility.ISelectionId =
          selectionBuilder.createSelectionId();

        const categoryValues: string[] = [];

        values.yAxis.map((d, i) =&amp;gt; {
          categoryValues.push(d[index]);
        });

        let startDate: ISegment = { date: null, name: "" };
        startDate = {
          date: values.startDate &amp;amp;&amp;amp; moment(values.startDate[index]),
          name: dataView.categorical.categories.filter(
            (d) =&amp;gt; d.source.roles.startDate
          )[0].source.displayName,
          showOnTooltip: !!values.startDate[index],
          role: `startDate`,
        };

        const milestoneDate: Date =
          ((values.milestoneDate &amp;amp;&amp;amp;
            !isEmpty(values.milestoneDate[index]) &amp;amp;&amp;amp;
            values.milestoneDate[index]) as Date) || null;

        const task: Task = {
          index: index,
          yAxis: categoryValues,
          name: categoryValues[j],
          parentName: j === 0 ? null : categoryValues[j - 1],
          parentID: j === 0 ? null : j - 1,
          children: [],
          startDate: startDate,
          endDate: endDate,
          segments: Object.assign([], [startDate, ...segment, endDate]),
          visibility: true,
          seriesName: seriesName &amp;amp;&amp;amp; seriesName.name,
          selected: false,
          identity: selectionId,
          wasDowngradeDurationUnit,
          stepDurationTransformation,
          milestoneDate: milestoneDate &amp;amp;&amp;amp; moment(milestoneDate),
        };

        tasks.forEach((task) =&amp;gt; {
          if (task.endDate &amp;amp;&amp;amp; task.startDate) {
            task.endDate = task.endDate;
          } else {
            task.endDate = task.startDate;
          }
        });

        tasks.push(task);
      }
    }

    return tasks;
  }

//---------
  private prepareHierarchyData(tasks) {
    _(tasks).forEach((f) =&amp;gt; {
      f.children = _(tasks)
        .filter((g) =&amp;gt; g.parentName === f.name)
        .value();
    });

    const resultArray = _(tasks)
      .filter((f) =&amp;gt; f.parentName === null)
      .value();

    return _.unionBy(resultArray, (d) =&amp;gt; d.name);
  }&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;My capabilities.json looks like that:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;    "dataRoles": [
        {
            "displayName": "yAxis",
            "name": "yAxis",
            "kind": "Grouping"
        },
        {
            "displayName": "Legend",
            "name": "projectStatus",
            "kind": "Grouping"
        },
        {
            "displayName": "Milestone",
            "name": "milestoneDate",
            "kind": "Grouping"
        },
        {
            "displayName": "Start Date",
            "name": "startDate",
            "kind": "Grouping"
        },
        {
            "displayName": "End Date",
            "name": "endDate",
            "kind": "Measure"
        },
        {
            "displayName": "Phases",
            "name": "segment",
            "kind": "Measure"
        }
    ],
    "dataViewMappings": [
        {
            "conditions": [
                {
                    "yAxis": {
                        "max": 5
                    },
                    "projectStatus": {
                        "max": 1
                    },
                    "milestoneDate": {
                        "max": 1
                    },
                    "startDate": {
                        "max": 1
                    },
                    "endDate": {
                        "max": 1
                    },
                    "segment": {
                        "max": 10
                    }
                }
            ],
            "categorical": {
                "categories": {
                    "select": [
                        {
                            "for": {
                                "in": "yAxis"
                            }
                        },
                        {
                            "for": {
                                "in": "milestoneDate"
                            }
                        },
                        {
                            "for": {
                                "in": "startDate"
                            }
                        }
                    ]
                },
                "values": {
                    "group": {
                        "by": "projectStatus",
                        "select": [
                            {
                                "for": {
                                    "in": "endDate"
                                }
                            },
                            {
                                "for": {
                                    "in": "segment"
                                }
                            }
                        ]
                    }
                }
            }
        }
    ],&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I don't know how to move on. I was trying to create sth like these here&amp;nbsp;&lt;A href="https://observablehq.com/@d3/icicle?ui=classic" target="_blank"&gt;https://observablehq.com/@d3/icicle?ui=classic&lt;/A&gt;&amp;nbsp;but I don't have&lt;FONT color="#808080"&gt;&lt;EM&gt; values&lt;/EM&gt;&lt;/FONT&gt; so it doesn't work for me since I have dates only. Also I was reading about treemap but I don't know how to use it in that case.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Do you have any examples or solutions how to draw hierarchical table ? It doesn't has to be with plus/minus button.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I will be gratefull for any answear.&lt;/P&gt;</description>
    <pubDate>Wed, 20 Oct 2021 18:34:36 GMT</pubDate>
    <dc:creator>filipwydra</dc:creator>
    <dc:date>2021-10-20T18:34:36Z</dc:date>
    <item>
      <title>Custom visual with hierarchy table</title>
      <link>https://community.fabric.microsoft.com/t5/Developer/Custom-visual-with-hierarchy-table/m-p/2146463#M32495</link>
      <description>&lt;P&gt;Hello,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I would like to create hierarchical column like this one below:&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="filipwydra_0-1634753735785.png" style="width: 400px;"&gt;&lt;img src="https://community.fabric.microsoft.com/t5/image/serverpage/image-id/616593i72186D0107980281/image-size/medium?v=v2&amp;amp;px=400" role="button" title="filipwydra_0-1634753735785.png" alt="filipwydra_0-1634753735785.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I already created hierarchy in dataset:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;  private static hierarchyDataset(
    dataView: DataView,
    taskTypes: TaskTypes,
    settings: GanttSettings,
    host: IVisualHost
  &lt;span class="lia-unicode-emoji" title=":disappointed_face:"&gt;😞&lt;/span&gt; Task[] | any[] {
    let tasks: Task[] = [];
    const values: GanttColumns&amp;lt;any&amp;gt; =
      GanttColumns.getCategoricalValues(dataView);

    if (!values.yAxis) {
      return tasks;
    }

    const groupValues: GanttColumns&amp;lt;DataViewValueColumn&amp;gt;[] =
      GanttColumns.getGroupedValueColumns(dataView);

    let endDate: ISegment = { date: null, name: "" };

    for (let j = 0; j &amp;lt; values.yAxis.length; j++) {
      for (let index = 0; index &amp;lt; values.yAxis[0].length; index++) {
        let seriesName: TaskTypeMetadata = null;
        let wasDowngradeDurationUnit: boolean = false;
        let stepDurationTransformation: number = 0;
        let segment: ISegment[] = [];
        const selectionBuilder: ISelectionIdBuilder = host
          .createSelectionIdBuilder()
          .withCategory(dataView.categorical.categories[0], index);

        if (groupValues) {
          groupValues.forEach((group: GanttColumns&amp;lt;any&amp;gt;) =&amp;gt; {
            if (group.endDate &amp;amp;&amp;amp; group.endDate.values[index] !== null) {
              seriesName = find(
                taskTypes.types,
                (typeMeta: TaskTypeMetadata) =&amp;gt;
                  typeMeta.name === group.endDate.source.groupName
              );

              if (seriesName) {
                selectionBuilder.withCategory(seriesName.selectionColumn, 0);
              }
              endDate = {
                date: group.endDate.values[index]
                  ? moment(group.endDate.values[index] as Date)
                  : null,
                name: group.endDate.source.displayName,
                showOnTooltip: !!group.endDate.values[index],
                role: `endDate`,
              };

              if (typeof endDate === "string" || typeof endDate === "number") {
                endDate = endDate;
              }
            }

            group.segment.map((d, i) =&amp;gt; {
              if (d &amp;amp;&amp;amp; d.values[index] !== null) {
                seriesName = find(
                  taskTypes.types,
                  (typeMeta: TaskTypeMetadata) =&amp;gt;
                    typeMeta.name === d.source.groupName
                );

                if (seriesName) {
                  selectionBuilder.withCategory(seriesName.selectionColumn, 0);
                }
                segment[i] = {
                  date:
                    d.values[index] &amp;amp;&amp;amp; Date.parse(d.values[index])
                      ? moment(d.values[index] as Date)
                      : null,
                  name: d.source.displayName || null,
                  showOnTooltip: !!d.values[index],
                  role: `segment${i}`,
                };
              }
            });
          });
        }

        const selectionId: powerbi.extensibility.ISelectionId =
          selectionBuilder.createSelectionId();

        const categoryValues: string[] = [];

        values.yAxis.map((d, i) =&amp;gt; {
          categoryValues.push(d[index]);
        });

        let startDate: ISegment = { date: null, name: "" };
        startDate = {
          date: values.startDate &amp;amp;&amp;amp; moment(values.startDate[index]),
          name: dataView.categorical.categories.filter(
            (d) =&amp;gt; d.source.roles.startDate
          )[0].source.displayName,
          showOnTooltip: !!values.startDate[index],
          role: `startDate`,
        };

        const milestoneDate: Date =
          ((values.milestoneDate &amp;amp;&amp;amp;
            !isEmpty(values.milestoneDate[index]) &amp;amp;&amp;amp;
            values.milestoneDate[index]) as Date) || null;

        const task: Task = {
          index: index,
          yAxis: categoryValues,
          name: categoryValues[j],
          parentName: j === 0 ? null : categoryValues[j - 1],
          parentID: j === 0 ? null : j - 1,
          children: [],
          startDate: startDate,
          endDate: endDate,
          segments: Object.assign([], [startDate, ...segment, endDate]),
          visibility: true,
          seriesName: seriesName &amp;amp;&amp;amp; seriesName.name,
          selected: false,
          identity: selectionId,
          wasDowngradeDurationUnit,
          stepDurationTransformation,
          milestoneDate: milestoneDate &amp;amp;&amp;amp; moment(milestoneDate),
        };

        tasks.forEach((task) =&amp;gt; {
          if (task.endDate &amp;amp;&amp;amp; task.startDate) {
            task.endDate = task.endDate;
          } else {
            task.endDate = task.startDate;
          }
        });

        tasks.push(task);
      }
    }

    return tasks;
  }

//---------
  private prepareHierarchyData(tasks) {
    _(tasks).forEach((f) =&amp;gt; {
      f.children = _(tasks)
        .filter((g) =&amp;gt; g.parentName === f.name)
        .value();
    });

    const resultArray = _(tasks)
      .filter((f) =&amp;gt; f.parentName === null)
      .value();

    return _.unionBy(resultArray, (d) =&amp;gt; d.name);
  }&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;My capabilities.json looks like that:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;    "dataRoles": [
        {
            "displayName": "yAxis",
            "name": "yAxis",
            "kind": "Grouping"
        },
        {
            "displayName": "Legend",
            "name": "projectStatus",
            "kind": "Grouping"
        },
        {
            "displayName": "Milestone",
            "name": "milestoneDate",
            "kind": "Grouping"
        },
        {
            "displayName": "Start Date",
            "name": "startDate",
            "kind": "Grouping"
        },
        {
            "displayName": "End Date",
            "name": "endDate",
            "kind": "Measure"
        },
        {
            "displayName": "Phases",
            "name": "segment",
            "kind": "Measure"
        }
    ],
    "dataViewMappings": [
        {
            "conditions": [
                {
                    "yAxis": {
                        "max": 5
                    },
                    "projectStatus": {
                        "max": 1
                    },
                    "milestoneDate": {
                        "max": 1
                    },
                    "startDate": {
                        "max": 1
                    },
                    "endDate": {
                        "max": 1
                    },
                    "segment": {
                        "max": 10
                    }
                }
            ],
            "categorical": {
                "categories": {
                    "select": [
                        {
                            "for": {
                                "in": "yAxis"
                            }
                        },
                        {
                            "for": {
                                "in": "milestoneDate"
                            }
                        },
                        {
                            "for": {
                                "in": "startDate"
                            }
                        }
                    ]
                },
                "values": {
                    "group": {
                        "by": "projectStatus",
                        "select": [
                            {
                                "for": {
                                    "in": "endDate"
                                }
                            },
                            {
                                "for": {
                                    "in": "segment"
                                }
                            }
                        ]
                    }
                }
            }
        }
    ],&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I don't know how to move on. I was trying to create sth like these here&amp;nbsp;&lt;A href="https://observablehq.com/@d3/icicle?ui=classic" target="_blank"&gt;https://observablehq.com/@d3/icicle?ui=classic&lt;/A&gt;&amp;nbsp;but I don't have&lt;FONT color="#808080"&gt;&lt;EM&gt; values&lt;/EM&gt;&lt;/FONT&gt; so it doesn't work for me since I have dates only. Also I was reading about treemap but I don't know how to use it in that case.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Do you have any examples or solutions how to draw hierarchical table ? It doesn't has to be with plus/minus button.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I will be gratefull for any answear.&lt;/P&gt;</description>
      <pubDate>Wed, 20 Oct 2021 18:34:36 GMT</pubDate>
      <guid>https://community.fabric.microsoft.com/t5/Developer/Custom-visual-with-hierarchy-table/m-p/2146463#M32495</guid>
      <dc:creator>filipwydra</dc:creator>
      <dc:date>2021-10-20T18:34:36Z</dc:date>
    </item>
    <item>
      <title>Re: Custom visual with hierarchy table</title>
      <link>https://community.fabric.microsoft.com/t5/Developer/Custom-visual-with-hierarchy-table/m-p/2152871#M32571</link>
      <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://community.fabric.microsoft.com/t5/user/viewprofilepage/user-id/329928"&gt;@filipwydra&lt;/a&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I think you can try to transform your table in Power Query Editor and then let your table in format: Level1, Level2,Level3,...,Values. Then add these columns in Matrix visual, and turn off Stepped layout in Format.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Then you can get result you want.&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="1.png" style="width: 845px;"&gt;&lt;img src="https://community.fabric.microsoft.com/t5/image/serverpage/image-id/618810i0F6C4B287F241242/image-size/large?v=v2&amp;amp;px=999" role="button" title="1.png" alt="1.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Best Regards,&lt;BR /&gt;Rico Zhou&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.&lt;/P&gt;</description>
      <pubDate>Mon, 25 Oct 2021 07:45:07 GMT</pubDate>
      <guid>https://community.fabric.microsoft.com/t5/Developer/Custom-visual-with-hierarchy-table/m-p/2152871#M32571</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2021-10-25T07:45:07Z</dc:date>
    </item>
    <item>
      <title>Re: Custom visual with hierarchy table</title>
      <link>https://community.fabric.microsoft.com/t5/Developer/Custom-visual-with-hierarchy-table/m-p/2155644#M32598</link>
      <description>&lt;P&gt;I found solution I need here:&amp;nbsp;&lt;A href="https://observablehq.com/@mojaie/collapsible-tree-with-checkboxes-d3-js?ui=classic" target="_blank" rel="noopener"&gt;https://observablehq.com/@mojaie/collapsible-tree-with-checkboxes-d3-js?ui=classic&lt;/A&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 26 Oct 2021 11:04:28 GMT</pubDate>
      <guid>https://community.fabric.microsoft.com/t5/Developer/Custom-visual-with-hierarchy-table/m-p/2155644#M32598</guid>
      <dc:creator>filipwydra</dc:creator>
      <dc:date>2021-10-26T11:04:28Z</dc:date>
    </item>
  </channel>
</rss>

