首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用D3JS渲染一个普通的晶格?

如何用D3JS渲染一个普通的晶格?
EN

Stack Overflow用户
提问于 2015-02-16 19:56:31
回答 1查看 667关注 0票数 2

我期待着在D3JS中实现一种算法或布局,以呈现一个“通用”网格的图形,一个不一定是二项式的网格。

我想要获得的结果的一个例子是:

我想要将网格可视化为一个从下到上的层次结构,类似于树型结构。

我试图调整一个力量布局,但效果很差,特别是因为很难正确地定位层次结构的级别。

我对输入的形式没有任何限制,它可以更适合这个过程。

EN

回答 1

Stack Overflow用户

发布于 2015-02-17 10:13:56

你可以做这样的事情,但我不确定它有多大用处。它利用了cola.js库。

代码语言:javascript
复制
// Sample data set
        var json = {
            nodes: [
                    { "name": 'Beverage' },
                    { "name": 'nonAlcoholic' },
                    { "name": 'sparkling' },
                    { "name": 'alcoholic' },
                    { "name": 'hot' },
                    { "name": 'caffeinic' },
                    { "name": 'MineralWater' },
                    { "name": 'madeFromGrain' },
                    { "name": 'madeFromGrapes' },
                    { "name": 'HerbTea' },
                    { "name": 'Coffee' },
                    { "name": 'Cola' },
                    { "name": 'Beer' },
                    { "name": 'Wine' },
                    { "name": 'Champagne' },
                    { "name": '' }
                   ],
            links: [
                    { "source": 0, "target": 1},
                    { "source": 0, "target": 2},
                    { "source": 0, "target": 3},
                    { "source": 1, "target": 4},
                    { "source": 1, "target": 5},
                    { "source": 1, "target": 6},
                    { "source": 2, "target": 6},
                    { "source": 2, "target": 7},
                    { "source": 2, "target": 14},
                    { "source": 3, "target": 7},
                    { "source": 3, "target": 8},
                    { "source": 4, "target": 9},
                    { "source": 4, "target": 10},
                    { "source": 5, "target": 10},
                    { "source": 5, "target": 11},
                    { "source": 6, "target": 11},
                    { "source": 7, "target": 12},
                    { "source": 8, "target": 13},
                    { "source": 8, "target": 13},
                    { "source": 13, "target": 14},
                    { "source": 10, "target": 15},
                    { "source": 11, "target": 15},
                    { "source": 12, "target": 15},
                    { "source": 14, "target": 15},
                   ]
        };
  
        var width = 800, height = 600, n = 10000;
  
        var svg = d3.select('#vis').append('svg').attr('width', width).attr('height', height);

        var force = cola.d3adaptor()
                        .linkDistance(80)
                        .size([width, height])
                        .nodes(json.nodes)
                        .links(json.links)
                        .flowLayout("y", 25)
                        .on("tick", tick)
                        .start();
  
        var node = svg.selectAll("circle.node")
                       .data(json.nodes)
                     .enter().append("circle")
                       .attr("class", "node")
                       .attr("r", 5);

        var text = svg.selectAll("text.label")
                       .data(json.nodes)
                     .enter().append("text")
                       .attr("class", "label")
                       .text(function(d) { return d.name; });

        var link = svg.selectAll("line.link")
                       .data(json.links)
                     .enter().append("line")
                       .attr("class", "link");

        function tick() {
            link.attr("x1", function(d) { return d.source.x; })
                .attr("y1", function(d) { return d.source.y; })
                .attr("x2", function(d) { return d.target.x; })
                .attr("y2", function(d) { return d.target.y; });

            node.attr("cx", function(d) { return d.x; })
                .attr("cy", function(d) { return d.y; });

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

        function hover(d) {
            switch(d3.event.type) {
                case "mouseover": var tip = svg.append("g")
                                               .attr("class", "tip")
                                               .attr("transform", "translate(" + d3.event.x + "," + d3.event.y + ")");
                                  var rect = tip.append("rect")
                                                .attr("fill", "white");
                                  var text = tip.append("text")
                                                .text(d.name);
                                  var bounds = text.node().getBBox();
                                  rect.attr("x", bounds.x)
                                      .attr("y", bounds.y)
                                      .attr("width", bounds.width)
                                      .attr("height", bounds.height);
                                  
                                  break;
                case "mouseout":  svg.selectAll("g.tip")
                                      .remove();
                                  break;
                default: break;
            }
        }
代码语言:javascript
复制
        text {
            font: 10px sans-serif;
        }

        line {
            stroke: #000;
            stroke-width: 1.5px;
        }

        circle {
            stroke: #fff;
            stroke-width: 1.5px;
        }
代码语言:javascript
复制
<div id="vis"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="http://marvl.infotech.monash.edu/webcola/cola.v3.min.js"></script>

使用cola.js,您可以指定额外的约束来帮助正确地进行布局。现在,我对它施加的唯一约束是一个flowLayout参数。这样做的好处是布局是可重复的,并且使用d3 force布局实现类似的结果可能非常困难(尽管,公平地说,它并不打算以这种方式使用)。

我不会说这是一个很好的结果,但是除了手动确定节点位置,或者接受标准的d3力布局之外,这可能是最简单和最快的方法之一,以获得接近您想要的东西。

编辑:显示悬停是如何使用的。

代码语言:javascript
复制
// Sample data set
        var json = {
            nodes: [
                    { "name": 'Beverage' },
                    { "name": 'nonAlcoholic' },
                    { "name": 'sparkling' },
                    { "name": 'alcoholic' },
                    { "name": 'hot' },
                    { "name": 'caffeinic' },
                    { "name": 'MineralWater' },
                    { "name": 'madeFromGrain' },
                    { "name": 'madeFromGrapes' },
                    { "name": 'HerbTea' },
                    { "name": 'Coffee' },
                    { "name": 'Cola' },
                    { "name": 'Beer' },
                    { "name": 'Wine' },
                    { "name": 'Champagne' },
                    { "name": '' }
                   ],
            links: [
                    { "source": 0, "target": 1},
                    { "source": 0, "target": 2},
                    { "source": 0, "target": 3},
                    { "source": 1, "target": 4},
                    { "source": 1, "target": 5},
                    { "source": 1, "target": 6},
                    { "source": 2, "target": 6},
                    { "source": 2, "target": 7},
                    { "source": 2, "target": 14},
                    { "source": 3, "target": 7},
                    { "source": 3, "target": 8},
                    { "source": 4, "target": 9},
                    { "source": 4, "target": 10},
                    { "source": 5, "target": 10},
                    { "source": 5, "target": 11},
                    { "source": 6, "target": 11},
                    { "source": 7, "target": 12},
                    { "source": 8, "target": 13},
                    { "source": 8, "target": 13},
                    { "source": 13, "target": 14},
                    { "source": 10, "target": 15},
                    { "source": 11, "target": 15},
                    { "source": 12, "target": 15},
                    { "source": 14, "target": 15},
                   ]
        };
  
        var width = 800, height = 600, n = 10000;
  
        var svg = d3.select('#vis').append('svg').attr('width', width).attr('height', height);

        var force = cola.d3adaptor()
                        .linkDistance(80)
                        .size([width, height])
                        .nodes(json.nodes)
                        .links(json.links)
                        .flowLayout("y", 25)
                        .on("tick", tick)
                        .start();
  
        var link = svg.selectAll("line.link")
                       .data(json.links)
                     .enter().append("line")
                       .attr("class", "link");

          var node = svg.selectAll("circle.node")
                       .data(json.nodes)
                     .enter().append("circle")
                       .attr("class", "node")
                       .attr("r", 10)
                       .on("mouseover", hover)
                       .on("mouseout", hover);



        function tick() {
            link.attr("x1", function(d) { return d.source.x; })
                .attr("y1", function(d) { return d.source.y; })
                .attr("x2", function(d) { return d.target.x; })
                .attr("y2", function(d) { return d.target.y; });

            node.attr("cx", function(d) { return d.x; })
                .attr("cy", function(d) { return d.y; });


        }

        function hover(d) {
            switch(d3.event.type) {
                case "mouseover": 
                    console.log(d3.event);
                    var tip = svg.append("g")
                                               .attr("class", "tip")
                                               .attr("transform", "translate(" + d3.event.clientX + "," + d3.event.clientY + ")");
                                  var rect = tip.append("rect")
                                                .attr("fill", "white");
                                  var text = tip.append("text")
                                                .text(d.name);
                                  var bounds = text.node().getBBox();
                                  rect.attr("x", bounds.x)
                                      .attr("y", bounds.y)
                                      .attr("width", bounds.width)
                                      .attr("height", bounds.height);
                                  
                                  break;
                case "mouseout":  svg.selectAll("g.tip")
                                      .remove();
                                  break;
                default: break;
            }
        }
代码语言:javascript
复制
text {
            font: 10px sans-serif;
        }

        line {
            stroke: #000;
            stroke-width: 1.5px;
        }

        circle {
            stroke: #fff;
            stroke-width: 1.5px;
        }
代码语言:javascript
复制
<div id="vis"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="http://marvl.infotech.monash.edu/webcola/cola.v3.min.js"></script>

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28540912

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档