【发布时间】:2020-12-11 17:29:14
【问题描述】:
我有一个用 javascript 和 d3 创建的 svg 图形。
我希望能够在您单击任何圆圈时放大它。
我以为我可以通过在整个图表上添加一个变换来做到这一点,即:
翻译 - 移动整个图表,使所选圆圈位于中心
scale - 扩展图表,使选定的圆圈占据整个空间
我错了!
我读了一点,然后尝试了:
翻译 - 所以圆的原点在 0,0
scale - 所以圆的半径被扩大到svg的大小
再次平移 - 将圆移回中心 - 平移按比例因子缩放
还是不行!
谁能解释一下我是怎么做到的?
代码如下:
<!DOCTYPE html>
<head>
<script src="https://d3js.org/d3.v3.min.js"></script>
<style>
text {
font: 24px "Helvetica Neue", Helvetica, Arial, sans-serif;
text-anchor: middle;
pointer-events: none;
}
circle {
fill: #ccc;
stroke: black;
}
.node:hover circle {
fill: orange;
}
</style>
</head>
<body>
<script>
var json = {
"name": "flare",
"children": [
{
"name": "analytics",
"children": [
{
"name": "cluster",
"children": [
{"name": "AgglomerativeCluster", "value": 3938},
{"name": "CommunityStructure", "value": 3812},
{"name": "HierarchicalCluster", "value": 6714},
{"name": "MergeEdge", "value": 743}
]
},
{
"name": "graph",
"children": [
{"name": "BetweennessCentrality", "value": 3534},
{"name": "ShortestPaths", "value": 5914},
{"name": "SpanningTree", "value": 3416}
]
}
]
},
{
"name": "animate",
"children": [
{"name": "Easing", "value": 17010},
{"name": "FunctionSequence", "value": 5842},
{
"name": "interpolate",
"children": [
{"name": "ArrayInterpolator", "value": 1983},
{"name": "ObjectInterpolator", "value": 1629},
{"name": "PointInterpolator", "value": 1675},
{"name": "RectangleInterpolator", "value": 2042}
]
},
{"name": "ISchedulable", "value": 1041},
{"name": "Parallel", "value": 5176},
{"name": "TransitionEvent", "value": 1116},
{"name": "Tween", "value": 6006}
]
},
{
"name": "query",
"children": [
{"name": "AggregateExpression", "value": 1616},
{"name": "Expression", "value": 5130},
{"name": "ExpressionIterator", "value": 3617},
{"name": "Fn", "value": 3240},
{"name": "If", "value": 2732},
{"name": "IsA", "value": 2039},
{"name": "Literal", "value": 1214},
{"name": "Match", "value": 3748},
{"name": "Maximum", "value": 843},
{
"name": "methods",
"children": [
{"name": "add", "value": 593},
{"name": "where", "value": 299},
{"name": "xor", "value": 354},
{"name": "_", "value": 264}
]
},
{"name": "Minimum", "value": 843},
{"name": "Not", "value": 1554},
{"name": "Or", "value": 970},
{"name": "Query", "value": 13896},
{"name": "Range", "value": 1594},
{"name": "StringUtil", "value": 4130},
{"name": "Sum", "value": 791},
{"name": "Variable", "value": 1124},
{"name": "Variance", "value": 1876},
{"name": "Xor", "value": 1101}
]
}
]
}
var bleed = 100,
width = 960,
height = 960;
var pack = d3.layout.pack()
.sort(null)
.size([width, height + bleed * 2])
.padding(2);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(0," + -bleed + ")");
var data = pack.nodes(json)
// .filter(function(d) { return !d.children; })
;
var node = svg.selectAll(".node")
.data(data)
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
node.append("circle")
.attr("r", function(d) { return d.r; });
node.filter(function(d) { return !d.children; })
.append("g")
.attr("class", "label")
.append("text")
.text(function(d) { return d.name; })
.attr("dy", function(d) {
// Cheat and calculate text length here
d.ctl = 2 * d.r / Math.max(this.getComputedTextLength(), 24);
return ".35em";
});
node.selectAll(".label")
.attr("transform", d => "scale(" + d.ctl + "," + d.ctl + ")");
</script>
</body>
</html>
【问题讨论】: