使用this JSFiddle作为我的示例,我的目的是使点击轴标签(组1,组2,组3)将打开数据中指定的相应链接。
我尝试将数据重新绑定到.ticks选项,但这仅适用于第一个轴标签。由于只将名称传递给轴映射,我不确定如何保留关系以向标签添加on('click'...)事件。
感谢您的时间和帮助。
var data = [{
"Items": [{
"Value": 3327,
"Name": {
"Value": "A"
},
}, {
"Value": 794,
"Name": {
"Value": "B"
},
}, {
"Value": 1999,
"Name": {
"Value": "C"
},
}, ],
"Type": "Group",
"Name": {
"Value": "Group 1"
},
"Link": "www.espn.com",
}, {
"Items": [{
"Value": 3317,
"Name": {
"Value": "A"
},
}, {
"Value": 787,
"Name": {
"Value": "B"
},
}, {
"Value": 2008,
"Name": {
"Value": "C"
},
}, ],
"Type": "Group",
"Name": {
"Value": "Group 2"
},
"Link": "http://www.stackoverflow.com",
}, {
"Items": [{
"Value": 3290,
"Name": {
"Value": "A"
},
}, {
"Value": 760,
"Name": {
"Value": "B"
},
}, {
"Value": 2019,
"Name": {
"Value": "C"
},
}, ],
"Type": "Group",
"Name": {
"Value": "Group 3"
},
"Link": "http://www.google.com",
}]
var variables = ['A', 'B', 'C'];
var width = 300;
var margin = {
left: 100
};
var height = 300;
var y0 = d3.scale.ordinal()
.rangeRoundBands([0, height], .1);
var y1 = d3.scale.ordinal();
var x = d3.scale.linear()
.range([0, width - margin.left]);
var yAxis = d3.svg.axis()
.scale(y0)
.orient('left');
var svg = d3.select('body').append('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('transform', 'translate(' + margin.left + ', 0)');
y0.domain(data.map(function (d) {
return d.Name.Value;
}));
y1.domain(variables).rangeRoundBands([0, y0.rangeBand()]);
x.domain([0, d3.max(data, function (d) {
return d3.max(d.Items, function (d) {
return d.Value;
});
})]);
svg.append('g')
.attr('transform', 'translate(0, 0)')
.call(yAxis);
var measures = svg.selectAll('.name')
.data(data)
.enter().append('g')
.attr('class', 'bar')
.attr('transform', function (d) {
return 'translate(0, ' + y0(d.Name.Value) + ')';
});
measures.selectAll('rect')
.data(function (d) {
return d.Items;
})
.enter().append('rect')
.attr('height', y1.rangeBand() - 1)
.attr('x', 0)
.attr('y', function (d) {
return y1(d.Name.Value)
})
.attr('width', function (d) {
return x(d.Value)
});
measures.selectAll('text')
.data(function (d) {
return d.Items;
})
.enter()
.append('text')
.attr('x', 10)
.attr('y', function (d) {
return y1(d.Name.Value) + y1.rangeBand() / 2
})
.text(function (d) {
if (d.Name.Value) {
return d.Name.Value + ' - ' + d.Value;
} else {
return d.Value;
}
})
.attr('dy', '.35em')
.style( 'fill', 'red' )
;
答案 0 :(得分:4)
我认为你是在正确的轨道上,因为可能已经意识到d3.svg.axis将规模上的域名绑定为刻度数据,即
var yAxis = d3.svg.axis()
.scale(y0)
和
y0.domain(data.map(function (d) {
return d.Name.Value;
}));
幸运的是,click
回调参数是数据本身(在本例中为d.Name.Value
)和当前d.Name.Value
的索引,因此data
中可以使用相同的索引。 1}}获取其链接,例如
d3.selectAll('.tick')
.on('click', function (d, i) {
console.log(data[i].Link)
})
答案 1 :(得分:1)
谢谢Mauricio Poppe。尝试您提出的解决方案,我发现至少在最新版本的 D3v6 中,第一个函数参数实际上代表鼠标事件。你的“d”有点误导我,因为我认为我可以直接传入一些“数据”。对我有用的方法与您的解决方案非常相似,但我猜使标准 D3 行为更加清晰:
d3.selectAll('.tick') .data(data) .on('click', (e, d) => { console.log(e); // e is the mouse click event console.log(d.Link); // d references the iterator object of data })