gpt4 book ai didi

javascript - 在 RAW 中添加 d3.js 交互式可缩放树形图

转载 作者:行者123 更新时间:2023-12-03 09:14:53 25 4
gpt4 key购买 nike

有没有办法在RAW中添加可缩放树形图。使用 d3.js 的进入-更新-退出模式在 RAW 中没有意义,因此如果没有此功能,是否可以在 RAW.js 中添加 d3.js 可缩放树形图

RAW文档位于adding new chart

In this way, D3's enter-update-exit pattern does not make too much sense within RAW's charts, since the selection is always empty when passed to the draw function. Since RAW is meant to be a tool for the production of non-interactive visualizations, to be elaborated using vector-graphics tools, this should not be perceived as a limitation, but, at the contrary, as a way to simplify charts' drawing code.

最佳答案

我已经能够在 RAW 中添加可缩放树形图。以下是代码。

zoomableTreemap.js

(function(){

var tree = raw.models.tree();

var chart = raw.chart()
.title('Zoomable Treemap')
.description(
"A space filling visualization of data hierarchies and proportion between elements. The different hierarchical levels create visual clusters through the subdivision into rectangles proportionally to each element's value. Treemaps are useful to represent the different proportion of nested hierarchical data structures.<br/>Based on <a href='http://bl.ocks.org/mbostock/4063582'>http://bl.ocks.org/mbostock/4063582</a>")
.thumbnail("/raw/imgs/treemap.png")
.category('Hierarchies')
.model(tree)

var rawWidth = chart.number()
.title('Width')
.defaultValue(100)
.fitToWidth(true)

var rawHeight = chart.number()
.title("Height")
.defaultValue(500)

var padding = chart.number()
.title("Padding")
.defaultValue(0)

var colors = chart.color()
.title("Color scale")

chart.draw(function (selection, root){

root.name = 'ZoomableTree';

var margin = {top: 20, right: 0, bottom: 0, left: 0},
width = +rawWidth(),
height = +rawHeight() - margin.top - margin.bottom,
formatNumber = d3.format(",d"),
transitioning;

var x = d3.scale.linear()
.domain([0, width])
.range([0, width]);

var y = d3.scale.linear()
.domain([0, height])
.range([0, height]);

console.log(padding());
console.log(+padding());
var treemap = d3.layout.treemap()
.padding(+padding())
.children(function(d, depth) { return depth ? null : d._children; })
.sort(function(a, b) { return a.value - b.value; })
.ratio(height / width * 0.5 * (1 + Math.sqrt(5)))
// Values are required in d3 treemap layout
// and our DB table do not have values field in it, so we are going to use 1 for all nodes.
// The value decides the size/area of rectangle in d3 treemap layout so effectively we are going to have
// even sized rectangles
.value(function(d) { return 1; })
.round(false);

var svg = selection
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.bottom + margin.top)
.style("margin-left", -margin.left + "px")
.style("margin.right", -margin.right + "px")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.style("shape-rendering", "crispEdges")


var grandparent = svg.append("g")
.attr("class", "grandparent");

grandparent.append("rect")
.attr("y", -margin.top)
.attr("width", width)
.attr("height", margin.top)
.style("fill", function (d) { return colors()(d.color); })
.style("stroke","#fff")

grandparent.append("text")
.attr("x", 6)
.attr("y", 6 - margin.top)
.attr("dy", ".75em");

initialize(root);
//console.log(root);
//throw '';
accumulate(root);
layout(root);
display(root);

function initialize(root) {
root.x = root.y = 0;
root.dx = width;
root.dy = height;
root.depth = 0;
}

// Aggregate the values for internal nodes. This is normally done by the
// treemap layout, but not here because of our custom implementation.
// We also take a snapshot of the original children (_children) to avoid
// the children being overwritten when when layout is computed.
function accumulate(d) {
return (d._children = d.children)
? d.value = d.children.reduce(function(p, v) { return p + accumulate(v); }, 0)
: d.value;
}

// Compute the treemap layout recursively such that each group of siblings
// uses the same size (1×1) rather than the dimensions of the parent cell.
// This optimizes the layout for the current zoom state. Note that a wrapper
// object is created for the parent node for each group of siblings so that
// the parent’s dimensions are not discarded as we recurse. Since each group
// of sibling was laid out in 1×1, we must rescale to fit using absolute
// coordinates. This lets us use a viewport to zoom.
function layout(d) {
if (d._children) {
//console.log(d);
//throw 'stop';
treemap.nodes({_children: d._children});
d._children.forEach(function(c) {
//console.log(d);
c.x = d.x + c.x * d.dx;
c.y = d.y + c.y * d.dy;
c.dx *= d.dx;
c.dy *= d.dy;
c.parent = d;
//console.log(c);
layout(c);
});
}
}

function display(d) {
grandparent
.datum(d.parent)
.on("click", transition)
.select("text")
.text(name(d));

var g1 = svg.insert("g", ".grandparent")
.datum(d)
.attr("class", "depth");

var g = g1.selectAll("g")
.data(d._children)
.enter().append("g");

g.filter(function(d) { return d._children; })
.classed("children", true)
.on("click", transition);

g.selectAll(".child")
.data(function(d) { return d._children || [d]; })
.enter().append("rect")
.attr("class", "child")
.call(rect);

g.append("rect")
.attr("class", "parent")
.call(rect)
.append("title")
.text(function(d) { return formatNumber(d.value); })
.style("fill", function (d) { return colors()(d.color); })
.style("stroke","#fff")

g.append("text")
.attr("dy", ".75em")
.text(function(d) { return d.name; })
.call(text);

function transition(d) {
if (transitioning || !d) return;
transitioning = true;

var g2 = display(d),
t1 = g1.transition().duration(750),
t2 = g2.transition().duration(750);

// Update the domain only after entering new elements.
x.domain([d.x, d.x + d.dx]);
y.domain([d.y, d.y + d.dy]);

// Enable anti-aliasing during the transition.
svg.style("shape-rendering", null);

// Draw child nodes on top of parent nodes.
svg.selectAll(".depth").sort(function(a, b) { return a.depth - b.depth; });

// Fade-in entering text.
g2.selectAll("text").style("fill-opacity", 0);

// Transition to the new view.
t1.selectAll("text").call(text).style("fill-opacity", 0);
t2.selectAll("text").call(text).style("fill-opacity", 1);
t1.selectAll("rect").call(rect);
t2.selectAll("rect").call(rect);

// Remove the old node when the transition is finished.
t1.remove().each("end", function() {
svg.style("shape-rendering", "crispEdges");
transitioning = false;
});
}

return g;
}

function text(text) {
text.attr("x", function(d) { return x(d.x) + 6; })
.attr("y", function(d) { return y(d.y) + 6; });
}

function rect(rect) {
rect.attr("x", function(d) { return x(d.x); })
.attr("y", function(d) { return y(d.y); })
.attr("width", function(d) { return x(d.x + d.dx) - x(d.x); })
.attr("height", function(d) { return y(d.y + d.dy) - y(d.y); })
.style("fill", function (d) { return colors()(d.color); })
.style("stroke","#fff");
}

function name(d) {
return d.parent
? name(d.parent) + "." + d.name
: d.name;
}


})
})();

chart.css

#chart {
background: #ddd;
}

text {
pointer-events: none;
}

.grandparent text {
font-weight: bold;
}

rect {
fill: none;
stroke: #fff;
}

rect.parent,
.grandparent rect {
stroke-width: 2px;
}

.grandparent rect {
fill: orange;
}

.grandparent:hover rect {
fill: #ee9700;
}

.children rect.parent,
.grandparent rect {
cursor: pointer;
}

.children rect.parent {
fill: #bbb;
fill-opacity: .5;
}

.children:hover rect.child {
fill: #bbb;
}

Index.html

只需在 raw 的索引页中包含 css 和 js 即可。

关于javascript - 在 RAW 中添加 d3.js 交互式可缩放树形图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31982847/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com