Vega-Lite Binned Line Chart - vega-lite

I'm currently loving Vega-Lite but I'm running into an issue and while I've tried a lot of different things I can't seem to figure it out.
Is there a way to get the following Vega-Lite chart to have the line start and end at the edges instead of starting/ending in the middle of the bin?
const data = [
{ "start_time": "2021-07-10T00:00:00Z", "end_time": "2021-07-10T01:00:00Z", "value": 30 },
{ "start_time": "2021-07-10T01:00:00Z", "end_time": "2021-07-10T02:00:00Z", "value": 100 },
{ "start_time": "2021-07-10T02:00:00Z", "end_time": "2021-07-10T03:00:00Z", "value": 190 },
{ "start_time": "2021-07-10T03:00:00Z", "end_time": "2021-07-10T04:00:00Z", "value": 120 },
{ "start_time": "2021-07-10T04:00:00Z", "end_time": "2021-07-10T05:00:00Z", "value": 70 },
{ "start_time": "2021-07-10T05:00:00Z", "end_time": "2021-07-10T06:00:00Z", "value": 60 },
{ "start_time": "2021-07-10T06:00:00Z", "end_time": "2021-07-10T07:00:00Z", "value": 33 },
{ "start_time": "2021-07-10T07:00:00Z", "end_time": "2021-07-10T08:00:00Z", "value": 127 },
{ "start_time": "2021-07-10T08:00:00Z", "end_time": "2021-07-10T09:00:00Z", "value": 200 },
{ "start_time": "2021-07-10T09:00:00Z", "end_time": "2021-07-10T10:00:00Z", "value": 50 },
{ "start_time": "2021-07-10T10:00:00Z", "end_time": "2021-07-10T11:00:00Z", "value": 60 },
{ "start_time": "2021-07-10T11:00:00Z", "end_time": "2021-07-10T12:00:00Z", "value": 70 },
{ "start_time": "2021-07-10T12:00:00Z", "end_time": "2021-07-10T13:00:00Z", "value": 80 },
{ "start_time": "2021-07-10T13:00:00Z", "end_time": "2021-07-10T14:00:00Z", "value": 90 },
{ "start_time": "2021-07-10T14:00:00Z", "end_time": "2021-07-10T15:00:00Z", "value": 100 },
{ "start_time": "2021-07-10T15:00:00Z", "end_time": "2021-07-10T16:00:00Z", "value": 22 },
{ "start_time": "2021-07-10T16:00:00Z", "end_time": "2021-07-10T17:00:00Z", "value": 190 },
{ "start_time": "2021-07-10T17:00:00Z", "end_time": "2021-07-10T18:00:00Z", "value": 37 },
{ "start_time": "2021-07-10T18:00:00Z", "end_time": "2021-07-10T19:00:00Z", "value": 33 },
{ "start_time": "2021-07-10T19:00:00Z", "end_time": "2021-07-10T20:00:00Z", "value": 150 },
{ "start_time": "2021-07-10T20:00:00Z", "end_time": "2021-07-10T21:00:00Z", "value": 170 },
{ "start_time": "2021-07-10T21:00:00Z", "end_time": "2021-07-10T22:00:00Z", "value": 130 },
{ "start_time": "2021-07-10T22:00:00Z", "end_time": "2021-07-10T23:00:00Z", "value": 200 },
{ "start_time": "2021-07-10T23:00:00Z", "end_time": "2021-07-10T24:00:00Z", "value": 55 }
];
const spec = {
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"autosize": {
"type": "fit",
"resize": true,
"contains": "content"
},
"height": 150,
"width": "container",
"data": { "values": data },
"mark": {
"type": "line",
"point": true
},
"encoding": {
"x": {
"field": "start_time",
"bin": { "binned": true },
"type": "temporal",
"title": "Time"
},
"x2": {
"field": "end_time"
},
"y": {
"field": "value",
"type": "quantitative",
"title": "Count"
}
}
};
vegaEmbed('#vis', spec);
#vis {
width: 100%;
}
<script src="https://cdn.jsdelivr.net/npm/vega#5.20.2"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-lite#5.0.0"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-embed#6.18.2"></script>
<div id="vis"></div>

You can give padding in scale of x-axis, with that you will be able to remove spacing. There are other configs like innerPadding which you can check in documentation. But padding seemed to work. Also noticed that by removing the x2 encoding gave the same result of start/end connecting with edge. Refer the editor and snipped below:
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"autosize": {"type": "fit", "resize": true, "contains": "content"},
"height": 150,
"width": "container",
"data": {
"values": [
{
"start_time": "2021-07-10T00:00:00Z",
"end_time": "2021-07-10T01:00:00Z",
"value": 30
},
{
"start_time": "2021-07-10T01:00:00Z",
"end_time": "2021-07-10T02:00:00Z",
"value": 100
},
{
"start_time": "2021-07-10T02:00:00Z",
"end_time": "2021-07-10T03:00:00Z",
"value": 190
},
{
"start_time": "2021-07-10T03:00:00Z",
"end_time": "2021-07-10T04:00:00Z",
"value": 120
},
{
"start_time": "2021-07-10T04:00:00Z",
"end_time": "2021-07-10T05:00:00Z",
"value": 70
},
{
"start_time": "2021-07-10T05:00:00Z",
"end_time": "2021-07-10T06:00:00Z",
"value": 60
},
{
"start_time": "2021-07-10T06:00:00Z",
"end_time": "2021-07-10T07:00:00Z",
"value": 33
},
{
"start_time": "2021-07-10T07:00:00Z",
"end_time": "2021-07-10T08:00:00Z",
"value": 127
},
{
"start_time": "2021-07-10T08:00:00Z",
"end_time": "2021-07-10T09:00:00Z",
"value": 200
},
{
"start_time": "2021-07-10T09:00:00Z",
"end_time": "2021-07-10T10:00:00Z",
"value": 50
},
{
"start_time": "2021-07-10T10:00:00Z",
"end_time": "2021-07-10T11:00:00Z",
"value": 60
},
{
"start_time": "2021-07-10T11:00:00Z",
"end_time": "2021-07-10T12:00:00Z",
"value": 70
},
{
"start_time": "2021-07-10T12:00:00Z",
"end_time": "2021-07-10T13:00:00Z",
"value": 80
},
{
"start_time": "2021-07-10T13:00:00Z",
"end_time": "2021-07-10T14:00:00Z",
"value": 90
},
{
"start_time": "2021-07-10T14:00:00Z",
"end_time": "2021-07-10T15:00:00Z",
"value": 100
},
{
"start_time": "2021-07-10T15:00:00Z",
"end_time": "2021-07-10T16:00:00Z",
"value": 22
},
{
"start_time": "2021-07-10T16:00:00Z",
"end_time": "2021-07-10T17:00:00Z",
"value": 190
},
{
"start_time": "2021-07-10T17:00:00Z",
"end_time": "2021-07-10T18:00:00Z",
"value": 37
},
{
"start_time": "2021-07-10T18:00:00Z",
"end_time": "2021-07-10T19:00:00Z",
"value": 33
},
{
"start_time": "2021-07-10T19:00:00Z",
"end_time": "2021-07-10T20:00:00Z",
"value": 150
},
{
"start_time": "2021-07-10T20:00:00Z",
"end_time": "2021-07-10T21:00:00Z",
"value": 170
},
{
"start_time": "2021-07-10T21:00:00Z",
"end_time": "2021-07-10T22:00:00Z",
"value": 130
},
{
"start_time": "2021-07-10T22:00:00Z",
"end_time": "2021-07-10T23:00:00Z",
"value": 200
},
{
"start_time": "2021-07-10T23:00:00Z",
"end_time": "2021-07-10T24:00:00Z",
"value": 55
}
]
},
"mark": {"type": "line", "point": true},
"encoding": {
"x": {
"field": "start_time",
"bin": {"binned": true},
"scale": {"padding": "-8"},
"type": "temporal",
"title": "Time"
},
"x2": {"field": "end_time"},
"y": {"field": "value", "type": "quantitative", "title": "Count"}
}
}

There are at least 2 ways to do so as far as I know:
Band : Adding bandPosition in x encoding (easier as designed)
See Vega Editor
"x": {
...,
"bandPosition": 0,
"scale": { "domain": ["2021-07-10T00:00:00Z", "2021-07-10T23:00:00Z"]},
},
Axis : Adding tickOffset and labelOffset in axis of x encoding (ticks/labels are separated and more controllable in terms of px)
See Vega Editor
"x": {
...,
"axis": { "tickOffset": 10, "labelOffset": 10 }
},

Related

vega-lite dougnut chart with a dropdown is not working as expected. What am I doing wrong?

I have a vega-lite chart that I need a dropdown for and am having trouble getting it to work as expected. It looks to me like by default it is selecting data for the last element in the data [agent 'Tommy'] and the colors are fine for the data that's there. When another agent is selected the colors do not update correctly. null is in the list and that seems to reset the chart back to the correct colors for the last agent again. This is my json in the editor. Any help would be appreciated.
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {
"values": [
{"agent": "Mabel", "type": "answered less than 20", "value": 9},
{"agent": "Mabel", "type": "answered less than 15", "value": 15},
{"agent": "Mabel", "type": "answered less than 10", "value": 24},
{"agent": "Mabel", "type": "answered less than 5", "value": 11},
{"agent": "Mabel", "type": "answered greater than 20", "value": 4},
{"agent": "Mabel", "type": "abandon system", "value": 0},
{"agent": "Mabel", "type": "abandon agent", "value": 9},
{"agent": "Bart", "type": "answered less than 20", "value": 3},
{"agent": "Bart", "type": "answered less than 15", "value": 1},
{"agent": "Bart", "type": "answered less than 10", "value": 6},
{"agent": "Bart", "type": "answered less than 5", "value": 14},
{"agent": "Bart", "type": "answered greater than 20", "value": 11},
{"agent": "Bart", "type": "abandon system", "value": 0},
{"agent": "Bart", "type": "abandon agent", "value": 8},
{"agent": "Tommy", "type": "answered less than 20", "value": 48},
{"agent": "Tommy", "type": "answered less than 15", "value": 18},
{"agent": "Tommy", "type": "answered less than 10", "value": 11},
{"agent": "Tommy", "type": "answered less than 5", "value": 15},
{"agent": "Tommy", "type": "answered greater than 20", "value": 2},
{"agent": "Tommy", "type": "abandon system", "value": 0},
{"agent": "Tommy", "type": "abandon agent", "value": 11}
]
},
"description": "test",
"height": 200,
"layer": [
{
"encoding": {
"color": {
"condition": {"param": "Agents", "field": "type", "scale": {"scheme": "spectral"}, "type": "nominal"},
"value": "grey"
},
"theta": {"field": "value", "type": "quantitative"},
"tooltip": [
{"field": "type", "type": "nominal"},
{"field": "value", "type": "quantitative"}
]
},
"mark": {"innerRadius": 50, "outerRadius": 100, "type": "arc"},
"params": [
{
"bind": {
"input": "select",
"options": [null, "Mabel", "Bart", "Tommy"]
},
"name": "Agents",
"select": {"fields": ["agent"], "type": "point"}
}
]
},
{
"encoding": {"text": {"field": "total", "type": "nominal"}},
"mark": {
"fontSize": 23,
"fontWeight": "bold",
"tooltip": "Calls answered within 20 seconds",
"type": "text"
}
}
],
"title": "Agent Service Levels",
"width": 200
}
this json worked:
the keys were:
the color condition
the transform
the auto size with the resize set to true to fix the legend after the filter update.
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {
"values": [
{
"agent": "Mabel",
"type": "answered less than 20",
"value": 5
},
{
"agent": "Mabel",
"type": "answered less than 15",
"value": 15
},
{
"agent": "Mabel",
"type": "answered less than 10",
"value": 16
},
{
"agent": "Mabel",
"type": "answered less than 5",
"value": 13
},
{
"agent": "Mabel",
"type": "answered greater than 20",
"value": 2
},
{
"agent": "Mabel",
"type": "abandon system",
"value": 0
},
{
"agent": "Mabel",
"type": "abandon agent",
"value": 8
},
{
"agent": "Bart",
"type": "answered less than 20",
"value": 8
},
{
"agent": "Bart",
"type": "answered less than 15",
"value": 28
},
{
"agent": "Bart",
"type": "answered less than 10",
"value": 21
},
{
"agent": "Bart",
"type": "answered less than 5",
"value": 7
},
{
"agent": "Bart",
"type": "answered greater than 20",
"value": 1
},
{
"agent": "Bart",
"type": "abandon system",
"value": 0
},
{
"agent": "Bart",
"type": "abandon agent",
"value": 3
},
{
"agent": "Tommy",
"type": "answered less than 20",
"value": 15
},
{
"agent": "Tommy",
"type": "answered less than 15",
"value": 9
},
{
"agent": "Tommy",
"type": "answered less than 10",
"value": 14
},
{
"agent": "Tommy",
"type": "answered less than 5",
"value": 5
},
{
"agent": "Tommy",
"type": "answered greater than 20",
"value": 12
},
{
"agent": "Tommy",
"type": "abandon system",
"value": 0
},
{
"agent": "Tommy",
"type": "abandon agent",
"value": 10
}
]
},
"description": "test",
"height": 200,
"layer": [
{
"encoding": {
"color": {
"condition": {
"param": "Agents",
"field": "type",
"type": "nominal",
"scale": {
"scheme": "spectral"
}
},
"value": null
},
"opacity": {
"condition": {
"param": "industry",
"value": 1
},
"value": 0.2
},
"theta": {
"field": "value",
"type": "quantitative"
},
"tooltip": [
{
"field": "type",
"type": "nominal"
},
{
"field": "value",
"type": "quantitative"
}
]
},
"mark": {
"innerRadius": 50,
"outerRadius": 100,
"type": "arc"
},
"params": [
{
"bind": {
"input": "select",
"options": [
"{none}",
"Mabel",
"Bart",
"Tommy"
]
},
"name": "Agents",
"select": {
"fields": [
"agent"
],
"type": "point"
}
},
{
"bind": "legend",
"name": "industry",
"select": {
"fields": [
"type"
],
"type": "point"
}
}
],
"transform": [
{
"filter": {
"field": "agent",
"equal": {
"expr": "Agents_agent"
}
}
}
]
},
{
"encoding": {
"text": {
"value": "100%"
}
},
"mark": {
"fontSize": 23,
"fontWeight": "bold",
"tooltip": "Calls answered within 20 seconds",
"type": "text"
}
}
],
"title": "Agent Service Levels",
"width": 300,
"autosize": {
"type": "pad",
"contains": "padding",
"resize": true
}
}

Vega bar line chart opacity issue

In Vega Barline chart, I am looking help, when mouseover on Bar chart, line chart should be blur but all bar should be with opacity 1, similar when mouseover on line chart, bar chart should be blur.
In Vega Barline chart, I am looking help, when mouseover on Bar chart, line chart should be blur but all bar should be with opacity 1, similar when mouseover on line chart, bar chart should be blur.
I tried with below JSON
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"background": "transparent",
"width": 600,
"height": 300,
"style": "linear",
"data": [
{ "name": "barlineChart_store" },
{ "name": "barChart_store" },
{ "name": "lineChart_store" },
{
"name": "source_0",
"values": [ {
"year": 2013,
"value": 10
},
{
"year": 2014,
"value": 19
},
{
"year": 2015,
"value": 33
},
{
"year": 2016,
"value": 74
},
{
"year": 2017,
"value": 87
},
{
"year": 2018,
"value": 13
}, {
"year": 2019,
"value": 110
} ,
{
"year": 2020,
"value": 40
},
{
"year": 2021,
"value": 50
},{
"year": 2022,
"value": 49
}]
},
{
"name": "source_2",
"values": [ {
"year": 2013,
"value": 279670000
},
{
"year": 2014,
"value": 1017789660
},
{
"year": 2015,
"value": 4604761843
},
{
"year": 2016,
"value": 1829007526
},
{
"year": 2017,
"value": 21831592682
},
{
"year": 2018,
"value": 9236173024
},{
"year": 2019,
"value": 9848990024
},{
"year": 2020,
"value": 13365764829
},{
"year": 2021,
"value": 27294260073
},{
"year": 2022,
"value": 9982818889
}]
},
{
"name": "data_0",
"source": "source_0",
"transform": [
{
"type": "formula",
"expr": "timeParse(datum[\"year\"],'%Y')",
"as": "year",
},
{
"field": "year",
"type": "timeunit",
"units": ["year"],
"as": ["year_year", "year_year_end"],
},
{
"type": "stack",
"groupby": ["year_year"],
"field": "value",
"sort": { "field": [], "order": [] },
"as": ["value_start", "value_end"],
"offset": "zero",
},
{
"type": "filter",
"expr": "isValid(datum[\"value\"]) && isFinite(+datum[\"value\"])",
},
],
},
{
"name": "data_1",
"source": "source_2",
"transform": [
{
"type": "formula",
"expr": "timeParse(datum[\"year\"],'%Y')",
"as": "year",
},
{
"field": "year",
"type": "timeunit",
"units": ["year"],
"as": ["year_year", "year_year_end"],
},
],
},
{
"name": "data_2",
"source": "source_2",
"transform": [
{
"type": "formula",
"expr": "timeParse(datum[\"year\"],'%Y')",
"as": "year",
},
{
"field": "year",
"type": "timeunit",
"units": ["year"],
"as": ["year_year", "year_year_end"],
},
],
},
{
"name": "data_3",
"source": "data_2",
"transform": [
{
"type": "filter",
"expr": "isValid(datum[\"value\"]) && isFinite(+datum[\"value\"])",
},
],
},
],
"marks": [
{
"type": "group",
"name": "concat_0_group",
"signals": [
{
"name": "mouse__move",
"on": [
{
"events": [
{
"source": "scope",
"type": "mouseover",
},
],
"update":
"datum && item().mark.marktype !== \"group\" ? {unit: \"concat_0\", fields: recentTransaction_name, values: [(item().isVoronoi ? datum.datum : datum)[\"value\"]]} : null",
"force": true,
},
{
"events": [{ "source": "view", "type": "mouseout" }],
"update": "null",
},
],
},
{
"name": "recentTransaction_name",
"value": [{ "type": "E", "field": "value" }],
},
{
"name": "updated_barlinechart",
"on": [
{
"events": { "signal": "mouse__move" },
"update": "modify(\"barlineChart_store\", mouse__move, true)",
},
],
},
{
"name": "updated_linechart",
"on": [
{
"events": { "signal": "mouse__move" },
"update": "modify(\"lineChart_store\", mouse__move, true)",
},
],
},
{
"name": "updated_barchart",
"on": [
{
"events": { "signal": "mouse__move" },
"update": "modify(\"barChart_store\", mouse__move, true)",
},
],
},
],
"marks": [
{
"name": "bar",
"type": "rect",
"style": ["rect"],
"from": {"data": "data_0"},
"encode": {
"update": {
"fill": { "value": "#b14891" },
"description": {
"signal": "\"start (year): \" + (timeFormat(datum[\"year_start\"], timeUnitSpecifier([\"year\"], {\"year-month\":\"%b %Y \",\"year-month-date\":\"%b %d, %Y \"}))) + \"; end (year): \" + (timeFormat(datum[\"year_end\"], timeUnitSpecifier([\"year\"], {\"year-month\":\"%b %Y \",\"year-month-date\":\"%b %d, %Y \"})))"
},
"x": { "scale": "x", "field": "year_year" },
"width": { "scale": "x", "band": 1 },
"y": { "scale": "layer_0_y", "field": "value_end",
},
"y2": { "scale": "layer_0_y", "field": "value_start" },
"tooltip": {
"signal": "{'Value of Transactions': datum.value}",
},
"opacity": [
{
"test":
"(!length(data('barChart_store')) || vlSelectionTest('barChart_store', datum)) ",
"value": 1,
},
{ "value": 0.2 },
],
"fillopacity": [
{
"test":
"(length(data('barChart_store')) || vlSelectionTest('barChart_store', datum)) ",
"value": 1
},
{"value": 0.2}
],
},
"hover": {
"fillOpacity": {"value": 1}
}
}
},
{
"name": "line",
"type": "line",
"style": ["line"],
"from": { "data": "data_1" },
"encode": {
"update": {
"strokeWidth": { "value": 3 },
"stroke": { "value": "#35a4e8" },
"description": {
"signal":
"'year (year): ' + (timeFormat(datum['year_year'], '%Y'))",
},
"x": { "scale": "x", "field": "year_year", "band": 0.5 },
"y": { "scale": "layer_2_y", "field": "value" ,
},
"tooltip": {
"signal": "{'Value of Transactions': datum.value}",
},
"opacity": [
{
"test":
"(!length(data('barlineChart_store')) || vlSelectionTest('barlineChart_store', datum)) ",
"value": 1,
},
{ "value": 0.7 },
],
"hover": {
"fillOpacity": {"value": 1}
}
},
},
},
{
"name": "point",
"type": "symbol",
"style": ["point"],
"from": { "data": "data_1" },
"encode": {
"update": {
"fill": { "value": "#24242d" },
"stroke": { "value": "#35a4e8" },
"strokeWidth": { "value": 3.5 },
"size" : {"value": "100"},
"ariaRoleDescription": { "value": "point" },
"description": {
"signal":
"'year (year): ' + (timeFormat(datum['year_year'], '%Y'))",
},
"opacity": [
{
"test":
"(!length(data('barlineChart_store')) || vlSelectionTest('barlineChart_store', datum)) ",
"value": 1,
},
{ "value": 0.2 },
],
"x": { "scale": "x", "field": "year_year", "band": 0.5 },
"y": { "scale": "layer_2_y", "field": "value" },
"tooltip": {
"signal": "{'Value of Transactions': datum.value}",
},
},
},
}
],
},
],
"scales": [
{
"name": "x",
"type": "band",
"domain": {
"fields": [
{ "data": "data_0", "field": "year_year" },
{ "data": "data_1", "field": "year_year" },
{ "data": "data_2", "field": "year_year" },
],
"sort": true,
},
"range": [0, { "signal": "width" }],
"padding": 0.6,
},
{
"name": "layer_0_y",
"type": "linear",
"domain": { "data": "data_0", "fields": ["value_start", "value_end"] },
"range": [{ "signal": "height" }, 0],
"nice": true,
"zero": true,
},
{
"name": "layer_2_y",
"type": "linear",
"domain": {
"fields": [
{ "data": "data_2", "field": "value" },
],
},
"range": [{ "signal": "height" }, 0],
"nice": true,
"zero": true,
},
{
"name": "color",
"type": "ordinal",
"domain": ["Number of Transactions", "Value of Transactions"],
"range": ["#ca61aa", "#35a4e8"],
},
],
"axes": [
{
"scale": "x",
"orient": "bottom",
"grid": false,
"labelAngle": 0,
"format": "%Y",
"formatType": "time",
"labelBaseline": "top",
"labelFlush": true,
"labelOverlap": true,
"zindex": 0,
"labelPadding":10,
},
{
"scale": "layer_0_y",
"orient": "left",
"grid": true,
"labelOverlap": true,
"tickCount": { "signal": "ceil(height/80)" },
"zindex": 0,
"title":"Value",
"titleColor":"white",
"labelPadding":10,
},
{
"scale": "layer_2_y",
"orient": "right",
"grid": false,
"labelOverlap": true,
"tickCount": { "signal": "ceil(height/80)" },
"format":".2s",
"zindex": 0,
"title":"Amount",
"titleColor":"white",
"labelPadding":10,
},
],
"legends": [{ "labelColor": "#c4c4cd ", "fill": "color", "direction": "horizontal" ,"orient":"bottom",
"encode": {
"labels": {
"name": "category_legend_labels",
"interactive": true
},
"symbols": {
"name": "category_legend_symbols",
"interactive": true
},
"entries": {
"name": "category_legend_entries",
"interactive": true,
"update": {"fill": {"value": "transparent"}}
}
}}],
"config": { "axis": { "labelColor": "white", "title": "" ,"domain": false, "grid": false,"gridColor": "#979797", "ticks": false},"legend": { "columns":{"signal": "3"},"orient": "bottom",
"layout": {"bottom": {"anchor": "middle"}},
"labelColor": "white"}}
}

Delete select elements in a JSON structure with jq

I want to delete certain elements in a JSON file that match a search criteria while maintaining the rest of the JSON structure. The element I wish to match and remove is an object in the .chapter array - .tags.title that contains the text #MKR#
I've got some idea how to select the correct elements using:
jq -r '.chapters[] | select(.tags.title | contains("#MKR#"))' metadata.json
but don't know how to select and delete those elements whilst leaving the rest of the structure intact.
Example Input JSON - metadata.json:
{
"chapters": [
{
"id": 0,
"time_base": "1/3000",
"start": 0,
"start_time": "0.000000",
"end": 9200,
"end_time": "3.066667",
"tags": {
"title": "Start"
}
},
{
"id": 1,
"time_base": "1/3000",
"start": 9200,
"start_time": "3.066667",
"end": 15000,
"end_time": "5.000000",
"tags": {
"title": "Example(1) #MKR#"
}
},
{
"id": 2,
"time_base": "1/3000",
"start": 15000,
"start_time": "5.000000",
"end": 18900,
"end_time": "6.300000",
"tags": {
"title": "Example(2)"
}
},
{
"id": 3,
"time_base": "1/3000",
"start": 18900,
"start_time": "6.300000",
"end": 124299,
"end_time": "41.433000",
"tags": {
"title": "Example(3) #MKR#"
}
},
{
"id": 4,
"time_base": "1/3000",
"start": 124299,
"start_time": "41.433000",
"end": 225700,
"end_time": "75.233333",
"tags": {
"title": "Example(4) #MKR#"
}
},
{
"id": 5,
"time_base": "1/3000",
"start": 225700,
"start_time": "75.233333",
"end": 231900,
"end_time": "77.300000",
"tags": {
"title": "Example(5) #MKR#"
}
}
],
"format": {
"filename": "video_mkr_temp.mp4",
"nb_streams": 3,
"nb_programs": 0,
"format_name": "mov,mp4,m4a,3gp,3g2,mj2",
"format_long_name": "QuickTime / MOV",
"start_time": "0.000000",
"duration": "968.300000",
"size": "399977859",
"bit_rate": "3304577",
"probe_score": 100,
"tags": {
"major_brand": "mp42",
"minor_version": "512",
"compatible_brands": "isomiso2avc1mp41",
"creation_time": "2020-04-12T00:46:21.000000Z"
}
}
}
Example Output JSON I want to achieve:
{
"chapters": [
{
"id": 0,
"time_base": "1/3000",
"start": 0,
"start_time": "0.000000",
"end": 9200,
"end_time": "3.066667",
"tags": {
"title": "Start"
}
},
{
"id": 2,
"time_base": "1/3000",
"start": 15000,
"start_time": "5.000000",
"end": 18900,
"end_time": "6.300000",
"tags": {
"title": "Example(2)"
}
},
],
"format": {
"filename": "video_mkr_temp.mp4",
"nb_streams": 3,
"nb_programs": 0,
"format_name": "mov,mp4,m4a,3gp,3g2,mj2",
"format_long_name": "QuickTime / MOV",
"start_time": "0.000000",
"duration": "968.300000",
"size": "399977859",
"bit_rate": "3304577",
"probe_score": 100,
"tags": {
"major_brand": "mp42",
"minor_version": "512",
"compatible_brands": "isomiso2avc1mp41",
"creation_time": "2020-04-12T00:46:21.000000Z"
}
}
}
Any thoughts greatly appreciated.
Thanks
You can filter out your chapters with something like this:
jq '.chapters |= map(select(.tags.title | contains("#MKR#") | not))' metadata.json
The -r option is only useful when the filter output is a string, whereas here it is a json object.

Customise vega-lite Line Graph Axis Labels

What I want to do is really simple, but I just can't seem to get it right. I have a feeling I'm going to be embarrassed by the answer!
I have a line graph with "attempt" along the x-axis and "grade" along the y-axis, with grade being a number between 0 and 100. I simply want to change the y-axis so that, instead of seeing the raw number, a grade is show, say with 0 - 20 representing "E", 20-40 being "D" etc up to "A" (80-100). How can I do that? I don't want to use discrete values because I want to visually show where within a grade boundary a grade falls. I'm not sure whether I yet want to simply display the grade bands on the line or put them in the middle of their ticks, but just getting somewhere with this would help a lot!
Here is what I've been working with in the vega-lite editor:
{
"$schema": "https://vega.github.io/schema/vega-lite/v3.json",
"data": {
"values": [
{
"attempt": 1,
"score": 30
},
{
"attempt": 2,
"score": 60
},
{
"attempt": 3,
"score": 75
},
{
"attempt": 4,
"score": 58
},
{
"attempt": 5,
"score": 67
}
]
},
"mark": {
"type": "line",
"color": "#22bc9a",
"point": {
"filled": false
}
},
"encoding": {
"x": {
"field": "attempt",
"type": "quantitative",
"axis": {
"grid": false,
"tickCount": 5,
"title": "Attempt"
}
},
"y": {
"field": "score",
"scale": {"domain": [0, 100]},
"type": "quantitative",
"axis": {
"tickCount": 5,
"title": "Grade"
}
},
"opacity": {"value": 0.3}
},
"config": {
"autosize": "fit",
"axis": {
"labelColor": "#bebec8",
"tickColor": "#bebec8",
"titleColor": "black",
"titleFontWeight": "normal",
"titleFontSize": 11,
"labelFont": "Helvetica",
"titleFont": "Helvetica",
"gridOpacity": 0.4,
"gridWidth": 1.5,
"domain": false
},
"view": {
"strokeWidth": 0
}
}
}
Thanks in advance.
What about something like this: I add a dataframe with the grade category, and use this to layer some text. I remove the labels of the axis and so the text acts as if it were the labels of the axis.
The chart looks like this, and here is a link to the editor:
Schema (Note that I did it with Python's Altair, so it may not be canonical Vega-lite, and I did not use your settings either, sorry about that):
{
"$schema": "https://vega.github.io/schema/vega-lite/v2.6.0.json",
"config": {
"view": {
"height": 300,
"width": 400
}
},
"datasets": {
"data-1acee7c5d817865a529b53e022474ce8": [
{
"label": "E",
"x_min": 1,
"y_med": 10
},
{
"label": "D",
"x_min": 1,
"y_med": 30
},
{
"label": "C",
"x_min": 1,
"y_med": 50
},
{
"label": "B",
"x_min": 1,
"y_med": 70
},
{
"label": "A",
"x_min": 1,
"y_med": 90
}
],
"data-8e6359ea3034b8410708361bb10fafd5": [
{
"attempt": 1,
"score": 30
},
{
"attempt": 2,
"score": 60
},
{
"attempt": 3,
"score": 75
},
{
"attempt": 4,
"score": 58
},
{
"attempt": 5,
"score": 67
}
]
},
"layer": [
{
"data": {
"name": "data-1acee7c5d817865a529b53e022474ce8"
},
"encoding": {
"text": {
"field": "label",
"type": "ordinal"
},
"x": {
"field": "x_min",
"scale": {
"zero": false
},
"type": "quantitative"
},
"y": {
"axis": {
"labels": false,
"tickCount": 5,
"ticks": false
},
"field": "y_med",
"type": "quantitative"
}
},
"mark": {
"dx": -15,
"dy": 8,
"size": 15,
"type": "text"
}
},
{
"data": {
"name": "data-8e6359ea3034b8410708361bb10fafd5"
},
"encoding": {
"x": {
"axis": {
"tickCount": 5
},
"field": "attempt",
"title": "Attempt",
"type": "quantitative"
},
"y": {
"field": "score",
"scale": {
"domain": [
0,
100
]
},
"title": "Grade",
"type": "quantitative"
}
},
"mark": {
"point": true,
"type": "line"
}
}
]
}
Using a slighly modified dataframe for the categories (with x_max, y_min and y_max added), you can add another layer with colored rectangles, that can help read the values:
Here is a link to the editor
And here is the schema
{
"$schema": "https://vega.github.io/schema/vega-lite/v2.6.0.json",
"config": {
"view": {
"height": 300,
"width": 400
}
},
"datasets": {
"data-1acee7c5d817865a529b53e022474ce8": [
{
"label": "E",
"x_min": 1,
"y_med": 10
},
{
"label": "D",
"x_min": 1,
"y_med": 30
},
{
"label": "C",
"x_min": 1,
"y_med": 50
},
{
"label": "B",
"x_min": 1,
"y_med": 70
},
{
"label": "A",
"x_min": 1,
"y_med": 90
}
],
"data-39ffbda2b5d5fe96de84d9e308d920ff": [
{
"label": "E",
"x_max": 5,
"x_min": 1,
"y_max": 20,
"y_med": 10,
"y_min": 0
},
{
"label": "D",
"x_max": 5,
"x_min": 1,
"y_max": 40,
"y_med": 30,
"y_min": 20
},
{
"label": "C",
"x_max": 5,
"x_min": 1,
"y_max": 60,
"y_med": 50,
"y_min": 40
},
{
"label": "B",
"x_max": 5,
"x_min": 1,
"y_max": 80,
"y_med": 70,
"y_min": 60
},
{
"label": "A",
"x_max": 5,
"x_min": 1,
"y_max": 100,
"y_med": 90,
"y_min": 80
}
],
"data-8e6359ea3034b8410708361bb10fafd5": [
{
"attempt": 1,
"score": 30
},
{
"attempt": 2,
"score": 60
},
{
"attempt": 3,
"score": 75
},
{
"attempt": 4,
"score": 58
},
{
"attempt": 5,
"score": 67
}
]
},
"layer": [
{
"data": {
"name": "data-39ffbda2b5d5fe96de84d9e308d920ff"
},
"encoding": {
"color": {
"field": "label",
"scale": {
"scheme": "greenblue"
},
"type": "ordinal"
},
"x": {
"field": "x_min",
"scale": {
"zero": false
},
"title": "Attempt",
"type": "quantitative"
},
"x2": {
"field": "x_max",
"type": "quantitative"
},
"y": {
"axis": null,
"field": "y_min",
"type": "quantitative"
},
"y2": {
"field": "y_max",
"type": "quantitative"
}
},
"mark": "rect"
},
{
"data": {
"name": "data-1acee7c5d817865a529b53e022474ce8"
},
"encoding": {
"text": {
"field": "label",
"type": "ordinal"
},
"x": {
"field": "x_min",
"scale": {
"zero": false
},
"type": "quantitative"
},
"y": {
"axis": {
"labels": false,
"tickCount": 5,
"ticks": false
},
"field": "y_med",
"type": "quantitative"
}
},
"mark": {
"dx": -15,
"dy": 8,
"size": 15,
"type": "text"
}
},
{
"data": {
"name": "data-8e6359ea3034b8410708361bb10fafd5"
},
"encoding": {
"x": {
"axis": {
"tickCount": 5
},
"field": "attempt",
"title": "Attempt",
"type": "quantitative"
},
"y": {
"field": "score",
"scale": {
"domain": [
0,
100
]
},
"title": "Grade",
"type": "quantitative"
}
},
"mark": {
"point": true,
"type": "line"
}
}
]
}
To get it working, I first had to change the encoding of the x and y axis to be ordinal. Then I mapped your input data values to letter grades before creating the schema:
//replace every score value with correct letter grade
values.forEach(datapoint => {
if(datapoint.score > 90) {
datapoint.score = "A";
} else if(datapoint.score > 80) {
datapoint.score = "B";
} else if (datapoint.score > 70) {
//so on...
}
});
Here is a working example in the vega-lite editor:
Line Chart with Ordinal Values
Here is the schema:
{
"$schema": "https://vega.github.io/schema/vega-lite/v3.json",
"data": {
"values": [
{
"attempt": 1,
"score": "F"
},
{
"attempt": 2,
"score": "D"
},
{
"attempt": 3,
"score": "C"
},
{
"attempt": 4,
"score": "F"
},
{
"attempt": 5,
"score": "D"
}
]
},
"mark": {
"type": "line",
"color": "#22bc9a",
"point": {
"filled": false
}
},
"encoding": {
"x": {
"field": "attempt",
"type": "ordinal",
"axis": {
"title": "Attempt"
}
},
"y": {
"field": "score",
"type": "ordinal",
"axis": {
"title": "Grade"
}
},
"opacity": {"value": 0.3}
},
"config": {
"autosize": "fit",
"axis": {
"labelColor": "#bebec8",
"tickColor": "#bebec8",
"titleColor": "black",
"titleFontWeight": "normal",
"titleFontSize": 11,
"labelFont": "Helvetica",
"titleFont": "Helvetica",
"gridOpacity": 0.4,
"gridWidth": 1.5
},
"view": {
"strokeWidth": 0
}
}
}

Proton CEP Absence EPA not triggered

I am unable to get ProtonCEP to create an event based on an absence rule.
The EPA "MissingQueueDataRule" is supposed to create an event "MissingQueueData" in the case that no events of type "QueueContextUpdate" (the entityID of the event is not important) are received in a past time interval (30 seconds).
There are no visible errors in the logs.
{
"epn": {
"events": [
{
"name": "Device",
"createdDate": "Thu Nov 12 2015",
"attributes": [
{
"name": "datacount5",
"type": "Integer",
"dimension": 0,
"description": "The certainty that this event happen (value between 0 to 1)"
}
]
},
{
"name": "Queue",
"createdDate": "Thu Nov 12 2015",
"attributes": [
{
"name": "name",
"type": "String",
"dimension": "0"
},
{
"name": "volume",
"type": "Integer",
"dimension": "0"
}
]
},
{
"name": "DeviceContextUpdate",
"createdDate": "Thu Nov 12 2015",
"attributes": [
{
"name": "datacount5m",
"type": "Integer",
"dimension": 0,
"description": "The certainty that this event happen (value between 0 to 1)"
},
{
"name": "entityId",
"type": "String",
"dimension": "0"
},
{
"name": "entityType",
"type": "String",
"dimension": "0"
},
{
"name": "lastupdate",
"type": "Date",
"dimension": "0"
},
{
"name": "activationdate",
"type": "Date",
"dimension": "0"
},
{
"name": "efficiencyratio",
"type": "Double",
"dimension": "0"
}
]
},
{
"name": "QueueContextUpdate",
"createdDate": "Thu Nov 12 2015",
"attributes": [
{
"name": "volume",
"type": "Integer",
"dimension": "0"
},
{
"name": "entityId",
"type": "String",
"dimension": "0"
},
{
"name": "entityType",
"type": "String",
"dimension": "0"
}
]
},
{
"name": "QueueVolumeHigh",
"createdDate": "Wed Jan 27 2016",
"attributes": [
{
"name": "Certainty",
"type": "Double",
"defaultValue": "1",
"dimension": 0,
"description": "The certainty that this event happen (value between 0 to 1)"
},
{
"name": "OccurrenceTime",
"type": "Date",
"dimension": 0,
"description": "No value means it equals the event detection time, other option is to use one of the defined distribution functions with parameters"
},
{
"name": "ExpirationTime",
"type": "Date",
"dimension": 0
},
{
"name": "Cost",
"type": "Double",
"dimension": 0,
"description": "The cost of this event occurrence. Negative if this is an opportunity"
},
{
"name": "Duration",
"type": "Double",
"defaultValue": "0",
"dimension": 0,
"description": "Used in case the this event occur within an interval"
},
{
"name": "AffectedEntity",
"type": "String",
"dimension": "0"
},
{
"name": "AffectedEntityType",
"type": "String",
"dimension": "0"
},
{
"name": "EventType",
"type": "String",
"dimension": "0"
},
{
"name": "EventSeverity",
"type": "String",
"dimension": "0"
},
{
"name": "AffectedEntityVolume",
"type": "Integer",
"dimension": "0"
}
]
},
{
"name": "MissingQueueData",
"createdDate": "Wed Jan 27 2016",
"attributes": [
{
"name": "Certainty",
"type": "Double",
"defaultValue": "1",
"dimension": 0,
"description": "The certainty that this event happen (value between 0 to 1)"
},
{
"name": "OccurrenceTime",
"type": "Date",
"dimension": 0,
"description": "No value means it equals the event detection time, other option is to use one of the defined distribution functions with parameters"
},
{
"name": "ExpirationTime",
"type": "Date",
"dimension": 0
},
{
"name": "Cost",
"type": "Double",
"dimension": 0,
"description": "The cost of this event occurrence. Negative if this is an opportunity"
},
{
"name": "Duration",
"type": "Double",
"defaultValue": "0",
"dimension": 0,
"description": "Used in case the this event occur within an interval"
},
{
"name": "EventSeverity",
"type": "String",
"defaultValue": "\"Warning\"",
"dimension": "0"
}
]
}
],
"epas": [
{
"name": "CriticalQueueVolumeRule",
"description": "Emit a QueueVolumeHigh with Severity=Critical if any Queue volume > 1000",
"createdDate": "Wed Jan 27 2016",
"createdBy": "Pedro",
"epaType": "All",
"context": "CriticalQueueVolumeComb",
"inputEvents": [
{
"name": "QueueContextUpdate",
"filterExpression": "QueueContextUpdate.volume>1000",
"consumptionPolicy": "Consume",
"instanceSelectionPolicy": "First"
}
],
"computedVariables": [],
"evaluationPolicy": "Immediate",
"cardinalityPolicy": "Single",
"internalSegmentation": [],
"derivedEvents": [
{
"name": "QueueVolumeHigh",
"reportParticipants": false,
"expressions": {
"OccurrenceTime": "QueueContextUpdate.DetectionTime",
"Duration": "0",
"AffectedEntity": "QueueContextUpdate.entityId",
"AffectedEntityType": "QueueContextUpdate.entityType",
"EventType": "\"QueueVolumeHigh\"",
"EventSeverity": "\"Critical\"",
"AffectedEntityVolume": "QueueContextUpdate.volume"
}
}
]
},
{
"name": "MissingQueueDataRule",
"description": "Detect when the scripts stop working and sending queue data",
"createdDate": "Wed Jan 27 2016",
"epaType": "Absence",
"context": "MissingQueueDataWindow",
"inputEvents": [
{
"name": "QueueContextUpdate",
"alias": "Q1",
"consumptionPolicy": "Consume",
"instanceSelectionPolicy": "First"
}
],
"computedVariables": [],
"evaluationPolicy": "Deferred",
"cardinalityPolicy": "Single",
"internalSegmentation": [],
"derivedEvents": [
{
"name": "MissingQueueData",
"reportParticipants": false,
"expressions": {
"Certainty": "1.0",
"Duration": "0",
"EventSeverity": "\"Warning\""
}
}
]
}
],
"contexts": {
"temporal": [
{
"name": "Always",
"createdDate": "Wed Jan 27 2016",
"type": "TemporalInterval",
"atStartup": true,
"neverEnding": true,
"initiators": [],
"terminators": []
},
{
"name": "CriticalQueueVolumeWindow",
"description": "Start when queue volume > 1000, ends in 30seconds",
"createdDate": "Wed Jan 27 2016",
"createdBy": "Pedro",
"type": "TemporalInterval",
"atStartup": false,
"neverEnding": false,
"initiators": [
{
"initiatorType": "Event",
"initiatorPolicy": "Ignore",
"name": "QueueContextUpdate",
"condition": "QueueContextUpdate.volume>1000"
}
],
"terminators": [
{
"terminatorType": "Event",
"terminatorPolicy": "First",
"terminationType": "Terminate",
"name": "QueueContextUpdate",
"condition": " QueueContextUpdate.volume<500"
},
{
"terminatorType": "RelativeTime",
"terminationType": "Terminate",
"relativeTime": "300000"
}
]
},
{
"name": "MissingQueueDataWindow",
"createdDate": "Wed Jan 27 2016",
"type": "TemporalInterval",
"atStartup": false,
"neverEnding": false,
"initiators": [
{
"initiatorType": "Event",
"initiatorPolicy": "Add",
"name": "QueueContextUpdate"
}
],
"terminators": [
{
"terminatorType": "RelativeTime",
"terminationType": "Terminate",
"relativeTime": "10000"
}
]
}
],
"segmentation": [
{
"name": "QueueID",
"description": "Treat objects as distinct based on entityID",
"createdDate": "Wed Jan 27 2016",
"createdBy": "Pedro",
"participantEvents": [
{
"name": "QueueContextUpdate",
"expression": "QueueContextUpdate.entityId"
},
{
"name": "QueueVolumeHigh",
"expression": "QueueVolumeHigh.AffectedEntity"
}
]
}
],
"composite": [
{
"name": "CriticalQueueVolumeComb",
"createdDate": "Wed Jan 27 2016",
"temporalContexts": [
{
"name": "CriticalQueueVolumeWindow"
}
],
"segmentationContexts": [
{
"name": "QueueID"
}
]
}
]
},
"consumers": [
{
"name": "DeviceReport",
"createdDate": "Thu Nov 12 2015",
"type": "File",
"properties": [
{
"name": "filename",
"value": "/usr/share/tomcat/webapps/sample/SentinelMonitor_DeviceReport.txt"
},
{
"name": "formatter",
"value": "json"
},
{
"name": "delimiter",
"value": ";"
},
{
"name": "tagDataSeparator",
"value": "="
},
{
"name": "SendingDelay",
"value": "1000"
}
],
"events": [
{
"name": "Device"
}
]
},
{
"name": "QueueReport",
"createdDate": "Thu Nov 12 2015",
"type": "File",
"properties": [
{
"name": "filename",
"value": "/usr/share/tomcat/webapps/sample/SentinelMonitor_QueueReport.txt"
},
{
"name": "formatter",
"value": "json"
},
{
"name": "delimiter",
"value": ";"
},
{
"name": "tagDataSeparator",
"value": "="
},
{
"name": "SendingDelay",
"value": "1000"
}
],
"events": [
{
"name": "Queue"
}
]
},
{
"name": "DeviceContextUpdateReport",
"createdDate": "Thu Nov 12 2015",
"type": "File",
"properties": [
{
"name": "filename",
"value": "/usr/share/tomcat/webapps/sample/SentinelMonitor_DeviceContextUpdateReport.txt"
},
{
"name": "formatter",
"value": "json"
},
{
"name": "delimiter",
"value": ";"
},
{
"name": "tagDataSeparator",
"value": "="
},
{
"name": "SendingDelay",
"value": "1000"
}
],
"events": [
{
"name": "DeviceContextUpdate"
}
]
},
{
"name": "QueueContextUpdateReport",
"createdDate": "Thu Nov 12 2015",
"type": "File",
"properties": [
{
"name": "filename",
"value": "/usr/share/tomcat/webapps/sample/SentinelMonitor_QueueContextUpdateReport.txt"
},
{
"name": "formatter",
"value": "json"
},
{
"name": "delimiter",
"value": ";"
},
{
"name": "tagDataSeparator",
"value": "="
},
{
"name": "SendingDelay",
"value": "1000"
}
],
"events": [
{
"name": "QueueContextUpdate"
},
{
"name": "QueueVolumeHigh"
},
{
"name": "MissingQueueData"
}
]
}
],
"producers": [],
"name": "SentinelMonitor"
}
}
The issue is that the initiator of the temporal context that your EPA is using is the QueueContextUpdate event that you are looking to find. Since this event doesn't arrive, the context is not initiated... and the EPA is not active at all...
For testing, I would suggest to change the initiator of the temporal context to At Startup and try to run again.
Later, you will need to decide what is the right definition of this temporal context, and what is the right initiator. Maybe you want to set this temporal context to be of Sliding Time Window type?