question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Error w/gradient legends when interactively filtering dataset

See original GitHub issue

In the following spec (simplified from vega/vega-lite#3865), the gradient legend is driven by a scale with a backing dataset that is interactively filtered via brushing. When interaction begins, the code paths that calculate stops for the gradient legend produce NaNs. As a result, the Canvas renderer crashes while the browser throws errors when using the SVG renderer.

{
  "$schema": "https://vega.github.io/schema/vega/v4.json",
  "autosize": "pad",
  "padding": 5,
  "width": 200,
  "height": 200,
  "style": "cell",
  "data": [
    {"name": "box_store"},
    {"name": "source_0", "url": "data/cars.json"},
    {
      "name": "data_0",
      "source": "source_0",
      "transform": [
        {
          "type": "filter",
          "expr": "!(length(data(\"box_store\"))) || (vlInterval(\"box_store\", datum))"
        }
      ]
    }
  ],
  "signals": [
    {
      "name": "unit",
      "value": {},
      "on": [
        {"events": "mousemove", "update": "isTuple(group()) ? group() : unit"}
      ]
    },
    {
      "name": "box_x",
      "value": [],
      "on": [
        {
          "events": {"source": "scope", "type": "mousedown"},
          "update": "[x(unit), x(unit)]"
        },
        {
          "events": {
            "source": "window",
            "type": "mousemove",
            "consume": true,
            "between": [
              {"source": "scope", "type": "mousedown"},
              {"source": "window", "type": "mouseup"}
            ]
          },
          "update": "[box_x[0], clamp(x(unit), 0, width)]"
        }
      ]
    },
    {
      "name": "box_Horsepower",
      "on": [
        {
          "events": {"signal": "box_x"},
          "update": "box_x[0] === box_x[1] ? null : invert(\"x\", box_x)"
        }
      ]
    },
    {
      "name": "box_tuple",
      "on": [
        {
          "events": [{"signal": "box_Horsepower"}],
          "update": "box_Horsepower ? {unit: \"layer_0\", intervals: [{encoding: \"x\", field: \"Horsepower\", extent: box_Horsepower}]} : null"
        }
      ]
    },
    {
      "name": "box_modify",
      "on": [
        {
          "events": {"signal": "box_tuple"},
          "update": "modify(\"box_store\", box_tuple, true)"
        }
      ]
    }
  ],
  "marks": [
    {
      "name": "box_brush_bg",
      "type": "rect",
      "clip": true,
      "encode": {
        "enter": {"fill": {"value": "#333"}, "fillOpacity": {"value": 0.125}},
        "update": {
          "x": [
            {
              "test": "data(\"box_store\").length && data(\"box_store\")[0].unit === \"layer_0\"",
              "signal": "box_x[0]"
            },
            {"value": 0}
          ],
          "y": [
            {
              "test": "data(\"box_store\").length && data(\"box_store\")[0].unit === \"layer_0\"",
              "value": 0
            },
            {"value": 0}
          ],
          "x2": [
            {
              "test": "data(\"box_store\").length && data(\"box_store\")[0].unit === \"layer_0\"",
              "signal": "box_x[1]"
            },
            {"value": 0}
          ],
          "y2": [
            {
              "test": "data(\"box_store\").length && data(\"box_store\")[0].unit === \"layer_0\"",
              "field": {"group": "height"}
            },
            {"value": 0}
          ]
        }
      }
    },
    {
      "name": "layer_0_marks",
      "type": "symbol",
      "from": {"data": "source_0"},
      "encode": {
        "update": {
          "fill": {"value": "transparent"},
          "stroke": {"value": "lightgray"},
          "x": {"scale": "x", "field": "Horsepower"},
          "y": {"scale": "y", "field": "Acceleration"}
        }
      }
    },
    {
      "name": "layer_1_marks",
      "type": "symbol",
      "from": {"data": "data_0"},
      "encode": {
        "update": {
          "fill": {"value": "transparent"},
          "stroke": {"scale": "color", "field": "Cylinders"},
          "x": {"scale": "x", "field": "Horsepower"},
          "y": {"scale": "y", "field": "Acceleration"}
        }
      }
    }
  ],
  "scales": [
    {
      "name": "x",
      "type": "linear",
      "domain": {"data": "source_0", "field": "Horsepower"},
      "range": [0, {"signal": "width"}]
    },
    {
      "name": "y",
      "type": "linear",
      "domain": {"data": "source_0", "field": "Acceleration"},
      "range": [{"signal": "height"}, 0]
    },
    {
      "name": "color",
      "type": "sequential",
      "domain": {"data": "data_0", "field": "Cylinders"},
      "range": "ramp"
    }
  ],
  "legends": [{"stroke": "color", "title": "Cylinders"}]
}

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:6 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
jheercommented, Aug 22, 2018

Hmm. There are some different options along those lines. I’m not sure caching at init time makes sense as the data could drift over time (e.g., due to streaming updates). One could cache based on previous valid settings, but that also adds more cruft/bloat to the system. Instead, I propose:

  1. Fix up the vega-scale scaleFraction utility (used to generate gradient stops) to be robust to infinite values. This fixes the primary error observed here, though the gradient for empty selections will still look “bad”.
  2. Update the vega-transforms Extent transform to produce [undefined, undefined] instead of [Infinity, -Infinity] for empty data sets, as this seems like more appropriate semantics and better aligned with other libraries like D3.
  3. Leave higher-level decisions such as “caching” or enforcement of minimal domain extents to 3rd parties (e.g., end users of spec-generating libraries like Vega-Lite).
0reactions
jheercommented, Oct 12, 2018

Fixed in vega version 4.3.0.

Read more comments on GitHub >

github_iconTop Results From Across the Web

ParaView 5.10.0 Release Notes - Kitware Inc.
New features Rendering enhancements Plugin updates Filter changes Readers ... The filters Gradient and Gradient Of Unstructured DataSet have ...
Read more >
Filter Data from Your Views - Tableau Help
This article describes the many ways you can filter data from your view. It also describes how you can display interactive filters in...
Read more >
4. Displaying data - ParaView Documentation
Generally, executing a data processing filter or reader is time consuming on large datasets. If the pipeline module keeps on executing as you...
Read more >
Tecplot 360 User's Manual
The Plot Type, combined with a frame's dataset, active layers, ... approximate plot for style, data, and interactive view changes is rendered.
Read more >
Google Visualization API Reference | Charts
To make a read-only copy of a DataTable (optionally filtered to show ... for example as a column header in a table, or...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found