在树形图d3.js中解析json以获取不同的颜色

时间:2018-08-17 04:55:10

标签: javascript d3.js

我已点击this链接以供参考

但是此链接中的json不同。 我想解析:

[
    {\"name\":\"ABC\",\"amount\":489956},
    {\"name\":\"XYZ\",\"amount\":54554726}
]

我尝试使用此代码:

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

    var fader = function(color) {
        return d3.interpolateRgb(color, "#fff")(0.2);
    }, color = d3.scaleOrdinal(d3.schemeCategory20.map(fader)), format = d3
            .format(",d");

    var treemap = d3.treemap().tile(d3.treemapResquarify).size(
            [ width, height ]).round(true).paddingInner(1);

  var jsonResp = "{\"name\": \"schools\",\"children\":[{\"name\":\"ABC\",\"amount\":489956},{\"name\":\"XYZ\",\"amount\":54554726}]}";

    var data = JSON.parse(jsonResp);    
    var root = d3.hierarchy(data).eachBefore(
                function(d) {
                    d.data.id = (d.parent ? d.parent.data.id + "." : "")
                            + d.data.name;
                }).sum(sumBySize).sort(function(a, b) {
            return b.height - a.height || b.value - a.value;
        });

        treemap(root);

        var cell = svg.selectAll("g").data(root.leaves()).enter().append(
                "g").attr("transform", function(d) {
            return "translate(" + d.x0 + "," + d.y0 + ")";
        });

        cell.append("rect").attr("id", function(d) {
            return d.data.id;
        }).attr("width", function(d) {
            return d.x1 - d.x0;
        }).attr("height", function(d) {
            return d.y1 - d.y0;
        }).attr("fill", function(d) {
            return color(d.parent.data.id);
        });

        cell.append("clipPath").attr("id", function(d) {
            return "clip-" + d.data.id;
        }).append("use").attr("xlink:href", function(d) {
            return "#" + d.data.id;
        });

        cell.append("text").attr("clip-path", function(d) {
            return "url(#clip-" + d.data.id + ")";
        }).selectAll("tspan").data(function(d) {
            return d.data.name.split(/(?=[A-Z][^A-Z])/g);
        }).enter().append("tspan").attr("x", 4).attr("y", function(d, i) {
            return 13 + i * 10;
        }).text(function(d) {
            return d;
        });

        cell.append("title").text(function(d) {
            return  "Amount - "+format(d.value)+" ";
        });

        d3.selectAll("input").data([ sumBySize, sumByCount ], function(d) {
            return d ? d.name : this.value;
        }).on("change", changed);

        var timeout = d3.timeout(function() {
            d3.select("input[value=\"sumByCount\"]").property("checked",
                    true).dispatch("change");
        }, 2000);

        function changed(sum) {
            timeout.stop();
            treemap(root.sum(sum));
            cell.transition().duration(750).attr("transform", function(d) {
                return "translate(" + d.x0 + "," + d.y0 + ")";
            }).select("rect").attr("width", function(d) {
                return d.x1 - d.x0;
            }).attr("height", function(d) {
                return d.y1 - d.y0;
            });
        }
    });

    function sumBySize(d) {
        return d.amount;
    } 

但是对于解析后的json中的所有对象我都得到相同的颜色。我希望每个对象都具有不同的颜色,而无需更改上述json的结构。如何更改代码中的解析以获得每个对象的不同颜色?
我需要根据数字对json以及Crores or Lakhs中的金额进行分类,并在悬停时显示它。 我只是d3.js的初学者。

1 个答案:

答案 0 :(得分:0)

首先,您提供的代码存在几个问题:

  • 您从原始代码中删除了d3.json("flare.json", function(error, data) { ,但是忘记删除结尾的});导致错误
  • 您删除了其余代码中使用的sumByCount的定义,从而导致另一个错误

关于颜色问题,在此处设置矩形的颜色:

cell.append("rect").attr("id", function(d) {
            return d.data.id;
        }).attr("width", function(d) {
            return d.x1 - d.x0;
        }).attr("height", function(d) {
            return d.y1 - d.y0;
        }).attr("fill", function(d) {
            return color(d.parent.data.id);
        });

它由fill属性控制。这意味着d.parent.data.id

可能存在问题

d是数组root.leaves()的元素,如果在控制台中将其打印出来,则会看到d.parent.data.id与每个元素的'schools'相匹配。这就是色标返回相同颜色的原因。

如果直接使用d.data.id,并将示例中的html与数据一起使用,则会得到有效的代码(打印出root.leaves()):

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

var fader = function(color) {
    return d3.interpolateRgb(color, "#fff")(0.2);
  },
  color = d3.scaleOrdinal(d3.schemeCategory10.map(fader)),
  format = d3
  .format(",d");

var treemap = d3.treemap().tile(d3.treemapResquarify).size(
  [width, height]).round(true).paddingInner(1);


var jsonResp = "{\"name\": \"schools\",\"children\":[{\"name\":\"ABC\",\"amount\":489956},{\"name\":\"XYZ\",\"amount\":54554726}]}";

var data = JSON.parse(jsonResp);
var root = d3.hierarchy(data).eachBefore(
  function(d) {
    d.data.id = (d.parent ? d.parent.data.id + "." : "") +
      d.data.name;
  }).sum(sumBySize).sort(function(a, b) {
  return b.height - a.height || b.value - a.value;
});

treemap(root);
console.log(data);
console.log(root.leaves());

var cell = svg.selectAll("g").data(root.leaves()).enter().append(
  "g").attr("transform", function(d) {
  return "translate(" + d.x0 + "," + d.y0 + ")";
});

cell.append("rect").attr("id", function(d) {
  return d.data.id;
}).attr("width", function(d) {
  return d.x1 - d.x0;
}).attr("height", function(d) {
  return d.y1 - d.y0;
}).attr("fill", function(d) {
  return color(d.data.id);
});

cell.append("clipPath").attr("id", function(d) {
  return "clip-" + d.data.id;
}).append("use").attr("xlink:href", function(d) {
  return "#" + d.data.id;
});

cell.append("text").attr("clip-path", function(d) {
  return "url(#clip-" + d.data.id + ")";
}).selectAll("tspan").data(function(d) {
  return d.data.name.split(/(?=[A-Z][^A-Z])/g);
}).enter().append("tspan").attr("x", 4).attr("y", function(d, i) {
  return 13 + i * 10;
}).text(function(d) {
  return d;
});

cell.append("title").text(function(d) {
  return "Amount - " + format(d.value) + " ";
});

d3.selectAll("input").data([sumBySize, sumByCount], function(d) {
  return d ? d.name : this.value;
}).on("change", changed);

var timeout = d3.timeout(function() {
  d3.select("input[value=\"sumByCount\"]").property("checked",
    true).dispatch("change");
}, 2000);

function changed(sum) {
  timeout.stop();
  treemap(root.sum(sum));
  cell.transition().duration(750).attr("transform", function(d) {
    return "translate(" + d.x0 + "," + d.y0 + ")";
  }).select("rect").attr("width", function(d) {
    return d.x1 - d.x0;
  }).attr("height", function(d) {
    return d.y1 - d.y0;
  });
}

function sumByCount(d) {
  return d.children ? 0 : 1;
}

function sumBySize(d) {
  return d.amount;
}
<svg width="960" height="570"></svg>
<form>
  <label><input type="radio" name="mode" value="sumBySize" checked> Size</label>
  <label><input type="radio" name="mode" value="sumByCount"> Count</label>
</form>
<script src="https://d3js.org/d3.v4.min.js"></script>

但是这是一个快速解决方案,因为我没有时间完全分析这里发生的事情。我认为您应该花一些时间尝试完全理解您提供的链接中的代码,否则您可能会遇到很多问题其他问题。复制粘贴您不完全了解的内容通常会导致数小时的痛苦调试;)