How to query data by some conditions - mapbox-gl-js

I have a dataset, now I want to find the data(point) which have the value of "country" is "AU", and show them on the map,
how to express the variable in Mapbox JS GL code?
this is my code, but it is a filter method, I know it's wrong, how to express a condition not filter it?
var myFeatures = map.querySourceFeatures('my_layer'
filter: ["==", "country", "AU"]
});

You can filter source features like this:
const myFeatures = map.querySourceFeatures(
"points",
{
filter: ["==", ["get", "title"], "Mapbox SF"]
}
);
Here, "title" is the property name and "Mapbox SF" is the property value.
Here's a codepen to demonstrate this: https://codepen.io/manishraj/pen/jONQQgo

Related

Ag grid community Text Filter textMatcher (Text Custom Matcher) doesn't have any affect on filtering

textMatcher is not marked as "e" but trying to implement it in community version, in order to add some special capabilities to the filtering, doesn't have any affect:
columnDefs = [ {
field: 'country',
filter: 'agTextColumnFilter',
filterParams: {
defaultOption: 'contains',
textMatcher: ({ filter, value, filterText }) => {
// return true/false according to some decision
},
},
......
Is it only available in enterprise version or do I need to define something else in order to use it?

Mapbox js - tileset colors assignment

I am trying to create a colored uk areas map - I need the colors to be driven by local data (say for example sales by postcode), which will always change depending on user selections like report date ranges etc. I have a tileset source which I am assigning to a layer, as in the following (sensitive values blanked out):
this.map.addLayer({
"id": "uk-pc-data",
"type": "fill",
"source-layer": "***",
"source": {
type: 'vector',
url: '***'
}
});
I am then able to style the postcode areas within the tileset by addressing a name property on the tileset features, like so:
"paint": {
"fill-color": [
"match",
["get", "name", [{name: "PR"}, {name: "CH"}, {name: "LN"}]],
[
"PR",
"DD",
"AL",
"PO"
],
"hsla(344, 84%, 29%, 0.37)",
"hsla(131, 94%, 34%, 0)"
]
}
The above will assign one color to the matched areas, and a default to all the other (the non matched ones); What I would like to do, is computing the colour value locally (so based on data constantly changing) based on the feature name, like so
"paint": {
"fill-color": function (feature = {}) {
return localSalesByArea(feature.name)
}
}
This though does not seem to be possible: any help or pointers appreciated; I have been through examples from Mapbox
such as choroplet, heatmaps, expressions but these seem to rely on values delivered via the dataset itself (i.e Population), in my case the values which determine the color scale are separated (they come from an internal reporting api)
If the data on which the colours are determined does not exist in the tileset, you basically have to do a gigantic lookup by name.
You will have a function that generates the fill-color expression, something like:
function makeFillExpression(valuesByName) {
function valueToColor(value) {
return /* insert your choroplething special sauce here */;
}
return ret = [
"match",
["get", "name"],
Object.keys(valuesByName).map(name => valueToColor(valuesByName[name])),
'black'
];
}
Yes, it will be a very large and unwieldy expression.

How to use mapbox "case" expresion on nested properties?

How to use nested value in order to use case == operator? Something like:
this.map.setPaintProperty("somelayer", "fill-color",
["case",
["==", ["properties:some_prop"], someval],
"#34c0dd",
"#499bbc"]
where properties is dict:
properties = {
some_prop: 1,
some_prop2: 2,
// and so on
}
I have tried ["properties.some_prop"] and ["properties"]["some_prop"] and that does not work as well.
And how to print that mapbox query like console.log or something?
If properties is just the regular properties field on a GeoJSON object, then you don't mention it explicitly - all those fields are just accessed directly:
this.map.setPaintProperty("somelayer", "fill-color",
["case",
["==", ["get", "some_prop"], someval], "#34c0dd",
"#499bbc"
]);
Assuming #499bbc is the default colour you want.

AG-GRID Default Sort Model with Dynamic Column Defs

So I have a Grid setup that works with the Enterprise Row Model.
The columns are very dynamic and so the column defs are not known until the first query for rows is made to the server. This all works fine, but how can I set a default sort state when the column defs are not set until after the request has succeeded?
Once the grid has been set-up with the column defs you can just set the sort on any column
gridOptions.columnApi.getColumn(COLUMN_NAME).setSort("asc")
Adding a sort attribute to your colDef works too.
Example:
const columnDefs = [
{
headerName: 'Created Date',
field: 'CreateDate',
sort: 'desc',
sortingOrder: ['desc','asc'] //optional but for better sorting behaviour
}
]
Try this
const sort = [
{
colId: "firstName",
sort: "asc",
},
{
colId: "lastName"
},
];
this.gridApi.setSortModel(sort);

X Ray Scraper: Manipulate data before .write

I'm fiddling around with some scraping, and need to manipulate some of the data before writing it to my json file.
var Xray = require('x-ray');
var x = Xray();
x('http://myUrl.com', '#search_results div div a', [{
title: '.responsive_search_name_combined .search_name .title',
price: '.col.search_price.responsive_secondrow',
}])
.paginate('.search_pagination_right a.pagebtn:last-child#href')
.limit(10)
.write('data.json');
When saved, price looks like this: "price": "\r\n\t\t\t\t\t\t\t\t13,99€\t\t\t\t\t\t\t".
I guess its because theres a lot of spaces in div.col.search_price.responsive_secondrow.
<div class="col search_price responsive_secondrow">
9,99€ </div>
So my question is: Would it be possible to manipulate the data before .write?
Yes, you can simply provide a callback function that takes an object which is the result of your scrape. In this function you can take full control of any post-processing you want to do.
So your code would end up something like:
x('http://myUrl.com', '#search_results div div a', [{
title: '.responsive_search_name_combined .search_name .title',
price: '.col.search_price.responsive_secondrow',
}])
(function(products){
var cleanedProducts = [];
products.forEach(function(product){
var cleanedProduct = {};
cleanedProduct.price = product.price.trim();
//etc
cleanedProducts.push(cleanedProduct)
});
//write out results.json 'manually'
fs.writeFile('results.json', JSON.stringify(cleanedProducts));
})
You could use X-Ray native supported approach which is called filter functions and completely covers the case you described.
filters are custom defined functions allowing you to implement custom logic while processing scraped data.
See code sample below. There's a custom defined filter function with name of cleanUpText and apply it to scraped data price.
var Xray = require('x-ray');
var x = Xray({
filters: {
cleanUpText: function (value) { return value.replace('\r\n\t\t\t\t\t\t\t\t', '').replace('\t\t\t\t\t\t\t', ''); },
}
});
x('http://store.steampowered.com/search/?filter=topsellers', '#search_results div div a', [{
title: '.responsive_search_name_combined .search_name .title ',
price: '.col.search_price.responsive_secondrow | cleanUpText', // calling filter function 'cleanUpText'
}])
.paginate('.search_pagination_right a.pagebtn:last-child#href')
.limit(10)
.write('data.json');
data.json looks like below:
{"title": "PLAYERUNKNOWN'S BATTLEGROUNDS",
"price": "$29.99"},
{"title": "PAYDAY 2: Ultimate Edition",
"price": "$44.98"}