Reputation: 642
I'm trying to add data-driven hyperlinks to the y-axis labels for some D3.js charts that I'm creating. However, despite my best efforts to search online for a solution to this problem, I haven't yet found an exact solution (or I'm misunderstanding something in the solutions I've seen).
To keep things simple, I created a basic horizontal bar chart to use as an example. Here's the code:
var table = [
{ id: 1, name: 'Entity 1', value: 10 },
{ id: 2, name: 'Entity 2', value: 20 },
{ id: 3, name: 'Entity 3', value: 30 },
];
var height = 100;
var width = 300;
var leftMargin = 100;
var rightMargin = 10;
var topMargin = 10;
var bottomMargin = 50;
var x = d3.scale.linear()
.domain([0, 30])
.range([0, width]);
var y = d3.scale.ordinal()
.domain(table.map(function(d, i) {
return d.name; }))
.rangeRoundBands([0, height]);
var chart = d3
.select('body')
.append('svg')
.attr('height', height + topMargin + bottomMargin)
.attr('width', width + leftMargin + rightMargin);
var bars = chart
.selectAll('rect')
.data(table)
.enter()
.append('rect')
.attr('x', x(0) + leftMargin)
.attr('y', function(d, i) {
return y(d.name) + topMargin; })
.attr('height', y.rangeBand())
.attr('width', function(d, i) {
return x(d.value); });
var xAxis = d3.svg
.axis()
.scale(x)
.orient('bottom');
chart
.append('g')
.attr("transform", "translate(" + leftMargin + "," + (height + 15) + ")")
.call(xAxis);
var yAxis = d3.svg
.axis()
.scale(y)
.orient('left');
chart
.append('g')
.attr("transform", "translate(" + (leftMargin - 5) + "," + topMargin + ")")
.call(yAxis);
Here is the chart that this code produces (and yes, I've intentionally left it unstyled to keep things simple):
Essentially, what I need is for someone to demonstrate how to modify this code so that the y-axis labels are hyperlinks of the format "http://www.test.com/entity/{entityID}", where "{entityID"} is the integer ID associated with each row of the data".
I'm fine with either svg:a hyperlinks or a javascript on-click solution.
I've already looked at solutions that involve making the plot elements (e.g. the bars) hyperlinkable, but that solution doesn't solve this specific problem. In addition, I have multiple charts on the same page, so I'm not certain that a solution involving d3.selectAll('text') will work, unless there is a way to filter it to just the y-axis labels on a specific chart.
Any help you can provide would be greatly appreciated!
Upvotes: 3
Views: 224
Reputation: 15237
I feel like the selectAll
is the way to go. If you don't want to select all text elements, just add a class to the text or one of the text containers.
chart
.append('g')
.attr("transform", "translate(" + (leftMargin - 5) + "," + topMargin + ")")
.attr("class", "entityLink") //***THIS IS NEW***
.call(yAxis);
//*** THIS IS NEW ***
d3.selectAll(".entityLink text")
.on("click", function() { alert("hooray"); });
css
.entityLink text {
fill: blue;
cursor: pointer;
}
full example: https://jsfiddle.net/memrr22q/
You'll have to figure out how to get the right data into the click event, but seems fairly easy.
Upvotes: 2