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

Show dataset extent in right menu tab #3371

Merged
merged 9 commits into from
Oct 25, 2018
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.md).
- Extended the version restore view and added a view to restore older versions of a volume tracing. Access it through the dropdown next to the Save button. [#3349](https://github.com/scalableminds/webknossos/pull/3349)
- Added support to watch additional dataset directories, automatically creating symbolic links to the main directory [#3330](https://github.com/scalableminds/webknossos/pull/3330)
- A User can now have multiple layouts for tracing views. [#3299](https://github.com/scalableminds/webknossos/pull/3299)
- The info tab in tracing views now displays the extent of the current dataset. [#3371](https://github.com/scalableminds/webknossos/pull/3371).

### Changed

Expand Down
19 changes: 19 additions & 0 deletions app/assets/javascripts/libs/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Maybe from "data.maybe";
import window, { document, location } from "libs/window";
import naturalSort from "javascript-natural-sort";
import type { APIUser } from "admin/api_flow_types";
import type { BoundingBoxObject } from "oxalis/store";

export type Comparator<T> = (T, T) => -1 | 0 | 1;
type UrlParams = { [key: string]: string };
Expand Down Expand Up @@ -129,6 +130,24 @@ export function computeArrayFromBoundingBox(bb: ?BoundingBoxType): ?Vector6 {
: null;
}

export function aggregateBoundingBox(boundingBoxes: Array<BoundingBoxObject>): BoundingBoxType {
const allCoordinates = [0, 1, 2].map(index =>
boundingBoxes.map(box => box.topLeft[index]).concat(
boundingBoxes.map(box => {
const bottomRight = [
box.topLeft[0] + box.width,
box.topLeft[1] + box.height,
box.topLeft[2] + box.depth,
];
return bottomRight[index];
}),
),
);
const min = (([0, 1, 2].map(index => Math.min(...allCoordinates[index])): any): Vector3);
const max = (([0, 1, 2].map(index => Math.max(...allCoordinates[index])): any): Vector3);
return { min, max };
}

export function compareBy<T>(
collectionForTypeInference: Array<T>, // this parameter is only used let flow infer the used type
selector: T => number,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { getStats } from "oxalis/model/accessors/skeletontracing_accessor";
import { getPlaneScalingFactor } from "oxalis/model/accessors/flycam_accessor";
import Store from "oxalis/store";
import { formatScale } from "libs/format_utils";
import { aggregateBoundingBox } from "libs/utils";
import {
setAnnotationNameAction,
setAnnotationDescriptionAction,
Expand Down Expand Up @@ -89,7 +90,7 @@ export function calculateZoomLevel(flycam: Flycam, dataset: APIDataset): number
return zoom * width * baseVoxel;
}

export function formatZoomLevel(zoomLevel: number): string {
export function formatNumberToLength(zoomLevel: number): string {
if (zoomLevel < 1000) {
return `${zoomLevel.toFixed(0)} nm`;
} else if (zoomLevel < 1000000) {
Expand All @@ -99,6 +100,36 @@ export function formatZoomLevel(zoomLevel: number): string {
}
}

function getDatasetExtentInVoxel(dataset: APIDataset) {
const datasetLayers = dataset.dataSource.dataLayers;
const allBoundingBoxes = datasetLayers.map(layer => layer.boundingBox);
const unifiedBoundingBoxes = aggregateBoundingBox(allBoundingBoxes);
const { min, max } = unifiedBoundingBoxes;
const extent = {
width: max[0] - min[0],
height: max[1] - min[1],
depth: max[2] - min[2],
};
return extent;
}

function getDatasetExtentInLength(dataset: APIDataset) {
const extentInVoxel = getDatasetExtentInVoxel(dataset);
const scale = dataset.dataSource.scale;
const extent = {
width: extentInVoxel.width * scale[0],
height: extentInVoxel.height * scale[1],
depth: extentInVoxel.depth * scale[2],
};
return extent;
}

function formatExtentWithLength(extent: Object, formattingFunction: number => string) {
return `${formattingFunction(extent.width)} x ${formattingFunction(
extent.height,
)} x ${formattingFunction(extent.depth)}`;
}

class DatasetInfoTabView extends React.PureComponent<DatasetInfoTabProps> {
setAnnotationName = (newName: string) => {
this.props.setAnnotationName(newName);
Expand Down Expand Up @@ -226,14 +257,29 @@ class DatasetInfoTabView extends React.PureComponent<DatasetInfoTabProps> {
Store.getState().temporaryConfiguration.controlMode === ControlModeEnum.VIEW;

const zoomLevel = calculateZoomLevel(this.props.flycam, this.props.dataset);

const extentInVoxel = getDatasetExtentInVoxel(this.props.dataset);
const extent = getDatasetExtentInLength(this.props.dataset);
return (
<div className="flex-overflow info-tab-content">
{this.getTracingName(isPublicViewMode)}
{this.getDatasetName(isPublicViewMode)}

<p>Viewport Width: {formatZoomLevel(zoomLevel)}</p>
<p>Viewport Width: {formatNumberToLength(zoomLevel)}</p>
<p>Dataset Resolution: {formatScale(this.props.dataset.dataSource.scale)}</p>
<p>
<table>
<tbody>
<tr>
<td style={{ paddingRight: 8 }}>Dataset Extent:</td>
<td>{formatExtentWithLength(extentInVoxel, x => `${x}`)} Voxel³</td>
</tr>
<tr>
<td />
<td>{formatExtentWithLength(extent, formatNumberToLength)}</td>
</tr>
</tbody>
</table>
</p>

{this.getTracingStatistics()}
{this.getKeyboardShortcuts(isPublicViewMode)}
Expand Down
7 changes: 5 additions & 2 deletions app/assets/javascripts/oxalis/view/scalebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import * as React from "react";
import { connect } from "react-redux";
import constants, { OUTER_BORDER_ORTHO } from "oxalis/constants";
import type { OxalisState, Flycam } from "oxalis/store";
import { calculateZoomLevel, formatZoomLevel } from "oxalis/view/right-menu/dataset_info_tab_view";
import {
calculateZoomLevel,
formatNumberToLength,
} from "oxalis/view/right-menu/dataset_info_tab_view";
import type { APIDataset } from "admin/api_flow_types";

type Props = {|
Expand Down Expand Up @@ -42,7 +45,7 @@ function Scalebar({ flycam, dataset }: Props) {
borderRight: "1px solid",
}}
>
{formatZoomLevel(calculateZoomLevel(flycam, dataset) * scalebarWidthPercentage)}
{formatNumberToLength(calculateZoomLevel(flycam, dataset) * scalebarWidthPercentage)}
</div>
</div>
);
Expand Down