Как я могу локализовать круги в определенном регионе в d3.js - PullRequest
0 голосов
/ 07 мая 2018

Я создал график в d3, который читает массив и отображает данные, когда курсор мыши проходит по кругу.

Моя графика состоит из 3 объектов:

  1. основной круг, который расположен в центре страницы.
  2. цветная круговая диаграмма внутри основного круга.
  3. маленький кружок, соответствующий каждой записи массива, определенного в код.

enter image description here

Я хочу иметь возможность расположить маленькие круги на краю основного круга, как показано на рисунке ниже.

enter image description here

Есть идеи, как это сделать? Буду признателен за любой совет или помощь.

Я оставляю полный код созданной мною графики. Большое спасибо

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>D3 Test</title>
    <script src="//d3js.org/d3.v3.min.js"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
    <style>
        .underline {
            text-decoration: underline;
        }
    </style>
</head>
<body style="background-color: rgb(233, 236, 239)">
<br><legend align="center">D3 Test</legend><hr>
  <div class="container">
      <div class="jumbotron">
    <script type="text/javascript">
    var w = 1200;
    var h = 550;
    var padding = 20;
    var radius = Math.min(w, h);


    var dataset = [
          [ 600, 150]
    ];

    var data = [
            [5, 20, "1.- Lorem Ipsum es simplemente el texto de relleno de las imprentas y archivos de texto."],
            [480, 90, "2.- Lorem Ipsum ha sido el texto de relleno estándar de las industrias desde el año 1500"],
            [750, 50, "3.- cuando un impresor (N. del T. persona que se dedica a la imprenta) desconocido usó una galería de textos"],
            [100, 33, "4.- Es un hecho establecido hace demasiado tiempo que un"],
            [330, 95, "5.- Parecerlo un español que se puede leer. Muchos paquetes de autoedición y editores de páginas web usan el Lorem Ipsum como su te"],
            [410, 12, "6- Ingresó como texto de relleno en documentos electrónicos, quedan"],
            [475, 44, "7.- Esencialmente igual al original. Fue popularizado en los 60s "],
            [25, 67, " 8.- Más recientemente con software de autoedición, como por ejemplo Al"],
            [85, 21, "9.- Normal de las letras, al contrario de usar textos como por ejemplo "],
            [220, 88, "10.- Muchas variaciones de los pasajes de Lorem Ipsum disponibles, pero la mayoría sufrió alteraciones en al"]
          ];
    var data_colors = [ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13, 11, 12, 15, 20, 18, 17, 16, 18, 23, 25, 15, 20, 18, 17, 16, 18, 23, 25 ];

    var data_2 = [
        [122, 72]
    ];

      var xScale_data = d3.scale.linear()
                .domain([0, d3.max(data, function(d) { return d[0]; })])
                .range([padding, w - padding * 2]);

      var yScale_data = d3.scale.linear()
                .domain([0, d3.max(data, function(d) { return d[1]; })])
                .range([h - padding, padding * 4]);

      var rScale = d3.scale.linear()
                .domain([0, d3.max(dataset, function(d) { return d[1]; })])
                .range([2, 5]);

      var rScale_data = d3.scale.linear()
                .domain([0, d3.max(data, function(d) { return d[1]; })])
                .range([2, 5]);

      //Crear un elemento SVG
      var svg = d3.select("div.jumbotron")
        .append("svg")
            .attr("width", w)
            .attr("height", h)

      svg.selectAll("circle")
        .data(dataset)
        .enter()
        .append("circle")
            .attr("cx", w / 2)
            .attr("cy", h / 2)

            .attr("r", function(d) {
                return rScale(d[1]) * 25;
            })
            .attr("stroke", "rgb(255, 255, 255)")
            .attr("stroke-width", "8")
            .attr("fill", function(d) {
                return "rgb(233, 236, 239)";
            });

            svg.on("click", function() {
                document.getElementById("msg").setAttribute("style", "display:none;");
                document.getElementById("msg").innerHTML = '';
                d3.event.stopPropagation();
            });

      var dataCircle = d3.select("svg")
        .append("svg")
            .attr("width", w)
            .attr("height", h)

      dataCircle.selectAll("circle")
        .data(data)
        .enter()
        .append("circle")
            .attr("cx", function(d) {
                return xScale_data(d[0]);
            })
            .attr("cy", function(d) {
                return yScale_data(d[1]);
            })
            .attr("id", function(d){
                return "circle-" + d[1]
            })
            .on("mouseover", function(d) {
                document.getElementById("msg").removeAttribute("style");
                document.getElementById("circle-" + d[1]).setAttribute("stroke", "rgb(140, 233, 255)");
                document.getElementById("circle-" + d[1]).setAttribute("stroke-width", "5");
                document.getElementById("msg").innerHTML = d[2];
                d3.event.stopPropagation();
            })
            .on("mouseout", function(d) {
                document.getElementById("msg").setAttribute("style", "display:none;");
                document.getElementById("circle-" + d[1]).removeAttribute("stroke");
                document.getElementById("circle-" + d[1]).removeAttribute("stroke-width");
                document.getElementById("msg").innerHTML = '';
                d3.event.stopPropagation();
            })
            .on("click", function(d) {
                document.getElementById("msg").removeAttribute("style");
                document.getElementById("msg").innerHTML = d[2];
                d3.event.stopPropagation();
            })
            .attr("style", "cursor:pointer;")

            .attr("r", function(d) {
                return rScale_data(d[1]) * 8;
            })

            .attr("fill", function(d) {
                return "rgba(" + Math.floor((Math.random() * 255) + 0) + "," + Math.floor((Math.random() * 255) + 0) + "," + Math.floor((Math.random() * 255) + 0) + ", 0.30)";
            })

    var color = d3.scale.category20();

    var pie = d3.layout.pie()
        .value(function(d) { return 5; })
        .sort(null);

    var arc = d3.svg.arc()
        .innerRadius(radius - 508)
        .outerRadius(radius - 480);

    var svg = d3.select("svg")
        .append("svg")
            .attr("width", w )
            .attr("height", h )
            .append("g")
                .attr("transform", "translate(" + w / 2 + "," + h / 2 + ")");

    svg.datum(data_colors).selectAll("path")
        .data(pie)
        .enter()
        .append("path")
            .attr("cx", w / 2)
            .attr("cy", h / 2)
            .attr("r", 125)
            .attr("fill", function(d, i) { return color(i); })
            .attr("d", arc);

    </script>
      <div class="row">
        <div class="col-lg-12">
          <div id="msg" style="display:none;" class="underline alert alert-warning" align="center"></div>
        </div>
      </div>
    </div>
  </div>
</body>
</html>

1 Ответ

0 голосов
/ 08 мая 2018

Если вам не нужно быть слишком конкретным, когда маленькие кружочки расположены вокруг основного круга, вы можете использовать d3.forceRadial (https://github.com/d3/d3-force#forceRadial).

Если вы хотите более точно определить, где маленькие окружности появляются на окружности основного круга, вы можете написать функцию, которая задает координаты x и y (относительно центра окружности) на основе требуемого радиуса и угла. например

function xyCoordinates(angle, radius) {
            let radians = 0.0174532925
            let x = radius * Math.sin(a * radians)
            let y = radius * Math.cos(a * radians)
            return [x,y]        
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...