Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScriptError - Multi Series Line Chart with Tooltip from Vega-Lite examples page #3200

Open
tpellet opened this issue Sep 21, 2023 · 2 comments
Labels

Comments

@tpellet
Copy link

tpellet commented Sep 21, 2023

Hi all!

I have been using Altair to turn Vega-Lite specifications into html charts. I have an issue with some interactive chart templates from the Vega-Lite example library. Specifically, specifications that render proper html files in the Vega-Lite editor cannot be saved properly to html using altair.chart.save(). The issue looks similar to vega/vega-lite#7854.

For example, here is an interactive graph that I have been trying to save as html using Altair.

When I use exactly the same dictionary specification in Altair (up to boolean caps due to Python) and try:

chart = alt.Chart.from_dict(specification)
chart.save("chart.html")

the resulting html file cannot be read and I get the following error message:

image

For reference, the html file saved using Altair looks like this:

<!DOCTYPE html>
<html>
<head>
  <style>
    #vis.vega-embed {
      width: 100%;
      display: flex;
    }

    #vis.vega-embed details,
    #vis.vega-embed details summary {
      position: relative;
    }
  </style>
  <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega@5"></script>
  <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
  <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-embed@6"></script>
</head>
<body>
  <div id="vis"></div>
  <script>
    (function(vegaEmbed) {
      var spec = {"config": {"view": {"continuousWidth": 300, "continuousHeight": 300}}, "layer": [{"layer": [{"mark": "line"}, {"mark": "point", "transform": [{"filter": {"param": "hover", "empty": false}}]}], "encoding": {"color": {"field": "symbol", "type": "nominal"}, "y": {"field": "price", "type": "quantitative"}}}, {"mark": "rule", "encoding": {"opacity": {"condition": {"param": "hover", "value": 0.3, "empty": false}, "value": 0}, "tooltip": [{"field": "GOOGL", "type": "quantitative"}, {"field": "AAPL", "type": "quantitative"}]}, "transform": [{"pivot": "symbol", "value": "price", "groupby": ["date"]}]}], "data": {"name": "values"}, "datasets": {"values": [{"date": "2023-09-14T00:00:00+00:00", "price": 138.1, "symbol": "GOOGL"}, {"date": "2023-09-15T00:00:00+00:00", "price": 137.4, "symbol": "GOOGL"}, {"date": "2023-09-18T00:00:00+00:00", "price": 138.21, "symbol": "GOOGL"}, {"date": "2023-09-19T00:00:00+00:00", "price": 138.04, "symbol": "GOOGL"}, {"date": "2023-09-20T00:00:00+00:00", "price": 133.74, "symbol": "GOOGL"}, {"date": "2023-09-21T00:00:00+00:00", "price": 130.89999389648438, "symbol": "GOOGL"}, {"date": "2023-09-14T00:00:00+00:00", "price": 175.74, "symbol": "AAPL"}, {"date": "2023-09-15T00:00:00+00:00", "price": 175.01, "symbol": "AAPL"}, {"date": "2023-09-18T00:00:00+00:00", "price": 177.97, "symbol": "AAPL"}, {"date": "2023-09-19T00:00:00+00:00", "price": 179.07, "symbol": "AAPL"}, {"date": "2023-09-20T00:00:00+00:00", "price": 175.49, "symbol": "AAPL"}, {"date": "2023-09-21T00:00:00+00:00", "price": 174.6428985595703, "symbol": "AAPL"}]}, "encoding": {"x": {"field": "date", "type": "temporal"}}, "height": 300, "params": [{"name": "hover", "select": {"type": "point", "clear": "mouseout", "fields": ["date"], "nearest": true, "on": "mouseover"}, "views": []}], "width": 400, "$schema": "https://vega.github.io/schema/vega-lite/v5.json"};
      var embedOpt = {"mode": "vega-lite"};

      function showError(el, error){
          el.innerHTML = ('<div style="color:red;">'
                          + '<p>JavaScript Error: ' + error.message + '</p>'
                          + "<p>This usually means there's a typo in your chart specification. "
                          + "See the javascript console for the full traceback.</p>"
                          + '</div>');
          throw error;
      }
      const el = document.getElementById('vis');
      vegaEmbed("#vis", spec, embedOpt)
        .catch(error => showError(el, error));
    })(vegaEmbed);

  </script>
</body>
</html>
@tpellet tpellet added the bug label Sep 21, 2023
@joelostblom
Copy link
Contributor

Thanks for the report; I think you are correct that it is related to the parameters being lifted to top level. You can run the following to see which spec altair creates:

print(
    alt.Chart.from_json(
        '''{
          "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
          "data": {"name": "values"},
          "width": 400,
          "height": 300,
          "encoding": {"x": {"field": "date", "type": "temporal"}},
          "layer": [
            {
              "encoding": {
                "color": {"field": "symbol", "type": "nominal"},
                "y": {"field": "price", "type": "quantitative"}
              },
              "layer": [
                {"mark": "line"},
                {
                  "transform": [{"filter": {"param": "hover", "empty": false}}],
                  "mark": "point"
                }
              ]
            },
            {
              "transform": [{"pivot": "symbol", "value": "price", "groupby": ["date"]}],
              "mark": "rule",
              "encoding": {
                "opacity": {
                  "condition": {"value": 0.3, "param": "hover", "empty": false},
                  "value": 0
                },
                "tooltip": [
                  {"field": "GOOGL", "type": "quantitative"},
                  {"field": "AAPL", "type": "quantitative"}
                ]
              },
              "params": [
                {
                  "name": "hover",
                  "select": {
                    "type": "point",
                    "fields": ["date"],
                    "nearest": true,
                    "on": "mouseover",
                    "clear": "mouseout"
                  }
                }
              ]
            }
          ],
          "datasets": {
            "values": [
              {"date": "2023-09-14T00:00:00+00:00", "price": 138.1, "symbol": "GOOGL"},
              {"date": "2023-09-15T00:00:00+00:00", "price": 137.4, "symbol": "GOOGL"},
              {"date": "2023-09-18T00:00:00+00:00", "price": 138.21, "symbol": "GOOGL"},
              {"date": "2023-09-19T00:00:00+00:00", "price": 138.04, "symbol": "GOOGL"},
              {"date": "2023-09-20T00:00:00+00:00", "price": 133.74, "symbol": "GOOGL"},
              {
                "date": "2023-09-21T00:00:00+00:00",
                "price": 130.89999389648438,
                "symbol": "GOOGL"
              },
              {"date": "2023-09-14T00:00:00+00:00", "price": 175.74, "symbol": "AAPL"},
              {"date": "2023-09-15T00:00:00+00:00", "price": 175.01, "symbol": "AAPL"},
              {"date": "2023-09-18T00:00:00+00:00", "price": 177.97, "symbol": "AAPL"},
              {"date": "2023-09-19T00:00:00+00:00", "price": 179.07, "symbol": "AAPL"},
              {"date": "2023-09-20T00:00:00+00:00", "price": 175.49, "symbol": "AAPL"},
              {
                "date": "2023-09-21T00:00:00+00:00",
                "price": 174.6428985595703,
                "symbol": "AAPL"
              }
            ]
          }
        }'''
    ).to_json()
)

output:

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "config": {
    "view": {
      "continuousHeight": 300,
      "continuousWidth": 300
    }
  },
  "data": {
    "name": "values"
  },
  "datasets": {
    "values": [
      {
        "date": "2023-09-14T00:00:00+00:00",
        "price": 138.1,
        "symbol": "GOOGL"
      },
      {
        "date": "2023-09-15T00:00:00+00:00",
        "price": 137.4,
        "symbol": "GOOGL"
      },
      {
        "date": "2023-09-18T00:00:00+00:00",
        "price": 138.21,
        "symbol": "GOOGL"
      },
      {
        "date": "2023-09-19T00:00:00+00:00",
        "price": 138.04,
        "symbol": "GOOGL"
      },
      {
        "date": "2023-09-20T00:00:00+00:00",
        "price": 133.74,
        "symbol": "GOOGL"
      },
      {
        "date": "2023-09-21T00:00:00+00:00",
        "price": 130.89999389648438,
        "symbol": "GOOGL"
      },
      {
        "date": "2023-09-14T00:00:00+00:00",
        "price": 175.74,
        "symbol": "AAPL"
      },
      {
        "date": "2023-09-15T00:00:00+00:00",
        "price": 175.01,
        "symbol": "AAPL"
      },
      {
        "date": "2023-09-18T00:00:00+00:00",
        "price": 177.97,
        "symbol": "AAPL"
      },
      {
        "date": "2023-09-19T00:00:00+00:00",
        "price": 179.07,
        "symbol": "AAPL"
      },
      {
        "date": "2023-09-20T00:00:00+00:00",
        "price": 175.49,
        "symbol": "AAPL"
      },
      {
        "date": "2023-09-21T00:00:00+00:00",
        "price": 174.6428985595703,
        "symbol": "AAPL"
      }
    ]
  },
  "encoding": {
    "x": {
      "field": "date",
      "type": "temporal"
    }
  },
  "height": 300,
  "layer": [
    {
      "encoding": {
        "color": {
          "field": "symbol",
          "type": "nominal"
        },
        "y": {
          "field": "price",
          "type": "quantitative"
        }
      },
      "layer": [
        {
          "mark": "line"
        },
        {
          "mark": "point",
          "transform": [
            {
              "filter": {
                "empty": false,
                "param": "hover"
              }
            }
          ]
        }
      ]
    },
    {
      "encoding": {
        "opacity": {
          "condition": {
            "empty": false,
            "param": "hover",
            "value": 0.3
          },
          "value": 0
        },
        "tooltip": [
          {
            "field": "GOOGL",
            "type": "quantitative"
          },
          {
            "field": "AAPL",
            "type": "quantitative"
          }
        ]
      },
      "mark": "rule",
      "transform": [
        {
          "groupby": [
            "date"
          ],
          "pivot": "symbol",
          "value": "price"
        }
      ]
    }
  ],
  "params": [
    {
      "name": "hover",
      "select": {
        "clear": "mouseout",
        "fields": [
          "date"
        ],
        "nearest": true,
        "on": "mouseover",
        "type": "point"
      },
      "views": []
    }
  ],
  "width": 400
}

The params section looks the same in the output, but it is is lifted out from the layer to the top level. I am not sure what an action here would be but @ChristopherDavisUCI or @mattijn might have an idea.

@tpellet
Copy link
Author

tpellet commented Sep 21, 2023

Thank you for your response @joelostblom. It is a neat way of seeing what is going on!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants