# formatting title on hover in PLOT

**URL:** <https://talk.observablehq.com/t/formatting-title-on-hover-in-plot/5560>\
**Category:** Help\
**Created:** [September 9, 2021, 1:54pm UTC](https://talk.observablehq.com/t/formatting-title-on-hover-in-plot/5560 "2021-09-09T13:54:41Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![rbhttchr](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/rbhttchr/32/3261_2.png) [@rbhttchr](https://talk.observablehq.com/u/rbhttchr)\
**Post date:** [September 9, 2021, 1:54pm UTC](https://talk.observablehq.com/t/formatting-title-on-hover-in-plot/5560/1 "2021-09-09T13:54:41Z")

</div>

Hello,

I am sure this is a silly problem, but I need to understand how to work two things out.  
I have a large table with song/Film/Year/Composer/Lyricist/Singers. The link is [Giitaayan Archive](https://observablehq.com/@rbhttchr/hindifilmsongs_basic)

Problem 1: The first graph shows each song as a line, and the title on hover works fine. I can modify it as showing the film, composer, singers etc.  
Now I want to be able to show one or more of those PLUS the COUNT when I change the bins into films, composers, year, etc. For example, when I modify the graph to show each ‘rect’ as a composer, I want to be able to show \<composer: count\> in title on hover. I can accomplish either count or composer, (or year/lyricist etc.), but not both. Would please someone modify the code attached and show me?

Problem 2: Is it possible to create a graph based on x = values in two rows? Like in the code below, x: “Year”, if I want to do x: “Composer” PLUS “Singers”, to show the same person who appears both as composer and singer? Is it possible?

Thanks a ton and sorry for posting problems with obvious solutions,  
Rini

```auto
Plot.rectY(
      giitaayanW,
      Plot.binX(
        { y: "count", title: "count" },
        {
          rx: 15,
          x: "Year",
          fill: "Composer",
          title: `${(d) => d.Composer}, ${(v) => v.count}`
        }
      )
    ),

```

---

<div class="post-metadata">

**Author:** ![Fil](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/fil/32/207_2.png) [@Fil](https://talk.observablehq.com/u/Fil)\
**Post date:** [September 9, 2021, 5:25pm UTC](https://talk.observablehq.com/t/formatting-title-on-hover-in-plot/5560/2 "2021-09-09T17:25:12Z")

</div>

For the first question, try maybe

```auto
    Plot.rectY(
      giitaayanW,
      Plot.binX(
        { y: "count", title: v => `${v[0].Composer}, ${v.length}` },
        {
          rx: 15,
          x: "Year",
          fill: "Composer",
        }
      )
    ),

```

if the _title_ reducer is given only as an output, it gets passed the whole list of data for each group (i.e. all the films by each composer), and can return the name (taken from the first element), and the length of the group (number of films).

I’m less sure about the second question. Grouping is exclusive (each film will belong to only one group). You should be able to create a new list where each song appears once for its composer and once for each of its singers, then group from that, but it means a bit of “data wrangling” before you send it to plot. A good tool to do this is Array.flatMap(), for example:

```auto
data = giitaayanW.flatMap(song => [
    {...song, person: song.Composer, role: "composer"},
    ... (song.Singers || "").split(", ")
        .filter(singer => singer) // remove empty strings
        .map(singer => ({...song, person: singer, role: "singer"}))
])

```

and then you would group this data on “person”, and maybe reduce the title to show the number of songs and roles…

---

<div class="post-metadata">

**Author:** ![rbhttchr](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/rbhttchr/32/3261_2.png) [@rbhttchr](https://talk.observablehq.com/u/rbhttchr)\
**Post date:** [September 9, 2021, 6:47pm UTC](https://talk.observablehq.com/t/formatting-title-on-hover-in-plot/5560/3 "2021-09-09T18:47:00Z")

</div>

> [@Fil](#):
>
> ```auto
> Plot.rectY(
> giitaayanW,
> Plot.binX(
> { y: "count", title: v => `${v[0].Composer}, ${v.length}` },
> {
> rx: 15,
> x: "Year",
> fill: "Composer",
> }
> )
> ),
> 
> ```

Thanks so much, @Fil !  
The first solution works perfectly (I will try the second problem soon). A follow-up on the first solution. Why can’t I stack the Composers in descending order, by having the biggest rect at the bottom, then thinning out as I go up?

---

<div class="post-metadata">

**Author:** ![Fil](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/fil/32/207_2.png) [@Fil](https://talk.observablehq.com/u/Fil)\
**Post date:** [September 9, 2021, 7:19pm UTC](https://talk.observablehq.com/t/formatting-title-on-hover-in-plot/5560/4 "2021-09-09T19:19:49Z")

</div>

Ordering for the stackY transform can be done by adding an `order: "value"` option. But it will stack from smaller to larger, and what you want is the opposite.

To reverse the order, you can use `reverse: true`, however if you call this from within the Plot.binX transform, _reverse_ will be consumed by Plot.binX, and not passed up to Plot.stackY (which, in your case, doesn’t appear in the code because it is implicitly called by Plot.rectY). So, to make _reverse_ reach the stack transform, we need to write a destructured options object.

```auto
Plot.rectY(giitaayanW, {
      ...Plot.binX(
        {
          y: "count",
          // order: (a, b) => d3.descending(a.length, b.length),
          title: (v) => `${v[0].Composer}: ${v.length}`
        },
        {
          rx: 15,
          x: "Year",
          fill: "Composer"
        }
      ),
      order: "value",
      reverse: true
    })

```

I would also encourage you to test `order: "sum"` instead of `order: "value"`; it will make the ordering identical in each pile, making it easier to follow a composer across the years.

---

<div class="post-metadata">

**Author:** ![rbhttchr](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/rbhttchr/32/3261_2.png) [@rbhttchr](https://talk.observablehq.com/u/rbhttchr)\
**Post date:** [September 9, 2021, 10:42pm UTC](https://talk.observablehq.com/t/formatting-title-on-hover-in-plot/5560/5 "2021-09-09T22:42:34Z")

</div>

Thanks again, @Fil ! I am going to have tons of use for both order and sum, in various of my projects.

---

<div class="post-metadata">

**Author:** ![rbhttchr](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/rbhttchr/32/3261_2.png) [@rbhttchr](https://talk.observablehq.com/u/rbhttchr)\
**Post date:** [September 10, 2021, 9:38pm UTC](https://talk.observablehq.com/t/formatting-title-on-hover-in-plot/5560/6 "2021-09-10T21:38:47Z")

</div>

Hi @Fil,

I have tried out the solution to my second issue in the original posting, and am now able to just map one singer, Lata, from the singers column. This is the last chart on the page.  
I have a follow-up question/issue here. I am happy with the chart, but people without coding interests/skills who will be just looking at the graph will try to find the logic of binning and want information on a yearly basis. For instance, the years 1940-1945 share 3 columns. How, if I can at all, plot rects by year or (5 year or 10 years) and include the years in title on hover? Like, the most prolific singer in the chart, Lata, has columns with 99, 173 etc. songs… What are the year(s) for 99 songs? For 173 songs etc.?

Apologize for all these questions. I am a latecomer to the world of computing; my PhD was in Comparative Literature.

One more newbie question: where can I read more about the significance of the three dots (…) in so many of the code snippets that I see?

Sincerely,  
Rini

[https://observablehq.com/@rbhttchr/hindifilmsongs\_basic](https://observablehq.com/@rbhttchr/hindifilmsongs_basic)

---

<div class="post-metadata">

**Author:** ![mbostock](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/mbostock/32/9_2.png) [@mbostock](https://talk.observablehq.com/u/mbostock)\
**Post date:** [September 11, 2021, 3:59am UTC](https://talk.observablehq.com/t/formatting-title-on-hover-in-plot/5560/7 "2021-09-11T03:59:40Z")

</div>

You can also use an explicit stack transform, rather than relying on the implicit one, so that you can pass the _order_ and _reverse_ options to the stack transform explicitly.

```auto
Plot.rectY(
  giitaayanW,
  Plot.stackY(
    {order: "sum", reverse: true},
    Plot.binX(
      {y: "count", title: v => `${v[0].Composer}: ${v.length}`},
      {rx: 15, x: "Year", fill: "Composer"}
    )
  )
)

```

---

<div class="post-metadata">

**Author:** ![rbhttchr](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/rbhttchr/32/3261_2.png) [@rbhttchr](https://talk.observablehq.com/u/rbhttchr)\
**Post date:** [September 11, 2021, 2:29pm UTC](https://talk.observablehq.com/t/formatting-title-on-hover-in-plot/5560/8 "2021-09-11T14:29:51Z")

</div>

Thanks so much, @mbostock ! I now know two ways of doing the stack transform.  
Do you have any suggestions for making it clear what year does each rect represent? This is form the last query that I asked:  
“people without coding interests/skills who will be just looking at the graph will try to find the logic of binning and want information on a yearly basis. For instance, the years 1940-1945 share 3 columns. How, if I can at all, plot rects by year or (5 year or 10 years) and include the years in title on hover? Like, the most prolific singer in the chart, Lata, has columns with 99, 173 etc. songs… What are the year(s) for 99 songs? For 173 songs etc.?”

Thanks a ton,  
Rini

---

<div class="post-metadata">

**Author:** ![mbostock](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/mbostock/32/9_2.png) [@mbostock](https://talk.observablehq.com/u/mbostock)\
**Post date:** [September 11, 2021, 5:24pm UTC](https://talk.observablehq.com/t/formatting-title-on-hover-in-plot/5560/9 "2021-09-11T17:24:25Z")

</div>

> [@rbhttchr](#):
>
> Do you have any suggestions for making it clear what year does each rect represent?

You could presumably do something like `d3.extent(v, d => d.Year)` to compute the years represented by each bin, but that’s not ideal because it could be a subset of the bin’s extent. You’d probably have to call d3.bin yourself if you want this, rather than relying on Plot’s bin transform. Here’s the related issue in the Plot repo:

> <https://github.com/observablehq/plot/issues/435>
>
> A typical example would be to have the title of each bar show the date extent in… https://observablehq.com/@fil/plot-stargazer-history
> 
> ~~~js
> Plot.rectY(
> data,
> Plot.binX(
> {
> y: "count",
> title: (bin) =\> \`${bin.x1}…${bin.x2}\` // ⇐ something like this.
> },
> {
> x: "date",
> fill: "brown",
> thresholds: 100
> }
> )
> ),
> ~~~
