-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
VV - Implement Classifier Tool/Task (#6511)
* Create Volumetric Task and stub out Annotation
- Loading branch information
Showing
11 changed files
with
276 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
packages/lib-classifier/src/plugins/tasks/experimental/volumetric/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# Volumetric Task | ||
|
||
The volumetric task is a task type designed for use with structured volumetric JSON, as part of an NIH neuron mapping project. The task is a drawing/click-oriented task that constructs volumetric annotation data based on the clicked point in 3D space. | ||
|
||
The volumetric task requires subjects with a location of application/json mime type. The subject's location content is used to initialize the structured subject data to be annotated. | ||
|
||
The volumetric task does not support a required property. | ||
|
||
The volumetric task does not support tags (i.e. insertion, deletion). | ||
|
||
The volumetric task is disabled until the subject is loaded. |
95 changes: 95 additions & 0 deletions
95
...ges/lib-classifier/src/plugins/tasks/experimental/volumetric/components/VolumetricTask.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import { Box, Text } from "grommet" | ||
import { Blank } from "grommet-icons" | ||
import InputStatus from "../../../components/InputStatus" | ||
import { Markdownz } from "@zooniverse/react-components" | ||
import { observer } from "mobx-react" | ||
import PropTypes from "prop-types" | ||
import styled from "styled-components" | ||
import TaskInput from "../../../components/TaskInput" | ||
|
||
// Note: ANNOTATION_COUNT will be refactored in next PR to use MobX Annotations | ||
const ANNOTATION_COUNT = 3 | ||
const SVG_ARROW = "48 50, 48 15, 40 15, 50 0, 60 15, 52 15, 52 50" | ||
|
||
const StyledInstructionText = styled(Text)` | ||
margin: 0; | ||
padding: 0; | ||
width: 100%; | ||
> *:first-child { | ||
margin-top: 0; | ||
} | ||
` | ||
|
||
const StyledToolIcon = styled.div` | ||
background-color: #2d2d2d; | ||
display: flex; | ||
align-items: center; | ||
padding-left: 15px; | ||
&::after { | ||
content: " "; | ||
margin-right: 1ch; | ||
white-space: pre; | ||
} | ||
> svg { | ||
height: 1.5em; | ||
vertical-align: bottom; | ||
width: 1.5em; | ||
} | ||
` | ||
|
||
function VolumetricTask({ disabled = false, task }) { | ||
return ( | ||
<Box> | ||
<StyledInstructionText as="legend" size="small"> | ||
<Markdownz>{task.instruction}</Markdownz> | ||
</StyledInstructionText> | ||
|
||
{/* | ||
NOTE: Because there is only one active tool in a Volumetric project, | ||
we do checked=true & index=0 to hardcode this tool as active | ||
*/} | ||
|
||
<TaskInput | ||
checked={true} | ||
disabled={disabled} | ||
index={0} | ||
label={"3D Viewer"} | ||
labelIcon={ | ||
<StyledToolIcon> | ||
<Blank viewBox="0 0 100 100"> | ||
<polygon | ||
points={SVG_ARROW} | ||
fill="blue" | ||
transform="rotate(0 50 50)" | ||
/> | ||
<polygon | ||
points={SVG_ARROW} | ||
fill="green" | ||
transform="rotate(135 50 50)" | ||
/> | ||
<polygon | ||
points={SVG_ARROW} | ||
fill="red" | ||
transform="rotate(225 50 50)" | ||
/> | ||
</Blank> | ||
</StyledToolIcon> | ||
} | ||
labelStatus={<InputStatus count={ANNOTATION_COUNT} />} | ||
name="volumetric-tool" | ||
type="radio" | ||
/> | ||
</Box> | ||
) | ||
} | ||
|
||
VolumetricTask.propTypes = { | ||
task: PropTypes.shape({ | ||
instruction: PropTypes.string, | ||
}), | ||
} | ||
|
||
export default observer(VolumetricTask) |
24 changes: 24 additions & 0 deletions
24
...ib-classifier/src/plugins/tasks/experimental/volumetric/components/VolumetricTask.spec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { composeStory } from "@storybook/react" | ||
import { render, screen } from "@testing-library/react" | ||
import Meta, { Default } from "./VolumetricTask.stories" | ||
|
||
describe("VolumetricTask", function () { | ||
const DefaultStory = composeStory(Default, Meta) | ||
|
||
describe("when it renders", function () { | ||
it("should show the instruction", function () { | ||
render(<DefaultStory />) | ||
expect(screen.getByText("Volumetric the task")).to.be.ok() | ||
}) | ||
|
||
it("should show the label text", function () { | ||
render(<DefaultStory />) | ||
expect(screen.getByText("3D Viewer")).to.be.ok() | ||
}) | ||
|
||
it("should show the classification count", function () { | ||
render(<DefaultStory />) | ||
expect(screen.getByText("InputStatus.drawn")).to.be.ok() | ||
}) | ||
}) | ||
}) |
23 changes: 23 additions & 0 deletions
23
...classifier/src/plugins/tasks/experimental/volumetric/components/VolumetricTask.stories.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { MockTask } from '@stories/components' | ||
import VolumetricTask from './VolumetricTask' | ||
|
||
export default { | ||
title: 'Tasks / Volumetric', | ||
component: VolumetricTask, | ||
args: {}, | ||
argTypes: {} | ||
} | ||
|
||
const tasks = { | ||
T0: { | ||
strings: { | ||
instruction: 'Volumetric the task', | ||
}, | ||
taskKey: 'T0', | ||
type: 'volumetric', | ||
} | ||
} | ||
|
||
export function Default () { | ||
return (<MockTask tasks={tasks} />) | ||
} |
9 changes: 9 additions & 0 deletions
9
packages/lib-classifier/src/plugins/tasks/experimental/volumetric/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { default as TaskComponent } from "./components/VolumetricTask" | ||
import { default as TaskModel } from "./models/VolumetricTask" | ||
import { default as AnnotationModel } from "./models/VolumetricAnnotation" | ||
|
||
export default { | ||
TaskComponent, | ||
TaskModel, | ||
AnnotationModel | ||
} |
11 changes: 11 additions & 0 deletions
11
...s/lib-classifier/src/plugins/tasks/experimental/volumetric/models/VolumetricAnnotation.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { types } from 'mobx-state-tree' | ||
import Annotation from '../../../models/Annotation' | ||
|
||
const Volumetric = types | ||
.model('Volumetric', { | ||
taskType: types.literal('volumetric'), | ||
value: types.optional(types.string, ''), | ||
}) | ||
|
||
const VolumetricAnnotation = types.compose('VolumetricAnnotation', Annotation, Volumetric) | ||
export default VolumetricAnnotation |
23 changes: 23 additions & 0 deletions
23
packages/lib-classifier/src/plugins/tasks/experimental/volumetric/models/VolumetricTask.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import cuid from "cuid" | ||
import { types } from "mobx-state-tree" | ||
import Task from "../../../models/Task" | ||
import VolumetricAnnotation from "./VolumetricAnnotation" | ||
|
||
const Volumetric = types | ||
.model("Volumetric", { | ||
annotation: types.safeReference(VolumetricAnnotation), | ||
type: types.literal("volumetric"), | ||
}) | ||
.views((self) => ({ | ||
defaultAnnotation(id = cuid()) { | ||
return VolumetricAnnotation.create({ | ||
id, | ||
task: self.taskKey, | ||
taskType: self.type, | ||
}) | ||
}, | ||
})) | ||
|
||
const VolumetricTask = types.compose("VolumetricTask", Task, Volumetric) | ||
|
||
export default VolumetricTask |
77 changes: 77 additions & 0 deletions
77
...es/lib-classifier/src/plugins/tasks/experimental/volumetric/models/VolumetricTask.spec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import VolumetricTask from "@plugins/tasks/experimental/volumetric" | ||
|
||
describe("Model > VolumetricTask", function () { | ||
const volumetricTask = { | ||
taskKey: "T0", | ||
type: "volumetric", | ||
} | ||
|
||
const singleChoiceTask = { | ||
answers: [ | ||
{ label: "yes", next: "S2" }, | ||
{ label: "no", next: "S3" }, | ||
], | ||
strings: { | ||
question: "Do you exist?", | ||
}, | ||
required: "", | ||
taskKey: "T1", | ||
type: "single", | ||
} | ||
|
||
it("should exist", function () { | ||
const task = VolumetricTask.TaskModel.create(volumetricTask) | ||
expect(task).to.be.ok() | ||
expect(task).to.be.an("object") | ||
}) | ||
|
||
it("should error for invalid tasks", function () { | ||
let errorThrown = false | ||
try { | ||
VolumetricTask.TaskModel.create(singleChoiceTask) | ||
} catch (e) { | ||
errorThrown = true | ||
} | ||
expect(errorThrown).to.be.true() | ||
}) | ||
|
||
describe("Views > defaultAnnotation", function () { | ||
let task | ||
|
||
before(function () { | ||
task = VolumetricTask.TaskModel.create(volumetricTask) | ||
}) | ||
|
||
it("should be a valid annotation", function () { | ||
const annotation = task.defaultAnnotation() | ||
expect(annotation.id).to.be.ok() | ||
expect(annotation.task).to.equal("T0") | ||
expect(annotation.taskType).to.equal("volumetric") | ||
}) | ||
|
||
it("should generate unique annotations", function () { | ||
const firstAnnotation = task.defaultAnnotation() | ||
const secondAnnotation = task.defaultAnnotation() | ||
expect(firstAnnotation.id).to.not.equal(secondAnnotation.id) | ||
}) | ||
}) | ||
|
||
describe("with an annotation", function () { | ||
let annotation | ||
let task | ||
|
||
before(function () { | ||
task = VolumetricTask.TaskModel.create(volumetricTask) | ||
annotation = task.defaultAnnotation() | ||
}) | ||
|
||
it("should start up with an empty string", function () { | ||
expect(annotation.value).to.equal("") | ||
}) | ||
|
||
it("should update annotations", function () { | ||
annotation.update("Hello there!") | ||
expect(annotation.value).to.equal("Hello there!") | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters