首页 > 解决方案 > 将单独的 vega 图表链接在一起?

问题描述

是否可以在网页上链接多个 vega 图表而不将它们组合成一个组合图表?

我正在尝试在仪表板中执行此操作,以允许我更好地控制样式,特别是通过将图形放在不同的图块上并使它们具有响应性。根据文档,组合图表无法响应"width": "container".

我创建了以下两个示例图表并将它们嵌入到一个 HTML 文件中,但出现以下异常:Uncaught (in promise) Error: Cannot find a selection named "selector002".

有什么办法可以让 Vega 工作吗?vconcat或者,如果我能以某种方式让它适应其父容器的大小,我会对图表感到满意。

{
    "config": {
        "view": {
            "continuousWidth": 400,
            "continuousHeight": 300
        }
    },
    "data": {
        "name": "data-07d1121d4bb402da807ced7f89269752"
    },
    "mark": "point",
    "encoding": {
        "x": {
            "type": "quantitative",
            "field": "A"
        },
        "y": {
            "type": "quantitative",
            "field": "B"
        }
    },
    "selection": {
        "selector002": {
            "type": "interval",
            "encodings": [
                "x"
            ]
        }
    },
    "width": "container",
    "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json",
    "datasets": {
        "data-07d1121d4bb402da807ced7f89269752": [
            {
                "A": 0.1,
                "B": 0.5,
                "C": 1.0
            },
            {
                "A": 0.1,
                "B": 0.8,
                "C": 0.0
            },
            {
                "A": 0.0,
                "B": 1.0,
                "C": 1.0
            },
            {
                "A": 0.2,
                "B": 0.8,
                "C": 1.0
            },
            {
                "A": 0.2,
                "B": 0.9,
                "C": 0.0
            }
        ]
    }
}
{
    "config": {
        "view": {
            "continuousWidth": 400,
            "continuousHeight": 300
        }
    },
    "data": {
        "name": "data-07d1121d4bb402da807ced7f89269752"
    },
    "mark": "bar",
    "encoding": {
        "color": {
            "type": "ordinal",
            "field": "B"
        },
        "x": {
            "type": "quantitative",
            "field": "A"
        },
        "y": {
            "type": "ordinal",
            "field": "C"
        }
    },
    "transform": [
        {
            "filter": {
                "selection": "selector002"
            }
        }
    ],
    "width": "container",
    "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json",
    "datasets": {
        "data-07d1121d4bb402da807ced7f89269752": [
            {
                "A": 0.1,
                "B": 0.5,
                "C": 1.0
            },
            {
                "A": 0.1,
                "B": 0.8,
                "C": 0.0
            },
            {
                "A": 0.0,
                "B": 1.0,
                "C": 1.0
            },
            {
                "A": 0.2,
                "B": 0.8,
                "C": 1.0
            },
            {
                "A": 0.2,
                "B": 0.9,
                "C": 0.0
            }
        ]
    }
}

标签: vega-lite

解决方案


有一个与此相关的未解决问题:https ://github.com/vega/vega-lite/issues/1830

我对这个问题的最新回复可以帮助你:

这是使用当前版本的 VegaLite ( vega@5.17.0, vega-lite@4.17.0, vega-embed@6.12.2) 的 hack,假设您在 中进行了brush选择vegalite_spec_for_minimap

vegaEmbed(`#minimap`, vegalite_spec_for_minimap)
    .then(function(minimapVe){
        minimapVe.view.addSignalListener('brush', function(signalName, e) {
            console.log("updated");
        });
     });

这是一个完整的例子:

timestampBounds = [1610580331317, 1610845273208];
chart_data.data.name = 'datatable';
vegaEmbed(`#main-chart`, chart_data).then(function(mainChartVe){
    // create a copy of data for the mini-map
    var minimap_data = $.extend(true, {}, chart_data);

    // set the height for minimap
    minimap_data.height = '50';

    // if you have an initial selection, apply it on the minimap
    if(timestampBounds) {
        minimap_data.selection = {"brush": {"type": "interval", "encodings": ["x"], "init": {"x": timestampBounds}}};
    } else {
        minimap_data.selection = {"brush": {"type": "interval", "encodings": ["x"]}};
    }

    function updateChartDataBasedOnSelection(timestampArr) {
        var filteredValues = minimap_data.data.values.filter(x => x.timestamp >= timestampArr[0] && x.timestamp <= timestampArr[1]);
        var changeset = vega.changeset().remove(vega.truthy).insert(filteredValues);
        mainChartVe.view.change('datatable', changeset).run();
    }

    // Have an initial selection
    if(timestampBounds) updateChartDataBasedOnSelection(timestampBounds);

    vegaEmbed(`#minimap`, minimap_data)
        .then(function(minimapVe){
            minimapVe.view.addSignalListener('brush', function(signalName, e) {
                if(e && e.timestamp) {
                    // update the main chart based on the selected data
                    updateChartDataBasedOnSelection(e.timestamp);
                }
            });
        });
});

推荐阅读