svg - 如何使用d3.js更新现有svg元素的填充颜色?

标签 svg d3.js

因此,我尝试使用用Illustrator生成的.svg文件制作 map ,因为它是荷兰的 map ,区域不那么直接。

所有地区都有自己的#ID。

现在,我正在尝试根据数据集中每个区域的颜色进行着色。我可以在一个区域上通过CSS ive强制在区域上使用颜色,但这显然不是一个好的解决方案。

例如,如果我尝试选择(#id),然后更改.attr(“fill”,“red”);它不起作用。

如何根据数据集中的d [1]值使用d3.js通过id更新区域颜色?

文件:https://gist.github.com/gordonhatusupy/9466794

实时链接:http://www.gordonjakob.me/regio_map/

最佳答案

问题是您的Illustrator文件已经在各个<path>元素上指定了填充颜色,并且您的id值用于父<g>元素。子元素从父元素继承样式,但前提是子元素没有自己的值。

您可以做几件事来更改它:

  • 更改Illustrator文件,以使路径没有填充。然后,它们将继承父对象上设置的填充颜色。
  • 使用d3.selectAll("g#id path")d3.select("g#id").selectAll("path")直接选择路径;任一版本都会选择ID为“id”的<path>元素的后代的所有<g>元素。然后,您可以直接设置fill属性以覆盖Illustrator中的值。


  • 正如对主要问题的评论中所讨论的那样,如果您想更进一步,并实际上将数据连接到元素以供将来引用(例如,在事件处理程序中),最简单的方法是遍历数据集,选择每个元素,然后使用 .datum(newData) 方法将数据附加到每个元素:
    dataset.forEach(function(d){ //d is of form [id,value]
        d3.select("g#"+d[0]) //select the group matching the id
          .datum(d) //attach this data for future reference
          .selectAll("path, polygon") //grab the shapes
          .datum(d) //attach the data directly to *each* shape for future reference
          .attr("fill", colour(d[1]) ); //colour based on the data
    });
    

    http://jsfiddle.net/ybAj5/6/

    如果将来希望能够选择所有顶级<g>元素,建议您也给它们一个类,以便可以使用d3.select("g.region")进行选择。例如:
    dataset.forEach(function(d){ //d is of form [id,value]
        d3.select("g#"+d[0]) //select the group matching the id
          .datum(d) //attach this data for future reference
          .classed("region", true) //add a class, without erasing any existing classes
          .selectAll("path, polygon") //grab the shapes
          .datum(d) //attach the data directly to *each* shape for future reference
          .attr("fill", colour(d[1]) ); //colour based on the data
    });
    
    d3.selectAll("g.region")
      .on("click", function(d,i) {
             infoBox.html("<strong>" + d[0] + ": </strong>" + d[1] ); 
              //print the associated data to the page
      });
    

    示例实现:http://jsfiddle.net/ybAj5/7/

    尽管使用dataset.forEach似乎并没有使用d3的全部功能,但实际上比尝试一次附加整个数据集要简单得多-尤其是因为区域的结构存在这种可变性,其中一些区域已经嵌套<g>元素:
    //Option two: select all elements at once and create a datajoin
    d3.selectAll("g[id]") //select only g elements that have id values
        .datum(function(){
            var id=d3.select(this).attr("id"); 
            return [id, null]; })
            //create an initial [id, value] dataset based on the id attribute, 
            //with null value for now
        .data(dataset, function(d){return d[0];}) 
           //use the first entry in [id,value] as the key
           //to match the dataset with the placeholder data we just created for each
        .selectAll("path, polygon") //grab the shapes
        .datum(function(){
            return d3.select(this.parentNode).datum() ||
            d3.select(this.parentNode.parentNode).datum();
        }) //use the parent's data if it exists, else the grandparent's data
        .attr("fill", function(d){return d?colour(d[1]):"lightgray";});
             //set the colour based on the data, if there is a valid data element
             //else use gray.
    

    This fiddle显示了上面的代码,但我再次建议使用forEach方法。

    关于svg - 如何使用d3.js更新现有svg元素的填充颜色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22304196/

    相关文章:

    javascript - "import"使用 webpack ing d3 和 d3-cloud

    javascript - 使用 Javascript 连接 SVG 圆圈

    javascript - 如何使用 DC.js 使用以下数据类型渲染多折线图 - JAVASCRIPT (DC.js)

    javascript - 如何画一条线到从 Angular 派生的点?

    javascript - 为什么在 <table> 单元格中使用 SVG 强制表格为 100% 宽度?

    javascript - 最小交叉点布局算法

    javascript - 在 d3js 图表中的栏顶部添加文本 - 未添加 <text> 元素

    jquery - 在 jvectormap 中设置各个区域的样式

    google-chrome - 如何解决 Chrome 73 上 SVG 旋转 CSS 中的错误?

    html - 引用网站图标时,MIME 类型声明(使用 type 属性)是否是必需的?