我在D3中做过基本的事情,所以我对它没有深入的了解。 我用条形图创建了可缩放的圆形包装图。
以下是代码:
var xr, yr, xaxis, yaxis, bar, bg;
var svg = d3.select("svg"),
margin = 20,
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom;
diameter = +svg.attr("width"),
g = svg.append("g").attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")");
var color = d3.scaleLinear()
.domain([-1, 5])
.range(["hsl(152,80%,80%)", "hsl(228,30%,40%)"])
.interpolate(d3.interpolateHcl);
var pack = d3.pack()
.size([diameter - margin, diameter - margin])
.padding(2);
d3.json("occupation.json", function(error, root) {
if (error) throw error;
root = d3.hierarchy(root)
.sum(function(d) {
return d.size;
})
.sort(function(a, b) {
return b.value - a.value;
});
var focus = root,
nodes = pack(root).descendants(),
view;
var circle = g.selectAll("circle")
.data(nodes.filter(function(d) {
return d.height > 0
}))
.enter().append("circle")
.attr("class", function(d) {
return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root";
})
.style("fill", function(d) {
return d.children ? color(d.depth) : null;
})
.on("click", function(d) {
if (focus !== d) {
if (d.children) {
zoom(d), d3.event.stopPropagation();
} else {
var nextMonthVal = prompt("Please enter target value you want to set");
if (nextMonthVal) {
alert("You have set the target of Rs. " + nextMonthVal + " for next Month");
}
}
}
});
var leaf = g.selectAll(".bars")
.data(nodes.filter(function(d) {
return d.height == 1
}))
.enter()
.append("g")
.attr("x", 0)
.attr("y", 0)
.attr("height", function(d) {
return d.x + d.r
})
.attr("width", function(d) {
return d.y + d.r
})
.attr("class", "bars")
.each(function(d) {
drawBarData(this, this.__data__, d);
})
var text = g.selectAll(".label")
.data(nodes.filter(function(d) {
return d.height > 0
}))
.enter().append("text")
.attr("class", "label")
.style("fill-opacity", function(d) {
return d.parent === root ? 1 : 0;
})
.style("display", function(d) {
return d.parent === root ? "inline" : "none";
})
.text(function(d) {
return d.data.name + " " + d.data.size + " Rs.";
});
var node = g.selectAll("circle,.bars,.label");
svg
.style("background", color(-1))
.on("click", function() {
zoom(root);
});
zoomTo([root.x, root.y, root.r * 2 + margin]);
function zoom(d) {
var focus0 = focus;
focus = d;
var transition = d3.transition()
.duration(d3.event.altKey ? 7500 : 750)
.tween("zoom", function(d) {
var i = d3.interpolateZoom(view, [focus.x, focus.y, focus.r * 2 + margin]);
return function(t) {
zoomTo(i(t), focus);
};
});
transition.selectAll(".label")
.filter(function(d) {
return d.parent === focus || this.style.display === "inline";
})
.style("fill-opacity", function(d) {
return d.parent === focus ? 1 : 0;
})
.on("start", function(d) {
if (d.parent === focus) this.style.display = "inline";
})
.on("end", function(d) {
if (d.parent !== focus) this.style.display = "none";
});
}
function zoomTo(v, focus) {
var k = diameter / v[2];
view = v;
node.attr("transform", function(d) {
return "translate(" + (d.x - v[0]) * k + "," + (d.y - v[1]) * k + ")";
});
circle.attr("r", function(d) {
return d.r * k;
});
if (focus && focus.height == 1) {
var data2 = focus.children.map(function(d) {
return d.data
})
var data1 = []
rectwidth = focus.r,
rectheight = focus.r;
barsize = data2.length;
maxDataPoint = d3.max(data2, function(d) {
return d.size
});
var linearScale = d3.scaleLinear()
.domain([0, maxDataPoint])
.range([0, rectheight]);
for (var i = 0; i < data2.length; i++) {
data1.push({
name: data2[i].name,
size: linearScale(data2[i].size)
})
}
bg.attr("transform", function(d) {
console.log(d);
return "translate(" + (d.x - v[0]) * k + "," + (d.y - v[1]) * k + ")";
})
bar.attr("x", function(d, i) {
console.log("D ::: >", d);
return i * (rectwidth / data1.length);
})
.attr("y", function(d) {
return rectheight - d.size;
})
.attr("width", focus.r / data1.length - 2)
.attr("height", function(d) {
return d.size;
});
}
}
function drawBarData(ele, data, d) {
if (!data && !data.parent)
return;
var data2 = data.children.map(function(e) {
return e.data
})
var data1 = []
rectwidth = d.r,
rectheight = d.r;
barsize = data2.length;
maxDataPoint = d3.max(data2, function(d) {
return d.size
});
var linearScale = d3.scaleLinear()
.domain([0, maxDataPoint])
.range([0, rectheight]);
for (var i = 0; i < data2.length; i++) {
data1.push({
name: data2[i].name,
size: linearScale(data2[i].size)
})
}
bg = d3.select(ele).attr("transform", "translate(" + 0 + "," + 0 + ")").append("g")
.attr("class", "chart-wrapper")
.attr("transform", function(d) {
console.log('BG ::: >>>', d);
return "translate(" + -d.r / 2 + "," + -d.r / 2 + ")";
});
bar = bg.selectAll(".bar")
.data(data1)
.enter()
.append('rect')
.attr("class", "bar")
.attr("x", function(d, i) {
return i * (rectwidth / data1.length);
})
.attr("y", function(d) {
return rectheight - d.size;
})
.attr("width", d.r / data1.length - 2)
.attr("height", function(d) {
return d.size;
});
}
});
body {
padding: 50px;
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}
a {
color: #00B7FF;
}
.container {
width: 400px;
}
.node {
cursor: pointer;
}
.node:hover {
border: #000;
border-width: 1.5px;
}
.node--leaf {
color: white;
}
.label {
font: 11px "Helvetica Neue", Helvetica, Arial, sans-serif;
text-align: center;
text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff, 0 -1px 0 #fff;
}
.label,
.node--root {
pointer-events: none;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="960" height="960"></svg>
(json没有足够的空间 - 参考plunkr)
按照我的理解,我放置了条形图。但我也希望在每个节点的焦点上放大条形图。我不知道该怎么做。
如果有人有想法或解决方案,请帮助我。