Related
I came across this pie chart vega lite visualization:
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"description": "A simple pie chart with labels.",
"data": {
"values": [
{"category": "a", "value": 4},
{"category": "b", "value": 6},
{"category": "c", "value": 10},
{"category": "d", "value": 3},
{"category": "e", "value": 7},
{"category": "f", "value": 8}
]
},
"encoding": {
"theta": {"field": "value", "type": "quantitative", "stack": true},
"color": {"field": "category", "type": "nominal", "legend": null}
},
"layer": [{
"mark": {"type": "arc", "outerRadius": 80}
}, {
"mark": {"type": "text", "radius": 90},
"encoding": {
"text": {"field": "category", "type": "nominal"}
}
}]
}
It renders as follows:
My data contains color key:
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"description": "A simple pie chart with labels.",
"data": {
"values": [
{"category": "a", "value": 4, "color": "rgb(121, 199, 227)"},
{"category": "b", "value": 6, "color": "rgb(140, 129, 22)"},
{"category": "c", "value": 10, "color": "rgb(96, 43, 199)"},
{"category": "d", "value": 3, "color": "rgb(196, 143, 99)"},
{"category": "e", "value": 7, "color": "rgb(12, 103, 19)"},
{"category": "f", "value": 8, "color": "rgb(196, 243, 129)"}
]
},
"encoding": {
"theta": {"field": "value", "type": "quantitative", "stack": true},
"color": {"field": "color", "type": "nominal", "legend": null}
},
"layer": [{
"mark": {"type": "arc", "outerRadius": 80}
}, {
"mark": {"type": "text", "radius": 90},
"encoding": {
"text": {"field": "category", "type": "nominal"}
}
}]
}
I want to use the rgb() color value specified in this color key's value to color individual pie. I tried specifying this field in color channel: "field": "color".
"color": {"field": "color", "type": "nominal", "legend": null}
However, no use. It still renders the same as above. How can use color value specified in field's value as actual color?
PS: Link to above visualization.
The documentation says:
To directly encode the data value, the scale property can be set to null.
So you need to set the scale to null.
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"description": "A simple pie chart with labels.",
"data": {
"values": [
{"category": "a", "value": 4, "color": "rgb(121, 199, 227)"},
{"category": "b", "value": 6, "color": "rgb(140, 129, 22)"},
{"category": "c", "value": 10, "color": "rgb(96, 43, 199)"},
{"category": "d", "value": 3, "color": "rgb(196, 143, 99)"},
{"category": "e", "value": 7, "color": "rgb(12, 103, 19)"},
{"category": "f", "value": 8, "color": "rgb(196, 243, 129)"}
]
},
"encoding": {
"theta": {"field": "value", "type": "quantitative", "stack": true},
"color": {"field": "color", "type": "nominal", "legend": null, "scale":null}
},
"layer": [
{"mark": {"type": "arc", "outerRadius": 80}},
{
"mark": {"type": "text", "radius": 90},
"encoding": {"text": {"field": "category", "type": "nominal"}}
}
]
}
This outputs:
I need to write a Jsonata query to turn array of objects into list of key/value objects where the key is the index of the object. For example I need to turn the following JSON structure
{
"Account": {
"Account Name": "Firefly",
"Order": [
{
"OrderID": "order103",
"Product": [
{
"Product Name": "Bowler Hat",
"ProductID": 858383,
"SKU": "0406654608",
"Description": {
"Colour": "Purple",
"Width": 300,
"Height": 200,
"Depth": 210,
"Weight": 0.75
},
"Price": 34.45,
"Quantity": 2
},
{
"Product Name": "Trilby hat",
"ProductID": 858236,
"SKU": "0406634348",
"Description": {
"Colour": "Orange",
"Width": 300,
"Height": 200,
"Depth": 210,
"Weight": 0.6
},
"Price": 21.67,
"Quantity": 1
}
]
}
]
}
}
Into the following json structure.
{
"result": {
"0": {
"Product Name": "Bowler Hat",
"ProductID": 858383,
"SKU": "0406654608",
"Description": {
"Colour": "Purple",
"Width": 300,
"Height": 200,
"Depth": 210,
"Weight": 0.75
},
"Price": 34.45,
"Quantity": 2
},
"1": {
"Product Name": "Trilby hat",
"ProductID": 858236,
"SKU": "0406634348",
"Description": {
"Colour": "Orange",
"Width": 300,
"Height": 200,
"Depth": 210,
"Weight": 0.6
},
"Price": 21.67,
"Quantity": 1
}
}
}
I appreciate any help to find the right Jsonata query or queries that could achieve this transformation.
One solution that I found is to use positional variable binding (#).
{
"result": Account.Order.Product#$i{
$string($i): $
}
}
The full solution on JSONata Playground: https://stedi.link/4Pj8Rvd
Suppose I have an elasticsearch index called 'neighborhood' and in there I am storing documents ( example far below) with the following settings and mappings.
There are many nested fields in the model and so I am using copy_to on many of them to make searching easier - e.g. I just do a match query on the _nayberz field.
The search works quite well, however I would like for matches where the ratedTags[n].rating (it can be 1-5) is higher to rank higher
Mappings:
{
"properties": {
"_nayberz": {
"type": "text",
"analyzer": "autocomplete",
"store" : true
},
"describedTagCombos": {
"type": "nested",
"properties": {
"tags": {
"type": "nested",
"properties": {
"keywords": {
"type": "text",
"analyzer": "autocomplete",
"boost": 5,
"copy_to": "_nayberz"
},
"name": {
"type": "text",
"analyzer": "autocomplete",
"boost": 5,
"copy_to": "_nayberz"
},
"synonym": {
"type": "text",
"analyzer": "autocomplete",
"boost": 5,
"copy_to": "_nayberz"
}
}
}
}
},
"name": {
"type": "text",
"fielddata" : true,
"copy_to": "_nayberz",
"boost": 1
},
"ratedTags": {
"type": "nested",
"properties": {
"tags": {
"type": "nested",
"properties": {
"keywords": {
"type": "text",
"boost": 5,
"copy_to": "_nayberz"
},
"name": {
"type": "text",
"boost": 5,
"copy_to": "_nayberz"
},
"synonym": {
"type": "text",
"boost": 5,
"copy_to": "_nayberz"
}
}
}
}
}
}
}
{
"id": 6475,
"neighborhoodId": 2495,
"name": "Some neighborhood name",
"xMin": -87.7351229157221,
"xMax": -87.687849915678,
"xAvg": -87.7114864157001,
"yMin": 41.9316410223988,
"yMax": 41.9466920224128,
"yAvg": 41.9391665224058,
"city": {
"id": 539,
"name": "SomeCity",
"county": "SomeCounty",
"state": {
"id": 174,
"name": "Illinois",
"abbreviation": "IL",
"country": "USA"
}
},
"ratedTags": [
{
"id": 11572,
"rating": 2,
"tags": [
{
"id": 2323,
"tagId": 36,
"name": "shopping options",
"synonym": "",
"keywords": "shopping options, shopping, shop, shopper, shoppers, shops"
}
]
},
{
"id": 11418,
"rating": 3,
"tags": [
{
"id": 2292,
"tagId": 5,
"name": "public transportation options",
"synonym": "",
"keywords": "public transport, public transportation"
}
]
},
{
"id": 11434,
"rating": 4,
"tags": [
{
"id": 2295,
"tagId": 8,
"name": "quiet",
"synonym": "",
"keywords": "quiet, chill, peaceful, not noisy, not loud, not too noisy, not too loud, relaxed"
}
]
},
{
"id": 11458,
"rating": 3,
"tags": [
{
"id": 2300,
"tagId": 13,
"name": "expensive relative to other neighborhoods",
"synonym": "costly",
"keywords": "upscale, chic"
}
]
},
{
"id": 11469,
"rating": 4,
"tags": [
{
"id": 2302,
"tagId": 15,
"name": "restaurants",
"synonym": "",
"keywords": "restaurants, restaurant, eatery, eateries"
}
]
},
{
"id": 11477,
"rating": 2,
"tags": [
{
"id": 2304,
"tagId": 17,
"name": "clean",
"synonym": "",
"keywords": "clean, cleanest, not dirty"
}
]
},
{
"id": 11603,
"rating": 3,
"tags": [
{
"id": 2329,
"tagId": 42,
"name": "safe compared to other neighborhoods",
"synonym": "",
"keywords": "safe, safety, safest, not dangerous"
}
]
},
{
"id": 11557,
"rating": 2,
"tags": [
{
"id": 2320,
"tagId": 33,
"name": "green space and parks",
"synonym": "",
"keywords": "green space, green, parks, open space, nature"
}
]
},
{
"id": 11577,
"rating": 2,
"tags": [
{
"id": 2324,
"tagId": 37,
"name": "tourist attractions",
"synonym": "sightseeing options",
"keywords": "tourist attractions, sightseeing, attractions, sightsee, tourist"
}
]
},
{
"id": 11582,
"rating": 2,
"tags": [
{
"id": 2325,
"tagId": 38,
"name": "entertainment options",
"synonym": "fun options",
"keywords": "fun, entertainment, good time, enjoyment, enjoy, pleasure"
}
]
},
{
"id": 11588,
"rating": 3,
"tags": [
{
"id": 2326,
"tagId": 39,
"name": "cafes",
"synonym": "coffee shops",
"keywords": "cafes, coffee shops, cafe, coffee shop, coffee houses, coffee house, café, cafés"
}
]
},
{
"id": 11594,
"rating": 4,
"tags": [
{
"id": 2327,
"tagId": 40,
"name": "dining options",
"synonym": "",
"keywords": "dining places, dining spots, dining options, restaurants, food options, food places, places to eat, eateries, dining, fast food, chain restaurant, chain restaurants, eatery"
}
]
}
],
"describedTagCombos": [
{
"id": 26842,
"descriptor": "Foodies: must try a polish sausage in this neighborhood",
"tags": [
{
"id": 2302,
"tagId": 15,
"name": "restaurants",
"synonym": "",
"keywords": "restaurants, restaurant, eatery, eateries"
},
{
"id": 2327,
"tagId": 40,
"name": "dining options",
"synonym": "",
"keywords": "dining places, dining spots, dining options, restaurants, food options, food places, places to eat, eateries, dining, fast food, chain restaurant, chain restaurants, eatery"
}
]
},
{
"id": 26843,
"descriptor": "Addison Mall in area with a Target, Starbucks, etc.",
"tags": [
{
"id": 2323,
"tagId": 36,
"name": "shopping options",
"synonym": "",
"keywords": "shopping options, shopping, shop, shopper, shoppers, shops"
}
]
}
]
}
Settings:
{
"analysis": {
"filter": {
"autocomplete_filter": {
"type": "edge_ngram",
"min_gram": 3,
"max_gram": 20
},
"english_stop": {
"type": "stop",
"stopwords": [
"a",
"an",
"and",
"are",
"as",
"at",
"be",
"but",
"by",
"for",
"if",
"in",
"into",
"is",
"it",
"no",
"not",
"of",
"on",
"or",
"such",
"that",
"the",
"their",
"then",
"there",
"these",
"they",
"this",
"to",
"was",
"will",
"with",
"have"
]
}
},
"analyzer": {
"autocomplete": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"autocomplete_filter",
"english_stop"
]
}
}
}
}
I think the best candidate here is the field_value_factor function:
GET neighborhoods/_search
{
"query": {
"bool": {
"should": [
{
"query_string": {
"default_field": "_nayberz",
"query": "enjoy"
}
},
{
"nested": {
"path": "ratedTags",
"query": {
"function_score": {
"functions": [
{
"field_value_factor": { <--
"field": "ratedTags.rating",
"factor": 1
}
}
],
"boost_mode": "sum"
}
}
}
}
]
}
}
}
Good time of day!
formerly = Vega-lite heat map text properties
1)How to build a new X2-axis in this scheme, which takes into account the original X-axis
{"window": [{"op": "count", "field": "x", "as": "x2"}], "groupby": ["y"]}
{
"$schema": "https://vega.github.io/schema/vega-lite/v2.4.3.json",
"config": {"view": {"height": 300, "width": 400}},
"data": {
"values": [
{"x": "X1", "y": "Y1", "z": 1,"Name":"Name3"}
{"x": "X3", "y": "Y1", "z": 9,"Name":"Name2"}
{"x": "X3", "y": "Y1", "z": 25,"Name":"Name1"}
{"x": "X0", "y": "Y2", "z": 1,"Name":"Name1"}
{"x": "X1", "y": "Y2", "z": 2,"Name":"Name1"}
{"x": "X4", "y": "Y2", "z": 20,"Name":"Name1"}
{"x": "X5", "y": "Y2", "z": 40,"Name":"Name1"}
]
},
"transform": [
{"window": [{"op": "count", "field": "x", "as": "x2"}], "groupby": ["y"]}
{"window": [{"op": "count", "field": "Name", "as": "x7"}], "groupby": ["x","y"]}
{
"calculate": "'https://google.com/search?q='+datum.y",
"as": "web"
}
],
"encoding": {
"x": {"field": "x2", "type": "ordinal", "title": "X"},
"y": {"field": "y", "type": "ordinal", "title": "Y"}
},
"layer": [
{
"mark": "rect",
"encoding": {
"color": {
"field": "z",
"scale": {"scheme": "redyellowgreen"},
"type": "quantitative"
}
"tooltip": [
{"field": "x", "type": "ordinal", title: "text"}
{"field": "y", "type": "ordinal", title: "text1"}
{"field": "z", "type": "ordinal", title: "text2"}
]
"href": {"field": "web"}
}
},
{
"mark": {"type": "text", "fontSize": 10, "dy": -20},
"encoding": {
"text": {"field": "x"},
"color": {"value": "black"}
}
},
{
"mark": {"type": "text", "fontSize": 20, "dy": 40},
"encoding": {
"text": {"field": "x7"},
"color": {"value": "black"}
}
},
{
"mark": {"type": "text", "fontSize": 20, "dy": 20},
"encoding": {
"text": {"field": "z", "type": "quantitative"},
"color": {"value": "black"}
}
}
]
}
2)how to make clear color boundaries? like here:
I use it:
"color": {"aggregate": "average","field": "z", "type": "quantitative","format": ".0f", "scale": { "domain": [0,20,25,35],"range": ["#6ce165", "#E0ED15", "#ED9715", "#CE4334"]}}
3) how to add text here:
{
"mark": {"type": "text", "fontSize": 20, "dy": 40},
"encoding": {
"text": {"field": "x7"},+ Text????
"color": {"value": "black"}
}
},
Please only ask one question per post. I do not understand what you are asking in the first or third part of your question, so I will answer the second.
You can make the color scale discrete using a binned encoding:
"encoding": {
"color": {
"field": "z",
"scale": {"scheme": "redyellowgreen"},
"type": "ordinal",
"bin": true
}
}
Here is the result (Vega Editor):
I have the following json:
{
"release": {
"genres": {
"genre": "Electronic"
},
"identifiers": {
"identifier": [
{
"description": "Text",
"value": "5 709498 101026",
"type": "Barcode"
},
{
"description": "String",
"value": 5709498101026,
"type": "Barcode"
}
]
},
"status": "Accepted",
"videos": {
"video": [
{
"title": "Future 3 - Renaldo",
"duration": 446,
"description": "Future 3 - Renaldo",
"src": "http://www.youtube.com/watch?v=hpc9aQpnUjc",
"embed": true
},
{
"title": "Future 3 - Silver M from album We are the Future / 1995 Denmark / Archivos de Kraftwerkmusik",
"duration": 461,
"description": "Future 3 - Silver M from album We are the Future / 1995 Denmark / Archivos de Kraftwerkmusik",
"src": "http://www.youtube.com/watch?v=nlcHRI8iV4g",
"embed": true
},
{
"title": "Future 3 - Bubbles At Dawn",
"duration": 710,
"description": "Future 3 - Bubbles At Dawn",
"src": "http://www.youtube.com/watch?v=ABBCyvGMOFw",
"embed": true
}
]
},
"labels": {
"label": {
"catno": "APR 010CD",
"name": "April Records"
}
},
"companies": {
"company": {
"id": 26184,
"catno": "",
"name": "Voices Of Wonder",
"entity_type_name": "Published By",
"resource_url": "http://api.discogs.com/labels/26184",
"entity_type": 21
}
},
"styles": {
"style": [
"Abstract",
"IDM",
"Downtempo"
]
},
"formats": {
"format": {
"text": "",
"name": "CD",
"qty": 1,
"descriptions": {
"description": "Album"
}
}
},
"country": "Denmark",
"id": 5375,
"released": "1995-00-00",
"artists": {
"artist": {
"id": 5139,
"anv": "",
"name": "Future 3",
"role": "",
"tracks": "",
"join": ""
}
},
"title": "We Are The Future 3",
"master_id": 638422,
"tracklist": {
"track": [
{
"position": 1,
"duration": "8:04",
"title": "Future 3"
},
{
"position": 2,
"duration": "7:38",
"title": "Silver M"
},
{
"position": 3,
"duration": "7:27",
"title": "Renaldo"
},
{
"position": 4,
"duration": "6:04",
"title": "B.O.Y.D."
},
{
"position": 5,
"duration": "6:12",
"title": "Fumble"
},
{
"position": 6,
"duration": "6:12",
"title": "Dawn"
},
{
"position": 7,
"duration": "11:54",
"title": "Bubbles At Dawn"
},
{
"position": 8,
"duration": "6:03",
"title": "D.A.W.N. At 6"
},
{
"position": 9,
"duration": "8:50",
"title": 4684351684651
}
]
},
"data_quality": "Needs Vote",
"extraartists": {
"artist": [
{
"id": 2647642,
"anv": "",
"name": "Danesadwork",
"role": "Cover",
"tracks": "",
"join": ""
},
{
"id": 2647647,
"anv": "",
"name": "Djon Edvard Petersen",
"role": "Photography By",
"tracks": "",
"join": ""
},
{
"id": 114164,
"anv": "",
"name": "Anders Remmer",
"role": "Written-By",
"tracks": "",
"join": ""
},
{
"id": 435979,
"anv": "",
"name": "Jesper Skaaning",
"role": "Written-By",
"tracks": "",
"join": ""
},
{
"id": 15691,
"anv": "",
"name": "Thomas Knak",
"role": "Written-By",
"tracks": "",
"join": ""
}
]
},
"notes": "© 1995 April Records APS ℗ 1995 April Records APS"
}
}
I am trying to get those titles which end with 'At Dawn'.
I am using the following command
r.db("discogs1").table("releases").filter(function(doc){ return doc('release')('title').match('At Dawn$')})
But I get errors as follows:
RqlRuntimeError: Expected type STRING but found NUMBER in:r.db("discogs1").table("releases").filter(function(var_24) { return var_24("release")("title").match("At Dawn$"); })
I tried different combinations but I can't seem to get it to work
It seems that some of your documents don't have a row('release')('title') property that is a string. Some of them are numbers, so when you try to call .match on them, they throw an error because .match only works on strings.
To see if this is true, try the following:
r.db("discogs1").table("releases")
.filter(r.row('release')('title').typeOf().ne('STRING'))
.count()
Ideally, the result of this should be 0, since no document should have a title property that's not a string. If it's higher than 0, that's why you're getting an error.
If you want to only get documents where the title is a string, you can do the following:
r.db("discogs1").table("releases")
.filter(r.row('release')('title').typeOf().eq('STRING'))
.filter(function(doc){ return doc('release')('title').match('At Dawn$')})
This query will work, because it will filter our all documents where the title is not a string.
If you want to coerce all title into strings, you can do the following:
r.db("discogs1").table("releases")
.filter(r.row('release')('title').typeOf().ne('STRING'))
.merge(function (row) {
return {
'title': row('title').coerceTo('string')
}
})
If you want to delete all documents where the title is not a string, you can do this:
r.db("discogs1").table("releases")
.filter(r.row('release')('title').typeOf().ne('STRING'))
.delete()