1

我有这个 geojson,收集我需要显示的值(subindex_1 等)和地理数据。

{"type": "FeatureCollection","features": [{ "type": "Feature", "id": 0, "properties": { "OBJECTID": 1454, "STAT_LEVL_": 2, "NUTS_ID": "AT11", "SHAPE_Leng": 6.10844425190757, "SHAPE_Area": 0.471234982131153, "subindex_1": 0.196981355, "categories": 4.0, "subindex_2": 0.414249207, "categori_1": 4.0, "subindex_3": -0.214948039, "categori_2": 3.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 17.064420928067833, 48.118214904109713 ], [ 17.06623558686395, 48.03111128189601 ], [ 17.091640810009615, 47.708102016186864 ], [ 16.746855638747039, 47.680882134245081 ], .... ] ] } },

每个子索引都连接到一个类别,该类别决定颜色类别

d3.json("eu.geo.json", function(world) {    
  svg.selectAll("path")
  .data(world.features)
  .enter().append("path")
  .attr("d", path)
  .attr("class", function(d) { return "nut cat" + d.properties.categories; })

只要我只显示一个子索引,它就可以正常工作,并且生成的图像很好。

现在我想不通的是,当我选择例如 subindex_2(categori_1) 时,如何根据新类别获取每个欧盟区域的类别变化。类是五个并且是固定的,所以 AT11 应该从 .cat4 更改为 .cat3

d3.selectAll("input").on("change", change(world));
function change(d){
    if(this.value == 'subindex_2') {
             //  alert("color change here");
             }

有什么帮助吗?正如您从问题中看到的那样,我对 d3 很陌生,可能我要问的问题很明显,但是在一天的搜索中,我还没有弄清楚该怎么做。


编辑:我会尽力解释得更好。我有一个带有 ID 的 geojson 表和三列给出的类别,说明该区域应该出现在哪个类别中:

     ID  |  C1  | C2  | C3  |  geodata   
  ----------------------------
    AT11 |   1  |  2  |  3  |  ...
    FR30 |   1  |  3  |  1  |  ...    
    RO52 |   5  |  4  |  3  |  ...

1:red
2:orange
3:yellow
4:green
5:blue

我需要点击从 C1 到 C2 或从 C3 到 C1 或任何可能的组合来改变等值线。哪一个是最好的解决方案?我应该为每条路径分配 ID 吗?有没有办法用 d3.js 自动做到这一点?

这是我到目前为止的完整代码。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>

body {
  background: #fcfcfa;
}

.stroke {
  fill: none;
  stroke: #000;
  stroke-width: 3px;
}

.fill {
  fill: #fff;
}

.graticule {
  fill: none;
  stroke: #777;
  stroke-width: .5px;
  stroke-opacity: .5;
}

.land {
  fill: #222;
}

.boundary {
  fill: none;
  stroke: #fff;
  stroke-width: .5px;
}
.tooltip {
  position: absolute;
  background: rgba(200,200,200,0.75);
  border: 1px solid #ddd;
  padding: 5px 12px;
  border-radius: 5px;
  box-shadow: 2px 2px 2px rgba(120,120,120,0.55);
  text-shadow: 0 1px 0 #eee;
}

  .tooltip-title{
    font-weight: bold;
    color: #333;
    margin-bottom: 5px;
  }

  .sub1 {
    font-size: 18px;
  }
  .sub2 {
    font-size: 18px;
  }
  .sub3 {
    font-size: 18px;
  }
  .hide{
    font-size:0px;
  }
.cat1{
  fill: #f00;
  stroke: #555;
  stroke-width: .2px;
}
.cat1.hover{
    fill: rgba(255,150,150,0.50);
}
.cat2{
  fill: #fd0;
  stroke: #555;
  stroke-width: .2px;
}
.cat2.hover{
    fill: rgba(255,200,150,0.50);
}
.cat3{
  fill: #ff0;
  stroke: #555;
  stroke-width: .2px;
}
.cat3.hover{
    fill: rgba(255,255,150,0.50);
}
.cat4{
  fill: #df0;
  stroke: #555;
  stroke-width: .2px;
}
.cat4.hover{
    fill: rgba(200,255,150,0.50);
}
.cat5{
  fill: #0f0;
  stroke: #555;
  stroke-width: .2px;
}
.cat5.hover{
    fill: rgba(150,255,150,0.50);
}
.hover {
    stroke: #fff;
    stroke-width: 1px;
}
form {
  position: absolute;
  right: 10px;
  top: 10px;
}
</style>
</head>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/d3.geo.projection.v0.min.js"></script>
<form>
  <label><input type="radio" name="mode" value="sub1" checked> subindex_1</label>
  <label><input type="radio" name="mode" value="sub2"> subindex_2</label>
  <label><input type="radio" name="mode" value="sub3"> subindex_3</label>
</form>
<script>
var index = 'subindex_1';
var width = 860,
    height = 860;

var projection = d3.geo.sinuMollweide()
    .center([-5, 0])
    .scale(1035)
    .translate([width / 2, height / 2])
    .precision(.1);

var path = d3.geo.path()
    .projection(projection);

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

tooltip.append("div")
    .attr("class", "tooltip-title");
tooltip.append("div")
    .attr("class", "sub1");
tooltip.append("div")
    .attr("class", "sub2");
tooltip.append("div")
    .attr("class", "sub3");


var graticule = d3.geo.graticule();

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

svg.append("defs").append("path")
    .datum({type: "Sphere"})
    .attr("id", "sphere")
    .attr("d", path);

svg.append("use")
    .attr("class", "stroke")
    .attr("xlink:href", "#sphere");

svg.append("use")
    .attr("class", "fill")
    .attr("xlink:href", "#sphere");

svg.append("path")
    .datum(graticule)
    .attr("class", "graticule")
    .attr("d", path);


d3.json("eu.geo.json", function(world) {

    svg.selectAll("path")
    .data(world.features)
    .enter().append("path")
    .attr("d", path)
    .attr("class", function(d) { return "nut cat" + d.properties.categories; })
    .attr("class1", function(d) { return "cat" + d.properties.categori_1; })
    .attr("class2", function(d) { return "cat" + d.properties.categori_2; })
    .on("mouseenter", function(d) {


    d3.select(this).classed('hover', true);
          tooltip.transition()
            .duration(100)
            .style("opacity", 1);
          tooltip.select('.tooltip-title')
            .text(d.properties.NUTS_ID);
          tooltip.select('.sub1')
            .text("subindex_1: " + d.properties.subindex_1); 
          tooltip.select('.sub2')
            .text("subindex_2: " + d.properties.subindex_2);
          tooltip.select('.sub3')   
            .text("subindex_3: " + d.properties.subindex_3 );
        })
        .on("mousemove", function(d) {
          tooltip.style("left", (d3.event.pageX+5) + "px")
            .style("top", (d3.event.pageY+5) + "px");
        })
        .on("mouseleave", function(d) {
            d3.select(this).classed('hover', false);
            tooltip.transition()
            .duration(100)
            .style("opacity", 0);
        });
    d3.selectAll("input").on("change", change(world));

    function change(d){
        if(this.value == 'sub1') {
            d3.selectAll('.sub1').classed('hide', false);
            d3.selectAll('.sub2').classed('hide', true);
            d3.selectAll('.sub3').classed('hide', true);
        };
        if(this.value == 'sub2') {
            //svg.selectAll("path").classed('cat' + d.properties.categori_1, true);
            d3.selectAll('.sub1').classed('hide', true);
            d3.selectAll('.sub2').classed('hide', false);
            d3.selectAll('.sub3').classed('hide', true);
        };
        if(this.value == 'sub3'){
            svg.selectAll("path").classed('cat' + d.properties.categori_2, true);
            d3.selectAll('.sub1').classed('hide', true);
            d3.selectAll('.sub2').classed('hide', true);
            d3.selectAll('.sub3').classed('hide', false);
        }
    }
});

d3.select(self.frameElement).style("height", height + "px");


</script>
<div>

</div>
</body>
</html>
4

1 回答 1

0

我知道这比看起来要容易得多,我不知何故陷入了尝试在 json 之外使用不同的功能并尝试通过正常编程来解决它,而实际上,d3 的工作方式很好,它实际上只是一行我需要,所以我只是做了这个改变:

d3.selectAll("input").on("change", function change(world)
{
  if(this.value == 'sub1') {
    d3.selectAll('path.nut').attr('class', function(d) { return "nut cat" + d.properties.categories;});
  };
  if(this.value == 'sub2') {
    d3.selectAll('path.nut').attr('class', function(d) { return "nut cat" + d.properties.categori_1;});
  };
  if(this.value == 'sub3'){
    d3.selectAll('path.nut').attr('class', function(d) { return "nut cat" + d.properties.categori_2;});
   };
}
);

感谢 mccannf 的评论,它真的让我走上了通往解决方案的正确道路。

于 2013-05-24T09:15:58.507 回答