Charlie Morton
Charlie Morton

Reputation: 787

Make d3 graphviz graph fit screen but not scale svg

I've made use of the basic zoom to fit window example in d3-graphviz

Which is great, however, I'd like to make it so that the svg doesn't automatically fill the whole screen. And doesn't effectively change the zoom when the svg increases.

If I transition the graph to have an extra node, it appears to zoom out (because the SVG has been made to fill the page)

If zoom is turned off then each node is a set size which is great (regardless of if the graph has 1 or 100 nodes).

I'd like to make it so that a new render will by default have a node of that original size. And if a transition involves adding new nodes or edges (thus increasing the size) the zoom is maintained.

edit: I guess I want to keep zoom enabled, the graph size to be equal to the window size, but not scale the svg itself although I may have that back to front

Upvotes: 1

Views: 1551

Answers (1)

magjac
magjac

Reputation: 937

Here is how you can do that:

<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="https://d3js.org/d3.v5.js"></script>
<script src="https://unpkg.com/@hpcc-js/[email protected]/dist/index.min.js"></script>
<script src="https://unpkg.com/[email protected]/build/d3-graphviz.js"></script>
<div id="graph" style="text-align: center;"></div>
<script>

var dotIndex = 0;
var margin = 20; // to avoid scrollbars
var width = window.innerWidth - margin;
var height = window.innerHeight - margin;
var graphviz = d3.select("#graph").graphviz()
    .transition(function () {
        return d3.transition("main")
            .ease(d3.easeLinear)
            .delay(500)
            .duration(1500);
    })
    .on("initEnd", render);

function render() {
    var dot = dots[dotIndex];
    graphviz
        .width(width)
        .height(height)
        .renderDot(dot)
        .on("end", function () {
            dotIndex = (dotIndex + 1) % dots.length;
            render();
        });
}

var dots = [
  `digraph  {
     node [style="filled"]
     a [fillcolor="#d62728"]
     b [fillcolor="#1f77b4"]
     a -> b
   }`,
  `digraph  {
     node [style="filled"]
     a [fillcolor="#d62728"]
     c [fillcolor="#2ca02c"]
     b [fillcolor="#1f77b4"]
     a -> b
     a -> c
   }`,
  `digraph  {
     node [style="filled"]
     a [fillcolor="#d62728"]
     b [fillcolor="#1f77b4"]
     c [fillcolor="#2ca02c"]
     a -> b
     a -> c
   }`,
  `digraph  {
    node [style="filled"]
     a [fillcolor="#d62728" shape="box"]
     b [fillcolor="#1f77b4" shape="parallelogram"]
     c [fillcolor="#2ca02c" shape="pentagon"]
     a -> b
     a -> c
     b -> c
   }`,
  `digraph  {
     node [style="filled"]
     a [fillcolor="yellow" shape="star"]
     b [fillcolor="yellow" shape="star"]
     c [fillcolor="yellow" shape="star"]
     a -> b
     a -> c
     b -> c
   }`,
  `digraph  {
    node [style="filled"]
     a [fillcolor="#d62728" shape="triangle"]
     b [fillcolor="#1f77b4" shape="diamond"]
     c [fillcolor="#2ca02c" shape="trapezium"]
     a -> b
     a -> c
     b -> c
   }`,
  `digraph  {
    node [style="filled"]
     a [fillcolor="#d62728" shape="box"]
     b [fillcolor="#1f77b4" shape="parallelogram"]
     c [fillcolor="#2ca02c" shape="pentagon"]
     a -> b
     a -> c
     b -> c
   }`,
  `digraph  {
     node [style="filled"]
     a [fillcolor="#d62728"]
     b [fillcolor="#1f77b4"]
     c [fillcolor="#2ca02c"]
     a -> b
     a -> c
     c -> b
   }`,
  `digraph  {
     node [style="filled"]
     b [fillcolor="#1f77b4"]
     c [fillcolor="#2ca02c"]
     c -> b
   }`,
  `digraph  {
     node [style="filled"]
     b [fillcolor="#1f77b4"]
   }`,
];

</script>

Upvotes: 1

Related Questions