Я реализовал линейную диаграмму, используя Vega, у которой есть значения даты (временная метка) на оси X и количество (Numeri c значение) на оси Y. Для преобразования данных я использую выражение toDate(datum[\"dateTime\"])
. Я хочу нанести на график метку правила с указанным значением c отметки времени. Я могу нарисовать его, но он принимает значения цифра c для координат x, y, x2, y2, например. 150,0,150,300 соответственно. Теперь у меня есть отметка времени в качестве входных данных, которая является точкой, где я хочу построить вертикальную метку правила. Может кто-нибудь помочь мне, как сопоставить значение метки времени с соответствующим значением координаты х?
Spe c:
{
"$schema": "https://vega.github.io/schema/vega/v4.json",
"autosize": {"type": "pad", "resize": true},
"padding": 5,
"width": 1500,
"height": 300,
"style": "cell",
"signals": [
{ "name": "x", "value": 150,
"bind": {"input": "range", "min": 0, "max": 1554403500000, "step": 1} },
{ "name": "y", "value": 0,
"bind": {"input": "range", "min": 0, "max": 1554403500000, "step": 1} },
{ "name": "x2", "value": 150,
"bind": {"input": "range", "min": 0, "max": 200, "step": 1} },
{ "name": "y2", "value": 300,
"bind": {"input": "range", "min": 0, "max": 200, "step": 1} },
{ "name": "strokeWidth", "value": 1 },
{ "name": "strokeCap", "value": "butt" },
{ "name": "strokeDash", "value": [4,4]
},
{
"name": "clear",
"value": true,
"on": [
{"events": "mouseup[!event.item]", "update": "true", "force": true}
]
},
{
"name": "shift",
"value": false,
"on": [
{
"events": "@legendSymbol:click, @legendLabel:click",
"update": "event.shiftKey",
"force": true
}
]
},
{
"name": "clicked",
"value": null,
"on": [
{
"events": "@legendSymbol:click, @legendLabel:click",
"update": "{value: datum.value}",
"force": true
}
]
},
{
"name": "brush",
"value": 0,
"on": [
{"events": {"signal": "clear"}, "update": "clear ? [0, 0] : brush"},
{"events": "@xaxis:mousedown", "update": "[x(), x()]"},
{
"events": "[@xaxis:mousedown, window:mouseup] > window:mousemove!",
"update": "[brush[0], clamp(x(), 0, width)]"
},
{
"events": {"signal": "delta"},
"update": "clampRange([anchor[0] + delta, anchor[1] + delta], 0, width)"
}
]
},
{
"name": "anchor",
"value": null,
"on": [{"events": "@brush:mousedown", "update": "slice(brush)"}]
},
{
"name": "xdown",
"value": 0,
"on": [{"events": "@brush:mousedown", "update": "x()"}]
},
{
"name": "delta",
"value": 0,
"on": [
{
"events": "[@brush:mousedown, window:mouseup] > window:mousemove!",
"update": "x() - xdown"
}
]
},
{
"name": "domain",
"on": [
{
"events": {"signal": "brush"},
"update": "span(brush) ? invert('x', brush) : null"
}
]
}
],
"data": [
{"name": "table", "values": [
{
"dateTime":1554399600000,
"count":69,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554399900000,
"count":82,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554400200000,
"count":24,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554400500000,
"count":80,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554400800000,
"count":34,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554401100000,
"count":58,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554401400000,
"count":33,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554401700000,
"count":56,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554402000000,
"count":98,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554402300000,
"count":66,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554402600000,
"count":22,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554402900000,
"count":48,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554403200000,
"count":89,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554403500000,
"count":69,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554403800000,
"count":94,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554404100000,
"count":30,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554404400000,
"count":66,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554404700000,
"count":87,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554405000000,
"count":99,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554405300000,
"count":23,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554405600000,
"count":49,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554405900000,
"count":45,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554406200000,
"count":90,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554406500000,
"count":87,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554406800000,
"count":69,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554407100000,
"count":23,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554407400000,
"count":60,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554407700000,
"count":76,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554408000000,
"count":82,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554408300000,
"count":81,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554408600000,
"count":76,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554408900000,
"count":96,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554409200000,
"count":46,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554409500000,
"count":61,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554409800000,
"count":59,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554410100000,
"count":93,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554410400000,
"count":48,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554410700000,
"count":42,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554411000000,
"count":76,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554411300000,
"count":75,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554411600000,
"count":43,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554411900000,
"count":48,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554412200000,
"count":20,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554412500000,
"count":70,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554412800000,
"count":25,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554413100000,
"count":96,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554413400000,
"count":70,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554413700000,
"count":74,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554414000000,
"count":89,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554414300000,
"count":73,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554414600000,
"count":78,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554414900000,
"count":38,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554415200000,
"count":49,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554415500000,
"count":84,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554415800000,
"count":27,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554416100000,
"count":31,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554416400000,
"count":63,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554416700000,
"count":67,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554417000000,
"count":63,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554417300000,
"count":99,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554417600000,
"count":75,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554417900000,
"count":24,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554418200000,
"count":95,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554418500000,
"count":77,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554418800000,
"count":38,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554419100000,
"count":78,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554419400000,
"count":99,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554419700000,
"count":24,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554420000000,
"count":79,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554420300000,
"count":55,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554420600000,
"count":22,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554420900000,
"count":97,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554421200000,
"count":83,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554421500000,
"count":68,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554421800000,
"count":28,
"outlier":false,
"category":"React Vega",
"id":0
},
{
"dateTime":1554422100000,
"count":37,
"outlier":false,
"category":"React Vega",
"id":0
}
] },
{
"name": "data_0",
"source": "table",
"transform": [
{
"type": "formula",
"expr": "toDate(datum[\"dateTime\"])",
"as": "dateTime"
},
{
"type": "window",
"params": [null],
"as": ["rank"],
"ops": ["rank"],
"fields": [null],
"sort": {"field": ["dateTime"], "order": ["descending"]}
},
{"type": "filter", "expr": "datum.rank <= 10000"}
]
},
{
"name": "data_1",
"source": "data_0",
"transform": [
{
"type": "formula",
"as": "dateTime",
"expr": "toDate(datum[\"dateTime\"])"
}
]
},
{
"name": "data_2",
"source": "data_0",
"transform": [
{
"type": "formula",
"expr": "if(datum.outlier == true, datum.count, null)",
"as": "count"
},
{"type": "formula", "expr": "true", "as": "baseline"},
{
"type": "formula",
"as": "dateTime",
"expr": "toDate(datum[\"dateTime\"])"
}
]
},
{
"name": "data_3",
"source": "data_0",
"transform": [
{"type": "filter", "expr": "datum.outlier == true"},
{"type": "formula", "expr": "true", "as": "baseline"},
{
"type": "formula",
"as": "dateTime",
"expr": "toDate(datum[\"dateTime\"])"
}
]
},
{
"name": "selected",
"on": [
{"trigger": "clear", "remove": true},
{"trigger": "!shift", "remove": true},
{"trigger": "!shift && clicked", "insert": "clicked"},
{"trigger": "shift && clicked", "toggle": "clicked"}
]
}
],
"marks": [
{
"type": "rule",
"encode": {
"enter": {
"stroke": {"value": "red"}
},
"update": {
"x": {"signal": "x"},
"y": {"signal": "y"},
"x2": {"signal": "x2"},
"y2": {"signal": "y2"},
"strokeWidth": {"signal": "strokeWidth"},
"strokeDash": {"signal": "strokeDash"},
"strokeCap": {"signal": "strokeCap"},
"opacity": {"value": 1}
},
"hover": {
"opacity": {"value": 0.5}
}
}
},
{
"name": "layer_0_pathgroup",
"type": "group",
"from": {
"facet": {
"name": "faceted_path_layer_0_main",
"data": "data_1",
"groupby": ["category", "category"]
}
},
"encode": {
"update": {
"width": {"field": {"group": "width"}},
"height": {"field": {"group": "height"}}
}
},
"marks": [
{
"name": "layer_0_marks",
"type": "line",
"style": ["line"],
"sort": {"field": "datum[\"dateTime\"]", "order": "descending"},
"from": {"data": "faceted_path_layer_0_main"},
"encode": {
"update": {
"opacity": [
{
"test": "(!domain || inrange(datum.dateTime, domain)) && (!length(data('selected')) || indata('selected', 'value', datum.category))",
"value": 0.7
},
{"value": 0.15}
],
"stroke": [
{
"test": "(!domain || inrange(datum.dateTime, domain)) && (!length(data('selected')) || indata('selected', 'value', datum.category))",
"scale": "color",
"field": "category"
},
{"value": "#ccc"}
],
"tooltip": {
"signal": "{\"Time\": timeFormat(datum[\"dateTime\"], '%b %d, %Y %H:%M'), \"Count\": format(datum[\"count\"], \"\"), \"category\": ''+datum[\"category\"]}"
},
"x": {"scale": "x", "field": "dateTime"},
"y": {"scale": "y", "field": "count"},
"defined": {
"signal": "datum[\"dateTime\"] !== null && !isNaN(datum[\"dateTime\"]) && datum[\"count\"] !== null && !isNaN(datum[\"count\"])"
}
}
}
}
]
},
{
"name": "layer_1_pathgroup",
"type": "group",
"from": {
"facet": {
"name": "faceted_path_layer_1_main",
"data": "data_2",
"groupby": ["category"]
}
},
"encode": {
"update": {
"width": {"field": {"group": "width"}},
"height": {"field": {"group": "height"}}
}
},
"marks": [
{
"name": "layer_1_marks",
"type": "line",
"style": ["line"],
"sort": {"field": "datum[\"dateTime\"]", "order": "descending"},
"from": {"data": "faceted_path_layer_1_main"},
"encode": {
"update": {
"stroke": {"value": "red"},
"opacity": [
{
"test": "(!domain || inrange(datum.dateTime, domain)) && (!length(data('selected')) || indata('selected', 'value', datum.category))",
"value": 0.7
},
{"value": 0.15}
],
"tooltip": {
"signal": "{\"Time\": timeFormat(datum[\"dateTime\"], '%b %d, %Y %H:%M'), \"Count\": format(datum[\"count\"], \"\"), \"category\": ''+datum[\"category\"]}"
},
"x": {"scale": "x", "field": "dateTime"},
"y": {"scale": "y", "field": "count"},
"defined": {
"signal": "datum[\"dateTime\"] !== null && !isNaN(datum[\"dateTime\"]) && datum[\"count\"] !== null && !isNaN(datum[\"count\"])"
}
}
}
}
]
},
{
"name": "layer_2_marks",
"type": "symbol",
"style": ["circle"],
"from": {"data": "data_3"},
"encode": {
"update": {
"opacity": [
{
"test": "(!domain || inrange(datum.dateTime, domain)) && (!length(data('selected')) || indata('selected', 'value', datum.category))",
"value": 0.7
},
{"value": 0.15}
],
"fill": [
{
"test": "datum[\"dateTime\"] === null || isNaN(datum[\"dateTime\"]) || datum[\"count\"] === null || isNaN(datum[\"count\"])",
"value": null
},
{"value": "red"}
],
"tooltip": {
"signal": "{\"Time\": timeFormat(datum[\"dateTime\"], '%b %d, %Y %H:%M'), \"Count\": format(datum[\"count\"], \"\"), \"category\": ''+datum[\"category\"]}"
},
"x": {"scale": "x", "field": "dateTime"},
"y": {"scale": "y", "field": "count"},
"shape": {"value": "circle"}
}
}
}
],
"scales": [
{
"name": "x",
"type": "time",
"domain": {
"fields": [
{"data": "data_1", "field": "dateTime"},
{"data": "data_2", "field": "dateTime"},
{"data": "data_3", "field": "dateTime"}
]
},
"range": [0, {"signal": "width"}]
},
{
"name": "y",
"type": "linear",
"domain": {
"fields": [
{"data": "data_1", "field": "count"},
{"data": "data_2", "field": "count"},
{"data": "data_3", "field": "count"}
]
},
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
},
{
"name": "color",
"type": "ordinal",
"domain": {"data": "data_1", "field": "category", "sort": true},
"range": {"scheme": "tableau20"}
}
],
"axes": [
{
"scale": "x",
"orient": "bottom",
"grid": false,
"title": "Time",
"titleColor":"black",
"labelColor":"black",
"labelFlush": true,
"labelOverlap": true,
"tickCount": {"signal": "ceil(width/40)"},
"encode": {
"labels": {
"update": {
"text": {"signal": "timeFormat(datum.value, '%b %d, %Y %H:%M')"}
}
}
},
"zindex": 1
},
{
"scale": "y",
"orient": "left",
"grid": false,
"titleColor":"black",
"labelColor":"black",
"title": "Count",
"labelOverlap": true,
"tickCount": {"signal": "ceil(height/40)"},
"zindex": 1
}
],
"legends": [
{
"stroke": "color",
"orient": "top-left",
"title": "React Vega",
"titleColor":"black",
"labelColor":"black",
"encode": {
"symbols": {
"name": "legendSymbol",
"interactive": true,
"update": {
"fill": {"value": "transparent"},
"strokeWidth": {"value": 2},
"opacity": [
{
"test": "!length(data('selected')) || indata('selected', 'value', datum.value)",
"value": 0.7
},
{"value": 0.15}
],
"size": {"value": 64}
}
},
"labels": {
"name": "legendLabel",
"interactive": true,
"update": {
"opacity": [
{
"test": "!length(data('selected')) || indata('selected', 'value', datum.value)",
"value": 1
},
{"value": 0.25}
]
}
}
}
}
],
"config": {"axisY": {"minExtent": 30}}
}
Я добавил изображение метки правила для справки.