Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

#162 Data Annotation #415

Merged
merged 47 commits into from
Jul 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
68816f5
Merge pull request #2 from CyberReboot/master
hopetambala Jun 6, 2019
c3ab30f
Merge pull request #4 from hopetambala/#285-Styling-Ring-Menu
hopetambala Jun 12, 2019
490d9ac
refactor(): see data
hopetambala Jun 18, 2019
1a9ce5e
refactor(): add notes
hopetambala Jun 18, 2019
72fb69f
feat(): add position action to tooltip
hopetambala Jun 24, 2019
bc10f12
refactor(): remove extraneous
hopetambala Jun 25, 2019
0c35265
test(controls.test.js): add position testing to contro
hopetambala Jun 25, 2019
9644dd4
style(): make div look like post-it
hopetambala Jun 25, 2019
9162aff
revert(): back to mousemove
hopetambala Jun 25, 2019
be0553f
chore(selectedDatum): send selected data to redux store
hopetambala Jun 25, 2019
156a032
chore(): add data action to tooltip
hopetambala Jun 25, 2019
d8f7962
refactor(data sent to store): move console.log of data to Tooltip.js …
hopetambala Jun 25, 2019
7feb0ba
chore(): "disable" the show tooltip
hopetambala Jun 26, 2019
acc645b
fix(controls.test): add tests for position and datum
hopetambala Jun 26, 2019
70b38a1
feat(tooltip data): add ability to click on a node or element for too…
hopetambala Jun 26, 2019
2ac018c
Merge pull request #5 from CyberReboot/master
hopetambala Jun 26, 2019
6df43ad
Merge pull request #6 from hopetambala/feature-note-taking
hopetambala Jun 26, 2019
f304f0c
refactor(): cleaning up
hopetambala Jun 27, 2019
55d4175
chore(note taking): add notetaking actions
hopetambala Jun 27, 2019
bf71126
refactor(controls.test.js): refactor test so that changes to controls…
hopetambala Jun 28, 2019
f8b573b
Delete notetaking.js
hopetambala Jun 28, 2019
afb5a06
refactor(): remove custom input component
hopetambala Jun 28, 2019
84a1403
chore(note actions): add redux logic for note taking feature
hopetambala Jun 28, 2019
6f8a4eb
comment(data action): add comments to how I retrieve data
hopetambala Jul 1, 2019
82714d7
feat(add notes to store!): add notes with id to store
hopetambala Jul 1, 2019
93df0db
chore(): add actions to notes.js
hopetambala Jul 1, 2019
6894288
feat(labels): add ability to add labels to notes
hopetambala Jul 8, 2019
1652fcb
feat(add and remove notes): add and remove notes in the tooltip
hopetambala Jul 10, 2019
429feff
Merge pull request #7 from CyberReboot/master
hopetambala Jul 10, 2019
71d1bde
export()
hopetambala Jul 12, 2019
2deea19
feat(upload): get notes to be uploaded as well!
hopetambala Jul 12, 2019
dafd41f
Merge pull request #8 from hopetambala/feature-note-taking-
hopetambala Jul 12, 2019
f793a38
lint():
hopetambala Jul 12, 2019
2b4cd0e
Merge branch 'master' into master
rashley-iqt Jul 16, 2019
40a1f8b
refactor(semicolons)
hopetambala Jul 16, 2019
8ff4b59
refactor(naming): change names of variables to reflect intent
hopetambala Jul 16, 2019
aecd568
refactor(commenting): remove non-executed code
hopetambala Jul 16, 2019
f3bd551
refactor(readability): remove multline and add comma
hopetambala Jul 16, 2019
f83f7a1
refactor(spacing):
hopetambala Jul 16, 2019
cd0df85
chore(test): create a notes testing file to test notes reducer
hopetambala Jul 16, 2019
e2681e5
Merge branch 'master' into master
hopetambala Jul 16, 2019
2788ad7
fix(tooltip): overlap between d3 sliding dataset and notetip
hopetambala Jul 16, 2019
cd87c35
Merge branch 'master' of https://github.com/hopetambala/CRviz
hopetambala Jul 16, 2019
5aa13ae
fix(design): address rashley-iqt changes request
hopetambala Jul 17, 2019
75df891
lint(): fix linting errors int notes.test.js and tooltip
hopetambala Jul 17, 2019
209d2b7
fix(persistence of notes): user doesn't have to click away to get not…
hopetambala Jul 17, 2019
edcbc54
Merge pull request #12 from hopetambala/Data-Annotation-#415
hopetambala Jul 17, 2019
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
37 changes: 32 additions & 5 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
setHierarchyConfig, showNodes, colorBy, selectControls, setStartDataset, setEndDataset,
showBusy
} from 'domain/controls';
import { getAllNotes } from "./domain/notes";
import { getError, clearError } from "domain/error";
import { removeSearchIndex } from "epics/index-dataset-epic";
import { uploadDataset } from "epics/upload-dataset-epic";
Expand All @@ -30,23 +31,27 @@ import Visualization from 'features/visualization/Visualization';
import DatasetControls from 'features/dataset-controls/DatasetControls';
import DatasetSlider from 'features/dataset-controls/DatasetSlider';
import DatasetUpload from 'features/dataset-controls/DatasetUpload';
import { getDataToExport } from "features/dataset-controls/export"
import { getDataToExport } from "features/dataset-controls/export";
import TooltipControls from "features/tooltip/Tooltip";

import style from './App.module.css';

import datasets from './datasets';


const uuidv4 = require('uuid/v4');

Modal.setAppElement('#root');
const IMPORT = "import";
const EXPORT = "export";
const DATA = "data";
const CONTROLS = "controls";
const NOTES = "notes";
const defaultOptions = {
action: "",
data: true,
controls: true
controls: true,
notes: true
}
class App extends Component {

Expand All @@ -59,10 +64,11 @@ class App extends Component {
startUuid: null,
endUuid: null,
showOptions: false,
options:{
options: {
action: "",
data: true,
controls: true
controls: true,
notes: true,
},
selectedFile: null,
exportName: "dataset.json",
Expand Down Expand Up @@ -169,6 +175,7 @@ class App extends Component {
'file': this.state.selectedFile,
'includeData': this.state.options.data,
'includeControls': this.state.options.controls,
'includeNotes': this.state.options.notes,
})
}
this.setState({showOptions: false })
Expand All @@ -184,9 +191,10 @@ class App extends Component {
getDownloadUrl = () => {
const datasets = this.state.options.data && this.props.fullDatasets;
const controls = this.state.options.controls && this.props.controls;
const notes = this.state.options.notes && this.props.notes;
const keyFields = this.state.options.data && this.props.keyFields;
const ignoredFields = this.state.options.data && this.props.ignoredFields;
const exportData = getDataToExport(datasets, keyFields, ignoredFields, controls)
const exportData = getDataToExport(datasets, keyFields, ignoredFields, controls,notes)
hopetambala marked this conversation as resolved.
Show resolved Hide resolved
const urlObject = window.URL || window.webkitURL || window;
const json = JSON.stringify(exportData, null, 2);
const blob = new Blob([json], {'type': "application/json"});
Expand Down Expand Up @@ -460,6 +468,19 @@ class App extends Component {
</div>
<label >Controls</label>
</div>
<div className={`${style.checkboxContainer} input-group`}>
<div className={ style.switch }>
<input
type="checkbox"
id="notes-check"
checked={options.notes}
onChange={(evt) => this.setOptions(NOTES, evt.target.checked)}
/>
<label htmlFor="notes-check" className={ style.switchLabel }>
</label>
</div>
<label>Notes</label>
</div>
</div>
<div>
<span className={ style.centerSpan }>
Expand Down Expand Up @@ -492,6 +513,11 @@ class App extends Component {
loading={this.props.shouldShowBusy}
/>
</div>

<div >
<TooltipControls />
</div>

</div>
);
}
Expand All @@ -514,6 +540,7 @@ const mapStateToProps = state => {
endUuid: controls.end,
fullDatasets: datasets,
controls: controls,
notes: getAllNotes(state),
keyFields: getKeyFields(state),
ignoredFields: getIgnoredFields(state),
shouldShowBusy: controls.showBusy,
Expand Down
19 changes: 16 additions & 3 deletions src/domain/controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ const defaultState = {
start: null, // The uuid of the dataset to use as the starting point for comparison
end: null, // The uuid of the dataset to use as the end point for comparison
showBusy: false, //display the activity icon
position: [0,0], // The position used for a mouse click
datum: null //
};

// ACTIONS
// ACTION CREATORS

const setControls = createAction("SET_CONTROLS");
const setStartDataset = createAction("SET_START_DATASET");
Expand All @@ -20,17 +22,22 @@ const showNodes = createAction("SHOW_NODES");
const useDarkTheme = createAction("USE_DARK_THEME");
const colorBy = createAction("COLOR_BY");
const showBusy = createAction("SHOW_BUSY");
const setPosition = createAction("POSITION");
const setSelectedDatum = createAction("SETSELECTEDDATUM");

// REDUCERS

const reducer = handleActions(
{
[setControls]: (state, { payload }) =>{
[setControls]: (state, { payload }) => {
const hierarchyConfig = payload.hierarchyConfig || state.hierarchyConfig;
const shouldShowNodes = ('shouldShowNodes' in payload) ? !!payload.shouldShowNodes : state.shouldShowNodes;
const darkTheme = ('darkTheme' in payload) ? !!payload.darkTheme : state.darkTheme;
const colorBy = payload.colorBy || state.colorBy;
const start = payload.start || state.start;
const end = payload.end || state.end;
const showBusy = ('showBusy' in payload) ? !!payload.showBusy : state.showBusy;
const position = payload.position || state.position;
return {
...state,
hierarchyConfig: hierarchyConfig,
Expand All @@ -40,6 +47,7 @@ const reducer = handleActions(
start: start,
end: end,
showBusy: showBusy,
position: position
}
},
[setStartDataset]: (state, { payload }) => ({ ...state, start: payload }),
Expand All @@ -49,11 +57,16 @@ const reducer = handleActions(
[useDarkTheme]: (state, { payload }) => ({ ...state, darkTheme: !!payload }), // Convert payload to boolean for easier debugging
[colorBy]: (state, { payload }) => ({ ...state, colorBy: payload }),
[showBusy]: (state, { payload }) => ({ ...state, showBusy: !!payload }),
[setPosition]: (state, { payload }) => ({ ...state, position: payload }),
[setSelectedDatum]: (state, { payload }) => ({ ...state, selectedDatum: payload }),
},
defaultState
);

// SELECTORS
const selectControls = (state) => state.controls;
const getPosition = (state) => state.controls.position;
const getSelectedDatum = (state) => state.controls.selectedDatum;

export default reducer;
export { setControls, setHierarchyConfig, showNodes, colorBy, useDarkTheme, selectControls, setStartDataset, setEndDataset, showBusy };
export { setControls, setHierarchyConfig, showNodes, colorBy, useDarkTheme, selectControls, setStartDataset, setEndDataset, showBusy, setPosition, getPosition, setSelectedDatum, getSelectedDatum };
12 changes: 3 additions & 9 deletions src/domain/controls.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ describe("Controls reducer", () => {
'start': 't0',
'end': 'tn',
'showBusy': true,
'position': [0,0],
'datum': null
}

const action = setControls(controls);
Expand Down Expand Up @@ -62,15 +64,7 @@ describe("Controls reducer", () => {
const action = setHierarchyConfig(hierarchyConfig);
const result = reducer({}, action);

expect(selectControls(result)).to.deep.equal({
hierarchyConfig: hierarchyConfig,
shouldShowNodes: true,
darkTheme: false,
colorBy: null,
'start': null,
'end': null,
'showBusy': false,
});
expect(selectControls(result).hierarchyConfig).to.deep.equal(hierarchyConfig);

done();
});
Expand Down
58 changes: 58 additions & 0 deletions src/domain/notes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { createAction, handleActions } from "redux-actions";
hopetambala marked this conversation as resolved.
Show resolved Hide resolved

const defaultState = {
byId:[],
byHash: {
}
};

// ACTIONS
const addNote = createAction("ADD_NOTE");
const setNotes = createAction("SET_NOTE");
const removeNote = createAction("REMOVE_NOTE");

// REDUCERS
const reducer = handleActions(
{
[addNote]: (state, { payload }) => {
return {
byId: [ ...state.byId, payload.id],
byHash: {
...state.byHash,
[payload.id]: payload
}
}
},
[removeNote]: (state, { payload }) => {
const prunedIds = state.byId.filter(item => {
return item !== payload.id
})
delete state.byHash[payload.id]

return {
byId: prunedIds,
byHash: state.byHash
}
},

[setNotes]: (state, { payload }) => {
const byid = payload.byId || state.byId;
const byhash = payload.byHash || state.byHash;
return {
...state,
byId: byid,
byHash: byhash,
}
},
},
defaultState
);

// SELECTORS
const getNotesIndexedByHash = (state) => state.notes.byHash;
const getAllNotes = (state) => state.notes;


export default reducer;

export { addNote,setNotes,removeNote, getNotesIndexedByHash, getAllNotes};
94 changes: 94 additions & 0 deletions src/domain/notes.test.js.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import {
default as notes,
addNote,
setNotes,
removeNote,
getAllNotes,
} from "./notes";
import { combineReducers } from "redux";
import { expect } from "chai"

const reducer = combineReducers({ notes });

describe("Notes reducer", () => {

describe("add and remove notes", () => {
it("add a note", (done) => {
const note = {
id :'TestId',
note:{
title: "I'm the Title of a Notes",
labels: ['label a', 'label b', 'label c'],
content:" I'm the Content of a note"
}
};

const action = addNote(note);
const result = reducer({}, action);

const defaultState = {
byId:[`TestId`],
byHash: {
'TestId': {
id: "TestId",
note:{
title: "I'm the Title of a Notes",
labels: ['label a', 'label b', 'label c'],
content:" I'm the Content of a note"
}
}
}
};

expect(getAllNotes(result)).to.deep.equal(defaultState);

done();
});

it("remove a note", (done) => {
const note = {
id :'TestId',
note:{
title: "I'm the Title of a Notes",
labels: ['label a', 'label b', 'label c'],
content:" I'm the Content of a note"
}
};

const emptyState = {
byId:[],
byHash: {
}
};

const add_action = addNote(note);

const remove_action = removeNote(note.id);

reducer({}, add_action);
var result = reducer({}, remove_action);

expect(getAllNotes(result)).to.deep.equal(emptyState);

done();
});
});

describe("setNotes", () => {
it("sets the Control tree", (done) => {
const notes = {
'byId':[],
'byHash': {
}
}

const action = setNotes(notes);
const result = reducer({}, action);

expect(getAllNotes(result)).to.deep.equal(notes);

done();
});
});

});
4 changes: 3 additions & 1 deletion src/domain/root-reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import dataset from "./dataset";
import controls from "./controls";
import error from "./error";
import filter from "./filter";
import notes from "./notes";

export default combineReducers({
dataset,
search,
controls,
error,
filter
filter,
notes
});
Loading