Skip to content
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

Scale Bar #158

Merged
merged 14 commits into from
Apr 22, 2020
Merged

Scale Bar #158

merged 14 commits into from
Apr 22, 2020

Conversation

ilan-gold
Copy link
Collaborator

@ilan-gold ilan-gold commented Apr 21, 2020

This PR adds a scale bar:

scalebar

I would have liked the API be smaller (i.e no viewState) for the layer but it is not possible unfortunately: visgl/deck.gl#4504

Fixes #60.

@ilan-gold ilan-gold changed the title Ilan gold/scale bar Scale Bar Apr 21, 2020
@ilan-gold ilan-gold requested a review from manzt April 21, 2020 20:08
Copy link
Member

@manzt manzt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Made a view comments, principally I'd like to avoid copying fields from omexml directly and probably add something like loader.physicalSizes where we store the unit and value for each of the available physical dimensions (XYZ). This way, whatever metadata ends up like for zarr, we don't need to create some odd field on the loader that is an artifact of other metadata source (tiff omexml).

switch (position) {
case 'bottom-right': {
const yCoord =
boundingBox[2][1] - (boundingBox[2][1] - boundingBox[0][1]) * 0.085;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the 0.085 doing? maybe add this as an arg in getPosition with this default.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure.

Comment on lines +32 to +34
PhysicalSizeXUnit && PhysicalSizeXUnit.includes('µm')
? 'µm'
: this.PhysicalSizeXUnit;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this field often missing?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you describe what the 'odd behavior' is?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll leave a clearer note.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was a prepended character. Could have been an error but the µm is kind of wonky so it could be a python-javascript difference.

@@ -18,6 +19,17 @@ export default class DetailView extends VivView {
id: `${loader.type}${getVivId(id)}`,
viewportId: id
});
return [layer];
const { PhysicalSizeXUnit, PhysicalSizeX } = loader;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer that if these are on the loaders we use camelcase like other properties, rather than copying the omexml keys directly. Similar to tileSize, we assume that the PhysicalSizeX and PhysicalSizeY are the same for the image, so maybe we could just have the property physicalSize which is an object:

const { unit, value } = loader.physicalSize;

or if we want to add all sizes and scale bar just assumes x:

const { x, y, z } = loader.physicalSizes;
const { unit, value } = x;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will make it easy to implement on the zarr loader.

Copy link
Member

@manzt manzt Apr 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could even check size units in x and y and console.warn if they are different.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this. This was the thorniest point so I'm glad to have the feedback.

const { loader } = props;
const { id } = this;
const thisViewState = viewStates[id];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps layerViewState or viewStateUpdate or viewState? Confusing to prefix with this in javascript because it is a keyword...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense

Comment on lines 121 to 132
const { PhysicalSizeXUnit, PhysicalSizeX } = loader;
const scaleBarLayer =
PhysicalSizeXUnit && PhysicalSizeX
? new ScaleBarLayer({
id: getVivId(id),
loader,
PhysicalSizeXUnit,
PhysicalSizeX,
viewState: thisViewState
})
: null;
return [detailLayer, border, scaleBarLayer];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be clearer to me what's going on if we just pushed layers to an empty array, rather than adding a null here.

const layers = [];
// ...
layers.push(detailLayer);
// ...
layers.push(border);
// ... 
if (PhysicalSizeXUnit && PhysicalSizeX) {
  // ...
  layers.push(scaleBarLayer);
}

const layers = view.getLayers({ props: { loader } });
const layers = view.getLayers({
props: {
loader: { ...loader, PhysicalSizeXUnit: 'cm', PhysicalSizeX: 0.5 }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not just define these on the loader above?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The base test just checks for id-passing. This one checks that proper layers are rendered, for which this is needed and in the former case it is not. The OverviewView, for example, doesn't technically need this information.


generateViewTests(SideBySideView, defaultArguments);

test(`SideBySideView layer type and props check`, t => {
const view = new SideBySideView(defaultArguments);
const loader = { type: 'loads', isPyramid: true };
const layers = view.getLayers({
props: { loader },
props: {
loader: { ...loader, PhysicalSizeXUnit: 'cm', PhysicalSizeX: 0.5 }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here. probably just create the loader object initially in one place.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

@ilan-gold ilan-gold merged commit d3d7b2c into master Apr 22, 2020
@ilan-gold ilan-gold deleted the ilan-gold/scale_bar branch April 22, 2020 15:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add in a scale bar
2 participants