Несколько сегментов в одном сегменте в кольцевой диаграмме? - PullRequest
0 голосов
/ 07 октября 2019

Я ищу несколько сегментов в одном сегменте.

Каждый сегмент может иметь различную цветовую схему.

Я ищу что-то вроде этого:

Требуемая Dounut диаграмма

Я пробовал поискать в Google, я не могу найти никакого решения для нескольких сегментов в одном сегменте.

Кстати, я создаю PowerBi CustomVisual.

Вот мой код с использованием d3

<!DOCTYPE html>

    <head>
        <script src="https://d3js.org/d3.v4.min.js"></script>
    </head>

    <body>
        <svg></svg>
    </body>

    <script>
        // JSON data
        var nodeData = {
            "name": "TOPICS", "children": [{
                "name": "Active Members",
                "children": [{ "name": "Delta", "size": 230000 }, { "name": "United", "size": 400000 },{ "name": "American", "size": 750000 },{ "name": "Alaska", "size": 250000 }]
            }, {
                "name": "No of customers",
                "children": [{ "name": "Amex", "size": 204300 }, { "name": "Visa", "size": 300000 },{ "name": "Paypal", "size": 400000 },{ "name": "Others", "size": 120000 },{ "name": "Mastercard", "size": 110440 },{ "name": "Discover", "size": 400000 }]
            }, {
                "name": "No of claims Paid",
                "children": [{ "name": "Hospital 1", "size": 150000 }, { "name": "Hospital 2", "size": 200000 }, { "name": "Hospital 3", "size": 300000 }, { "name": "Hospital 4", "size": 500000 }]
            }, {
                "name": "no of amount paid",
                "children": [{ "name": "Pizza", "size": 500000 }, { "name": "Burger", "size": 300000 }, { "name": "Sandwich", "size": 450000 }, { "name": "Toast", "size": 250000 }]
            },
            {
                "name": "Medical Paid",
                "children": [{ "name": "Doctor 1", "size": 300000 }, { "name": "Doctor 2", "size": 200000 }]
            }, {
                "name": "Pharmacy Paid",
                "children": [{ "name": "CVS", "size": 200000 }, { "name": "Walgreens", "size": 100000 }, { "name": "Walrmart", "size": 200000 }, { "name": "Others", "size": 100000 }],
            }]
        };

        // Variables
        var width = 500;
        var height = 500;
        var radius = Math.min(width, height) / 3;
        var color = d3.scaleOrdinal(d3.schemeCategory10);
        var donutWidth = 25;

        // Create primary <g> element
        var g = d3.select('svg')
            .attr('width', width)
            .attr('height', height)
            .append('g')
            .attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')');

        // Data strucure
        var partition = d3.partition()
            .size([2 * Math.PI, radius]);

        // Find data root
        var root = d3.hierarchy(nodeData)
            .sum(function (d) { return d.size });

        // Size arcs
        partition(root);
        var arc = d3.arc()
            .startAngle(function (d) { return d.x0 })
            .endAngle(function (d) { return d.x1 })
            .innerRadius(radius - donutWidth)
            .outerRadius(radius)
            // .innerRadius(function (d) { return d.y0 })
            // .outerRadius(function (d) { return d.y1 })
            .padAngle(0.04);

        // Put it all together
        g.selectAll('path')
            .data(root.descendants())
            .enter().append('path')
            .attr("display", function (d) { return d.depth ? null : "none"; })
            .attr("d", arc)
            .style('stroke', '#fff')
            .style("fill", function (d) { return color((d.children ? d : d.parent).data.name); });
    </script>

1 Ответ

0 голосов
/ 10 октября 2019

Для этого вам нужно будет сделать 2 обновления в коде.

1) Создать цветовую шкалу для каждой темы, чтобы каждый дочерний узел получал уникальный цвет в своем сегменте.

2) Поскольку заполнение применяется к каждому сегменту в кольцевой диаграмме, вы можете создать иллюзию промежутков между родительскими сегментами, вставив фиктивные данные со значением, а затем закрасив эти сегменты белым.

     
      
        var nodeData = {
            "name": "TOPICS", "children": [{
                "name": "Active Members",
                "children": [{ "name": "Delta", "size": 230000 }, { "name": "United", "size": 400000 },{ "name": "American", "size": 750000 },{ "name": "Alaska", "size": 250000 }]
            }, {
                "name": "No of customers",
                "children": [{ "name": "Amex", "size": 204300 }, { "name": "Visa", "size": 300000 },{ "name": "Paypal", "size": 400000 },{ "name": "Others", "size": 120000 },{ "name": "Mastercard", "size": 110440 },{ "name": "Discover", "size": 400000 }]
            }, {
                "name": "No of claims Paid",
                "children": [{ "name": "Hospital 1", "size": 150000 }, { "name": "Hospital 2", "size": 200000 }, { "name": "Hospital 3", "size": 300000 }, { "name": "Hospital 4", "size": 500000 }]
            }, {
                "name": "no of amount paid",
                "children": [{ "name": "Pizza", "size": 500000 }, { "name": "Burger", "size": 300000 }, { "name": "Sandwich", "size": 450000 }, { "name": "Toast", "size": 250000 }]
            },
            {
                "name": "Medical Paid",
                "children": [{ "name": "Doctor 1", "size": 300000 }, { "name": "Doctor 2", "size": 200000 }]
            }, {
                "name": "Pharmacy Paid",
                "children": [{ "name": "CVS", "size": 200000 }, { "name": "Walgreens", "size": 100000 }, { "name": "Walrmart", "size": 200000 }, { "name": "Others", "size": 100000 }],
            }]
        };

        // Variables
        var width = 500;
        var height = 500;
        var radius = Math.min(width, height) / 3;
        //var color = d3.scaleOrdinal(d3.schemeCategory10);
        var donutWidth = 25;
      	
      	//CREATE A COLOUR SCALE PER CHILD TOPIC
      	var colourScale = {}
      	nodeData.children.forEach(function(d){
          colourScale[d.name] = d3.scaleOrdinal(d3.schemeCategory10);
        })
     
        //INSERT DATA INTO ARRAY TO CREATE GAPS IN THE DONUT CHART
      	var n = nodeData.children.length
        for (var i = 0; i < n; i++) {
          var position = (i * 2) + 1
          var parentName = "Gap" + i
          var childName = "GapChild"
          var gapData = {"name": parentName, "children": [{"name": childName, "size": 100000}]} //choose a size which gives the desired gap
          nodeData.children.splice(position, 0, gapData)
        }
      
        // Create primary <g> element
        var g = d3.select('svg')
            .attr('width', width)
            .attr('height', height)
            .append('g')
            .attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')');

        // Data strucure
        var partition = d3.partition()
            .size([2 * Math.PI, radius]);

        // Find data root
        var root = d3.hierarchy(nodeData)
            .sum(function (d) { return d.size });

        // Size arcs
        partition(root);
        var arc = d3.arc()
            .startAngle(function (d) { return d.x0 })
            .endAngle(function (d) { return d.x1 })
            .innerRadius(radius - donutWidth)
            .outerRadius(radius)
            .padAngle(0.001);

        // Put it all together
        g.selectAll('path')
            .data(root.descendants())
            .enter().append('path')
            .attr("visibility", function (d) { return d.depth == 2 ? "visible" : "hidden"; })
            .attr("d", arc)
            .style('stroke', '#fff')
            .style("fill", function (d) {
								// if the data is for "gap" child element or a parent node, then fill with white, else fill with categorical colour
          			if (d.data.name == "GapChild") {
                  	return "white"
                } else if (d.children) {
                  	return "white"
                } else {
                  	return colourScale[d.parent.data.name](d.data.name); 
                }
          	    
        		});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>


<body>
 <svg></svg>
 </body>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...