I have some scale
var y = d3.scalePoint().domain(['a','b','c']).range([0,100]);
I can make an axis for that scale
var y_axis = svg.append("g").attr("class", "axis").call(d3.axisLeft(y));
How can I make the ticks be links?
It's pretty straightforward to
d3.selectAll('.tick').on('click', (d) => open_link_related_to(d))
But since I want to be able to download an SVG of the plot and have the links continue to work, the strategy would need to look more like:
d3.selectAll('.tick').insert("a").attr("xlink:href", (d) => text_link_related_to(d))
However, insert
doesn't wrap the tick in the <a>
element -- it gets inserted below. Is it possible to wrap the label with tickformat
or by some other means?
答案 0 :(得分:3)
我认为最干净,惯用的方式是使用each()
。您始终可以使用tickFormat()
来完成此操作,但似乎有点尴尬。
使用each()
方法,我们可以选择轴中的所有<text>
元素,然后选择其父元素(即<g>
),将<a>
元素附加到父项,最后将this
(即文本本身)移至<a>
元素:
d3.selectAll(".tick text").each(function(d) {
const a = d3.select(this.parentNode).append("a")
.attr("xlink:href", "https://www." + d + ".com");//change this for your function
a.node().appendChild(this);
});
这是一个演示(顺便说一下,堆栈片段不会打开链接):
const w = 500,
h = 100;
const svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("heiht", h);
const scale = d3.scalePoint()
.domain(['google', 'stackOverflow', 'amazon'])
.range([50, w - 50]);
const axis = svg.append("g")
.attr("transform", "translate(0,50)")
.call(d3.axisBottom(scale))
d3.selectAll(".tick text").each(function(d) {
const a = d3.select(this.parentNode).append("a")
.attr("xlink:href", "https://www." + d + ".com")
.attr("target", "_blank");
a.node().appendChild(this);
})
<script src="https://d3js.org/d3.v5.min.js"></script>
这里是一个JSFiddle,您可以在其中实际打开链接:https://jsfiddle.net/xmtdfcks/
如果您检查刻度线,您会发现类似以下的内容:
<g class="tick" opacity="1" transform="translate(250.5,0)">
<line stroke="#000" y2="6"></line>
<a href="https://www.stackOverflow.com" target="blank">
<text fill="#000" y="9" dy="0.71em">stackOverflow</text>
</a>
</g>