Style layer depending on multiple feature properties - filter

is there way to paint features depending on its properties? For example, there is a Feature with int properties "level_a" and "level_b" and it is needed to fill Feature depending which property is greater. There is no way to compare them directly since filter supports only [">", feature(key), value] And features suppose to be in the same layer. Thank you.
Needed something like:
map.addLayer({
'id': 'foo',
'type': 'fill',
'source': 'source',
'filter': ['>', 'level_a', 'level_b'], //cannot insert properties directly an value field
'paint': {
'fill-color': '#blue',
}
});

Yes, expressions support this and much more: https://docs.mapbox.com/mapbox-gl-js/style-spec/expressions/
Using the newer syntax, this would work fine:
'filter': ['>', ['get', 'level_a'], ['get', 'level_b']]

Related

Which event(s) to use in place of Google Chat's "DeprecatedEvent"

I have several questions related to google.golang.org/api/chat/v1.
It seems the only available Event object is DeprecatedEvent. So, what is the non-deprecated one to use?
If DeprecatedEvent is indeed the intended one to use, inside the DeprecatedEvent object, there's a User *User field. However, it seems that the User object is different from what I actually got from the responses.
For example:
{
'eventTime': '2019-08-27T06:50:12.391141Z',
'user': {
'name': 'users/112...',
'email': 'iskandar.setiadi#...',
'avatarUrl': 'https://lh3.googleusercontent.com/a-/AAu...',
'displayName': 'Iskandar Setiadi',
'type': 'HUMAN'
},
'type': 'ADDED_TO_SPACE',
'space': {
'name': 'spaces/7ag...',
'type': 'DM'
}
}
In the API, User object only contains displayName, name, and type. It seems that email and avatarUrl are not there. Is v1 outdated or is there any alternatives that I don't know?

Cypress custom command for an array-like prevSubject

I'm writing a custom command getFirst, which returns the first element according to a given predicate. Everything works fine, but I wanted to specify a specific prevSubject parameter instead of true, in order to prevent improper usage.
In the documentation, the only mentioned options are false, true, optional, element, document or window, but it doesn't say how to specify an array-like structure, like the cy.each does.
Any idea how that could be done?
Here's my code:
Cypress.Commands.add('getFirst', {prevSubject: true},
<TSourceSubject, TPredicateSubject, TResult>(
subject: TSourceSubject,
getPredicateSubject : (sourceSubject : TSourceSubject) => Chainable<TPredicateSubject>,
predicate: (predicateSubject: TPredicateSubject) => boolean) => {
cy.wrap(subject).each((item : TSourceSubject) => {
getPredicateSubject(item).then<TPredicateSubject>((predicateSubject : any) => {
if (predicate(predicateSubject)) {
cy.wrap(item).as('getFirstItemAlias');
}
});
});
return cy.get('#getFirstItemAlias');
});
PS: If someone has an idea how to get rid of the getFirstItemAlias alias, or if there's some way to make its scope local, it would be very helpful too.
Thanks!
I was curious so I looked at Cypress' source code to see how this was done.
There aren't any additional undocumented options for prevSubject: https://github.com/cypress-io/cypress/blob/develop/packages/driver/src/cy/ensures.coffee#L21-L39
cy.each() is using { prevSubject: true } and explicitly checking that the subject is an array: https://github.com/cypress-io/cypress/blob/0f73bb7e1910296469f3f631a7f2303f4ecd035e/packages/driver/src/cy/commands/connectors.coffee#L374-L383

Sort by datetime, then group by date

I want to sort by a datetime value, and group by a date string.
I have found the sortProperty on the grouper:
You can set this configuration if you want the groups to be sorted on something other then the group string returned by the groupFn. This serves the same role as property on a normal Ext.util.Sorter.
So I tried the following, which only sorts the date correctly:
grouper:{
sortProperty: 'StartDate',
property: 'StartDateOnly',
direction: 'ASC'
},
and I tried the following, which only sorts the time correctly:
grouper:{
sortProperty: 'StartDate',
property: 'StartDateOnly',
direction: 'ASC'
},
sorters: [{
property: 'StartDate',
direction: 'ASC'
}]
You can try it here:
https://fiddle.sencha.com/#view/editor&fiddle/2cei
What am I doing wrong here?
The problem is that you make a sort on a string type but you have date by changing the code on your sencha fiddle like this :
Ext.application({
name : 'Fiddle',
launch : function() {
var mdl = Ext.define('', {
extend: 'Ext.data.Model',
fields: [{
/** #field {date} StartDate with format: Y-m-d H:i */
name: 'StartDate',
type: 'date',
dateFormat: 'Y-m-d H:i'
},{
name: 'StartDateOnly',
type: 'date', // <= here before it was 'string'
convert: function(v,rec) {
return Ext.Date.format(rec.get('StartDate'), 'D d.m.Y');
}
}]
});
...
Then you run, you can see that the group of date StartDateOnly is now order by ASC.
After that, you can retrieve this data in date format and convert it into a string. But if you make a sort on a string you will always have the first of February last like now.
The problem is that it does an alphabetical sort on the days of the week.
In order: Fri, Sat, Thu.
Sencha support did not provide a full solution, but helped me a bit on my way. They found how to "fix" the problem at hand and told me to change the data type of the StartDateOnly column to date, but neither did this fix prove universal nor did it make any sense that this fixed the problem at all. But it showed some underlying correlations, which helped me to dig into the problem and find a universal solution.
I would say the issue is a bug in ExtJS, but I am awaiting confirmation from Sencha on this. I have to yet find the exact line where the bug is introduced.
Problem description:
When sortProperty is set on the grouper and at least one sorter is added on the store, the "transform" function of the grouper is set to the "transform" function of the first sorter (otherwise, it is null).
Solution:
You can manually override the transform function on the grouper by adding the correct sort type explicitly to the grouper config:
grouper:{
sortProperty: 'StartDate',
property: 'StartDateOnly',
transform: Ext.data.SortTypes.asDate,
direction: 'ASC'
},

How to use the same type as input and return type?

A simple type like Location {lat lng}:
GraphQLInputObjectType({
name: 'Location',
fields: {
lat: { type: new GraphQLNonNull(GraphQLFloat) },
lng: { type: new GraphQLNonNull(GraphQLFloat) },
}
});
should be able to be used as both input and return type. What's the approach/pattern here?
Unfortunately, you can't use an (output) type for an input and vice versa. You can, however, create a custom scalar. Apollo has a great example of how to do in their docs. Then your new CoordinateScalar could easily be used for both input and output.
The other benefit to this approach is you can easily utilize an array for the coordinates if you wanted to (i.e. [34.000, -78.000]) rather than being forced to use an object.

GridFS - product images & thumbnails - what is the best DB sctructure?

I have a e-commerce website working on MongoDB + GridFS.
Each product may have up to 5 images.
Each image has 3 thumbnails of different sizes.
I need an advice on best DB structure for this.
Currently I'm thinking to store image IDs and also thumb IDs (IDs from GridFS) in each product:
{
'_id': 1,
'title': 'Some Product',
'images': [
{'id': '11', thumbs: {'small': '22', 'medium': '33'},
{'id': '44', thumbs: {'small': '55', 'medium': '66'}
]
}
Or would it be better to store path in GridFS?
{
'_id': '111',
'filename': '1.jpg',
'path': 'product/988/image/111/'
},
{
'_id': '222',
'filename': '1.jpg',
'path': 'product/988/image/111/thumbnail_small'
},
{
'_id': '333',
'filename': '1.jpg',
'path': 'product/988/image/111/thumbnail_large'
}
UPDATE: "path" field in GridFS is a "fake" path, not a real one. Just a quick way to find all related files. It is cheaper to have 1 indexed field than several fields with compound indexes.
If you will store the images with GridFS within MongoDB, I would go with the first one.
The second schema doesn't seem to be correct. I mean GridFS is supposed to store files, so with the id of the image you don't need any path within those documents. If you simply want to store the path of the file, directly embedd it into your primary collection, so you don't need this overhead of a somewhat useless collection.
In general see Storing Images in DB - Yea or Nay? if you really should store your images in dbms.
Additionally if you only save the path you may need few to no changes in case you're switching to some CDN to get your images to the customer.

Resources