<?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 How to structure data to then pass to d3.hierachy (or d3.treemap directly) in custom visual in Custom Visuals Development Discussion</title>
    <link>https://community.fabric.microsoft.com/t5/Custom-Visuals-Development/How-to-structure-data-to-then-pass-to-d3-hierachy-or-d3-treemap/m-p/1734349#M3608</link>
    <description>&lt;P&gt;Hi, I'm fairly new to developing custom visuals. I've gone through a few tutorials and messed around moving simple d3 visuals to power bi, and am now trying to make a custom treemap visual based on &lt;A href="https://www.d3-graph-gallery.com/graph/treemap_json.html" target="_self"&gt;this d3 treemap&lt;/A&gt;. I can make it work if I include the data directly in the visual, but I'm struggling in making sense how to structure the data from power bi into a format that can be used by d3.hierarchy then passed to d3.treemap, or used directly by d3.treemap.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I think the matrix data view mapping would be most appropriate, as it's a hierachical structure? Unfortunately, I haven't been able to find any tutorials or sample custom visuals using the matrix data view, and I've found the information on the&lt;A href="https://docs.microsoft.com/en-us/power-bi/developer/visuals/dataview-mappings" target="_self"&gt; Understand data view mapping&lt;/A&gt; page somewhat limited.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I've posted my visual.ts code below, and would greatly appreciate any help / pointing in the direction of relevant documention/tutorials/examples!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="markup"&gt;"use strict";

import "core-js/stable";
import "./../style/visual.less";
import powerbi from "powerbi-visuals-api";
import VisualConstructorOptions = powerbi.extensibility.visual.VisualConstructorOptions;
import VisualUpdateOptions = powerbi.extensibility.visual.VisualUpdateOptions;
import IVisual = powerbi.extensibility.visual.IVisual;
import EnumerateVisualObjectInstancesOptions = powerbi.EnumerateVisualObjectInstancesOptions;
import VisualObjectInstance = powerbi.VisualObjectInstance;
import DataView = powerbi.DataView;
import VisualObjectInstanceEnumerationObject = powerbi.VisualObjectInstanceEnumerationObject;
import { VisualSettings } from "./settings";
import * as d3 from 'd3';
import { values } from "d3";
import { getMeasureIndexOfRole } from "powerbi-visuals-utils-dataviewutils/lib/dataRoleHelper";



interface Finn {
    children: {
        name: string;
        children: {
            name: string;
            group: string;
            value: number;
            colname: string;
        }[];
        colname: string;
    }[];
    name: string;
}

export class Visual implements IVisual {
    private target: HTMLElement;
    private settings: VisualSettings;
    private container: d3.Selection&amp;lt;HTMLDivElement, any, HTMLDivElement, any&amp;gt;;

    constructor(options: VisualConstructorOptions) {
        console.log('Visual constructor', options);
        this.target = options.element;
        this.container = d3.select(this.target)
            .append('div')
            .attr('id', 'my_dataviz');
    }

    public update(options: VisualUpdateOptions) {
        //console.log('Visual update', options);
        //this.settings = Visual.parseSettings(options &amp;amp;&amp;amp; options.dataViews &amp;amp;&amp;amp; options.dataViews[0]);
       // this.container.selectAll('*').remove();
        //let dataViews = options.dataViews;
        
        var margin = { top: 10, right: 30, bottom: 30, left: 60 },
            width = options.viewport.width - margin.left - margin.right,
            height = options.viewport.height - margin.top - margin.bottom;

        var svg = this.container
            .append("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
            .append("g")
            .attr("transform",
                "translate(" + margin.left + "," + margin.top + ")");
        //data
        let data: Finn = {
            "children": [
                {
                    "name": "boss1",
                    "children": [
                        {
                            "name": "mister_a",
                            "group": "A",
                            "value": 28,
                            "colname": "level3"
                        },
                        {
                            "name": "mister_b",
                            "group": "A",
                            "value": 19,
                            "colname": "level3"
                        },
                        {
                            "name": "mister_c",
                            "group": "C",
                            "value": 18,
                            "colname": "level3"
                        },
                        {
                            "name": "mister_d",
                            "group": "C",
                            "value": 19,
                            "colname": "level3"
                        }
                    ],
                    "colname": "level2"
                },
                {
                    "name": "boss2",
                    "children": [
                        {
                            "name": "mister_e",
                            "group": "C",
                            "value": 14,
                            "colname": "level3"
                        },
                        {
                            "name": "mister_f",
                            "group": "A",
                            "value": 11,
                            "colname": "level3"
                        },
                        {
                            "name": "mister_g",
                            "group": "B",
                            "value": 15,
                            "colname": "level3"
                        },
                        {
                            "name": "mister_h",
                            "group": "B",
                            "value": 16,
                            "colname": "level3"
                        }
                    ],
                    "colname": "level2"
                },
                {
                    "name": "boss3",
                    "children": [
                        {
                            "name": "mister_i",
                            "group": "B",
                            "value": 10,
                            "colname": "level3"
                        },
                        {
                            "name": "mister_j",
                            "group": "A",
                            "value": 13,
                            "colname": "level3"
                        },
                        {
                            "name": "mister_k",
                            "group": "A",
                            "value": 13,
                            "colname": "level3"
                        },
                        {
                            "name": "mister_l",
                            "group": "D",
                            "value": 25,
                            "colname": "level3"
                        },
                        {
                            "name": "mister_m",
                            "group": "D",
                            "value": 16,
                            "colname": "level3"
                        },
                        {
                            "name": "mister_n",
                            "group": "D",
                            "value": 28,
                            "colname": "level3"
                        }
                    ],
                    "colname": "level2"
                }
            ],
            "name": "CEO"
        }
        // read json data
        // d3.json("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/data_dendrogram_full.json", function (data) {

        // Give the data to this cluster layout:
        var root = d3.hierarchy(data).sum(function (d) { return (&amp;lt;any&amp;gt;d).value }) // Here the size of each leave is given in the 'value' field in input data

        // Then d3.treemap computes the position of each element of the hierarchy
        d3.treemap()
            .size([width, height])
            .padding(2)
            (root)

        // use this information to add rectangles:
        svg
            .selectAll("rect")
            .data(root.leaves())
            .enter()
            .append("rect")
            .attr('x', function (d) { return (&amp;lt;any&amp;gt;d).x0; })
            .attr('y', function (d) { return (&amp;lt;any&amp;gt;d).y0; })
            .attr('width', function (d) { return (&amp;lt;any&amp;gt;d).x1 - (&amp;lt;any&amp;gt;d).x0; })
            .attr('height', function (d) { return (&amp;lt;any&amp;gt;d).y1 - (&amp;lt;any&amp;gt;d).y0; })
            .style("stroke", "black")
            .style("fill", "slateblue")

        // and to add the text labels
        svg
            .selectAll("text")
            .data(root.leaves())
            .enter()
            .append("text")
            .attr("x", function (d) { return (&amp;lt;any&amp;gt;d).x0 + 5 })    // +10 to adjust position (more right)
            .attr("y", function (d) { return (&amp;lt;any&amp;gt;d).y0 + 20 })    // +20 to adjust position (lower)
            .text(function (d) { return d.data.name })
            .attr("font-size", "15px")
            .attr("fill", "white")
    }
    //)
//}

    private static parseSettings(dataView: DataView): VisualSettings {
    return VisualSettings.parse(dataView) as VisualSettings;
}

    /**
     * This function gets called for each of the objects defined in the capabilities files and allows you to select which of the
     * objects and properties you want to expose to the users in the property pane.
     *
     */
    public enumerateObjectInstances(options: EnumerateVisualObjectInstancesOptions): VisualObjectInstance[] | VisualObjectInstanceEnumerationObject {
    return VisualSettings.enumerateObjectInstances(this.settings || VisualSettings.getDefault(), options);
}
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Sat, 20 Mar 2021 18:57:07 GMT</pubDate>
    <dc:creator>ahille</dc:creator>
    <dc:date>2021-03-20T18:57:07Z</dc:date>
    <item>
      <title>How to structure data to then pass to d3.hierachy (or d3.treemap directly) in custom visual</title>
      <link>https://community.fabric.microsoft.com/t5/Custom-Visuals-Development/How-to-structure-data-to-then-pass-to-d3-hierachy-or-d3-treemap/m-p/1734349#M3608</link>
      <description>&lt;P&gt;Hi, I'm fairly new to developing custom visuals. I've gone through a few tutorials and messed around moving simple d3 visuals to power bi, and am now trying to make a custom treemap visual based on &lt;A href="https://www.d3-graph-gallery.com/graph/treemap_json.html" target="_self"&gt;this d3 treemap&lt;/A&gt;. I can make it work if I include the data directly in the visual, but I'm struggling in making sense how to structure the data from power bi into a format that can be used by d3.hierarchy then passed to d3.treemap, or used directly by d3.treemap.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I think the matrix data view mapping would be most appropriate, as it's a hierachical structure? Unfortunately, I haven't been able to find any tutorials or sample custom visuals using the matrix data view, and I've found the information on the&lt;A href="https://docs.microsoft.com/en-us/power-bi/developer/visuals/dataview-mappings" target="_self"&gt; Understand data view mapping&lt;/A&gt; page somewhat limited.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I've posted my visual.ts code below, and would greatly appreciate any help / pointing in the direction of relevant documention/tutorials/examples!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="markup"&gt;"use strict";

import "core-js/stable";
import "./../style/visual.less";
import powerbi from "powerbi-visuals-api";
import VisualConstructorOptions = powerbi.extensibility.visual.VisualConstructorOptions;
import VisualUpdateOptions = powerbi.extensibility.visual.VisualUpdateOptions;
import IVisual = powerbi.extensibility.visual.IVisual;
import EnumerateVisualObjectInstancesOptions = powerbi.EnumerateVisualObjectInstancesOptions;
import VisualObjectInstance = powerbi.VisualObjectInstance;
import DataView = powerbi.DataView;
import VisualObjectInstanceEnumerationObject = powerbi.VisualObjectInstanceEnumerationObject;
import { VisualSettings } from "./settings";
import * as d3 from 'd3';
import { values } from "d3";
import { getMeasureIndexOfRole } from "powerbi-visuals-utils-dataviewutils/lib/dataRoleHelper";



interface Finn {
    children: {
        name: string;
        children: {
            name: string;
            group: string;
            value: number;
            colname: string;
        }[];
        colname: string;
    }[];
    name: string;
}

export class Visual implements IVisual {
    private target: HTMLElement;
    private settings: VisualSettings;
    private container: d3.Selection&amp;lt;HTMLDivElement, any, HTMLDivElement, any&amp;gt;;

    constructor(options: VisualConstructorOptions) {
        console.log('Visual constructor', options);
        this.target = options.element;
        this.container = d3.select(this.target)
            .append('div')
            .attr('id', 'my_dataviz');
    }

    public update(options: VisualUpdateOptions) {
        //console.log('Visual update', options);
        //this.settings = Visual.parseSettings(options &amp;amp;&amp;amp; options.dataViews &amp;amp;&amp;amp; options.dataViews[0]);
       // this.container.selectAll('*').remove();
        //let dataViews = options.dataViews;
        
        var margin = { top: 10, right: 30, bottom: 30, left: 60 },
            width = options.viewport.width - margin.left - margin.right,
            height = options.viewport.height - margin.top - margin.bottom;

        var svg = this.container
            .append("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
            .append("g")
            .attr("transform",
                "translate(" + margin.left + "," + margin.top + ")");
        //data
        let data: Finn = {
            "children": [
                {
                    "name": "boss1",
                    "children": [
                        {
                            "name": "mister_a",
                            "group": "A",
                            "value": 28,
                            "colname": "level3"
                        },
                        {
                            "name": "mister_b",
                            "group": "A",
                            "value": 19,
                            "colname": "level3"
                        },
                        {
                            "name": "mister_c",
                            "group": "C",
                            "value": 18,
                            "colname": "level3"
                        },
                        {
                            "name": "mister_d",
                            "group": "C",
                            "value": 19,
                            "colname": "level3"
                        }
                    ],
                    "colname": "level2"
                },
                {
                    "name": "boss2",
                    "children": [
                        {
                            "name": "mister_e",
                            "group": "C",
                            "value": 14,
                            "colname": "level3"
                        },
                        {
                            "name": "mister_f",
                            "group": "A",
                            "value": 11,
                            "colname": "level3"
                        },
                        {
                            "name": "mister_g",
                            "group": "B",
                            "value": 15,
                            "colname": "level3"
                        },
                        {
                            "name": "mister_h",
                            "group": "B",
                            "value": 16,
                            "colname": "level3"
                        }
                    ],
                    "colname": "level2"
                },
                {
                    "name": "boss3",
                    "children": [
                        {
                            "name": "mister_i",
                            "group": "B",
                            "value": 10,
                            "colname": "level3"
                        },
                        {
                            "name": "mister_j",
                            "group": "A",
                            "value": 13,
                            "colname": "level3"
                        },
                        {
                            "name": "mister_k",
                            "group": "A",
                            "value": 13,
                            "colname": "level3"
                        },
                        {
                            "name": "mister_l",
                            "group": "D",
                            "value": 25,
                            "colname": "level3"
                        },
                        {
                            "name": "mister_m",
                            "group": "D",
                            "value": 16,
                            "colname": "level3"
                        },
                        {
                            "name": "mister_n",
                            "group": "D",
                            "value": 28,
                            "colname": "level3"
                        }
                    ],
                    "colname": "level2"
                }
            ],
            "name": "CEO"
        }
        // read json data
        // d3.json("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/data_dendrogram_full.json", function (data) {

        // Give the data to this cluster layout:
        var root = d3.hierarchy(data).sum(function (d) { return (&amp;lt;any&amp;gt;d).value }) // Here the size of each leave is given in the 'value' field in input data

        // Then d3.treemap computes the position of each element of the hierarchy
        d3.treemap()
            .size([width, height])
            .padding(2)
            (root)

        // use this information to add rectangles:
        svg
            .selectAll("rect")
            .data(root.leaves())
            .enter()
            .append("rect")
            .attr('x', function (d) { return (&amp;lt;any&amp;gt;d).x0; })
            .attr('y', function (d) { return (&amp;lt;any&amp;gt;d).y0; })
            .attr('width', function (d) { return (&amp;lt;any&amp;gt;d).x1 - (&amp;lt;any&amp;gt;d).x0; })
            .attr('height', function (d) { return (&amp;lt;any&amp;gt;d).y1 - (&amp;lt;any&amp;gt;d).y0; })
            .style("stroke", "black")
            .style("fill", "slateblue")

        // and to add the text labels
        svg
            .selectAll("text")
            .data(root.leaves())
            .enter()
            .append("text")
            .attr("x", function (d) { return (&amp;lt;any&amp;gt;d).x0 + 5 })    // +10 to adjust position (more right)
            .attr("y", function (d) { return (&amp;lt;any&amp;gt;d).y0 + 20 })    // +20 to adjust position (lower)
            .text(function (d) { return d.data.name })
            .attr("font-size", "15px")
            .attr("fill", "white")
    }
    //)
//}

    private static parseSettings(dataView: DataView): VisualSettings {
    return VisualSettings.parse(dataView) as VisualSettings;
}

    /**
     * This function gets called for each of the objects defined in the capabilities files and allows you to select which of the
     * objects and properties you want to expose to the users in the property pane.
     *
     */
    public enumerateObjectInstances(options: EnumerateVisualObjectInstancesOptions): VisualObjectInstance[] | VisualObjectInstanceEnumerationObject {
    return VisualSettings.enumerateObjectInstances(this.settings || VisualSettings.getDefault(), options);
}
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sat, 20 Mar 2021 18:57:07 GMT</pubDate>
      <guid>https://community.fabric.microsoft.com/t5/Custom-Visuals-Development/How-to-structure-data-to-then-pass-to-d3-hierachy-or-d3-treemap/m-p/1734349#M3608</guid>
      <dc:creator>ahille</dc:creator>
      <dc:date>2021-03-20T18:57:07Z</dc:date>
    </item>
  </channel>
</rss>

