Sort axis by another field in Vega Lite - vega

I'm trying to sort ordinal data on the x axis by a different field from the one I'm using as a label. Both fields (I'll call them 'sortable' and 'nonsortable') are one-to-one, meaning one is computed from the other and there will never be an instance when one 'sortable' value will correspond to two different 'nonsortable' values, and vice versa.
I tried two approaches:
Changing the sort order to use a different field like this:
...
x: {
field: 'nonsortable',
sort: {
field: 'sortable',
op: 'count',
},
},
...
I wasn't sure which aggregate operation to use, but since the two fields are one-to-one, that shouldn't matter right?
This changed the order in a way that I don't understand, but it certainly didn't sort the axis by the 'sortable' field as intended.
Changing the label to a different field like this:
...
x: {
field: 'sortable',
axis: {
labelExpr: 'datum.nonsortable',
},
}
...
This didn't work at all. I think maybe I misunderstood how the label expressions work.
Is there another way to do this, or maybe a way salvage one of these attempts?

If no aggregation is required, you should pass the sort attribute without an aggregate. For example (vega editor link):
{
"data": {
"values": [
{"sortable": 5, "nonsortable": "five"},
{"sortable": 2, "nonsortable": "two"},
{"sortable": 3, "nonsortable": "three"},
{"sortable": 1, "nonsortable": "one"},
{"sortable": 4, "nonsortable": "four"}
]
},
"mark": "point",
"encoding": {
"x": {
"type": "nominal",
"field": "nonsortable",
"sort": {"field": "sortable"}
}
}
}

Related

What is equivalent to multiple types in OpenAPI 3.1? anyOf or oneOf?

I want to change multiple types (supported in the latest drafts of JSON Schema so does OpenAPI v3.1) to anyOf, oneOf but I am a bit confused to which the types would be mapped to. Or can I map to any of the two.
PS. I do have knowledge about anyOf, oneOf, etc. but multiple types behavior is a little ambiguous. (I know the schema is invalid but it is just an example that is more focused towards type conversion)
{
"type": ["null", "object", "integer", "string"],
"properties": {
"prop1": {
"type": "string"
},
"prop2": {
"type": "string"
}
},
"enum": [2, 3, 4, 5],
"const": "sample const entry",
"exclusiveMinimum": 1.22,
"exclusiveMaximum": 50,
"maxLength": 10,
"minLength": 2,
"format": "int32"
}
I am converting it this way.
{
"anyOf": [{
"type": "null"
},
{
"type": "object",
"properties": {
"prop1": {
"type": "string"
},
"prop2": {
"type": "string"
}
}
},
{
"type": "integer",
"enum": [2, 3, 4, 5],
"exclusiveMinimum": 1.22,
"exclusiveMaximum": 50,
"format": "int32"
},
{
"type": "string",
"maxLength": 10,
"minLength": 2,
"const": "sample const entry"
}
]
}
anyOf gives you a closer match for the semantics than oneOf;
The problem (or benefit!) of oneOf is that it will fail if you happen to match 2 different cases.
That is unlikely to be what you want, given the source of your conversion which has those looser semantics.
Imagine converting ["integer","number"], for example; if the input was a 1, you'd match both and fail using oneOf.
First of all, your example is not valid:
The initial schema doesn't match anything, it's an "impossible" schema. The "enum": [2, 3, 4, 5] and "const": "sample const entry" constraints are mutually exclusive, and so are "const": "sample const entry" and "maxLength": 10.
The rewritten schema is not equivalent to the original schema because the enum and const were moved from the root level into subschemas. Yes, this way the schema makes more sense and will sort of work (e.g. it will match the specified numbers - but not strings! because of const vs maxLength contradiction), but it's not the same the original schema.
With regard to oneOf/anyOf:
It depends.
The choice between anyOf and oneOf depends on the context, i.e. whether an instance is can match more than one subschema or exactly one subschema. In other words, whether multiple subschema match is considered OK or an error. Nullable references typically need anyOf rather than oneOf, but other cases vary from schema to schema.
For example,
"type": ["number", "integer"]
corresponds to anyOf because there's an overlap - integer values are also valid "number" values in JSON Schema.
Whereas
"type": ["string", "integer"]
can be represented using either oneOf or anyOf. oneOf is semantically closer since strings and integers are totally different data types with no overlap. But technically anyOf also works, it's just there won't be more than one subschema match in this particular case.
In your example, all base type values are distinct with no overlap, so I would use oneOf, but technically anyOf will also work.

How to set one schema for n-1 elements and another for the nth element

For example, look at the schema:
"type": "array",
"items": {
"oneOf":[
{"type": "number"},
{"type": "string"}
]
}
}
The schema would then allow a list of numbers and the last element would be a string. and the string can be optional.
For example:
{
"list_of_items" : [ 3, 4, 5, "hello"]
}
is allowed.
{
"list_of_items" : [ 3, "hello" , 4, 5 ]
}
Is not allowed because text is only allowed on the last element.
From reading the documentation. I see how to do a constant amount of numbers and a text element.
Or all numbers,
But I don't see how to create n-1 numbers and text for the nth.
It could be that is is not something json-schema can do.
Thanks.

How to filter entities with nested arrays with CosmosDB

I have an entity like this:
{
"id": "xxxx",
"attributes": [{
"name": "name-01",
"value": "value-01"
}, {
"name": "name-02",
"value": "value-02"
}
]
}
Our "questions" to data usually: Give me entities with attribute or attribute with particular value;
in SQL it was written like as:
select *
from c
where
and array_contains(c.attributes, { "name": "name-01", "value": "value-01" }, true)
and array_contains(c.attributes, { "name": "name-02", "value": "value-02" }, true)
but I would like to extend a model to allow have suggestion of values in each attribute by transform an entity to:
{
"id": "xxxx",
"attributes": [{
"name": "name_01",
"value": "value-01",
"suggestions": ["a", "b", "c"]
}, {
"name": "name_02",
"value": "value-02",
"suggestions": ["a", "d", "e"]
}
]
}
With that structure I would like to ask: Give me all entities that has specified attribute and value equals to "XYZ" or suggestions array contains "XYZ";
In general scenario if always add value into array of suggestions the ask would be "Give me all entities that has specified attribute and suggestions contains XYZ"
N.B. Also I would like to make queries : Give me all entities that has more ALL specified attributes with constraints per each by suggestions?
Please suggest how to write such queries or rebuild a structure of entities in Cosmos DB;
P.S. We can technically switch from SQL to other protocol to better make such queries;
This should be doable using ARRAY_CONTAINS along with iterating the attributes array.
Give me items with value "value-01" or suggestion "f":
SELECT DISTINCT VALUE(c)
FROM c JOIN attr IN c.attributes
WHERE attr["value"] = "value-01" OR ARRAY_CONTAINS(attr.suggestions, "f")
Give me items with value "value-01" or both suggestions "a" and "f":
SELECT DISTINCT VALUE(c)
FROM c JOIN attr IN c.attributes
WHERE attr["value"] = "value-01" OR
ARRAY_CONTAINS(attr.suggestions, "a") AND ARRAY_CONTAINS(attr.suggestions, "f")

Structures DB Schema Design

I am working on db schema for the below json. product has different parameterCategories and categories has different parameters. same parameter may belong to different categories. product can have 1 or more categories. product may have same categories with different parameters. let me know if my approach is correct. should I keep productCategory-section and section-parameters linking or simple table would work as I created below. all products of the same category will have same section and parameters so I am linking productCategory with parameters.
table Parameters
parameterid
parameterName
standard
value
parametersection
productCategory
{
"productCategory": "electronic",
"products": {
"productId": "productId",
"productName": "productName",
"productParameterSections": [
{
"productParameterSectionId": "appearance",
"parameters": [
{
"parameterId": "color",
"unit": "",
"standard": "red",
"val": "light red"
},
{
"parameterId": "brightness",
"unit": "",
"standard": "high",
"val": "medium"
}
]
},
{
"productParameterSectionId": "quantitative",
"parameters": [
{
"parameterId": "length",
"unit": "cm",
"standard": "440",
"val": "400"
},
{
"parameterId": "height",
"unit": "cm",
"standard": "red",
"val": "400"
}
]
}
]
}
}
Recently we work on the same schema design. What we did is as below:
Made a list of all the parameters possible and all the different fields in the parameters possible.
Then we created templates like here it is a category which is a combination of some of the parameters.
Then that template is assigned to any entity like product in this case.
Pros of this approach
- You can add as many parameters as you want in the list
- you can customize the template as you want and attach it to the entity
How to use it
Use parameters as a contact like an array of objects.
Create a template with an array of the selected parameters so that it is creating a copy of the selected parameter for every category to keep the constant array safe from updates.
The template is the second table which can have other fields like template name ( category name ) who created it when it is last updated even from which category it is created like a reference to own.
The final entity table ( product ) will have reference to that template table and also an array from that template. So reference provides information about parameters and you can update the copy with the values to use.
I hope it explains well, let me know if you still have any doubts.

radio with custom input in alpacajs with jsonschema?

I'm trying to create a field with several radio input options and an optional fill in the blank. The following schema doesn't seem to work in displaying output:
{
"oneOf": [
{
"enum": [
"Option 1",
"Option 2",
"Option 3"
]
}, {
"type":"string"
}
]
}
What should I be doing? Thanks!
Clarification: I'd like to output:
( ) option 1
( ) option 2
( ) option 3
(X) custom [__fill in the blank here__]
I'm sorry it was my mistake I accidently overrided that fiddle. Thank you for your clarification. If you want to have that layout in your page you must use two different components, a radio group buttons and a simple text field that automatically will be appended after the radio group (but you could do better using jquery and append it in a different place in the postRender function of Alpaca. So your schema must be like this :
"schema": {
"type": "object",
"properties": {
"oneOf": {
"required": true,
"enum": ['a', 'b', 'c', 'd']
},
"customResponse": {
"type": "string"
}
}
}
I added more options for the fields like disabling default sorting, disabling the input text for custom response because it must be enabled only when the user choose the 4th option.
Here's a more complete fiddle.
your schema properties should be enclosed into a properties object and if the "oneOf" refers to the group of radio buttons it should be an object not an array.
"properties": {
"oneOf": {
"required": true,
"enum": ["option1", "option2", "option3"]
}, ////
Here's a complete fiddle, hope it helps.
Tell me if you want something else.