Reputation: 31
I have used SVG polygon in the sunburst which I got from GitHub. The text that is rendered on the breadcrumb is not fitting the polygon. I have changed the width of the polygon but it isn't working. How do I wrap the text inside that svg:polygon?
This is the code:
var entering = g.enter().append("svg:g");
entering.append("svg:polygon")
.attr("width",100)//I have changed the width but it is not working
.attr("height",100)
.attr("points", breadcrumbPoints)
.style("fill", function(d) {
return color((d.children ? d : d.parent).name);
})
// .style("fill", function(d) { return colors[d.name]; });
entering.append("svg:text")
.attr("x", (b.w + b.t)/2)
.attr("y", b.h / 2)
.attr("dy", "0.35em")
.attr("text-anchor", "middle")
.text(function(d) {
return d.name;
});
The sunburst looks like this. The text is not fitting into the polygon breadcrumb and is not displayed correctly. Some part of the text has been cut.
Upvotes: 1
Views: 1904
Reputation:
To have the breadcrumbs update while moving mouse from left to right within a level(siblings) change var breadcrumbs to this:
var breadcrumbs = d3.select('#sequence').selectAll('.breadcrumb-custom')
.data(sequenceArray, function(d) { return d.name + d.depth; });
Upvotes: 1
Reputation: 31
Thanks everyone for your response. For increasing the size and for getting equal width of the breadcrumbs , I have changed the polygon points and my code now looks like this.
function breadcrumbPoints(d, i) {
var points = [];
points.push("0,0");
points.push(b.w*2 + ",0");
points.push(b.w*2 + b.t + "," + (b.h / 2));
points.push(b.w*2 + "," + b.h);
points.push("0," + b.h);
if (i > 0) { // Leftmost breadcrumb; don't include 6th vertex.
points.push(b.t + "," + (b.h / 2));
}
return points.join(" ");
}
// Update the breadcrumb trail to show the current sequence and percentage.
function updateBreadcrumbs(nodeArray, percentageString) {
// Data join; key function combines name and depth (= position in sequence).
var g = d3.select("#trail")
.selectAll("g")
.data(nodeArray, function(d) { return d.name + d.depth; });
// Add breadcrumb and label for entering nodes.
var entering = g.enter().append("svg:g");
entering.append("svg:polygon")
.attr("points", breadcrumbPoints)
.style("fill", function(d) { return color((d.children ? d : d.parent).name); })
// .style("fill", function(d) { return colors[d.name]; });
entering.append("svg:text")
.attr("x", (b.w + b.t/2))
.attr("y", b.h /2)
.attr("dy", "0.36em")
.attr("text-anchor", "middle")
.text(function(d) { return d.name; })
.style("fill", "white");
// Set position for entering and updating nodes.
g.attr("transform", function(d, i) {
return "translate(" + i * (b.w + b.s)*2+ ", 0)";
});
// Remove exiting nodes.
g.exit().remove();
// Now move and update the percentage at the end.
d3.select("#trail").select("#endlabel")
.attr("x", (nodeArray.length + 0.5) * (b.w*2 + b.s))
.attr("y", b.h / 2)
.attr("dy", "0.36em")
.attr("text-anchor", "middle")
.text(percentageString)
.style("fill", "green")
// Make the breadcrumb trail visible, if it's hidden.
d3.select("#trail")
.style("visibility", "");
}
Upvotes: 0
Reputation: 2229
The approach I would take to solve this issue is to use plain html and css. Let css take care of arranging the elements by using a small set of rules.
Instead of a svg lets create a container for the breadcrumbs
<div id="main">
<div id="sequence-container">
<div id="sequence" class="breadcrumbs-container"></div>
</div>
<!-- rest of html -->
</div>
Lets update a little your mouseover
function:
function mouseover(d) {
// ...
var sequenceArray = getAncestors(d);
// updateBreadcrumbs(sequenceArray, percentageString); remove this!
var breadcrumbs = d3.select('#sequence').selectAll('.breadcrumb-custom')
.data(sequenceArray); // join data
// usual update pattern
breadcrumbs.exit().remove();
breadcrumbs.attr('class', 'breadcrumb-custom')
breadcrumbs.enter()
.append('li')
.attr('class', 'breadcrumb-custom')
.append('a')
.style('background', function (d) {
return color((d.children ? d : d.parent).name);
})
.style('border-left-color', function (d) {
return color((d.children ? d : d.parent).name);
})
.html(function (d) {
return d.name
});
// ...
}
And we will also need to update the mouseleave
function:
function mouseleave(d) {
// ...
// Remove breadcrumbs
var breadcrumbs = d3.select('#sequence').selectAll('.breadcrumb-custom')
.data([]);
breadcrumbs.exit().remove();
// ...
}
You had a function in charge of breadcrumb initialization, we will also need to remove the call to the function:
function createVisualization(json) {
// initializeBreadcrumbTrail(); remove!
}
And now lets declare the css rules (got them from here https://css-tricks.com/triangle-breadcrumbs/) in order to get the visual aspect we want to achieve:
#sequence-container {
width: auto;
height: 80px;
}
.breadcrumbs-container {
list-style: none;
overflow: hidden;
font: 18px Helvetica, Arial, Sans-Serif;
}
.breadcrumbs-container li {
float: left;
}
.breadcrumbs-container li a {
color: white;
text-decoration: none;
font-size: 10px;
padding: 15px 0 10px 55px;
position: relative;
display: block;
float: left;
}
.breadcrumbs-container li a:after {
content: " ";
display: block;
width: 0;
height: 0;
border-top: 50px solid transparent;
border-bottom: 50px solid transparent;
border-left: 30px solid;
border-left-color: inherit;
position: absolute;
top: 50%;
margin-top: -50px;
left: 100%;
z-index: 2;
}
.breadcrumbs-container li a:before {
content: " ";
display: block;
width: 0;
height: 0;
border-top: 50px solid transparent;
border-bottom: 50px solid transparent;
border-left: 30px solid white;
position: absolute;
top: 50%;
margin-top: -50px;
margin-left: 1px;
left: 100%;
z-index: 1;
}
.breadcrumbs-container li:first-child a {
padding-left: 10px;
}
The end result looks like this:
Working fiddle: http://jsfiddle.net/zv3zvur6/1/
Upvotes: 0