多次更改信号的域或标签

Changing domain or label from signal more than once

我正在尝试使用信号来更改网页上 Vega 图表上的刻度域或轴标签。我将调试表达式放在信号以及比例尺和轴中,以验证信号是否正在接收从 javascript(例如 view.signal("xdomainMin",0);)发送的值,并在控制台中查看消息。

当 vegaEmbed 首次根据规范进行初始化时,一切正常。在 javascript 控制台中,信号更新表达式打印出初始值,然后比例域和轴标题表达式从信号中打印出相同的初始值。

但是,当我从 javascript 发送信号以更改域名或标签时,信号会被接收并打印到控制台,但域名和标题信号表达式不会在之后打印出任何内容第一次。就好像它们只能设置一次,永久。

如果我从信号中删除 value: 初始值设定项,那么控制台会显示该值未定义,随后在发送信号值时,信号会获取该值但不会传播到域或标签。

如果 view.getState() 记录到控制台,则表明信号已更新为新值。但是,页面上的图表仍然具有旧的轴标签和旧的域比例尺。

这很奇怪,因为我看过其他示例代码,其中人们说他们能够从 javascript 动态修改域。例如:this SO question about changing the domain

这是一个简化的规范:

{
    "$schema": "https://vega.github.io/schema/vega/v5.json",
    "autosize": { "type": "fit", "contains": "padding" },
    "padding": 5,
    "width": 300,
    "height": 300,
    "data": [{
        "name": "xy",
        "values": [
            {"1": 1.0, "2": 12.0},
            {"1": 10.4, "2": 22.2},
            {"1": 20.8, "2": 42.5}
        ]
    }],
    "signals": [
        { "name": "xkey", "value": "1", "update": "debug('inside signal, xkey is ', xkey)" },
        { "name": "ykey", "value": "2", "update": "debug('inside signal, ykey is ', ykey)" },
        { "name": "xlabel", "value": "XXX", "update": "debug('inside signal, xlabel is ', xlabel)" },
        { "name": "ylabel", "value": "YYY", "update": "debug('inside signal, ylabel is ', ylabel)" },
        { "name": "xdomainMin", "value": -100, "update": "debug('inside signal, xdomainMin is ', xdomainMin)" },
        { "name": "xdomainMax", "value":  100, "update": "debug('inside signal, xdomainMax is ', xdomainMax)" }
    ],
    "scales": [{
        "name": "xscale",
        "domain": [0, 100],
        "domainMin": { "signal": "debug('DOMAIN CHANGE xdomainMin =', xdomainMin)" },
        "domainMax": { "signal": "debug('DOMAIN CHANGE xdomainMax =', xdomainMax)" },
        "range": "width"
    }, {
        "name": "yscale",
        "domain": [0, 100],
        "range": "height"
    }],
    "axes": [
        { "orient": "bottom", "scale": "xscale", "title": { "signal": "debug('CHANGE X LABEL =', xlabel)" } },
        { "orient": "left", "scale": "yscale", "title": { "signal": "debug('CHANGE Y LABEL =', ylabel)"} }
    ],
    "marks": [
        {
            "type": "symbol",
            "from": { "data": "xy" },
            "encode": {
                "enter": {
                    "x": { "scale": "xscale", "field": "1"},
                    "y": { "scale": "yscale", "field": "2"}
                },
                "update": {
                    "x": { "scale": "xscale", "field": {"signal": "debug('x ', datum[xkey], xkey)"} },
                    "y": { "scale": "yscale", "field": {"signal": "debug('y ', datum[ykey], ykey)"} },
                    "fill": { "value": "steelblue" }
                }
            }
        }
    ]
}

和javascript信号调用就是这样:

    vega_view.signal("xlabel", "test");
    vega_view.signal("xdomainMin", 0);
    vega_view.signal("xdomainMax", 42);
    vega_view.runAsync()
        .then( ()=>{
            console.log("\nSTATE:")
            console.log(vega_view.getState());
            console.log("\n");
        });

我什至无法想象无法通过信号更改轴标签。我做错了什么?

这是一个可以更新标题和域的简单示例。

{
  "$schema": "https://vega.github.io/schema/vega/v5.json",
  "description": "A basic bar chart example, with value labels shown upon mouse hover.",
  "width": 400,
  "padding": 5,

  "data": [
    {
      "name": "table",
      "values": [
        {"category": "A", "amount": 28},
        {"category": "B", "amount": 55},
        {"category": "C", "amount": 43},
        {"category": "D", "amount": 91},
        {"category": "E", "amount": 81},
        {"category": "F", "amount": 53},
        {"category": "G", "amount": 19},
        {"category": "H", "amount": 87}
      ]
    }
  ],

  "signals": [
    {
      "name": "domain",
      "value": ["A", "B", "C"]
    },
    {
      "name": "title",
      "value": "Title"
    }
  ],

  "scales": [
    {
      "name": "xscale",
      "type": "point",
      "domain": {"signal": "domain"},
      "range": "width"
    }
  ],

  "axes": [
    { "orient": "bottom", "scale": "xscale", "title": {"signal": "title"} }
  ]
}

您的规范中存在一些问题。首先,更新表达式调试表达式不正确。 debug 函数是一个有副作用的 noop,应该只取一个值。其次,field 应该是字段的名称,而不是值。这是有效的固定示例。

{
    "$schema": "https://vega.github.io/schema/vega/v5.json",
    "autosize": { "type": "fit", "contains": "padding" },
    "padding": 5,
    "width": 300,
    "height": 300,
    "data": [{
        "name": "xy",
        "values": [
            {"1": 1.0, "2": 12.0},
            {"1": 10.4, "2": 22.2},
            {"1": 20.8, "2": 42.5}
        ]
    }],
    "signals": [
        { "name": "xkey", "value": "1" },
        { "name": "ykey", "value": "2" },
        { "name": "xlabel", "value": "XXX" },
        { "name": "ylabel", "value": "YYY"},
        { "name": "xdomainMin", "value": -100 },
        { "name": "xdomainMax", "value":  100 }
    ],
    "scales": [{
        "name": "xscale",
        "domain": [0, 1],
        "domainMin": { "signal": "xdomainMin" },
        "domainMax": { "signal": "xdomainMax" },
        "range": "width"
    }, {
        "name": "yscale",
        "domain": [0, 100],
        "range": "height"
    }],
    "axes": [
        { "orient": "bottom", "scale": "xscale", "title": { "signal": "xlabel" } },
        { "orient": "left", "scale": "yscale", "title": { "signal": "ylabel"} }
    ],
    "marks": [
        {
            "type": "symbol",
            "from": { "data": "xy" },
            "encode": {
                "enter": {
                    "x": { "scale": "xscale", "field": "1"},
                    "y": { "scale": "yscale", "field": "2"}
                },
                "update": {
                    "x": { "scale": "xscale", "field": {"signal": "xkey"} },
                    "y": { "scale": "yscale", "field": {"signal": "ykey"} },
                    "fill": { "value": "steelblue" }
                }
            }
        }
    ]
}