AnnotationEditorWidget

Source

BackgroundScore.js
import React from 'react';
import PropTypes from 'prop-types';

import style from 'PVWStyle/ReactWidgets/AnnotationEditorWidget.mcss';

export default function render(props) {
return (
<div
className={style.backgroundScore}
style={{
background: props.color,
top: `${props.index * props.step + props.margin}px`,
height: props.fullHeight
? `calc(100% - ${2 * props.margin}px)`
: `${props.step - 2 * props.margin}px`,
}}
/>
);
}

render.propTypes = {
color: PropTypes.string,
index: PropTypes.number,
step: PropTypes.number,
margin: PropTypes.number,
fullHeight: PropTypes.bool,
};

render.defaultProps = {
index: 0,
step: 28,
margin: 1,
fullHeight: false,
color: undefined,
};
ScoreSelector.js
import React from 'react';
import PropTypes from 'prop-types';

import style from 'PVWStyle/ReactWidgets/AnnotationEditorWidget.mcss';

export default function render(props) {
const click = (event) => {
props.onChange(props.name, Number(event.target.getAttribute('data-score')));
};

return (
<section className={[style.scoreContainer, props.className].join(' ')}>
{props.scores.map((score, idx) => (
<div
key={idx}
className={
props.score === idx ? style.selectedScoreBlock : style.scoreBlock
}
style={{
background: score.color,
display: props.horizontal ? 'inline-block' : 'block',
}}
title={score.name}
data-score={idx}
onClick={click}
/>
))}
</section>
);
}

render.propTypes = {
name: PropTypes.string,
score: PropTypes.number,
scores: PropTypes.array,
onChange: PropTypes.func,
horizontal: PropTypes.bool,
className: PropTypes.string,
};

render.defaultProps = {
name: 'default',
horizontal: false,
onChange(name, score) {},
className: '',

score: undefined,
scores: undefined,
};
index.js
import React from 'react';
import PropTypes from 'prop-types';

import style from 'PVWStyle/ReactWidgets/AnnotationEditorWidget.mcss';

import OneScore from './OneScore';
import ManyScore from './ManyScore';
import placeHolder from './placeholder-full.png';
import AnnotationBuilder from '../../../Common/Misc/AnnotationBuilder';

const placeholderContainer = (
<div className={style.placeholderContainer}>
<div className={style.placeholderTitle}>Annotation Editor</div>
<div className={style.placeholderImageContainer}>
<img
src={placeHolder}
alt="Placeholder"
className={style.placeholderImage}
/>
</div>
<div className={style.placeholderSubtitle}>
No annotation currently available
</div>
</div>
);

export default function render(props) {
if (!props.annotation) {
return placeholderContainer;
}

const onSelectionChange = (selection, isEditDone) => {
const annotation = AnnotationBuilder.update(props.annotation, {
selection,
});

// Remove score if a divider is removed
if (
selection.type === 'partition' &&
selection.partition.dividers.length + 1 !== annotation.score.length
) {
let removedIdx = 0;
props.annotation.selection.partition.dividers.forEach((divider, idx) => {
if (selection.partition.dividers.indexOf(divider) === -1) {
removedIdx = idx;
}
});
annotation.score = annotation.score.filter(
(i, idx) => idx !== removedIdx
);
}

if (selection.type === 'empty') {
annotation.score = [];
}

props.onChange(annotation, isEditDone);
};

const onAnnotationChange = (event) => {
const value =
event.target.type === 'number' ? +event.target.value : event.target.value;
const name = event.target.name;
const type = event.type;

if (type === 'blur') {
const annotation = AnnotationBuilder.update(props.annotation, {
[name]: value,
});
props.onChange(AnnotationBuilder.markModified(annotation), true);
} else {
const annotation = Object.assign({}, props.annotation, { [name]: value });
props.onChange(annotation, false);
}
};

const onScoreChange = (idx, value) => {
const score = [].concat(props.annotation.score);
score[Number(idx)] = value;

const annotation = Object.assign({}, props.annotation, { score });
props.onChange(AnnotationBuilder.markModified(annotation), true);
};

const Render =
props.annotation.selection.type === 'partition' ? ManyScore : OneScore;

if (props.annotation.selection.type === 'empty') {
return placeholderContainer;
}

return (
<div
className={
props.annotation && props.annotation.readOnly
? style.disabledTopContainer
: style.topContainer
}
>
<Render
{...props}
onSelectionChange={onSelectionChange}
onAnnotationChange={onAnnotationChange}
onScoreChange={onScoreChange}
/>
</div>
);
}

render.propTypes = {
annotation: PropTypes.object,
scores: PropTypes.array,
ranges: PropTypes.object,
onChange: PropTypes.func,
getLegend: PropTypes.func,
rationaleOpen: PropTypes.bool,
showUncertainty: PropTypes.bool,
};

render.defaultProps = {
onChange(annotation, isEditDone) {},
rationaleOpen: false,
showUncertainty: true,

annotation: undefined,
scores: undefined,
ranges: undefined,
getLegend: undefined,
};