mapbox : how to combine two expressions to style a layer? - expression

I have this expressions that styles my layer when a feature is clicked:
the circle radius changes from 2 (default) to 5 (clicked).
'circle-radius'=> [
'case',
['boolean', ['feature-state', 'clicked'], false],
5,//clicked
2//default
]
But I also want that the radius changes when the feature is hovered:
'circle-radius'=> [
'case',
['boolean', ['feature-state', 'hovered'], false],
7,//hovered
2//default
]
How can I combine those two expressions into one ?
Thanks !

I found out:
'circle-radius'=>[
'case',
['boolean', ['feature-state', 'hovered'], false], 7,
['boolean', ['feature-state', 'clicked'], false], 5,
2 //else
]

Related

sync fetch eloquent laravel

i have this array:
$ingredients_alergens = [
1285 => [ //id from ingredient
4, //id from alergen
2
]
1286 => [
6
]
1287 => [
1
]
1288 => [
9
]
]
and i want make a massive sync similar to this:
$ingredient->alergens()->sync([1,3,8]);
but with all the array. I want make a Ășnic sync/upsert/something for a full list and don't do query to query. Because i have arrays/jsons from more than a thousand redords.
Are there any way to build a massive sync (into single query, like an upsert) into eloquent laravel?
You have many Ingredients (1285, 1286, 1287, 1288), so you'd need to get all of them first and then, for each of them, sync the relationship.
You could do it with these 2 lines using your $ingredients_alergens variable:
$ingredients_alergens = [
1285 => [4, 2],
1286 => [6],
1287 => [1],
1288 => [9],
];
Ingredient::findMany(array_keys($ingredients_alergens)) // findMany([1285, 1286, 1287, 1288])
->each(fn(Ingredient $i) => $i->alergens()->sync($ingredient_alergens[$i->id]));
If you do not want sync to delete existing alergens. (For example, you just want to add alergen 9 to ingredient 1288), use syncWithoutDetaching() instead of sync().

Adding missing rows of data in a collection - unexplanable Laravel behavior

I have a table of data and I need to fetch an array from it, that looks like this:
[
['Mon', 25],
['Tue', 13],
['Thu', 25]
]
I'm achieving this through some collection acrobatics. At some point I am mapping the collection adding the numerical value of that day (1 Monday, 2 Tuesday) as a key, so I can sortKeys() later.
The problem is not all days are always present and I want to add them with a value of 0 at their respective place.
My first attempt was foreach on an array of days of the week, and if
$collection->flatten()->search($day) returns false, prepend that day. This works fine, but Thu always get appended. It never returns true on the search even though it's copied and pasted and should be identical. All other days are skipped/prepended correctly...
Then I tried array_search on toArray() and the same thing happened. Thu never returns true ...
This is extremely weird, basically Thu == Thu returns false
Is there anyway I can use array_merge or something like that to make it better (or get it working at all?).
This is one way of doing it. It could be done much cleaner, if your data was structured different in the first place, like using day name/value as key, instead of having both in sub arrays, but I will keep to the original question:
$defaultDays = collect([
['Mon', 0],
['Tue', 0],
['Wed', 0],
['Thu', 0],
['Fri', 0],
['Sat', 0],
['Sun', 0],
]);
$days = [
['Mon', 25],
['Tue', 13],
['Thu', 25]
];
// Use $defaultDays to map, as we will need all seven days no matter what.
$days = $defaultDays->map(static function (array $defaultDay) use ($days) {
// Current match is the default day...
$match = $defaultDay;
foreach ($days as $day) {
if ($day[0] === $defaultDay[0]) {
$match = $day;
}
}
return $match;
});
This will result in:
Illuminate\Support\Collection {#1388
#items: array:7 [
0 => array:2 [
0 => "Mon"
1 => 25
]
1 => array:2 [
0 => "Tue"
1 => 13
]
2 => array:2 [
0 => "Wed"
1 => 0
]
3 => array:2 [
0 => "Thu"
1 => 25
]
4 => array:2 [
0 => "Fri"
1 => 0
]
5 => array:2 [
0 => "Sat"
1 => 0
]
6 => array:2 [
0 => "Sun"
1 => 0
]
]
}

RGeo - fix self-intersections

I have a bunch of polygons that have self-intersection which causes some errors in further postprocessing them (in particular - I can't calculate intersection area of those polygons with other polygons). Here is an example of broken polygon:
{
"type": "MultiPolygon",
"coordinates": [
[
[
[
6.881057785381658,
46.82373306675715
],
[
6.857171686909481,
46.81861230543794
],
[
6.857354659059071,
46.81856788926046
],
[
6.856993473052509,
46.82693029065604
],
[
6.8612894138116785,
46.83422796373707
],
[
6.86720955648855,
46.835636765630476
],
[
6.871281147359957,
46.83078486366309
],
[
6.871573291317274,
46.8306215963777
],
[
6.877608228639841,
46.82771553607934
],
[
6.877758462659651,
46.82772313420989
],
[
6.877852632482749,
46.827735617670285
],
[
6.880928107931434,
46.82630213148064
],
[
6.8810399979122305,
46.82622029042867
],
[
6.881117606743071,
46.826115612819855
],
[
6.881057785381658,
46.82373306675715
]
]
]
]
}
This is what it looks like on the map - as you can see, there is intersection of two polygon edges. RGeo throws an error, pointing intersection coordinate (I guess): => "Geos::GEOSException: TopologyException: Input geom 0 is invalid: Self-intersection at or near point 6.8573510795579145 46.818650764080992 at 6.8573510795579145 46.818650764080992". So, I have it at least.
My question is: is there a way to fix that intersection automatically? I read, that a possible solution is to insert 2 similar points with coordinates of self-intersection. But the problem is - the polygon has a specific order, and I don't know WHERE to insert those points.
Also, maybe there are some existing tools helping fix that...
The solution I would use is postgis's ST_MakeValid option for postgres if that is an option for you you could do something along the lines of ST_AsText(ST_MakeValid(geom_column)) or if you would rather pass in the text here is an example using the bowtie example shown in prepair:
select ST_AsText(ST_MakeValid(ST_GeomFromText('POLYGON((0 0, 0 10, 10 0, 10 10, 0 0))')));
st_astext
-----------------------------------------------------------
MULTIPOLYGON(((0 0,0 10,5 5,0 0)),((5 5,10 10,10 0,5 5)))
(1 row)
If that doesn't interest you, you could export those geometries and use a tool like prepair to convert them. To sum up how this works behind the scenes, it will split these "bowties" into multiple polygons which will then be made into a multipolygon. The same type of fix will applied to multipolygons.

Fill area above line in AmCharts

I'm plotting threshold violations. In some cases, thresholds are violated when the values are above the threshold. In this case, I fill the area below the line, like so:
However, in cases where values violate the threshold when they are below it, I want to fill the area above the line. Because I don't know how, the below image looks a bit weird. It'd be better if only the big dip at the beginning was in red. Like the reverse effect of the first image.
How can I fill the area above a line chart in AmCharts 3?
My current configuration (excuse the PHP, my frontend app eats JSON):
array(
'id' => 'major',
'valueAxis' => 'result',
'valueField' => 'result',
'type' => 'smoothedLine',
'lineThickness' => 2,
'lineAlpha' => 1,
'lineColor' => $threshold_at_top ? 'gold' : 'crimson',
'fillAlphas' => $threshold_at_top ? 0.001 : 0.1,
'negativeLineAlpha' => 1,
'negativeLineColor' => $threshold_at_top ? 'crimson' : 'gold',
'negativeFillAlphas' => $threshold_at_top ? 0.1 : 0.001,
'negativeBase' => $threshold_major,
'bullet' => 'none',
'balloon' => array(
'enabled' => false
)
),
array(
'id' => 'minor',
'valueAxis' => 'result',
'valueField' => 'result',
'type' => 'smoothedLine',
'lineThickness' => 2,
'lineAlpha' => $threshold_at_top ? 1 : 0,
'lineColor' => $threshold_at_top ? 'teal' : 'crimson',
'fillAlphas' => $threshold_at_top ? 0.001 : 0.1,
'negativeLineAlpha' => $threshold_at_top ? 0 : 1,
'negativeLineColor' => $threshold_at_top ? 'crimson' : 'teal',
'negativeFillAlphas' => $threshold_at_top ? 0.1 : 0.001,
'negativeBase' => $threshold_minor,
'bullet' => 'none',
'balloonText' => '<b>Result</b><br /><span style="font-size:1.5em;">[[value]]' . ( $last_datapoint->is_percentage ? ' %' : '' ) . '</span>',
'balloon' => array(
'adjustBorderColor' => false,
'color' => '#f1f1f1',
'fillColor' => '#2d87c3'
)
)
minor is the same line chart drawn on top of major.
What I've tried so far
When $threshold_at_top == true, I add another (invisible) top graph, which is simply the same value at each datapoint. This value is above all other values of the other graphs. For example, when I'm plotting a graph with results between 0 and 100, I plot this hidden top graph at 100.
Then I add it to the graphs object (as first element):
array_unshift( $options[ 'graphs' ], array(
'id' => 'top',
'valueAxis' => 'result',
'valueField' => 'top',
'type' => 'smoothedLine',
'lineAlpha' => 0,
'fillAlphas' => 0,
'bullet' => 'none',
'balloon' => array(
'enabled' => false
)
));
Then, I tell my existing major and minor graphs to 'fillToGraph' : 'top':
$options[ 'graphs' ][ 3 ][ 'fillToGraph' ] = 'top';
$options[ 'graphs' ][ 4 ][ 'fillToGraph' ] = 'top';
This gives the desired effect, but only when zoomed in enough:
When scrolling the same chart further to the right, new datapoints come into view, and it somehow messes up the area filled:
I reached out to AmCharts support, and they confirmed my suspicion (emphasis mine):
I checked with colleagues and I just wanted to let you know that
regular line graphs can support both fillToGraph and negativeFill at
the same time. You can see this behavior in the example below:
https://codepen.io/team/amcharts/pen/f8d6c8c5d3a2b4550a2b99f7486355e5?editors=0010
"graphs": [{
"id": "fromGraph",
"fillAlphas": 0.2,
"fillToGraph": "toGraph",
//"type": "smoothedLine",
"lineAlpha": 1,
"showBalloon": false,
"valueField": "fromValue",
"negativeBase": 40,
"negativeLineColor": "crimson"
}...
Therefore, we suggest using regular lines instead of smoothedLines, if
at all possible.
It's not possible to create my desired effect using smoothedLine graphs. See the bug below:

Dynamic layout additions in Rebol3

I would like to dynamically add a button to the layout of a view, with the actor causing this addition belonging to a button that is already part of the layout.
I started with this:
REBOL [title: "Dynamic Button Addition"]
tilesize: 60x60
curtile: 1
stylize [
p: button [
facets: [init-size: tilesize max-size: tilesize]
actors: [
on-action: [
++ curtile
append tiles compose [ p (to-string curtile) ]
print ? tiles/options/content
v/redraw
]
]
]
]
v: [
tiles: hgroup [ p "1" ]
]
view v
...which does not appear to have the value of tiles/options/content change with each click.
I can get it to change if make these changes:
append tiledata compose [ p (to-string curtile) ]
and
tiledata: [ p "1" ]
v: [
tiles: hgroup tiledata
However, this does not cause any change on screen. If I replace the last four lines with this:
v: view [
tiles: hgroup tiledata
]
...so that v is now the view rather than the view's layout, I get this error when I click:
** Script error: v has no value
** Where: actor all foreach do-actor unless do-face if actor all foreach do-actor if do-event do-event if do-event either -apply- wake-up loop -apply- wait forever try do-events if view do either either either -apply-
** Near: actor face :data
This makes sense to me, because v is not yet done being defined, until I exit the program, IIUC.
How, then, can I make changes to v before the program ends, but after it's been passed to view?
Not very nice, but working if you replace
v/redraw
with these two lines
unview/all
view v
And there is a real dynamic example on how to update a layout that has already be viewed
I will simplify it
stylize [
tbox: hpanel [
actors: [
on-make: [
append face/options [
content: [
]
]
do-actor/style face 'on-make none 'hpanel
]
]
]
]
view/across [
button "button 1"
on-action [
append-content test compose [
button ( join "button " 2 + length? test/gob)
]
]
test: tbox
]

Resources