【问题标题】:Get d3 Legend into Separate Div将 d3 Legend 放入单独的 div
【发布时间】:2017-08-22 20:44:54
【问题描述】:

我正在尝试将我的 cloropleth 地图的图例固定在地图右侧的白框中。我使用各种教程构建了地图,但对 D3 或 JS 不是很了解。我无法弄清楚这一点。

我这里有一个半工作版本:http://roachag.com/Portals/0/maps/basismap2.html

但是当试图将图例放在我想要的位置时,它不起作用。

    <!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Spot Corn Average Basis By County</title>
  <script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
  <script type="text/javascript" src="http://d3js.org/queue.v1.min.js"></script>
  <script type="text/javascript" src="http://d3js.org/topojson.v1.min.js"></script>


</head>
<style>

path {
  stroke:black;
  stroke-width: .5px;
}

body {
  font-family: Arial, sans-serif;
}

.city {
  font: 10px sans-serif;
  font-weight: bold;
}


.legend1 {
background: #FFFFFF;
stroke: black;
stroke-width: 1px;
height: 300px;
width: 150px;
  border: 1px;      
  border-radius: 8px;   
  border-color: black;   
  border-width: 1px;
  font: 12px;
  font-family: Arial, Helvetica, sans-serif
}


.legend {
background: #FFFFFF;
position: absolute;
    left:800px;
    top:500px;
height: 300px;
width: 150px;
  border: 1px;      
  border-radius: 8px;   
  border-color: black;   
  border-width: 1px;
  font: 12px;
  font-family: Arial, Helvetica, sans-serif
}



.background {
fill: none;
}

.states {
  fill: none;
  stroke: #000;
  stroke-linejoin: round;
}

.countries {
  fill: none;
  stroke: #000;
  stroke-linejoin: round;
}

div.tooltip {   
  position: absolute;           
  text-align: center;           
  width: 150px;                  
  height: 25px;                 
  padding: 2px;             
  font-size: 10px;     
  background: #FFFFE0;
  border: 1px;      
  border-radius: 8px;   
  border-color: black;              
}        
</style>
<body>
<h1>Spot Corn Average Basis By County</h1>
Double click or mouse-wheel to zoom. Click and drag to move.

<div id="chart" class="chart"></div>
    <div id="legend" class="legend"></div>

    </body>

  <script type="text/javascript">
  var width = 940 ,
  height = 720;

  // Setting color domains(intervals of values) for our map

  var color_domain = [-100, -75, -50, -40, -30, -20, -10, 0, 10, 20, 500]
  var ext_color_domain = [-500, -100, -75, -50, -40, -30, -20, -10, 0, 10, 20]
  var legend_labels = ["-100 or lower", "-100 to -75", "-75 to -50", "-50 to -40", "-40 to -30", "-30 to -20", "-20 to -10", "-10 to 0", "0 to +10", "+10 to +20", "+20 or higher"]              
  var color = d3.scale.threshold()
  .domain(color_domain)
  .range(["#B71C1C", "#E53935", "#E64A19", "#F57C00", "#ffa726", "#fff59d", "#E6EE9C", "#9CCC65", "#689F38", "#388E3C", "#1B5E20"]);

  var div = d3.select("#chart").append("div")   
  .attr("class", "tooltip")               
  .style("opacity", 0);

  var svg = d3.select("#chart").append("svg")
  .attr("width", width)
  .attr("height", height)
  .style("margin", "10px auto")
  .call(d3.behavior.zoom().on("zoom", function () {
    svg.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")")
  }))
  .append("g")


  var path = d3.geo.path()

  //Reading map file and data

  queue()
  .defer(d3.json, "us.json")
  .defer(d3.csv, "basis.csv")
  .await(ready);

  //Start of Choropleth drawing

  function ready(error, us, data) {
   var rateById = {};
   var nameById = {};
var rate = {};

   data.forEach(function(d) {
    rateById[d.id] = +d.rate;
    nameById[d.id] = d.name;
    rate[d.id] = d.rate;
  });
console.log(nameById)
  //Drawing Choropleth

  svg.append("g")
  .attr("class", "region")
  .selectAll("path")
  .data(topojson.feature(us, us.objects.counties).features)
  //.data(topojson.feature(map, map.objects.russia).features) <-- in case topojson.v1.js
  .enter().append("path")
  .attr("d", path)
  .style ( "fill" , function (d) { var value = rateById[d.id]
    if (value) {
    return color (rateById[d.id]);
  } else { return "#E0E0E0"; 
  }
  })
  .style("opacity", 1)


  //Adding mouseevents
  .on("mouseover", function(d) {
    d3.select(this).transition().duration(1).style("opacity", 1);
    div.transition().duration(1)
    .style("opacity", 1)
    div.text(nameById[d.id] + " : " + rateById[d.id])
    .style("left", (d3.event.pageX) + "px")
    .style("top", (d3.event.pageY -30) + "px");
  })
  .on("mouseout", function() {
    d3.select(this)
    .transition().duration(100)
    .style("opacity", 1);
    div.transition().duration(100)
    .style("opacity", 0);
  });

  }

  // <-- End of Choropleth drawing

  //Adding legend for our Choropleth

var svg2 = d3.select("#legend")
    .append("svg")
    .attr("width", 150)
    .attr("height", 300);

   var legend = svg2.append("g.legend")
   .data(ext_color_domain)
   .enter().append("g")
   .attr("class", "legend1")

   var ls_w = 20, ls_h = 20;

    legend.append("rect")
    .attr("x", 20)
    .attr("y", function(d, i){ return height - (i*ls_h) - 2*ls_h;})
    .attr("width", ls_w)
    .attr("height", ls_h)
    .style("fill", function(d, i) { return color(d); })
    .style("opacity", 1);

  legend.append("text")
  .attr("x", 50)
  .attr("y", function(d, i){ return height - (i*ls_h) - ls_h - 4;})
  .text(function(d, i){ return legend_labels[i]; });



  </script>


</body>

【问题讨论】:

    标签: javascript jquery html css d3.js


    【解决方案1】:

    您的“输入”选择错误:

    var legend = svg2.append("g.legend")
        .data(ext_color_domain)
        .enter().append("g")
        .attr("class", "legend1")
    

    append().data().enter().append() 的序列毫无意义。如果您查看API,您会看到data()

    将指定的数据数组与选定元素连接起来,返回一个表示更新选择的新选择。 (强调我的)

    因此,应该改为selectAll

    var legend = svg2.selectAll("g.legend")
        .data(ext_color_domain)
        .enter().append("g")
        .attr("class", "legend1")
    

    【讨论】:

    • 感谢您的回复。我进行了您建议的更改,现在我有了文本,但是没有出现矩形并且列表格式丢失了……还有什么我遗漏的吗? roachag.com/Portals/0/maps/basismap4.html
    • 由于这是一个不同的问题,请发布另一个问题。
    猜你喜欢
    • 2022-03-12
    • 2021-05-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-15
    • 1970-01-01
    • 1970-01-01
    • 2017-08-14
    • 1970-01-01
    相关资源
    最近更新 更多