I understand you have to manually count the number of elements to fill the title, even if the count is already done using `y: "count"`. I wonder if there is a way to get the computed value instead of replicating the computation.
Sure, in the case of "count" there is no computation, but if we replace by "sum" (which is my use case) we have to compute wth d3.sum(...) for example. And if we want to try various aggregation methods (min, max, mean, etc.) we have to change the code in two places. Thus, the point of my comment was more: do you know if it's possible to "just" read the result of the binning computation, in order to DRY?
it is *possible* but not easy:
Plot.map(
{ title: (d) => d.map((d) => `${d} g`) },
((A) => ({ title: A.y, ...A }))(
Plot.binX(
{ y: "sum" },
{ x: "body_mass", y: "body_mass", thresholds: 20 }
)
)
)
the lambda function in the middle duplicates the y channel to the title channel, then Plot.map transforms the title channel into the full text label.
I find addTooltips usedful even outside of Plot on a classic SVG chart. But then I have a small issue: the svg id attr is replaced inconditionnally. Maybe generate the unique id (id_generator) only if .attr('id') is null, or else use the existing value instead.
An alternative would be to add a class name. Also, we could use DOM.uid instead of this custom generator. And, custom styles might be given as JS properties (camelCased) and would have to be converted to css properties (prefixed-name).
Great point (and suggestion)! I switched it to using a class so it doesn't overwrite the ID. If you have any examples of how you've used this outside of plot, I'd be interested to see them!
Thanks!
I have another unrelated comment / feature request. I want to update the text in the tooltips, and there is currently no way to do it without using internals of your implementation (I do `nodes.attr('__title', getTitle);`). Ideally, the API would provide a way to 1) update the title text (I cannot just update the content of the <title> element, since it's removed when creating the tooltip), and 2) if one tooltip is currently shown when the title text is updated, update its content
Example of how I've used the tooltips outside of plot: https://observablehq.com/@huggingface/participants-bubbles-chart (not published yet)
@Sylvain thanks for sharing! I don't have a great thought for updating the tooltips... Perhaps you could call addTooltips on update....? And @Fil I don't think so... it's a hit for accessibility that we should consider, but really noisy to have them both present. Maybe we could implement something like this, but it feels messy: https://stackoverflow.com/questions/8078388/hiding-title-tags-on-hover
I don't know, but I have a new request :P. On a Line plot (https://observablehq.com/@observablehq/plot-line) with multiple overlapping lines, the selected element (line) seems to be nearly random, and generally, it's not the nearest line from the mouse pointer.
Sorry for the delay! I finally figured this out by selecting the path elements in the chart and adding the style ("pointer-events", "visibleStroke"). Let me know if that solves things for ya!
I am using this plugin in a (choropleth) map and I am now able to highlight the border of the polygon I am hovering on with a static color.
I would like to ask whether and eventually how it is possible to have a color reflecting some attributes of the underlying data.
See initial map in https://observablehq.com/@xoolive/worldfirs
Oh, that's really interesting... I don't think I realized that Plot is still drawing the ticks outside of the domain! To avoid this, you might just want to filter the data down to the domain (imperfect, for sure).
Thanks for sharing this plugin, it's really useful! One question, is there a way to get the title be an HTML object, as in title: (d) => html`<p>My custom tooltip!</p>`. Thanks!
Sorry for the long delayed reply, @aguformoso - unfortunately, it's a bit tricky to get HTML elements inside of SVG element, so that isn't currently supported.
Ah, fun idea! I'll chew on that one.... For now, the opinionated multiple lines is a nice default, but it would be great to allow users to pass arbitrary SVG content that would be wrapped in a span...
Is there a way to position the tooltip.
One issue I have is, if the tool tip is tall that when it's at the top of the chart it can be blocked by code lines from other cells as the tip appears behind.
Possible options: Left, Center (default), Right, Top (default), Bottom, Auto (if tip overflows edges of chart it puts it inside the chart by setting left right, top or bottom.
Super useful tooltip, Thanks Mike.
@Brett great idea -- I don't have time to work on that right now, but feel free to suggest a change. You could also use the boundingbox approach used to keep it horizontally within the chart to keep it within the charting space vertically.
@jonathan you can definitely format your values! You'll just need to do that in your title attribute. Something like title: d => d3.format(".0f")(d.value)
I'm repeatedly running into a problem where my tooltip appears mostly off the left side of the plot, I can only see the edge of the rectangle background and about half of the rightmost letter in the tooltip text. I see the same problem on this page with the unemployment area chart. Is there a setting I can adjust to fix that? Ideally I'd like my tooltip to show up right near the mouse, no matter what the data looks like.
E A Watson -- sorry for the issue! I believe it was related to a change in Plot's legend, which @Fil has now fixed. Are you still running into this error?
@Mike the good news is that I'm no longer running into the error in this notebook, the bad news is that I'm still running into it in mine. This makes me think it's now something weird that I'm doing. I made sure to update the dependency, and as far as I can tell I'm using addTooltips correctly. I passed my plot to addTooltips(), and I specified how I wanted the label formatted in the same way the Biscoe/Dream/Torgersen plot here does. I'm not sure how I'd troubleshoot this going forward, do you have any ideas?
I don't know that this is a pattern we want to promote, but at the same time this is exactly the experience I always want...
leaving these changes unpublished
here's the first example; but note that with the plugin approach we don't get tooltips on the shorthand Plot.mark(…).plot(), only on the full-fledged Plot.plot(…) call.
Plot.plot({
marks: [
Plot.rectY(
data,
Plot.binX(
{ y: "count", title: (elems) => `${elems.length} rows` },
{ x: "body_mass", thresholds: 20 }
)
)
],
tooltip: { fill: "gray", opacity: 0.5, "stroke-width": "3px", stroke: "red" }
})
There seems to be a bug with the tooltip when rendering numbers on a line chart. The tooltip isn't updating based on a given, but, instead, showing the same value. This can be reproduced by changing the value of "title" to "unemployed"
In effect if you try
```
title: (d) =>
`${d.industry} \n date: ${d.date.toLocaleString(undefined, {
"year": "numeric",
"month": "2-digit",
"day": "2-digit"
})} \n unemployed: ${d.unemployed}`
```
you see you always get the first value in the data, i.e. the date and the unemployed do not change as you hover
I know Plot is being worked on very actively, but don't know about this specific deliverable. Feel free to leave a comment in the PR, or give a :thumbs up: to show interest!
`addTooltips` doesn't appear to work when embedding a notebook. Within Observable, tooltip content changes as one hovers different points on a line. However, when embedding the notebook, the data remains static
Text colour could be changed here https://observablehq.com/@mkfreeman/plot-tooltip#hover
by adding this line, that makes the bold text red and other text green.
.style("color", (d, i) => (i === 0 ? "red" : "green"));
There might be a nicer way to do this vis CSS styles.
Totally agree! That would be a bit more effort (that I don't currently have time for), but if you're interested in exploring it a common technique is to use a voronoi diagram (at least for a scatterplot) https://observablehq.com/@d3/hover-voronoi