D3. js - ссылки не отображаются на карте (Leaflet) - PullRequest
0 голосов
/ 15 апреля 2020

Итак, я делаю простое представление на карте, где у меня есть узлы и ссылки, простые данные, чтобы проверить их, прежде чем я подключусь к файлу json и использую буклет. js для карта. Я покажу свой следующий JavaScrip, CSS и HTML.

По сути, я вижу, как мои узлы создаются на карте, но когда дело доходит до ссылок, они нигде не отображаются. Я уверен, что где-то допустил ошибку, но не могу понять где. Бьюсь об заклад, пара глаз fre sh может указать мне на мою ошибку basi c. Может кто-нибудь помочь мне, пожалуйста? (Примечание: до того, как я вставил карту и попытался соединить узлы ссылками, она работала просто отлично)

ВОПРОС Как я могу показать связи между узлами на карте?

$(document).ready(function() {
  $("#mapid").height(window.innerHeight);
  $('#slide-in').height(window.innerHeight);

  $(document).on('click', '#advanced', function() {
    if ($('#slide-in').hasClass('in')) {
      $('#slide-in').removeClass('in')
    } else {
      $('#slide-in').addClass('in')
    }
  });

  //A partir daqui 
  var map = L.map('mapid').setView([41.4079700, -8.5197800], 12)

  L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
    maxZoom: 18,
    attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
      '<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
      'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
    id: 'mapbox/streets-v10',
    tileSize: 512,
    zoomOffset: -1,
  }).addTo(map);

  //Mover o zoom para o canto inferior direito
  map.zoomControl.remove();
  L.control.zoom({
    position: 'bottomright'

  }).addTo(map);
  // Até aqui tá certo \\

  // Add a svg layer to the map
  L.svg().addTo(map);

  // dados provisórios
  var nodes = [{
      lat: 41.4579700,
      long: -8.5297800,
      private: 2,
      numContr: 10
    },
    {
      lat: 41.4379700,
      long: -8.5297800,
      private: 2,
      numContr: 20
    },
    {
      lat: 41.4579700,
      long: -8.4897800,
      private: 1,
      numContr: 40
    },
    {
      lat: 41.4179700,
      long: -8.4597800,
      private: 1,
      numContr: 50
    },
    {
      lat: 41.3879700,
      long: -8.5997800,
      private: 2,
      numContr: 10
    },
    {
      lat: 41.4779700,
      long: -8.5097800,
      private: 1,
      numContr: 30
    },
  ];

  var links = [{
      source: nodes[0],
      target: nodes[1],
      fraude: 1
    },
    {
      source: nodes[2],
      target: nodes[1],
      fraude: 2
    },
    {
      source: nodes[0],
      target: nodes[3],
      fraude: 1
    },
    {
      source: nodes[0],
      target: nodes[4],
      fraude: 2
    },
    {
      source: nodes[0],
      target: nodes[5],
      fraude: 1
    },
    {
      source: nodes[4],
      target: nodes[1],
      fraude: 1
    },
    {
      source: nodes[4],
      target: nodes[5],
      fraude: 1
    },
    {
      source: nodes[2],
      target: nodes[3],
      fraude: 1
    }
  ];

  //Adicionar os links 
  d3.select("#mapid")
    .select("svg")
    .selectAll("line")
    .data(links)
    .enter()
    .append("line")
    .attr("x1", function(d) {
      return d.source.x
    })
    .attr("y1", function(d) {
      return d.source.y
    })
    .attr("x2", function(d) {
      return d.target.x
    })
    .attr("y2", function(d) {
      return d.target.y
    })
    .style("stroke", function(d, i) {
      if (d.fraude == 2) {
        return "rgb(197,53,53)"
      } else {
        return "rgb(96,211,62"
      }
    })
    .style("stroke-width", 5)


  // Adicionar os nodes 
  d3.select("#mapid")
    .select("svg")
    .selectAll("myCircles")
    .data(nodes) //onde tão os dados
    .enter()
    .append("circle")
    .attr("cx", function(d) {
      return map.latLngToLayerPoint([d.lat, d.long]).x
    })
    .attr("cy", function(d) {
      return map.latLngToLayerPoint([d.lat, d.long]).y
    })
    .attr("r", function(d, i) {
      if (d.numContr >= 50) {
        return 20;
      } else {
        if (d.numContr < 50 && d.numContr > 25) {
          return 16;
        } else {
          if (d.numContr < 25 && d.numContr > 10) {
            return 12;
          } else {
            return 8;
          }
        }
      }
    })
    .attr("fill", function(d, i) {

      if (d.private == 1) {
        return "rgb(8,105,114)"
      } else {
        return "rgb(167,255,131)"
      }
    })
    .attr("stroke", "rgb(7,26,82)")
    .attr("stroke-width", 6)

  // Function that update circle position if something change
  function update() {
    d3.selectAll("circle")
      .attr("cx", function(d) {
        return map.latLngToLayerPoint([d.lat, d.long]).x
      })
      .attr("cy", function(d) {
        return map.latLngToLayerPoint([d.lat, d.long]).y
      })
  }

  // If the user change the map (zoom or drag), it update circle position:
  map.on("moveend", update)
})
body {
  margin: 0;
  padding: 0;
}

#menu-pesquisa {
  position: absolute;
  z-index: 1000;
  width: 324px;
  height: 24px;
  background: #fff;
  left: 0;
  margin: 10px;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2), 0 -1px 0px rgba(0, 0, 0, 0.02);
  min-height: relative;
  border-bottom: 0px solid transparent;
  padding: 5px 0px 20px 30px;
  text-align: center;
}

#slide-id h2 {
  margin: 0;
  padding: 0;
  margin-bottom: 10px;
}

#slide-in {
  padding: 10px;
  position: absolute;
  width: 250px;
  z-index: 1000;
  background: white;
  margin-left: -270px;
  transition: 0.5s;
}

#slide-in.in {
  margin-left: 0px;
}

#input-pesquisa {
  padding: 10px;
  font-size: 15px;
  border: 0;
  float: left;
  width: 65%;
  background: transparent;
  outline: none;
  margin-top: 2px;
}

#input-pesquisa::placeholder {
  opacity: 0.6;
  font-family: Arial, Helvetica, sans-serif;
}

#Pesquisa {
  box-sizing: border-box;
  border-style: hidden;
  background-color: inherit;
  text-align: justify;
  padding: 12px;
  padding-left: 30px;
  padding-right: 30px;
  outline: none;
  margin-top: -4px;
}

#Pesquisa .icon {
  background: url(/images/magnifying-glass.svg) no-repeat;
  float: left;
  width: 24px;
  height: 24px;
  color: white;
  border-left: none;
  cursor: pointer;
  border-color: transparent;
  position: center;
}

#numero-contrato {
  position: absolute;
  z-index: 1000;
  width: 280px;
  height: 80px;
  background: #fff;
  padding: 5px;
  left: 0;
  bottom: 15px;
  margin: 10px;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2), 0 -1px 0px rgba(0, 0, 0, 0.02);
  text-align: initial;
}

#numero-contrato h5 {
  padding: 0;
  margin-left: 5px;
  margin-top: 0px;
  font-family: Arial, Helvetica, sans-serif;
}

#tipo-contrato {
  position: absolute;
  z-index: 1000;
  width: 160px;
  height: 80px;
  background: #fff;
  padding: 5px;
  right: 230px;
  bottom: 15px;
  margin: 10px;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2), 0 -1px 0px rgba(0, 0, 0, 0.02);
  text-align: initial;
}

#tipo-contrato h5 {
  padding: 0;
  margin-left: 5px;
  margin-top: 0px;
  font-family: Arial, Helvetica, sans-serif;
}

#tipo-entidades {
  position: absolute;
  z-index: 1000;
  width: 160px;
  height: 80px;
  background: #fff;
  padding: 5px;
  right: 40px;
  bottom: 15px;
  margin: 10px;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2), 0 -1px 0px rgba(0, 0, 0, 0.02);
  text-align: initial;
}

#tipo-entidades h5 {
  padding: 0;
  margin-left: 5px;
  margin-top: 0px;
  font-family: Arial, Helvetica, sans-serif;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://d3js.org/d3.v5.min.js"></script>
  <link rel="stylesheet" href="/styles/styles.css">
  <link rel="stylesheet" href="/images/magnifying-glass.svg">
  <!-- Mapa -->
  <link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin="" />
  <script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js" integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew==" crossorigin=""></script>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js" type="text/javascript"></script>
  <title>Fraud Detection</title>

</head>

<body>
  <div id="slide-in">
    <h2>More info</h2>
  </div>

  <div id="tipo-entidades">
    <h5>Tipos de Entidades:</p>
  </div>

  <div id="tipo-contrato">
    <h5>Tipos de Contratos:</p>
  </div>

  <div id="numero-contrato">
    <h5>Número de contratos realizados:</p>
  </div>

  <div id="menu-pesquisa">
    <input type="text" id="input-pesquisa" placeholder="Pesquisar informações" name="Pesquisa"></input>
    <button id="Pesquisa"><span class="icon"></span></button>

  </div>
  <div>
    <!-- <button id="advanced" class="icon">Pesquisa Avançada</button> -->
  </div>

  <div id="mapid" style="width: 100%;"></div>
</body>

<script src='https://npmcdn.com/@turf/turf/turf.min.js'></script>

<script src="/scripts/force_directed_layout.js"></script>

</html>

1 Ответ

0 голосов
/ 16 апреля 2020

Я забыл адаптировать координаты lat и long к x и y осям от html, как я делал в кругах.

По сути, это мой результат:

d3.select("#mapid") 
    .select("svg")
    .selectAll("line")
    .data(links)    
    .enter()
    .append("line")
    .attr("x1", function(d) { return map.latLngToLayerPoint([d.source.lat, d.source.long]).x})
    .attr("y1", function(d) { return map.latLngToLayerPoint([d.source.lat, d.source.long]).y})
    .attr("x2", function(d) { return map.latLngToLayerPoint([d.target.lat, d.target.long]).x})
    .attr("y2", function(d) { return map.latLngToLayerPoint([d.target.lat, d.target.long]).y})
    .style("stroke", function(d, i)
    {
        if(d.fraude == 2)
        { return "rgb(197,53,53)"}
        else
        { return "rgb(96,211,62"}        
    })
    .style("stroke-width", 5)    

И я должен также обновить обновление функции, потому что если я не сделаю этого, строки будут оставаться в кадре все время:

function update() {
d3.selectAll("circle")
    .attr("cx", function(d){ return map.latLngToLayerPoint([d.lat, d.long]).x })
    .attr("cy", function(d){ return map.latLngToLayerPoint([d.lat, d.long]).y })

d3.selectAll("line")
    .attr("x1", function(d) { return map.latLngToLayerPoint([d.source.lat, d.source.long]).x})
    .attr("y1", function(d) { return map.latLngToLayerPoint([d.source.lat, d.source.long]).y})
    .attr("x2", function(d) { return map.latLngToLayerPoint([d.target.lat, d.target.long]).x})
    .attr("y2", function(d) { return map.latLngToLayerPoint([d.target.lat, d.target.long]).y})
}
...