Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Fractalis
fractal.js
Commits
5fa0cdd3
Commit
5fa0cdd3
authored
Feb 12, 2018
by
Sascha Herzinger
Browse files
lots of new tests and code cleanup
parent
4aa65d75
Pipeline
#3359
passed with stages
in 3 minutes and 39 seconds
Changes
18
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/main.js
View file @
5fa0cdd3
import
{
version
}
from
'
../package.json
'
import
{
version
}
from
'
../package.json
'
import
store
from
'
./store/store
'
import
RequestManager
from
'
./services/request-manager
'
import
ChartManager
from
'
./services/chart-manager
'
...
...
src/store/actions.js
View file @
5fa0cdd3
...
...
@@ -104,12 +104,12 @@ export default {
context
.
commit
(
types
.
UNSET_TASK
,
taskID
)
},
/**
* Commits
a control panel vm for keeping track of all such instances
.
* @param context The context of the action.
* @param
vm The vm of the
control panel.
* Commits
panel states to control them on a global level
.
* @param context
:
The context of the action.
* @param
options: An object that contains options for a
control panel.
*/
add
ControlPanel
:
(
context
,
vm
)
=>
{
context
.
commit
(
types
.
ADD
_CONTROL_PANEL
,
vm
)
set
ControlPanel
:
(
context
,
options
)
=>
{
context
.
commit
(
types
.
SET
_CONTROL_PANEL
,
options
)
},
/**
* Commits an option object if it is defined that all components can access for configuration.
...
...
src/store/getters.js
View file @
5fa0cdd3
...
...
@@ -5,7 +5,7 @@ export default {
requestManager
:
state
=>
state
.
requestManager
,
chartManager
:
state
=>
state
.
chartManager
,
stateManager
:
state
=>
state
.
stateManager
,
controlPanel
s
:
state
=>
state
.
controlPanel
s
,
controlPanel
:
state
=>
state
.
controlPanel
,
filter
:
state
=>
name
=>
state
.
filters
[
name
],
options
:
state
=>
state
.
options
}
src/store/mutation-types.js
View file @
5fa0cdd3
...
...
@@ -7,6 +7,6 @@ export default {
SET_FILTER
:
'
SET_FILTER
'
,
SET_TASK
:
'
SET_TASK
'
,
UNSET_TASK
:
'
UNSET_TASK
'
,
ADD
_CONTROL_PANEL
:
'
ADD
_CONTROL_PANEL
'
,
SET
_CONTROL_PANEL
:
'
SET
_CONTROL_PANEL
'
,
SET_OPTIONS
:
'
SET_OPTIONS
'
}
src/store/mutations.js
View file @
5fa0cdd3
...
...
@@ -34,8 +34,8 @@ export default {
[
types
.
UNSET_TASK
]
(
state
,
taskID
)
{
Vue
.
delete
(
state
.
tasks
,
taskID
)
},
[
types
.
ADD
_CONTROL_PANEL
]
(
state
,
vm
)
{
state
.
controlPanel
s
.
push
(
vm
)
[
types
.
SET
_CONTROL_PANEL
]
(
state
,
options
)
{
Object
.
assign
(
state
.
controlPanel
,
options
)
},
[
types
.
SET_OPTIONS
]
(
state
,
options
)
{
Object
.
assign
(
state
.
options
,
options
)
...
...
src/store/store.js
View file @
5fa0cdd3
...
...
@@ -12,7 +12,10 @@ const state = {
requestManager
:
null
,
chartManager
:
null
,
stateManager
:
null
,
controlPanels
:
[],
controlPanel
:
{
locked
:
false
,
expanded
:
false
},
subsets
:
[],
filters
:
{
ids
:
[]
...
...
@@ -22,9 +25,17 @@ const state = {
}
}
export
default
new
Vuex
.
Store
({
const
store
=
new
Vuex
.
Store
({
state
,
getters
,
actions
,
mutations
})
const
initialState
=
JSON
.
parse
(
JSON
.
stringify
(
store
.
state
))
export
function
resetState
()
{
store
.
replaceState
(
JSON
.
parse
(
JSON
.
stringify
(
initialState
)))
}
export
default
store
src/vue/charts/Boxplot.vue
View file @
5fa0cdd3
<
template
>
<chart
v-on:resize=
"resize"
>
<control-panel
class=
"fjs-control-panel"
>
<control-panel
class=
"fjs-control-panel"
name=
"Boxplot Panel"
>
<data-box
class=
"fjs-data-box"
header=
"Numerical Variables"
dataType=
"numerical"
...
...
src/vue/charts/CorrelationAnalysis.vue
View file @
5fa0cdd3
<
template
>
<chart
v-on:resize=
"resize"
>
<control-panel
class=
"fjs-control-panel"
>
<control-panel
class=
"fjs-control-panel"
name=
"Correlation Analysis"
>
<data-box
class=
"fjs-data-box"
header=
"Numerical Variables"
dataType=
"numerical,numerical_array"
...
...
src/vue/charts/Heatmap.vue
View file @
5fa0cdd3
<
template
>
<chart
v-on:resize=
"resize"
>
<control-panel
class=
"fjs-control-panel"
>
<control-panel
class=
"fjs-control-panel"
name=
"Heatmap Panel"
>
<data-box
class=
"fjs-data-box"
header=
"Numerical Variables"
dataType=
"numerical_array"
...
...
src/vue/charts/PCA.vue
View file @
5fa0cdd3
<
template
>
<chart
v-on:resize=
"resize"
>
<control-panel
class=
"fjs-control-panel"
>
<control-panel
class=
"fjs-control-panel"
name=
"PCA Panel"
>
<data-box
class=
"fjs-data-box"
header=
"Numerical Variables"
dataType=
"numerical,numerical_array"
...
...
src/vue/components/ControlPanel.vue
View file @
5fa0cdd3
<
template
>
<div
class=
"fjs-control-panel"
:style=
"
{width:
shown ? '15vw' : '1vw'
, left: left, right: right}"
:style=
"
{width:
width
, left: left, right: right}"
v-show="focused"
@mouseover="locked ? noop() : show()"
@mouseout="locked ? noop() : hide()">
@mouseover="show()"
@mouseout="hide()">
<span
class=
"fjs-panel-label"
v-show=
"!expanded"
>
Control Panel
</span>
<div
class=
"fjs-panel-header"
>
<span
v-show=
"
shown"
>
{{
chartN
ame
}}
</span>
<span
v-show=
"
expanded"
>
{{
n
ame
}}
</span>
<i
class=
"fjs-lock-btn material-icons"
@
click=
"toggleLock"
>
{{
lockIcon
}}
</i>
</div>
<span
class=
"fjs-panel-label"
v-show=
"!shown"
>
Control Panel
</span>
<div
v-show=
"shown"
>
<div
v-show=
"expanded"
>
<slot/>
<hr
class=
"fjs-seperator"
/>
<task-view/>
...
...
@@ -22,75 +22,68 @@
import
store
from
'
../../store/store
'
export
default
{
name
:
'
control-panel
'
,
props
:
{},
data
()
{
return
{
focused
:
true
,
locked
:
false
,
expanded
:
false
,
shown
:
true
focused
:
true
}
},
props
:
{
name
:
{
type
:
String
,
required
:
true
}
},
computed
:
{
locked
()
{
return
store
.
getters
.
controlPanel
.
locked
},
expanded
()
{
return
store
.
getters
.
controlPanel
.
expanded
},
lockIcon
()
{
return
this
.
locked
?
'
lock
'
:
'
lock_open
'
},
chartName
()
{
return
this
.
$parent
.
$parent
.
$options
.
name
},
left
()
{
return
store
.
getters
.
options
.
controlPanelPosition
===
'
left
'
?
0
:
''
},
right
()
{
return
store
.
getters
.
options
.
controlPanelPosition
===
'
right
'
?
0
:
''
},
width
()
{
return
this
.
expanded
?
'
15vw
'
:
'
1vw
'
}
},
methods
:
{
noop
()
{},
toggleLock
()
{
this
.
locked
=
!
this
.
locked
this
.
propagateState
()
store
.
dispatch
(
'
setControlPanel
'
,
{
locked
:
!
store
.
getters
.
controlPanel
.
locked
})
},
show
()
{
this
.
expanded
=
true
this
.
propagateState
(
)
this
.
shown
=
true
if
(
!
this
.
locked
)
{
store
.
dispatch
(
'
setControlPanel
'
,
{
expanded
:
true
}
)
}
},
hide
()
{
this
.
expanded
=
false
this
.
propagateState
(
)
this
.
shown
=
false
if
(
!
this
.
locked
)
{
store
.
dispatch
(
'
setControlPanel
'
,
{
expanded
:
false
}
)
}
},
focus
()
{
this
.
unfocusAll
()
this
.
focused
=
true
this
.
$nextTick
(()
=>
{
this
.
expanded
?
this
.
show
(
false
)
:
this
.
hide
(
false
)
this
.
expanded
?
this
.
show
()
:
this
.
hide
()
})
},
unFocus
()
{
this
.
focused
=
false
},
unfocusAll
()
{
store
.
getters
.
controlPanels
.
forEach
(
panel
=>
{
panel
.
unFocus
()
})
},
propagateState
()
{
store
.
getters
.
controlPanels
.
forEach
(
panel
=>
{
panel
.
locked
=
this
.
locked
panel
.
expanded
=
this
.
expanded
Array
.
prototype
.
forEach
.
call
(
document
.
querySelectorAll
(
'
.fjs-control-panel
'
),
panel
=>
{
panel
.
__vue__
.
unFocus
()
})
}
},
mounted
()
{
window
.
addEventListener
(
'
resize
'
,
()
=>
{
this
.
expanded
?
this
.
show
(
false
)
:
this
.
hide
(
false
)
})
this
.
hide
()
},
created
()
{
store
.
dispatch
(
'
addControlPanel
'
,
this
)
this
.
unfocusAll
()
this
.
focused
=
true
},
...
...
src/vue/components/DataBox.vue
View file @
5fa0cdd3
...
...
@@ -65,7 +65,8 @@
},
computed
:
{
items
()
{
return
store
.
getters
.
data
.
filter
(
item
=>
~
this
.
dataType
.
split
(
'
,
'
).
map
(
s
=>
s
.
trim
()).
indexOf
(
item
.
data_type
))
return
store
.
getters
.
data
.
filter
(
item
=>
~
this
.
dataType
.
split
(
'
,
'
).
map
(
s
=>
s
.
trim
()).
indexOf
(
item
.
data_type
))
},
transformedIDs
()
{
return
this
.
selectedIDs
.
map
(
id
=>
`$
${
JSON
.
stringify
({
id
,
filters
:
{
feature
:
this
.
featureFilter
[
id
]
}})}
$`
)
...
...
src/vue/components/TaskView.vue
View file @
5fa0cdd3
<
template
>
<div
class=
"fjs-task-view"
>
<div
class=
"fjs-state-container"
v-for=
"task in incompleteTasks"
>
<div
class=
"fjs-state-container"
v-for=
"task in tasks"
v-if=
"task.taskState === 'SUBMITTED' || task.taskState === 'FAILED'"
>
<loader
class=
"fjs-loader"
:style=
"
{opacity: task.taskState === 'SUBMITTED' ? 1 : 0}"/>
<span
class=
"fjs-submitted"
v-if=
"task.taskState === 'SUBMITTED'"
>
{{
task
.
taskName
}}
</span>
<span
class=
"fjs-failed"
v-else
>
{{
task
.
taskMessage
}}
</span>
...
...
@@ -17,18 +19,9 @@
components
:
{
Loader
},
data
()
{
return
{
}
},
computed
:
{
tasks
()
{
return
store
.
getters
.
tasks
},
incompleteTasks
()
{
return
Object
.
keys
(
this
.
tasks
)
.
filter
(
key
=>
{
return
this
.
tasks
[
key
].
taskState
!==
'
SUCCESS
'
})
.
map
(
key
=>
this
.
tasks
[
key
])
}
},
methods
:
{
...
...
test/charts/multi/multi-chart.html
View file @
5fa0cdd3
...
...
@@ -88,10 +88,10 @@
}
function
setCharts
()
{
//
fjs.setChart('correlation-analysis', '.container-1')
fjs
.
setChart
(
'
correlation-analysis
'
,
'
.container-1
'
)
fjs
.
setChart
(
'
boxplot
'
,
'
.container-2
'
)
//
fjs.setChart('heatmap', '.container-3')
//
fjs.setChart('pca-analysis', '.container-4')
fjs
.
setChart
(
'
heatmap
'
,
'
.container-3
'
)
fjs
.
setChart
(
'
pca-analysis
'
,
'
.container-4
'
)
}
function
resize
()
{
...
...
test/control-panel-test.js
0 → 100644
View file @
5fa0cdd3
import
ControlPanel
from
'
../src/vue/components/ControlPanel.vue
'
import
Vue
from
'
vue
'
import
store
,
{
resetState
}
from
'
../src/store/store
'
describe
(
'
ControlPanel
'
,
()
=>
{
let
vm
beforeEach
(()
=>
{
resetState
()
const
div1
=
document
.
createElement
(
'
div
'
)
div1
.
id
=
'
div1
'
const
div2
=
document
.
createElement
(
'
div
'
)
div2
.
id
=
'
div2
'
document
.
body
.
appendChild
(
div1
)
document
.
body
.
appendChild
(
div2
)
const
Component
=
Vue
.
extend
(
ControlPanel
)
vm
=
new
Component
({
propsData
:
{
name
:
'
foo
'
}}).
$mount
(
'
#div1
'
)
})
afterEach
(()
=>
{
document
.
body
.
innerHTML
=
''
})
it
(
'
is not locked initially
'
,
()
=>
{
expect
(
vm
.
lockIcon
).
toBe
(
'
lock_open
'
)
expect
(
vm
.
locked
).
toBeFalsy
()
})
it
(
'
is locked if other panel is locked
'
,
()
=>
{
const
Component
=
Vue
.
extend
(
ControlPanel
)
const
_vm
=
new
Component
({
propsData
:
{
name
:
'
foo
'
}}).
$mount
(
'
#div2
'
)
_vm
.
$el
.
querySelector
(
'
.fjs-lock-btn
'
).
click
()
Vue
.
nextTick
(()
=>
{
expect
(
vm
.
lockIcon
).
toBe
(
'
lock
'
)
expect
(
vm
.
locked
).
toBeTruthy
()
})
})
it
(
'
is not expanded initially
'
,
()
=>
{
expect
(
vm
.
expanded
).
toBeFalsy
()
})
it
(
'
is expanded if other panel is expanded
'
,
()
=>
{
const
Component
=
Vue
.
extend
(
ControlPanel
)
const
_vm
=
new
Component
({
propsData
:
{
name
:
'
foo
'
}}).
$mount
(
'
#div2
'
)
expect
(
_vm
.
expanded
).
toBeFalsy
()
expect
(
vm
.
expanded
).
toBeFalsy
()
_vm
.
show
()
Vue
.
nextTick
(()
=>
{
expect
(
_vm
.
expanded
).
toBeTruthy
()
expect
(
vm
.
expanded
).
toBeTruthy
()
})
})
it
(
'
adapts width when expanded state changes
'
,
()
=>
{
expect
(
vm
.
width
).
toBe
(
'
1vw
'
)
store
.
dispatch
(
'
setControlPanel
'
,
{
expanded
:
true
})
Vue
.
nextTick
(()
=>
{
expect
(
vm
.
width
).
toBe
(
'
15vw
'
)
})
})
it
(
'
expands when show() is called and not locked
'
,
()
=>
{
expect
(
vm
.
expanded
).
toBeFalsy
()
expect
(
vm
.
locked
).
toBeFalsy
()
vm
.
show
()
Vue
.
nextTick
(()
=>
{
expect
(
vm
.
expanded
).
toBeTruthy
()
expect
(
vm
.
locked
).
toBeFalsy
()
})
})
it
(
'
does not expand when show() is called and locked
'
,
()
=>
{
expect
(
vm
.
locked
).
toBeFalsy
()
expect
(
vm
.
expanded
).
toBeFalsy
()
vm
.
toggleLock
()
vm
.
show
()
Vue
.
nextTick
(()
=>
{
expect
(
vm
.
locked
).
toBeTruthy
()
expect
(
vm
.
expanded
).
toBeFalsy
()
})
})
it
(
'
collapses when hide() is called and not locked
'
,
()
=>
{
vm
.
show
()
Vue
.
nextTick
(()
=>
{
expect
(
vm
.
expanded
).
toBeTruthy
()
expect
(
vm
.
locked
).
toBeFalsy
()
vm
.
hide
()
Vue
.
nextTick
(()
=>
{
expect
(
vm
.
expanded
).
toBeFalsy
()
})
})
})
it
(
'
does not collapse when hide() is called and locked
'
,
()
=>
{
vm
.
show
()
vm
.
toggleLock
()
Vue
.
nextTick
(()
=>
{
expect
(
vm
.
expanded
).
toBeTruthy
()
expect
(
vm
.
locked
).
toBeTruthy
()
vm
.
hide
()
Vue
.
nextTick
(()
=>
{
expect
(
vm
.
expanded
).
toBeTruthy
()
})
})
})
it
(
'
new panel has auto focus
'
,
()
=>
{
const
Component
=
Vue
.
extend
(
ControlPanel
)
const
_vm
=
new
Component
({
propsData
:
{
name
:
'
foo
'
}}).
$mount
(
'
#div2
'
)
expect
(
vm
.
focused
).
toBeFalsy
()
expect
(
_vm
.
focused
).
toBeTruthy
()
})
})
test/data-box-test.js
View file @
5fa0cdd3
import
Vue
from
'
vue
'
import
DataBox
from
'
../src/vue/components/DataBox.vue
'
import
store
from
'
../src/store/store
'
import
store
,
{
resetState
}
from
'
../src/store/store
'
describe
(
'
DataBox
'
,
()
=>
{
afterEach
(()
=>
{
store
.
state
.
data
=
[]
resetState
()
})
it
(
'
has correct name
'
,
()
=>
{
...
...
test/state-manager-test.js
View file @
5fa0cdd3
...
...
@@ -3,22 +3,20 @@ import RequestManager from '../src/services/request-manager'
import
ChartManager
from
'
../src/services/chart-manager
'
import
Vue
from
'
vue
'
import
stateSaver
from
'
../src/vue/mixins/state-saver
'
import
store
from
'
../src/store/store
'
import
store
,
{
resetState
}
from
'
../src/store/store
'
import
Chart
from
'
../src/vue/components/Chart.vue
'
describe
(
'
state manager
'
,
()
=>
{
let
stateManager
beforeAll
(()
=>
{
let
vm
beforeEach
(()
=>
{
resetState
()
stateManager
=
new
StateManager
()
const
chartManager
=
new
ChartManager
()
const
requestManager
=
new
RequestManager
(
{
handler
:
''
,
dataSource
:
''
,
fractalisNode
:
''
,
getAuth
:
()
=>
{}})
store
.
dispatch
(
'
setRequestManager
'
,
requestManager
)
store
.
dispatch
(
'
setChartManager
'
,
chartManager
)
})
let
vm
beforeEach
(()
=>
{
const
container
=
document
.
createElement
(
'
div
'
)
const
el
=
document
.
createElement
(
'
div
'
)
el
.
id
=
'
chart
'
...
...
test/task-view-test.js
0 → 100644
View file @
5fa0cdd3
import
TaskView
from
'
../src/vue/components/TaskView.vue
'
import
store
,
{
resetState
}
from
'
../src/store/store
'
import
Vue
from
'
vue
'
import
RequestManager
from
'
../src/services/request-manager
'
describe
(
'
TaskView
'
,
()
=>
{
let
vm
beforeEach
(()
=>
{
resetState
()
const
requestManager
=
new
RequestManager
(
{
handler
:
''
,
dataSource
:
''
,
fractalisNode
:
''
,
getAuth
:
()
=>
{}})
store
.
dispatch
(
'
setRequestManager
'
,
requestManager
)
const
Component
=
Vue
.
extend
(
TaskView
)
vm
=
new
Component
().
$mount
()
})
it
(
'
shows all SUBMITTED or FAILED tasks in store
'
,
()
=>
{
store
.
dispatch
(
'
setTask
'
,
{
taskID
:
1
,
taskName
:
'
A
'
,
taskState
:
'
SUBMITTED
'
})
store
.
dispatch
(
'
setTask
'
,
{
taskID
:
2
,
taskName
:
'
B
'
,
taskState
:
'
SUCCESS
'
})
store
.
dispatch
(
'
setTask
'
,
{
taskID
:
3
,
taskName
:
'
C
'
,
taskState
:
'
SUBMITTED
'
})
store
.
dispatch
(
'
setTask
'
,
{
taskID
:
4
,
taskName
:
'
D
'
,
taskState
:
'
FAILED
'
})
store
.
dispatch
(
'
setTask
'
,
{
taskID
:
5
,
taskName
:
'
E
'
,
taskState
:
'
YAY
'
})
store
.
dispatch
(
'
setTask
'
,
{
taskID
:
6
,
taskName
:
'
F
'
,
taskState
:
'
PENDING
'
})
Vue
.
nextTick
(()
=>
{
expect
(
Object
.
keys
(
store
.
getters
.
tasks
).
length
).
toBe
(
6
)
expect
(
Object
.
keys
(
vm
.
incompleteTasks
).
length
).
toBe
(
2
)
expect
(
vm
.
$el
.
querySelectorAll
(
'
.fjs-state-container
'
).
length
).
toBe
(
3
)
expect
(
vm
.
$el
.
querySelectorAll
(
'
.fjs-submitted
'
).
length
).
toBe
(
2
)
expect
(
vm
.
$el
.
querySelectorAll
(
'
.fjs-failed
'
).
length
).
toBe
(
1
)
})
})
it
(
'
cancel button works
'
,
()
=>
{
store
.
dispatch
(
'
setTask
'
,
{
taskID
:
1
,
taskName
:
'
A
'
,
taskState
:
'
SUBMITTED
'
})
store
.
dispatch
(
'
setTask
'
,
{
taskID
:
2
,
taskName
:
'
B
'
,
taskState
:
'
FAILED
'
})
Vue
.
nextTick
(()
=>
{
expect
(
Object
.
keys
(
store
.
getters
.
tasks
).
length
).
toBe
(
2
)
expect
(
vm
.
$el
.
querySelectorAll
(
'
.fjs-state-container
'
).
length
).
toBe
(
2
)
vm
.
$el
.
querySelectorAll
(
'
.fjs-cancel-btn
'
).
forEach
(
button
=>
button
.
click
())
Vue
.
nextTick
(()
=>
{
expect
(
Object
.
keys
(
store
.
getters
.
tasks
).
length
).
toBe
(
0
)
expect
(
vm
.
$el
.
querySelectorAll
(
'
.fjs-state-container
'
).
length
).
toBe
(
0
)
})
})
})
})
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment