1

I am able to prepare following visualization with vegalite:

enter image description here

The code for this visualization looks like following:

{
  "width": 400,
  "config": {"view": {"continuousWidth": 600, "continuousHeight": 300}},
  "data": {
    "values": [
      {"title": "Quiz-1", "my-score": 62, "max": 80, "avg": 45, "min": 15, "my-actual-score": 124, "max-score": 160, "avg-score": 90, "min-score": 30  },
      {"title": "Quiz-2", "my-score": 48, "max": 48, "avg": 30, "min": 10, "my-actual-score": 24, "max-score": 24, "avg-score": 15, "min-score": 5  },
      {"title": "Quiz-3", "my-score": 54, "max": 62, "avg": 36, "min": 12, "my-actual-score": 54, "max-score": 62, "avg-score": 36, "min-score": 12  },
      {"title": "Quiz-4", "my-score": 27, "max": 69, "avg": 50, "min": 9 , "my-actual-score": 27, "max-score": 69, "avg-score": 50, "min-score": 9  },
      {"title": "Quiz-5", "my-score": 40, "max": 48, "avg": 30, "min": 11, "my-actual-score": 80, "max-score": 96, "avg-score": 60, "min-score": 22  },
      {"title": "Quiz-6", "my-score": 50, "max": 55, "avg": 28, "min": 5 , "my-actual-score": 50, "max-score": 55, "avg-score": 28, "min-score": 5  }
    ]
  },
  "transform": [{"fold": ["max", "avg", "min", "my-score"]}],
  "usermeta": {"embedOptions": {"renderer": "svg"}},
  "encoding": {
    "x": {"field": "title", "type": "nominal", "axis": {"title": "Quizzes"}}
  },
  "layer": [
    {
      "mark": {"type": "bar", "width": {"band": 0.2}},
      "transform": [{"filter": "datum.key == 'my-score' "}],
      "encoding": {
        "y": {
          "field": "value",
          "type": "quantitative",
          "axis": {"title": "Percentage Score"}
        },
        "color": {"field": "key", "scale": {"range": ["#312eaa"]}, "legend": {"title": ""}},
        "tooltip": [{"field": "value", "type": "quantitative"}]
      }
    },
    {
      "mark": {"type": "line"},
      "transform": [
        {
          "filter": "datum.key == 'max' || datum.key == 'min' ||datum.key == 'avg'  "
        }
      ],
      "encoding": {
        "y": {"field": "value", "type": "quantitative"},
        "stroke": {
          "field": "key",
          "scale": {"range": ["#02c754", "red", "#02b6de"]},
          "legend": {"title": ""}
        }
      }
    },
    {
      "mark": {"type": "circle", "size":100, "opacity": "100%"},
      "params": [
                    {
                        "name": "highlight-max",
                        "select": { "type": "point", "on": "mouseover" }
                    }
                ],
      "transform": [
        {
          "filter": "datum.key == 'max' || datum.key == 'min' ||datum.key == 'avg'"
        }
      ],
      "encoding": {
        "y": {"field": "value", "type": "quantitative"},
        "fill": {
          "field": "key",
          "scale": {"range": ["#02c754", "red", "#02b6de"]},
          "legend": null
        },
        "size": {
                  "condition": { "param": "highlight-max", "empty": false, "value": 250}
        },
        "tooltip": [{"field": "value", "type": "quantitative"}]
      }
    }
  ],
  "title": "Quiz Scores",
  "$schema": "https://vega.github.io/schema/vega-lite/v5.6.json"
}

There are some discrepancies in this visualization:

enter image description here

First issue is that when hovered on any one circle, all circles in that quiz / column gets animated (increases their size as can be seen in figure above).

Second issue is that the tooltip simply says value: V (where V is corresponding value) when hovered on anything: bar, max/red circle, green/avg circle and blue/min circle. Note that there are two set of values in each record. For example, if we consider this record:

{"title": "Quiz-3", "my-score": 54, "max": 62, "avg": 36, "min": 12, "my-actual-score": 54, "max-score": 62, "avg-score": 36, "min-score": 12  }

then, we have first set:

"my-score": 54, "max": 62, "avg": 36, "min": 12

and second set:

"my-actual-score": 54, "max-score": 62, "avg-score": 36, "min-score": 12

First set is some what normalization (say percentage) of actual score given in second set. I want to show both when hovered on. For example when someone hovers on red circle, I want to show tooltip containing: Avg: 36%, 62, instead of just value: 36 as shown in above image. How can I achieve this?

PS: You can try out this visualization here.

MsA
  • 2,599
  • 3
  • 22
  • 47

1 Answers1

1

Try the following - it should give you what you need as a template to fill in the rest of the tooltip values.

{
  "width": 400,
  "config": {"view": {"continuousWidth": 600, "continuousHeight": 300}},
  "data": {
    "values": [
      {
        "title": "Quiz-1",
        "my-score": 62,
        "max": 80,
        "avg": 45,
        "min": 15,
        "my-actual-score": 124,
        "max-score": 160,
        "avg-score": 90,
        "min-score": 30
      },
      {
        "title": "Quiz-2",
        "my-score": 48,
        "max": 48,
        "avg": 30,
        "min": 10,
        "my-actual-score": 24,
        "max-score": 24,
        "avg-score": 15,
        "min-score": 5
      },
      {
        "title": "Quiz-3",
        "my-score": 54,
        "max": 62,
        "avg": 36,
        "min": 12,
        "my-actual-score": 54,
        "max-score": 62,
        "avg-score": 36,
        "min-score": 12
      },
      {
        "title": "Quiz-4",
        "my-score": 27,
        "max": 69,
        "avg": 50,
        "min": 9,
        "my-actual-score": 27,
        "max-score": 69,
        "avg-score": 50,
        "min-score": 9
      },
      {
        "title": "Quiz-5",
        "my-score": 40,
        "max": 48,
        "avg": 30,
        "min": 11,
        "my-actual-score": 80,
        "max-score": 96,
        "avg-score": 60,
        "min-score": 22
      },
      {
        "title": "Quiz-6",
        "my-score": 50,
        "max": 55,
        "avg": 28,
        "min": 5,
        "my-actual-score": 50,
        "max-score": 55,
        "avg-score": 28,
        "min-score": 5
      }
    ]
  },
  "transform": [{"fold": ["max", "avg", "min", "my-score"]}],
  "usermeta": {"embedOptions": {"renderer": "svg"}},
  "encoding": {
    "x": {"field": "title", "type": "nominal", "axis": {"title": "Quizzes"}}
  },
  "layer": [
    {
      "mark": {"type": "bar", "width": {"band": 0.2}},
      "transform": [{"filter": "datum.key == 'my-score' "}],
      "encoding": {
        "y": {
          "field": "value",
          "type": "quantitative",
          "axis": {"title": "Percentage Score"}
        },
        "color": {
          "field": "key",
          "scale": {"range": ["#312eaa"]},
          "legend": {"title": ""}
        },
        
        "tooltip": [{"field": "key", "title":"Attribute"},{"field": "value", "type": "quantitative", "title":"Score"}]
      }
    },
    {
      "mark": {"type": "line"},
      "transform": [
        {
          "filter": "datum.key == 'max' || datum.key == 'min' ||datum.key == 'avg'  "
        }
      ],
      "encoding": {
        "y": {"field": "value", "type": "quantitative"},
        "stroke": {
          "field": "key",
          "scale": {"range": ["#02c754", "red", "#02b6de"]},
          "legend": {"title": ""}
        }
      }
    },
    {
      "mark": {"type": "circle", "size": 100, "opacity": "100%"},
      "params": [
        {
          "name": "highlight-max",
          "select": {"type": "point", "on": "mouseover", "encodings": ["x","y", "fill"]}
        }
      ],
      "transform": [
        {
          "filter": "datum.key == 'max' || datum.key == 'min' ||datum.key == 'avg'"
        }
      ],
      "encoding": {
        "y": {"field": "value", "type": "quantitative"},
        "fill": {
          "field": "key",
          "scale": {"range": ["#02c754", "red", "#02b6de"]},
          "legend": null
        },
        "size": {
          "condition": {"param": "highlight-max", "empty": false,  "value": 250}
        },
        "tooltip": [{"field": "key", "title":"Attribute"},{"field": "value", "type": "quantitative", "title":"Score"}]
      }
    }
  ],
  "title": "Quiz Scores",
  "$schema": "https://vega.github.io/schema/vega-lite/v5.6.json"
}
Davide Bacci
  • 16,647
  • 3
  • 10
  • 36
  • I ended up doing something like [this](https://pastebin.com/1NqR7QQa). In this code, I have taken long route to calculate multiple columns + ternary operator, because `tooltip2` gives weird values and `tooltip3` always generated false ([screenshot](https://i.postimg.cc/HnvSYLkt/image.png)). **Q1.** Why? I ended up using `tooltip5` which is created using `tooltip4` and `tooltipTitle`. **Q2.** Any better way to achieve this? – MsA Mar 19 '23 at 22:33
  • **Q3.** What does `"encodings": ["x","y", "fill"]` mean in `select`? [Doc says](https://vega.github.io/vega-lite/docs/selection.html#selection-props): "The corresponding data field values must match for a data tuple to fall within the selection.", But unable to make sense out of it! – MsA Mar 19 '23 at 22:33
  • Sorry - not sure what you mean by Q1 & Q2 but the code I have provided should answer your question as it was originally posed. You might be better off marking this as solved and asking a new question and stating exactly what the problem is and your expected results. – Davide Bacci Mar 19 '23 at 22:50
  • Regarding Q3, I can't explain any more than the docs I'm afraid. I'm not overly familiar with interactivity and just saw that it could take an array of encodings to narrow down which data point was being hovered over. Without the array, the hover doesn't work properly. – Davide Bacci Mar 19 '23 at 22:51