Why do groups not respect the parent's padding, except at the top level? - layout

What exactly is the behavior of padding for group marks in Vega? At the top-most level the children groups respect the top-level padding, but this doesn't seem the case for the children's children, they don't respect their parent's padding.
For example, here I would expect to get a rectangle centered in a rectangle centered in another rectangle:
Open the Chart in the Vega Editor
Instead each rectangle seems to be anchored at the origin of the top-level coordinate system.
Note that replacing "padding": {"signal": "level_2_padding"} with "padding": {"value": 0} doesn't seem to have any effect, so I'm not even sure if inner groups can have padding?
How can I best implement nested groups that respect the parent's padding?

There is no padding property on a Group mark. Instead, you can access group properties using Field Values. Something like the following should work.
Editor
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"autosize": "none",
"config": {"group": {"stroke": "black"}},
"signals": [
{"name": "target_height", "value": 400},
{"name": "target_width", "value": 300},
{"name": "level_0_padding", "value": 64},
{"name": "level_1_padding", "update": "1/2 * level_0_padding"},
{"name": "level_2_padding", "update": "1/4 * level_0_padding"},
{"name": "level_0_height", "update": "target_height - 2*level_0_padding"},
{"name": "level_0_width", "update": "target_width - 2*level_0_padding"},
{"name": "level_1_width", "update": "level_0_width - 2*level_1_padding"},
{"name": "level_1_height", "update": "level_0_height - 2*level_1_padding"}
],
"width": {"signal": "level_0_width"},
"height": {"signal": "level_0_height"},
"padding": {"signal": "level_0_padding"},
"marks": [
{
"type": "group",
"signals": [
{
"name": "level_2_width",
"update": "level_1_width - 2*level_2_padding"
},
{
"name": "level_2_height",
"update": "level_1_height - 2*level_2_padding"
}
],
"encode": {
"update": {
"width": {"signal": "level_1_width"},
"height": {"signal": "level_1_height"},
"x": {"signal": "level_0_width-level_1_width - level_1_padding"},
"y": {"signal": "level_0_height-level_1_height - level_1_padding"},
"stroke": {"value": "red"},
"strokeOpacity": {"value": 0.5}
}
},
"marks": [
{
"type": "group",
"encode": {
"update": {
"width": {"signal": "level_2_width"},
"height": {"signal": "level_2_height"},
"x": {
"field": {"group": "width"},
"mult": 0.5,
"offset": {"signal": "-level_2_width/2"}
},
"y": {
"field": {"group": "height"},
"mult": 0.5,
"offset": {"signal": "-level_2_height/2"}
},
"stroke": {"value": "blue"},
"strokeOpacity": {"value": 0.5}
}
}
}
]
}
]
}

I'll accept David's answer, but also post my own to complement David's.
Here's an alternative solution specification, like David's spec it uses the "x" and "y" group properties, but I think it's a bit simpler and closer to what I need: Open the Chart in the Vega Editor
An important point that I have to mention is that using layout prevents x and y from working, that is: groups directly contained in a layout/grid may not be offset using x or y.

Related

Can't get transform_filter to work in Altair

For my teaching notes I am trying to implement this vega-lite example in Altair:
{
"data": {"url": "data/seattle-weather.csv"},
"layer": [{
"params": [{
"name": "brush",
"select": {"type": "interval", "encodings": ["x"]}
}],
"mark": "bar",
"encoding": {
"x": {
"timeUnit": "month",
"field": "date",
"type": "ordinal"
},
"y": {
"aggregate": "mean",
"field": "precipitation",
"type": "quantitative"
},
"opacity": {
"condition": {
"param": "brush", "value": 1
},
"value": 0.7
}
}
}, {
"transform": [{
"filter": {"param": "brush"}
}],
"mark": "rule",
"encoding": {
"y": {
"aggregate": "mean",
"field": "precipitation",
"type": "quantitative"
},
"color": {"value": "firebrick"},
"size": {"value": 3}
}
}]
}
I getting the separate charts (bar and rule to work) was easy, but I run into issues in making mark_rule interactive.
import altair as alt
from vega_datasets import data
df = data.seattle_weather()
selection = alt.selection_interval(encodings=['x'])
base = alt.Chart(df).add_selection(selection)
bar_i = base.mark_bar().encode(
x="month(date):T",
y="mean(precipitation):Q",
opacity=alt.condition(selection, alt.value(1.0), alt.value(0.7)))
rule_i = base.mark_rule().transform_filter(selection).encode(y="mean(precipitation):Q")
(bar_i + rule_i).properties(width=600)
The error reads
Javascript Error: Duplicate signal name: "selector013_scale_trigger"
This usually means there's a typo in your chart specification. See the javascript console for the full traceback.
It looks like the chart you're interested in creating is part of Altair's example gallery: https://altair-viz.github.io/gallery/selection_layer_bar_month.html
import altair as alt
from vega_datasets import data
source = data.seattle_weather()
brush = alt.selection(type='interval', encodings=['x'])
bars = alt.Chart(source).mark_bar().encode(
x='month(date):O',
y='mean(precipitation):Q',
opacity=alt.condition(brush, alt.OpacityValue(1), alt.OpacityValue(0.7)),
).add_selection(
brush
)
line = alt.Chart(source).mark_rule(color='firebrick').encode(
y='mean(precipitation):Q',
size=alt.SizeValue(3)
).transform_filter(
brush
)
bars + line
The error you're seeing comes from the fact that base includes the selection, and both layers are derived from base, so the same selection is declared twice within the single chart.

Microsoft Teams Adaptive Card - Dark Mode Color Issue

I am trying to develope a simple messagaging extension app for Microsoft Teams. With the use of Task Modules I can load a simple Adative Card. Works as designed. The only problem I have with it, is that my Adaptive Card has a color issue withing Microsoft Teams in Dark Mode.
Take a look at the image below. 1 shows a very simple Adaptive Card designed via https://adaptivecards.io/designer/ (preview mode). 2 the very same Adaptive Card but now an actual snippet from Microsoft Teams. As you can see the card below has some color issues which makes the input hard to see.
Here is the code I've used:
public async handleTeamsMessagingExtensionFetchTask(
context: TurnContext,
action: any
): Promise<any> {
const adaptiveCard = CardFactory.adaptiveCard({
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"size": "Medium",
"weight": "Bolder",
"text": "${title}"
},
{
"type": "Input.Text",
"placeholder": "Placeholder text"
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Submit"
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.3"
});
return {
task: {
type: 'continue',
value: {
card: adaptiveCard,
height: 535,
title: '${title}',
url: null,
width: 500
}
}
};
}
There's not much that can be done about the input box itself in this case, but maybe try changing the colour of the label above it, something like this (I've changed some of your property names as well, as they were invalid case - things like "medium" instead of "Medium":
"size": "medium",
"weight": "bolder",
"text": "${title}",
"color": "good"
Color allows the following values:
"default"
"dark"
"light"
"accent"
"good"
"warning"
"attention"
If you nest your Text input into a Container, you are able change the Container's style to provide a coloured background upon which the Text input sits.
It's not necessarily right for your use case, but it could be a workaround of interest
Container Style colour options
{
"type": "Container",
"style": "emphasis",
"bleed": true,
"items": [
{
"type": "TextBlock",
"text": "Request New Ticket",
"wrap": true,
"fontType": "Default",
"style": "heading",
"size": "Large",
"color": "Good",
"weight": "Bolder",
"horizontalAlignment": "Center"
}
]
}

How to correctly use LUIS ML-features?

I just stumbled over the new "ML-features" in LUIS and I am not sure if I really understand how to use them correctly. The documentation seems very abstract and vague to me:
https://learn.microsoft.com/de-de/azure/cognitive-services/luis/luis-concept-feature
Besides a good general explanation a solution for the following example would be very welcome:
Example
Intent: OpenABox
Sample utterances: "open the green box", "open the azure box".
Entity: ColorEntity (no prebuilt entity).
The color should understand "green", "blue", "azure" and "olive", where "olive" should be regarded as synonym to "green" and "azure" to "blue".
Solution Proposal
I assume you would have to
Add an intent
Add a list-entity, that lists all colors and assigns their synonyms?
Add a phrase list, that again lists some, but maybe not all, colors, without respect to their meaning?
Make the ML-feature global?
Mark the values as interchangable?
Add a ML-entity, and assign the list entity as well as the phrase list as features?
Make the list-entity-feature required?
Add sample utterances and mark the entities with the list-entity? Or with the ML-entity? Or both?
Add the ML-Entity as feature to the intent? Or the phrase list? Or the list-entity? Or none at all?
Is it correct, that there is no way to confirm the correct resolution of "olive" to its canonical form "green" using the test panel? So I have to use the API to test this?
The Model
This model has been created as described above. It seems to do its job. But is this really the optimal way to do it? There seems to be a lot of redundancy in there.
{
"luis_schema_version": "7.0.0",
"intents": [
{
"name": "None",
"features": []
},
{
"name": "OpenABox",
"features": [
{
"modelName": "ColorMLEntity",
"isRequired": false
}
]
}
],
"entities": [
{
"name": "ColorMLEntity",
"children": [],
"roles": [],
"features": [
{
"featureName": "ColorPhraseList",
"isRequired": false
},
{
"modelName": "ColorListEntity",
"isRequired": true
}
]
}
],
"hierarchicals": [],
"composites": [],
"closedLists": [
{
"name": "ColorListEntity",
"subLists": [
{
"canonicalForm": "green",
"list": [
"olive"
]
},
{
"canonicalForm": "blue",
"list": [
"azure"
]
}
],
"roles": []
}
],
"prebuiltEntities": [],
"utterances": [
{
"text": "open the azure box",
"intent": "OpenABox",
"entities": [
{
"entity": "ColorMLEntity",
"startPos": 9,
"endPos": 13,
"children": []
}
]
},
{
"text": "open the green box",
"intent": "OpenABox",
"entities": [
{
"entity": "ColorMLEntity",
"startPos": 9,
"endPos": 13,
"children": []
}
]
}
],
"versionId": "0.1",
"name": "ColorTest",
"desc": "",
"culture": "en-us",
"tokenizerVersion": "1.0.0",
"patternAnyEntities": [],
"regex_entities": [],
"phraselists": [
{
"name": "ColorPhraseList",
"mode": true,
"words": "green,blue,azure,olive",
"activated": true,
"enabledForAllModels": false
}
],
"regex_features": [],
"patterns": [],
"settings": []
}
Features are supposed to be signals relevant to an intent, or an entity.
So for this example,
Create an ML entity "ColorEntity",
Label the utterances
Add ColorEntity as a feature for the intent
Then you can add a feature to ColorEntity, either a list entity or phrase list, no need for both.

Vega lite use one data field for the axis and another for the label

In Vega Lite, is it possible to use one field of the data values as the axis value, and another field as the label?
If this is my vega lite spec, then the graph works correctly, but shows the dates on the x-axis. How can I show the day names on the x-axis instead?
{
"$schema": "https://vega.github.io/schema/vega-lite/v2.json",
"description": "basic line graph",
"data": {
"values": [
{"date":"2017-08-15", "dayName":"Tue","item":"foo","count":"0"},
{"date":"2017-08-16", "dayName":"Wed","item":"foo","count":"11"},
{"date":"2017-08-17", "dayName":"Thu","item":"foo","count":"7"},
{"date":"2017-08-18", "dayName":"Fri","item":"foo","count":"28"},
{"date":"2017-08-19", "dayName":"Sat","item":"foo","count":"0"},
{"date":"2017-08-20", "dayName":"Sun","item":"foo","count":"0"},
{"date":"2017-08-21", "dayName":"Mon","item":"foo","count":"0"}
]},
"mark": {
"type": "line",
"interpolate": "monotone"
},
"encoding": {
"x": {"field": "date", "type": "temporal"},
"y": {"field": "count", "type": "quantitative"}
}
}
It shows the date field, August 16, August 17 on the x-axis. How can I make it show the dayName field instead? It should show Tue, Wed, and so on.
You can use timeUnit.
{
"$schema": "https://vega.github.io/schema/vega-lite/v2.json",
"description": "basic line graph",
"data": {
"values": [
{"date":"2017-08-15", "dayName":"Tue","item":"foo","count":"0"},
{"date":"2017-08-16", "dayName":"Wed","item":"foo","count":"11"},
{"date":"2017-08-17", "dayName":"Thu","item":"foo","count":"7"},
{"date":"2017-08-18", "dayName":"Fri","item":"foo","count":"28"},
{"date":"2017-08-19", "dayName":"Sat","item":"foo","count":"0"},
{"date":"2017-08-20", "dayName":"Sun","item":"foo","count":"0"},
{"date":"2017-08-21", "dayName":"Mon","item":"foo","count":"0"}
]},
"mark": {
"type": "line",
"interpolate": "monotone"
},
"encoding": {
"x": {
"timeUnit": "day",
"field": "date",
"type": "temporal"
},
"y": {"field": "count", "type": "quantitative"}
}
}
If you want to customize the label format, you can add axis format, as well

Update inner object in arangodb

I have an object stored in arangodb which has additional inner objects, my current use case requires that I update just one of the elements.
Store Object
{
"status": "Active",
"physicalCode": "99999",
"postalCode": "999999",
"tradingCurrency": "USD",
"taxRate": "14",
"priceVatInclusive": "No",
"type": "eCommerce",
"name": "John and Sons inc",
"description": "John and Sons inc",
"createdDate": "2015-05-25T11:04:14+0200",
"modifiedDate": "2015-05-25T11:04:14+0200",
"physicalAddress": "Corner moon and space 9 station",
"postalAddress": "PO Box 44757553",
"physicalCountry": "Mars Sector 9",
"postalCountry": "Mars Sector 9",
"createdBy": "john.doe",
"modifiedBy": "john.doe",
"users": [
{
"id": "577458630580",
"username": "john.doe"
}
],
"products": [
{
"sellingPrice": "95.00",
"inStock": "10",
"name": "School Shirt Green",
"code": "SKITO2939999995",
"warehouseId": "723468998682"
},
{
"sellingPrice": "95.00",
"inStock": "5",
"name": "School Shirt Red",
"code": "SKITO245454949495",
"warehouseId": "723468998682"
},
{
"sellingPrice": "95.00",
"inStock": "10",
"discount": "5%",
"name": "School Shirt Blue",
"code": "SKITO293949495",
"warehouseId": "723468998682"
}
]
}
I want to change just one of the products stock value
{
"sellingPrice": "95.00",
"inStock": "10",
"discount": "5%",
"name": "School Shirt Blue",
"code": "SKITO293949495",
"warehouseId": "723468998682"
}
Like update store product stock less 1 where store id = x, something to this effect
FOR store IN stores
FILTER store._key == "837108415472"
FOR product IN store.products
FILTER product.code == "SKITO293949495"
UPDATE product WITH { inStock: (product.inStock - 1) } IN store.products
Apart from the above possibly it makes sense to store product as a separate document in collection store_products. I believe in NOSQL that is the best approach to reduce document size.
Found answer
here arangodb-aql-update-single-object-in-embedded-array and there
arangodb-aql-update-for-internal-field-of-object
I however believe it is best to maintain separate documents and rather use joins when retrieving. Updates easily

Resources