Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@lucide/lab": "^0.1.2",
"@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-checkbox": "^1.0.3",
"@radix-ui/react-dialog": "^1.0.4-rc.9",
Expand Down
2 changes: 2 additions & 0 deletions ui/src/components/filtering/filter-control.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { AlgorithmFilter, NotAlgorithmFilter } from './filters/algorithm-filter'
import { CollectionFilter } from './filters/collection-filter'
import { DateFilter } from './filters/date-filter'
import { ImageFilter } from './filters/image-filter'
import { OODScoreFilter } from './filters/ood-score-filter'
import { PipelineFilter } from './filters/pipeline-filter'
import { ScoreFilter } from './filters/score-filter'
import { SessionFilter } from './filters/session-filter'
Expand All @@ -22,6 +23,7 @@ const ComponentMap: {
} = {
algorithm: AlgorithmFilter,
classification_threshold: ScoreFilter,
determination_ood_score: OODScoreFilter,
collection: CollectionFilter,
date_end: DateFilter,
date_start: DateFilter,
Expand Down
38 changes: 38 additions & 0 deletions ui/src/components/filtering/filters/ood-score-filter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Slider } from 'nova-ui-kit'
import { useEffect, useState } from 'react'
import { useUserPreferences } from 'utils/userPreferences/userPreferencesContext'
import { FilterProps } from './types'

export const OODScoreFilter = ({ value, onAdd }: FilterProps) => {
const { userPreferences, setUserPreferences } = useUserPreferences()
const [displayValue, setDisplayValue] = useState(
userPreferences.oodScoreThreshold
)

useEffect(() => {
if (value?.length) {
setDisplayValue(Number(value))
}
}, [value])

return (
<div className="w-full h-12 flex items-center">
<Slider
invertedColors
min={0}
max={1}
step={0.01}
value={[displayValue]}
onValueChange={([value]) => setDisplayValue(value)}
onValueCommit={([value]) => {
setDisplayValue(value)
onAdd(`${value}`)
setUserPreferences({ ...userPreferences, oodScoreThreshold: value })
}}
/>
<span className="w-12 text-right body-overline text-muted-foreground">
{displayValue}
</span>
</div>
)
}
38 changes: 38 additions & 0 deletions ui/src/components/ood-score.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { faceAlien } from '@lucide/lab'
import { Occurrence } from 'data-services/models/occurrence'
import { BasicTooltip } from 'design-system/components/tooltip/basic-tooltip'
import { Icon } from 'lucide-react'
import { CONSTANTS, ProgressCircle } from 'nova-ui-kit'
import { STRING, translate } from 'utils/language'

const OOD_SCORE_THRESHOLD = 0.3

export const OODScore = ({ occurrence }: { occurrence: Occurrence }) => {
const color = (() => {
if (occurrence.determinationOODScore >= OOD_SCORE_THRESHOLD) {
return CONSTANTS.COLORS.secondary[500]
}
if (occurrence.determinationOODScore > 0) {
return CONSTANTS.COLORS.neutral[500]
}
return CONSTANTS.COLORS.neutral[200]
})()

return (
<BasicTooltip
content={translate(STRING.OUT_OF_DISTRIBUTION_SCORE, {
score: `${occurrence.determinationOODScore}`,
})}
>
<div className="flex items-center gap-3">
<ProgressCircle
color={color}
progress={occurrence.determinationOODScore}
>
<Icon className="w-4 h-4" iconNode={faceAlien} />
</ProgressCircle>
<span>{occurrence.determinationOODScoreLabel}</span>
</div>
</BasicTooltip>
)
}
9 changes: 4 additions & 5 deletions ui/src/data-services/models/classification-details.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash'
import { Algorithm } from './algorithm'
import { Taxon } from './taxa'

Expand All @@ -24,8 +23,8 @@ export class ClassificationDetails {
.slice(0, 5)
.filter(({ taxon }: any) => !!taxon)
.map(({ logit, score, taxon }: any) => ({
logit: _.round(logit, 4),
score: _.round(score, 4),
logit,
score,
taxon: new Taxon(taxon),
}))
: []
Expand All @@ -36,10 +35,10 @@ export class ClassificationDetails {
}

get logit(): number {
return _.round(this._classification.logit, 4)
return this._classification.logit
}

get score(): number {
return _.round(this._classification.score, 4)
return this._classification.score
}
}
6 changes: 2 additions & 4 deletions ui/src/data-services/models/occurrence-details.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash'
import { getFormatedTimeString } from 'utils/date/getFormatedTimeString/getFormatedTimeString'
import { UserPermission } from 'utils/user/types'
import { Algorithm } from './algorithm'
Expand Down Expand Up @@ -131,9 +130,8 @@ export class OccurrenceDetails extends Occurrence {
let label = 'No classification'

if (classification) {
label = `${classification.taxon.name} (${_.round(
classification.score,
4
label = `${classification.taxon.name} (${classification.score.toFixed(
2
)})`
}

Expand Down
11 changes: 6 additions & 5 deletions ui/src/data-services/models/occurrence.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash'
import { getFormatedDateString } from 'utils/date/getFormatedDateString/getFormatedDateString'
import { getFormatedDateTimeString } from 'utils/date/getFormatedDateTimeString/getFormatedDateTimeString'
import { getFormatedTimeString } from 'utils/date/getFormatedTimeString/getFormatedTimeString'
Expand Down Expand Up @@ -71,19 +70,21 @@ export class Occurrence {
get determinationScore(): number {
const score = this._occurrence.determination_details.score

if (score === undefined) {
if (!score) {
return 0
}

return _.round(this._occurrence.determination_score, 4)
return this._occurrence.determination_score
}

get determinationOODScore(): number {
const ood_score = this._occurrence.determination_ood_score
if (ood_score === undefined) {

if (!ood_score) {
return 0
}
return _.round(ood_score, 4)

return ood_score
}

get determinationScoreLabel(): string {
Expand Down
8 changes: 3 additions & 5 deletions ui/src/data-services/models/species-details.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash'
import { ServerSpecies, Species } from './species'

export type ServerSpeciesDetails = ServerSpecies & any // TODO: Update this type
Expand All @@ -20,10 +19,9 @@ export class SpeciesDetails extends Species {
image_url: occurrence.best_detection.url,
caption: this.isUnknown
? 'Center of cluster'
: `${occurrence.determination.name} (${_.round(
occurrence.determination_score,
4
)})`,
: `${
occurrence.determination.name
} (${occurrence.determination_score.toFixed(2)})`,
}
}
}
4 changes: 2 additions & 2 deletions ui/src/design-system/components/card/card.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
}

.image {
// max-width: 100%;
// max-height: 100%;
max-width: 100%;
max-height: 100%;
position: absolute;
top: 50%;
left: 50%;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@
box-sizing: border-box;
overflow: hidden;

img {
max-width: 100%;
max-height: 100%;
}

&:not(.visible) {
opacity: 0;
transition-delay: 0;
Expand Down
4 changes: 3 additions & 1 deletion ui/src/design-system/components/tooltip/basic-tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ export const BasicTooltip = ({
{children}
</Tooltip.Trigger>
<Tooltip.Content side="bottom">
<span className="block">{content}</span>
<span className="block text-center whitespace-break-spaces">
{content}
</span>
</Tooltip.Content>
</Tooltip.Root>
</Tooltip.Provider>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ const MachinePredictionDetails = ({
<div className="w-full flex items-center gap-4">
<BasicTooltip
content={translate(STRING.MACHINE_PREDICTION_SCORE, {
score,
score: `${score}`,
})}
>
<div className="px-1">
Expand Down
26 changes: 23 additions & 3 deletions ui/src/pages/occurrence-details/occurrence-details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ import {
BlueprintCollection,
BlueprintItem,
} from 'components/blueprint-collection/blueprint-collection'
import { OODScore } from 'components/ood-score'
import { OccurrenceDetails as Occurrence } from 'data-services/models/occurrence-details'
import { InfoBlock } from 'design-system/components/info-block/info-block'
import {
InfoBlockField,
InfoBlockFieldValue,
} from 'design-system/components/info-block/info-block'
import * as Tabs from 'design-system/components/tabs/tabs'
import { BasicTooltip } from 'design-system/components/tooltip/basic-tooltip'
import { SearchIcon } from 'lucide-react'
Expand Down Expand Up @@ -151,7 +155,7 @@ export const OccurrenceDetails = ({
name: occurrence.determinationVerifiedBy?.name,
})
: translate(STRING.MACHINE_PREDICTION_SCORE, {
score: occurrence.determinationScore,
score: `${occurrence.determinationScore}`,
})
}
>
Expand Down Expand Up @@ -228,7 +232,23 @@ export const OccurrenceDetails = ({
<Tabs.Trigger value={TABS.RAW} label="Raw" />
</Tabs.List>
<Tabs.Content value={TABS.FIELDS}>
<InfoBlock fields={fields} />
<div className="grid gap-6">
<InfoBlockField
label={translate(STRING.FIELD_LABEL_OOD_SCORE)}
>
<div>
<OODScore occurrence={occurrence} />
</div>
</InfoBlockField>
{fields.map((field, index) => (
<InfoBlockField key={index} label={field.label}>
<InfoBlockFieldValue
value={field.value}
to={field.to}
/>
</InfoBlockField>
))}
</div>
</Tabs.Content>
<Tabs.Content value={TABS.IDENTIFICATION}>
<div className={styles.identifications}>
Expand Down
Loading