-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
- Add coverage percentiles getColorValue prop to grid layer #614
Conversation
bb58330
to
1dbcc84
Compare
@@ -62,6 +62,23 @@ Color scale domain, default is set to the range of point counts in each cell. | |||
Color ranges as an array of colors formatted as `[255, 255, 255]`. Default is | |||
[colorbrewer](http://colorbrewer2.org/#type=sequential&scheme=YlOrRd&n=6) `6-class YlOrRd`. | |||
|
|||
##### `getColorValue` (Function, optional) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason not to just call this getValue
?
The description can explain that this is used to calculate value.
##### `getColorValue` (Function, optional)
Note to self: It would be nice to be able to show more clearly the expected return type of the accessors (in this case number)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because the value is only used to calculate color, not elevation, so I thought it would be nice to make it clear in the name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And in the future when I add another feature to calculate elevation based on points value I can use getElevationValue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds like we are establishing a new proposed pattern here. Maybe add a section with proposed rules to API GUIDELINES
docs/layers/grid-layer.md
Outdated
- Default: `points => points.length` | ||
|
||
`getColorValue` is the accessor function to get the value that cell color is based on. | ||
It takes an array of points inside each cell as arguments, returns a value. For example, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"returns a value" => "returns a number"?
|
||
- Default: `1` | ||
|
||
Cell size multiplier, clamped between 0 - 1. The final size of cell |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Specify whether coverage is linear or area based? I assume this is just a clamped radiusScale
factor, i.e. linear.
Filter bins and re-calculate color by `upperPercentile`. Hexagons with counts | ||
bigger than the upperPercentile counts will be hidden. | ||
Filter bins and re-calculate color by `upperPercentile`. Hexagons with value | ||
larger than the upperPercentile will be hidden. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be cool if they were just made really transparent / ghosted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This reason of doing this is to filter out really big numbers and re calculate color. When colors for are recalculated, the larger bins that fall outside the percentile range will not have accurate color any more, so we have to hide it. Also if we want to display transparency, we have to always enable depthTest
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the larger bins that fall outside the percentile range will not have accurate color any more, so we have to hide i
I thought we could make the filtered out hexes a white transparent color - i.e. they would desaturate and just become ghosts, but could still retain their elevation and give the user a feeling for what he has filtered out.
Also if we want to display transparency, we have to always enable depthTest.
I guess this could be an optional feature. A prop...
function getMean(pts, key) { | ||
const filtered = pts.filter(pt => Number.isFinite(pt[key])); | ||
|
||
return filtered.length ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the check?
[].reduce((acc, elt) => acc + elt, 0) => 0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if value is null or undefined, we do not include it when calculate Mean, so we need to get the total number of elements that are not null to divide the sum by...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if value is null or undefined, we do not include it when calculate Mean, so we need to get the total number of elements that are not null to divide the sum by
Then the comparison should not use filtered.length
, but just filtered
right? Perhaps a good opportunity to add a test case that triggers this bug, since you are working on coverage anyway?
@@ -25,18 +25,20 @@ import {pointToDensityGridData} from './grid-aggregator'; | |||
import {linearScale, quantizeScale} from '../../../utils/scale-utils'; | |||
import {defaultColorRange} from '../../../utils/color-utils'; | |||
|
|||
const defaultCellSize = 1000; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1, looks cleaner after the change
} | ||
|
||
function _needsReSortBins(oldProps, props) { | ||
return oldProps.getColorValue !== props.getColorValue; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would recommend giving this update criterion another round of thought, as it is inconsistent with updateTriggers which we use to make sure we don't update when functions change.
This is to handle the common cases of ad-hoc functions and bound functions:
new Layer({
getColorValue: () => {}, // new function every render,
getColorValue: this._getColorValue.bind(this), // new function every render,
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added comment to layer doc.
If people pass in a new function every time, the layer is just going to sort the bins on every render, which won't result in error showing colors. But if we don't check the function change, and not re sort the bins when it actually changed. we have no way to detect whether some one pass in a new function to calculate color value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we have no way to detect whether some one pass in a new function to calculate color value.
Unless we expand updateTriggers
to cover this case (but that would probably require a discussion and a separate PR).
OK for now, but I think it is a potential API design issue that we have different behavior for accessors and other functions. We might want to call it out in one of our documents (possibly API guidelines if you decided to update there).
|
||
Object.assign(this.state, {layerData, countRange}); | ||
this.onPercentileChange(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
onPercentileChanged
is quite suggestive of a callback (i.e. calling a function from another component). I'd change this to percenticlesChanged();
or similar
|
||
return quantizeScale(colorDomain, colorRange, cell.count); | ||
return color.concat([alpha]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure how frequently this is called, but cloning arrays (Array.concat) seems like a recipe for bad performance. Can quantizeScale
just take an alpha
argument?
@@ -171,34 +170,34 @@ export default class HexagonLayer extends CompositeLayer { | |||
}; | |||
} | |||
|
|||
_onPercentileChange() { | |||
onPercentileChange() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these callbacks? If not, I'd avoid the on...
naming convention.
Changes Unknown when pulling 30b5858 on grid-colorValue-percentile into ** on master**. |
Changes Unknown when pulling 171edd5 on grid-colorValue-percentile into ** on master**. |
* add getColorValue percentile coverage to grid layer * add layer tests * added grid/hex layer test * fix typo * reset yarn.lock * address comments * replace concat
coverage
,lowerPercentile
,upperPercentile
andgetColorValue
to layer prop_onGetSublayerColor
, use bin.value instead of bin.points.length to calculate color