Vega Lite - set parameter array max value based on data - arrays

I am relatively new to Vega Lite and have a question that I'm hoping is fairly straightforward.
I have a parameter array called myExtent that I've hard coded to [0, 6]. I'd like to be able to set the upper value of the array based on the data. Here, because the 4th row has "flag" = 1, I'd like to set the upper limit to the "score" for that row, or 6. So,
{"name": "myExtent", "value": [0, (value of score for the row in the dataset where flag = 1)]}
Is something like this possible, or is there an alternative way I should be thinking about this?
`
{"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"params": [
{"name": "myExtent", "value": [0, 6]}
],
"data": {
"values": [
{"game": 1, "score": 2, "flag": 0},
{"game": 2, "score": 4, "flag": 0},
{"game": 3, "score": 5, "flag": 0},
{"game": 4, "score": 6, "flag": 1},
{"game": 5, "score": 9, "flag": 0}
]
},
"mark": {"type": "area"},
"transform": [
{
"density": "score",
"extent": {"signal": "myExtent"}
}
],
"encoding": {
"x": {"field": "value", "type": "quantitative", "scale": {"domain": [0, 10]}},
"y": {"field": "density", "type": "quantitative"}
}
}
`
Just to get started, I have tried something like this:
`
"params": [
{"name": "upperLimit", "value": 6},
{"name": "myExtent", "value": [0, {"expr": "upperLimit"}]}
],
`
However, that (a) doesn't seem to work and (b) doesn't (yet) get at how to set the upperLimit parameter to the score for row 4.

What is the logic behind providing a dynamic extent and not letting it calculate from the whole dataset? This is quite difficult to do in VL and you probably need Vega. Having said that, if you can add a column with the max extent repeated for the whole dataset, it can be achieved. I have repurposed the flag column here to do what you want.
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"params": [
{"name": "val", "expr": "data('source_0')[0]['flag']"},
{"name": "myExtent", "expr": "[0,val]"}
],
"data": {
"values": [
{"game": 1, "score": 2, "flag": 6},
{"game": 2, "score": 4, "flag": 6},
{"game": 3, "score": 5, "flag": 6},
{"game": 4, "score": 6, "flag": 6},
{"game": 5, "score": 9, "flag": 6}
]
},
"mark": {"type": "area"},
"transform": [
{"calculate": "datum.flag==1?datum.score:0", "as": "new"},
{"joinaggregate": [{"op": "max", "field": "new", "as": "test"}]},
{"density": "score", "extent": {"signal": "myExtent"}}
],
"encoding": {
"x": {
"field": "value",
"type": "quantitative",
"scale": {"domain": [0, 10]}
},
"y": {"field": "density", "type": "quantitative"}
}
}

With David Bacci's excellent guidance (thanks again!), I was able to build a solution that seems to accomplish what I was after. By flagging one of the rows with flag = 1, the user can see a density graph that helps them understand the percentile rank of the score in question (in this case, they're interested in game 4):
{"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"params": [
{"name": "upperLimit", "expr": "data('data_1')[0]['maxScore']"},
{"name": "myExtent", "expr": "[0,upperLimit]"}
],
"data": {
"name": "rawData",
"values": [
{"game": 1, "score": 2, "flag": 0},
{"game": 2, "score": 4, "flag": 0},
{"game": 3, "score": 5, "flag": 0},
{"game": 4, "score": 6, "flag": 1},
{"game": 5, "score": 9, "flag": 0}
]
},
"layer": [
{ // first layer to perform the transform without density
"mark": {"type": "area", "opacity": 0.1},
"transform": [
{"calculate": "datum.flag==1?datum.score:0", "as": "myScore"},
{"joinaggregate": [{"op": "max", "field": "myScore", "as": "maxScore"}]}
],
"encoding": {
"x": {"field": "game", "type": "quantitative", "scale": {"domain": [0, 10]}, "title": null}
}
},
{ // second layer to show whole sample with low opacity
"mark": {"type": "area", "opacity": 0.1},
"transform": [{"density": "score", "extent": [0, 10]}],
"encoding": {
"x": {
"field": "value",
"type": "quantitative"
},
"y": {"field": "density", "type": "quantitative", "title": null}
}
},
{ // third layer to show partial sample based on flagged row
"mark": {"type": "area"},
"transform": [
{"density": "score", "extent": {"signal": "myExtent"}}
],
"encoding": {
"x": {
"field": "value",
"type": "quantitative"
},
"y": {"field": "density", "type": "quantitative"}
}
}
]
}
This approach creates 3 layers, the first with a transform that David suggested to find the score in question, but without the density function. The second layer has a density function that shows the whole sample and the third layer shows just the part of the sample of interest. The parameters then refer not to the raw data source, but to data_1, which is the output of the first transform. Thanks to the online Vega Lite editor for helping me figure that bit out. But, especially thanks to David Bacci for pointing me in the right direction!

Related

Solr get facets on each root document

I have a JSON with documents and each document has a few _childDocuments_ I want to search in the parent and get back the parents and facets on each parent separate
Here is a sample JSON
[{
"id": 1,
"productName": "Ford Explorer",
"_childDocuments_": [{
"id": 6,
"color": "blue",
"price": 1000
},
{
"id": 7,
"color": "red",
"price": 2000
}
]
},
{
"id": 1,
"productName": "Ford F150",
"_childDocuments_": [{
"id": 10,
"color": "blue",
"price": 5000
},
{
"id": 11,
"color": "red",
"price": 6000
}
]
},
{
"id": 2,
"productName": "Toyota Highlander",
"_childDocuments_": [{
"id": 8,
"color": "green",
"price": 1200
},
{
"id": 9,
"color": "red",
"price": 2000
}
]
}
]
I want when I search for Ford I should get back all Fords and in each root document get back facets of the children.
Something like this:
[{
"id": 1,
"productName": "Ford Explorer",
"facets": {
"count": 2,
"prices": {
"buckets": [{
"val": 2000,
"count": 1
},
{
"val": 3000,
"count": 1
}
]
}
}
},
{
"id": 1,
"productName": "Ford F150",
"facets": {
"count": 2,
"prices": {
"buckets": [{
"val": 5000,
"count": 1
},
{
"val": 6000,
"count": 1
}
]
}
}
}
]
This is what I got so far
q={!parent+which=type:parent}&json.facet={ "prices": {
"type": "range",
"field": "price",
"start": 1000,
"end": 1000,
"gap": 1000
}
,
}
But this is only returning facets on all child documents.
Thanks in advance

How to access a field in relation in eloquent orm

I wrote this code to get the product information with it's images and category:
->where('category_id', 5)
->with('category', 'Files')->get();
my result is:
{
"id": 2,
"name": "test",
"price": 13000,
"description": "some text ...",
"shop_id": 1,
"rate": 0,
"category_id": 5,
"discount_percent": 20,
"category": {
"id": 5,
"name": "cat1",
"shop_id": 1
},
"files": [
{
"id": 99,
"disk_name": "5ef1af07d6d98778754621.jpg",
"file_name": "13330983_xl.jpg",
"file_size": 69813,
"content_type": "image/jpeg",
"title": null,
"description": null,
"field": "product_gallery",
"sort_order": 99,
"created_at": "2020-06-23 07:28:07",
"updated_at": "2020-06-23 07:28:10",
"path":...... storage/app/uploads/public/5ef/1af/07d/5ef1af07d6d98778754621.jpg",
"extension": "jpg"
}
]
}
now i want to access the path field, how can i do it?
i use this way for access but i don't get result:
products[0].files[0].path
You should use toArray() function to convert data likes this
->where('category_id', 5)
->with('category', 'Files')->get()->toArray();
And then access
products[0]['files'][0]['path']

How to get separate dictionary of each record from list of dictionaries without using multiple loop?

In current data "children" key will be fix. If there is any child data available then there then it must in list of dictionary format.
If there is no any children available then it no "children" key is available in dictionary.
I don't want to use the loop to bifurcate this data.
I want the same consistent sequence data. Please note there will any number of hierarchy available.
I want all this data in list of dictionary format like given requirement data example.
Current data.
{
"id": 2,
"parent_id": 1,
"name": "0",
"is_active": true,
"position": 1,
"level": 1,
"children": [
{
"id": 8,
"parent_id": 1,
"name": "01",
"is_active": false,
"position": 1,
"level": 2,
"children": [
"id": 9,
"parent_id": 1,
"name": "010",
"is_active": false,
"position": 1,
"level": 2,
"children": [
<'Here N number of hirerchy availabe'>
]
]
},
],
"id": 3,
"parent_id": 1,
"name": "1",
"is_active": true,
"position": 1,
"level": 1,
"children": [
{
"id": 5,
"parent_id": 1,
"name": "03",
"is_active": false,
"position": 1,
"level": 2,
"children": [
"id": 6,
"parent_id": 1,
"name": "030",
"is_active": false,
"position": 1,
"level": 2,
"children": [
<'Here N number of hirerchy availabe'>
]
]
},
]
}
Requirement.
[{
"id": 2,
"parent_id": 1,
"name": "0",
"is_active": true,
"position": 1,
"level": 1,
},
{
"id": 3,
"parent_id": 1,
"name": "01",
"is_active": false,
"position": 1,
"level": 2,
},
{
"id": 3,
"parent_id": 1,
"name": "01",
"is_active": false,
"position": 1,
"level": 2,
},{
<N Number of dictionary data with consistant sequence>
}]
The suitable answer will definitely acceptable.
You can flatten the given nested data structure with a recursive function like this:
def flatten(data):
if isinstance(data, dict):
return [data, *flatten(data.pop('children', ()))]
return [subrecord for record in data for subrecord in flatten(record)]
Demo: https://repl.it/#blhsing/BlankHatefulResources
I have found the solution to my question. Below code is working for me.
if isinstance(categories, dict):
values = {
'name': categories.get('name'),
'parent_id': categories.get('parent_id'),
'magento_id': categories.get('id'),
'instance_id': instance.id
}
self.category_list.append(values)
self._analyse_response_data(categories.get('children_data'), instance)
if isinstance(categories, list):
for category in categories:
values = {
'name': category.get('name'),
'parent_id': category.get('parent_id'),
'magento_id': category.get('id'),
'instance_id': instance.id
}
self.category_list.append(values)
self._analyse_response_data(category.get('children_data'), instance)
return self.category_list
I have used recursion to fulfil my requirement.

Resultset mapper or formatter in Cakephp 3

I have 2 Collections/ Result sets the first one is products and second one is sizes
"products": [
{
"category_id": 5,
"id": 5,
"code": "A",
"name": "Pizzabrot",
"description": "",
"product_prices": [
{
"product_id": 5,
"price": 2.5,
"size_id": 15
},
{
"product_id": 5,
"price": 3.5,
"size_id": 16
}
]
},
{
"category_id": 5,
"id": 6,
"code": "B",
"name": "Pizzabrot mit Knoblauch",
"description": "",
"product_prices": [
{
"product_id": 6,
"price": 3,
"size_id": 15
},
{
"product_id": 6,
"price": 4,
"size_id": 16
}
]
}]
AND
"sizes": [
{
"id": 15,
"name": "Klein",
"category_id": 5
},
{
"id": 16,
"name": "Gro\u00df",
"category_id": 5
}
]
I want to replace every product_prices.size_id with it's name from sizes Collection
From what I can see it would probably be better to associate ProductPrices and Sizes and fetch them with your Products.
If this does not fit your needs for some reason, you could find the sizes by using a find('list') (see Docs) like this:
$query = $this->Sizes->find('list', [
'keyField' => 'id',
'valueField' => 'name'
]);
$sizes = $query->toArray();
Then loop through the products and its product_prices and do something like.
$product_price->size_id = $sizes[$product_price->size_id];
Please prefer the first solution. ;-)

ElasticSearch Read element on array

I'm working with Elasticsearch, currently I have a struct like that
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "999999",
"_type": "content",
"_id": "NmYTku",
"_score": 1,
"_source": {
"internal_id": "NmYTk4",
"external_id": "Ga_UI502",
"
"images": [
{
"uri_id": "2939306",
"url": "14mast_head.jpg",
"type": "Masthead",
"orientation": "Landscape",
"x_resolution": 3280,
"y_resolution": 1480
},
{
"uri_id": "Galavision/POST_poster/2939306",
"url": "140603_29un_erro_poster.jpg",
"type": "Poster",
"orientation": "Portrait",
"x_resolution": 720,
"y_resolution": 405
},
{
"uri_id": "Galavision/POST_poster_title/2939306",
"url": "140603_29un_erro_poster_title.jpg",
"type": "PosterWithTitle",
"orientation": "Portrait",
"x_resolution": 924,
"y_resolution": 518
},
{
"uri_id": "Galavision/POST_poster_cover/2939306",
"url": "140603_29poster_cover.jpg",
"type": "Poster",
"orientation": "Landscape",
"x_resolution": 600,
"y_resolution": 868
}
]
}
}
]
}
}
I was wondering, how can I get only one value from my array e.g.
I want to have only the images with oritentation on Landscape and type Poster. I tried with This query but it only returns me all the image elements.
{
"query": {
"filtered": {
"filter": { "term":{"_id":"NmYTku"} }
}
},
"_source": ["images"]
}
I don't have idea how do a filter on the elements
Are you using nested or child fields for the images? If not, that doc is actually being indexed like:
...
images.uri_id = [1, 2, 3, 4, etc..]
images.url = [1, 2, 3, 4, etc..]
images.type = [1, 2, 3, 4, etc..]
...
so the distinction between individual elements is gone. Try giving this a read:
http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/complex-core-fields.html
If you don't need to query, why not just filter out the ones you like client side?
Try this:
{
"filtered": {
"query": {
"match": { "term": "_id" : "NmYTku" }
},
"_source": [images]{
"orientation": "landscape",
"type": "Poster",
}
}

Resources