-
Notifications
You must be signed in to change notification settings - Fork 307
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
feat(annotation) Add default annontation properties #694
base: master
Are you sure you want to change the base?
Changes from 3 commits
47f8d34
356c42c
03eaf93
324342f
43c3e4a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -54,6 +54,7 @@ import { | |
import { parseDataTypeValue } from "#src/util/lerp.js"; | ||
import { getRandomHexString } from "#src/util/random.js"; | ||
import { NullarySignal, Signal } from "#src/util/signal.js"; | ||
import { formatLength } from "#src/util/spatial_units.js"; | ||
import { Uint64 } from "#src/util/uint64.js"; | ||
|
||
export type AnnotationId = string; | ||
|
@@ -106,6 +107,7 @@ export interface AnnotationNumericPropertySpec | |
min?: number; | ||
max?: number; | ||
step?: number; | ||
format?: (x: number) => string; | ||
} | ||
|
||
export const propertyTypeDataType: Record< | ||
|
@@ -496,6 +498,9 @@ export function formatNumericProperty( | |
property: AnnotationNumericPropertySpec, | ||
value: number, | ||
): string { | ||
if (property.format) { | ||
return property.format(value); | ||
} | ||
const formattedValue = | ||
property.type === "float32" ? value.toPrecision(6) : value.toString(); | ||
const { enumValues, enumLabels } = property; | ||
|
@@ -695,6 +700,13 @@ export interface AnnotationTypeHandler<T extends Annotation = Annotation> { | |
annotation: T, | ||
callback: (vec: Float32Array, isVector: boolean) => void, | ||
) => void; | ||
defaultProperties: ( | ||
annotation: T, | ||
scales: Float64Array, | ||
) => { | ||
properties: AnnotationNumericPropertySpec[]; | ||
values: number[]; | ||
}; | ||
} | ||
|
||
function serializeFloatVector( | ||
|
@@ -814,6 +826,33 @@ export const annotationTypeHandlers: Record< | |
callback(annotation.pointA, false); | ||
callback(annotation.pointB, false); | ||
}, | ||
defaultProperties(annotation: Line, scales: Float64Array) { | ||
const properties: AnnotationNumericPropertySpec[] = []; | ||
const values: number[] = []; | ||
const rank = scales.length; | ||
if ( | ||
rank === annotation.pointA.length && | ||
rank === annotation.pointB.length | ||
) { | ||
properties.push({ | ||
type: "float32", | ||
identifier: "Length", | ||
default: 0, | ||
description: "Length of the line annotation in nanometers", | ||
format: formatLength, | ||
}); | ||
let length = 0; | ||
for (let dim = 0; dim < rank; dim++) { | ||
length += | ||
(((annotation.pointA[dim] - annotation.pointB[dim]) / 1e-9) * | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This shouldn't always be nanometers --- it should take into account the units set in the coordinate space. If all dimensions have the same base unit, e.g. meter, then you could just choose an appropriate scale automatically as in the scale bar. If there are mixed units, e.g. meters and seconds, then probably just don't display the length at all. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I updated it to use globalCoordinateSpace.units and using |
||
scales[dim]) ** | ||
2; | ||
} | ||
length = Math.sqrt(length); | ||
values.push(length); | ||
} | ||
return { properties, values }; | ||
}, | ||
}, | ||
[AnnotationType.POINT]: { | ||
icon: "⚬", | ||
|
@@ -858,6 +897,11 @@ export const annotationTypeHandlers: Record< | |
visitGeometry(annotation: Point, callback) { | ||
callback(annotation.point, false); | ||
}, | ||
defaultProperties(annotation: Point, scales: Float64Array) { | ||
annotation; | ||
scales; | ||
return { properties: [], values: [] }; | ||
}, | ||
}, | ||
[AnnotationType.AXIS_ALIGNED_BOUNDING_BOX]: { | ||
icon: "❑", | ||
|
@@ -926,6 +970,14 @@ export const annotationTypeHandlers: Record< | |
callback(annotation.pointA, false); | ||
callback(annotation.pointB, false); | ||
}, | ||
defaultProperties( | ||
annotation: AxisAlignedBoundingBox, | ||
scales: Float64Array, | ||
) { | ||
annotation; | ||
scales; | ||
return { properties: [], values: [] }; | ||
}, | ||
}, | ||
[AnnotationType.ELLIPSOID]: { | ||
icon: "◎", | ||
|
@@ -994,6 +1046,11 @@ export const annotationTypeHandlers: Record< | |
callback(annotation.center, false); | ||
callback(annotation.radii, true); | ||
}, | ||
defaultProperties(annotation: Ellipsoid, scales: Float64Array) { | ||
annotation; | ||
scales; | ||
return { properties: [], values: [] }; | ||
}, | ||
}, | ||
}; | ||
|
||
|
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -1854,6 +1854,19 @@ export function UserLayerWithAnnotationsMixin< | |||
|
||||
const { relationships, properties } = annotationLayer.source; | ||||
const sourceReadonly = annotationLayer.source.readonly; | ||||
const globalCoordinateSpace = | ||||
this.manager.root.coordinateSpace.value; | ||||
const defaultProperties = annotationTypeHandlers[ | ||||
annotation.type | ||||
].defaultProperties(annotation, globalCoordinateSpace.scales); | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is still not correct --- you need to transform the scales, taking into account the various affine transforms that apply, similar to what is done here: neuroglancer/src/ui/annotations.ts Line 1073 in 5898236
|
||||
const allProperties = [ | ||||
...defaultProperties.properties, | ||||
...properties, | ||||
]; | ||||
const allValues = [ | ||||
...defaultProperties.values, | ||||
...annotation.properties, | ||||
]; | ||||
|
||||
// Add the ID to the annotation details. | ||||
const label = document.createElement("label"); | ||||
|
@@ -1872,8 +1885,10 @@ export function UserLayerWithAnnotationsMixin< | |||
label.appendChild(valueElement); | ||||
parent.appendChild(label); | ||||
|
||||
for (let i = 0, count = properties.length; i < count; ++i) { | ||||
const property = properties[i]; | ||||
for (let i = 0, count = allProperties.length; i < count; ++i) { | ||||
const property = allProperties[i]; | ||||
const value = allValues[i]; | ||||
|
||||
const label = document.createElement("label"); | ||||
label.classList.add("neuroglancer-annotation-property"); | ||||
const idElement = document.createElement("span"); | ||||
|
@@ -1886,7 +1901,6 @@ export function UserLayerWithAnnotationsMixin< | |||
if (description !== undefined) { | ||||
label.title = description; | ||||
} | ||||
const value = annotation.properties[i]; | ||||
const valueElement = document.createElement("span"); | ||||
valueElement.classList.add( | ||||
"neuroglancer-annotation-property-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.
Should probably just say "length of the line annotation", with a type of string, and then the value can include the appropriate unit suffix.