kingmakerking
kingmakerking

Reputation: 2089

Fit the d3js graph in a simple html page

I am trying to use the example from here, and my files are as follows:

index.html

<!DOCTYPE html>
<html>
<head>
<title>Test Page</title>
<meta charset="utf-8">
<style>

.node circle {
  fill: #999;
}

.node text {
  font: 10px sans-serif;
}

.node--internal circle {
  fill: #555;
}

.node--internal text {
  text-shadow: 0 1px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff;
}

.link {
  fill: none;
  stroke: #555;
  stroke-opacity: 0.4;
  stroke-width: 1.5px;
}

html, body {
    height: 100%;
}

html {
    display: table;
    margin: auto;
}

body {
    display: table-cell;
    vertical-align: middle;
}

</style>
</head>
<body>
<svg width="960" height="2000"></svg>
<script src="d3.js"></script>
<script>

var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height"),
    g = svg.append("g").attr("transform", "translate(40,0)");

var tree = d3.cluster()
    .size([height, width - 160]);

var stratify = d3.stratify()
    .parentId(function(d) { return d.id.substring(0, d.id.lastIndexOf(".")); });

d3.csv("test.csv", function(error, data) {
  if (error) throw error;

  var root = stratify(data)
      .sort(function(a, b) { return (a.height - b.height) || a.id.localeCompare(b.id); });

  tree(root);

  var link = g.selectAll(".link")
      .data(root.descendants().slice(1))
    .enter().append("path")
      .attr("class", "link")
      .attr("d", function(d) {
        return "M" + d.y + "," + d.x
            + "C" + (d.parent.y + 100) + "," + d.x
            + " " + (d.parent.y + 100) + "," + d.parent.x
            + " " + d.parent.y + "," + d.parent.x;
      });

  var node = g.selectAll(".node")
      .data(root.descendants())
    .enter().append("g")
      .attr("class", function(d) { return "node" + (d.children ? " node--internal" : " node--leaf"); })
      .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })

  node.append("circle")
      .attr("r", 2.5);

  node.append("text")
      .attr("dy", 3)
      .attr("x", function(d) { return d.children ? -8 : 8; })
      .style("text-anchor", function(d) { return d.children ? "end" : "start"; })
      .text(function(d) { return d.id.substring(d.id.lastIndexOf(".") + 1); });
});

</script>
</body>
</html>

and test.csv

id
country
country.USA
country.Canada
country.Russia
country.China
country.India
country.England
country.USA.Wisconsin
country.USA.Wisconsin.Madison
country.USA.Washington DC
country.Canada.Toronto
country.Canada.Ottawa
country.Russia.St Petersburg
country.India.Karnataka
country.India.Maharashtra
country.India.Delhi
country.India.Karnataka.Bangalore
country.India.Karnataka.Bangalore.city
country.India.Karnataka.Bangalore.rural
country.India.Karnataka.Mysore
country.India.Karnataka.Mangalore
country.India.Maharashtra.Mumbai
country.India.Maharashtra.Pune

The resulting output is cutting off the first node, i.e. instead of country, it is displaying just ountry as highlighted in the screenshot below: enter image description here

How to resolve this? This is just a sample, I have actual csv with the name of the nodes of length 10 Characters. How to auto-adjust the final output.

Upvotes: 0

Views: 147

Answers (2)

Ian
Ian

Reputation: 34489

Your line with the g defined in it, you probably just want to increase the x translation.

g = svg.append("g").attr("transform", "translate(40,0)");

becomes

g = svg.append("g").attr("transform", "translate(60,0)");

This moves the group which contains the entire visualization over some additional pixels. If you want to get clever about it you could actually measure the length of the string "country" and translate by that amount. For example:

const countryText = g.append("g")
                     .attr("class", "node") //apply all the same classes to ensure css rules match
                     .append("text")
                    .text("country");

const width = countryText.node().getComputedTextLength()
g.attr("transform", `translate(${width}, 0)`);

Server Side: A word of warning about measuring strings though. This is only supported in an environment with a browser, which can make server side rendering (or automated tests that use something like Node) very difficult to work with.

Upvotes: 3

Gerardo Furtado
Gerardo Furtado

Reputation: 102174

If you look at Bostock's code, you can see that he's appending everything to a group, which is being translated 40 pixels to the right:

g = svg.append("g").attr("transform", "translate(40,0)");

Solution: translate more than that:

g = svg.append("g").attr("transform", "translate(50,0)");

Here is your updated bl.ocks: https://bl.ocks.org/anonymous/c873ba1afc1d58a1ea5a13a093468d39

Upvotes: 1

Related Questions