Commit f9125b8a authored by Sascha Herzinger's avatar Sascha Herzinger
Browse files

Added control panel and moved controls there for every visualisation.

Also made sizes more dynamic
parent b8600249
This diff is collapsed.
<template>
<div :class="`fjs-boxplot fjs-vm-uid-${this._uid}`">
<div class="fjs-data-box-container">
<control-panel class="fjs-control-panel">
<data-box class="fjs-data-box"
header="Numerical Variables"
dataType="numerical"
......@@ -11,16 +12,18 @@
dataType="categorical"
v-on:update="update_catData">
</data-box>
</div>
<hr class="fjs-seperator"/>
<div class="fjs-parameter-container">
<label for="fjs-show-data-check">Show Points</label>
<input id="fjs-show-data-check" type="checkbox" v-model="params.showData"/>
<label for="fjs-jitter-data-check">Jitter Data</label>
<label for="fjs-show-data-check">Show Points</label>
<br/>
<input id="fjs-jitter-data-check" type="checkbox" v-model="params.jitter"/>
<label for="fjs-show-kde-check">Show Density Est.</label>
<label for="fjs-jitter-data-check">Jitter Data</label>
<br/>
<input id="fjs-show-kde-check" type="checkbox" v-model="params.showKDE"/>
<label for="fjs-show-kde-check">Show Density Est.</label>
</div>
</control-panel>
<div class="fjs-vis-container">
<svg :width="width"
......@@ -99,7 +102,7 @@
v-tooltip="{arrow: true, theme: 'light'}"
:cx="point.jitter"
:cy="scales.y(point.value)"
r="4"
r="0.4%"
v-for="point in points[label]"
v-if="params.showData">
</circle>
......@@ -125,6 +128,7 @@
import deepFreeze from 'deep-freeze-strict'
import { truncateTextUntil } from '../mixins/utils'
import tooltip from '../directives/tooltip'
import ControlPanel from '../components/ControlPanel.vue'
export default {
name: 'boxplot',
data () {
......@@ -272,7 +276,7 @@
axis () {
const x = d3.axisBottom(this.scales.x).tickFormat(d => {
// noinspection JSSuspiciousNameCombination
return truncateTextUntil({text: d, font: `14px Roboto`, maxWidth: this.margin.bottom})
return truncateTextUntil({text: d, font: `0.875rem Roboto`, maxWidth: this.margin.bottom})
})
const y = d3.axisLeft(this.scales.y)
return { x, y }
......@@ -296,7 +300,7 @@
}
},
'args': {
handler: function (newArgs, oldArgs) {
handler: function () {
if (this.validArgs) {
this.runAnalysisWrapper(this.args)
}
......@@ -360,6 +364,7 @@
}
},
components: {
ControlPanel,
DataBox,
TaskView
},
......@@ -387,12 +392,10 @@
width: 100%
display: flex
flex-direction: column
.fjs-data-box-container
height: 160px
display: flex
justify-content: space-around
.fjs-control-panel
hr
width: 100%
margin: 10% 0 10% 0
.fjs-vis-container
flex: 1
display: flex
......@@ -406,7 +409,7 @@
.fjs-lower-whisker, .fjs-upper-whisker, .fjs-antenna
shape-rendering: crispEdges
stroke: black
stroke-width: 2px
stroke-width: 1px
.fjs-below-median-box
stroke: none
fill: rgb(205, 232, 254)
......@@ -423,7 +426,7 @@
.fjs-kde
fill: none
stroke: black
stroke-width: 2px
stroke-width: 0.2%
</style>
......@@ -431,16 +434,15 @@
<style lang="sass">
.fjs-boxplot-axis
shape-rendering: crispEdges
stroke-width: 2px
.tick
shape-rendering: crispEdges
text
font-size: 18px
font-size: 1rem
line
stroke: #999
.fjs-x-axis
.tick
text
text-anchor: start
font-size: 14px
font-size: 1rem
</style>
<template>
<div :class="`fjs-correlation-analysis fjs-vm-uid-${this._uid}`">
<div class="fjs-data-box-container">
<control-panel class="fjs-control-panel">
<data-box class="fjs-data-box"
header="X and Y variables"
dataType="numerical"
......@@ -11,20 +12,19 @@
dataType="categorical"
v-on:update="update_categoryData">
</data-box>
</div>
<div class="fjs-parameter-container">
<span>{{ error }}</span>
<hr class="fjs-seperator"/>
<fieldset class="fjs-correlation-method">
<legend>Correlation Method</legend>
<input type="radio" id="fjs-param-method-1" value="pearson" v-model="params.method">
<label for="fjs-param-method-1">Pearson</label>
<br/>
<input type="radio" id="fjs-param-method-2" value="spearman" v-model="params.method">
<label for="fjs-param-method-2">Spearman</label>
<br/>
<input type="radio" id="fjs-param-method-3" value="kendall" v-model="params.method">
<label for="fjs-param-method-3">Kendall</label>
</fieldset>
</div>
</control-panel>
<div class="fjs-vis-container">
<svg :height="height" :width="width">
......@@ -36,21 +36,19 @@
<g class="fjs-brush"></g>
<text :x="padded.width / 2"
y="-10"
text-anchor="middle"
font-size="16">
text-anchor="middle">
{{ shownResults.x_label }}
</text>
<text :x="padded.width + 10"
:y="padded.height / 2"
text-anchor="middle"
font-size="16"
:transform="`rotate(90 ${padded.width + 10} ${padded.height / 2})`">
{{ shownResults.y_label }}
</text>
<circle class="fjs-scatterplot-point"
:cx="scales.x(point.x)"
:cy="scales.y(point.y)"
r="4"
r="0.4%"
:fill="categoryColors[categories.indexOf(point.category) % categoryColors.length]"
:stroke="subsetColors[point.subset]"
:title="point.tooltip"
......@@ -74,11 +72,11 @@
<caption>Selected points</caption>
<tr>
<td>Coefficient</td>
<td>{{ tmpResults.coef }}</td>
<td>{{ parseFloat(tmpResults.coef).toFixed(4) }}</td>
</tr>
<tr>
<td>p-value</td>
<td>{{ tmpResults.p_value }}</td>
<td>{{ parseFloat(tmpResults.p_value).toFixed(4) }}</td>
</tr>
<tr>
<td>Method</td>
......@@ -94,11 +92,11 @@
<caption>Subset: {{ i + 1 }}</caption>
<tr>
<td>Coefficient</td>
<td>{{ stats.coef }}</td>
<td>{{ parseFloat(stats.coef).toFixed(4) }}</td>
</tr>
<tr>
<td>p-value</td>
<td>{{ stats.p_value }}</td>
<td>{{ parseFloat(stats.p_value).toFixed(4) }}</td>
</tr>
<tr>
<td>Method</td>
......@@ -111,7 +109,6 @@
</table>
</div>
</div>
<task-view></task-view>
</div>
</template>
......@@ -122,8 +119,8 @@
import * as d3 from 'd3'
import { TweenLite } from 'gsap'
import tooltip from '../directives/tooltip.js'
import TaskView from '../components/TaskView.vue'
import deepFreeze from 'deep-freeze-strict'
import ControlPanel from '../components/ControlPanel.vue'
export default {
name: 'correlation-analysis',
data () {
......@@ -144,7 +141,7 @@
p_value: 0,
slope: 0,
intercept: 0,
method: '',
method: 'pearson',
x_label: '',
y_label: '',
data: []
......@@ -154,7 +151,7 @@
p_value: 0,
slope: 0,
intercept: 0,
method: '',
method: 'pearson',
x_label: '',
y_label: '',
data: []
......@@ -455,8 +452,8 @@
window.removeEventListener('resize', this.handleResize)
},
components: {
DataBox,
TaskView
ControlPanel,
DataBox
},
directives: {
tooltip
......@@ -507,30 +504,25 @@
width: 100%
display: flex
flex-direction: column
.fjs-data-box-container
height: 160px
display: flex
justify-content: space-around
.fjs-parameter-container
text-align: center
.fjs-control-panel
hr
width: 100%
margin: 10% 0 10% 0
.fjs-correlation-method
width: 0
white-space: nowrap
border: solid 1px #bbb
border: solid 1px #fff
text-align: left
border-radius: 8px
margin: 10px
margin: 1%
.fjs-vis-container
flex: 1
display: flex
svg
flex: 1
flex: 4
.fjs-lin-reg-line
stroke: #ff5e00
stroke-width: 4px
stroke-width: 0.4%
.fjs-lin-reg-line:hover
opacity: 0.4
.fjs-histogram-polyline
......@@ -545,24 +537,24 @@
.fjs-brush
stroke-width: 0
.fjs-table-container
width: 200px
flex: 1
display: flex
flex-direction: column
.fjs-stats-table
margin: 5px
width: 100%
margin: 1%
border-spacing: 0
border-collapse: collapse
font-size: 14px
font-size: 0.875rem
tr:nth-child(even)
background-color: #ddd
td, th
max-width: 100px
overflow: hidden
text-overflow: ellipsis
white-space: nowrap
border: 1px #ccc solid
border-collapse: collapse
padding: 5px
padding: 2%
</style>
<!--CSS for dynamically created components-->
......@@ -574,5 +566,5 @@
line
stroke: #999
text
font-size: 10px
font-size: 0.875rem
</style>
<template>
<div :class="`fjs-heatmap fjs-vm-uid-${this._uid}`">
<div class="fjs-data-box-container">
<control-panel>
<data-box class="fjs-data-box"
header="Numerical Array Data"
dataType="numerical_array"
v-on:update="update_numericArrayData">
</data-box>
</div>
<div class="fjs-parameter-container">
</div>
</control-panel>
<div class="fjs-vis-container">
<svg height="100%" width="100%">
......@@ -62,6 +59,7 @@
import TaskView from '../components/TaskView.vue'
import deepFreeze from 'deep-freeze-strict'
import { truncateTextUntil } from '../mixins/utils'
import ControlPanel from '../components/ControlPanel.vue'
export default {
name: 'heatmap',
data () {
......@@ -154,7 +152,7 @@
sigBars () {
return this.results.stats.map(d => {
return {
x: - this.sigScales.x(d[this.selectedSigMes]),
x: -this.sigScales.x(d[this.selectedSigMes]),
y: this.sigScales.y(d.variable),
width: this.sigScales.x(d[this.selectedSigMes]),
height: this.gridBox.height,
......@@ -210,7 +208,7 @@
},
watch: {
'args': {
handler: function (newArgs, oldArgs) {
handler: function () {
if (this.validArgs) {
this.runAnalysisWrapper(this.args)
}
......@@ -225,6 +223,7 @@
window.removeEventListener('resize', this.handleResize)
},
components: {
ControlPanel,
DataBox,
TaskView
},
......@@ -246,11 +245,6 @@
display: flex
flex-direction: column
.fjs-data-box-container
height: 160px
display: flex
justify-content: space-around
.fjs-parameter-container
text-align: center
......
<template>
<div :class="`fjs-control-panel fjs-vm-uid-${this._uid}`">
<span class="fjs-lock-btn" v-html="lockIcon" @click="toggleLock"></span>
<slot></slot>
<task-view></task-view>
<div class="fjs-balancer"></div>
</div>
</template>
<script>
import TaskView from './TaskView.vue'
export default {
name: 'control-panel',
data () {
return {
locked: false
}
},
computed: {
lockIcon () {
return this.locked ? '&#128274;' : '&#128275;'
}
},
methods: {
toggleLock () {
this.locked = !this.locked
console.log(this.locked)
}
},
components: {
TaskView
}
}
</script>
<style lang="sass" scoped>
.fjs-control-panel
background: rgba(0, 0, 0, 0.8)
color: white
position: fixed
display: flex
flex-direction: column
justify-content: center
right: 0
top: 0
padding: 1%
height: 100%
width: 15%
.fjs-lock-btn
margin-bottom: auto
cursor: pointer
.fjs-balancer
margin-top: auto
</style>
......@@ -2,20 +2,15 @@
<div :class="`fjs-data-box fjs-vm-uid-${_uid}`">
<label :for="`fjs-data-window-${_uid}`" :tooltip="tooltip">{{ header }}</label>
<div :id="`fjs-data-window-${_uid}`" class="fjs-data-window">
<div class="fjs-data-entry-container"
:data-state="item.etl_state"
v-for="item in items">
<div class="fjs-data-entry-container" :data-state="item.etl_state" v-for="item in items">
<div class="fjs-data-entry-header"
:class="{'fjs-selected': !!~selectedIDs.indexOf(item.task_id)}"
:data-state="item.etl_state">
<span class="fjs-cross" v-if="item.etl_state === 'FAILURE'">&#xd7;</span>
<input :id="`fjs-checkbox-${item.task_id}-${_uid}`"
type="checkbox"
:value="item.task_id"
v-model="selectedIDs"
v-if="item.etl_state === 'SUCCESS'"/>
<label :for="`fjs-checkbox-${item.task_id}-${_uid}`">{{ item.label }}</label>
<span :data-id="item.task_id" @click="toggleTaskId(item.task_id)">{{ item.label }}</span>
<span class="fjs-options" @click="toggleDataEntryBody(item.task_id)">&#9776;</span>
</div>
<div class="fjs-data-entry-body" :data-state="item.etl_state" :data-id="item.task_id">
<div class="fjs-action-btns">
<button class="fjs-reload-btn" @click="reloadData(item.task_id)">&#8635;</button>
......@@ -23,6 +18,7 @@
</div>
{{ item.etl_message }}
</div>
</div>
</div>
</div>
......@@ -78,6 +74,14 @@
}
},
methods: {
toggleTaskId (taskID) {
const idx = this.selectedIDs.indexOf(taskID)
if (~idx) {
this.selectedIDs.splice(idx, 1)
} else {
this.selectedIDs.push(taskID)
}
},
toggleDataEntryBody (taskID) {
const $body = $(`.fjs-vm-uid-${this._uid} .fjs-data-entry-body[data-id="${taskID}"]`)
$body.slideToggle(500)
......@@ -94,49 +98,41 @@
<style lang="sass" scoped>
.fjs-data-box
width: 50%
display: flex
justify-content: space-around
flex-direction: column
text-align: center
margin: 10px
width: 100%
text-align: start
margin: 2%
> label
font-size: 16px
font-size: 1rem
.fjs-data-window
flex: 1
border: 1px solid #ccc
border: 1px solid #fff
border-radius: 8px
font-size: 14px
font-size: 0.875rem
overflow-y: scroll
padding: 5px
padding: 1%
.fjs-data-entry-container
display: flex
flex-direction: column
.fjs-data-entry-header
display: flex
background-color: #eee
padding: 5px
margin: 2px
label
flex: 1
&[data-state="FAILURE"]
background-color: #ffcbcb
&[data-state="PENDING"]
color: #bbb
.cross
color: red
padding: 5px
.options
justify-content: space-between
cursor: pointer
white-space: nowrap
padding: 1.5%
margin: 0.5%
.fjs-selected
background-color: #007cfb
.fjs-data-entry-body
display: none
padding: 5px
padding: 1%
&[data-state="FAILURE"]
background-color: #ffcbcb
.fjs-action-btns
text-align: center
button
height: 25px
font-size: 14px
height: 1.5rem
font-size: 0.75rem
font-weight: bold
</style>
......@@ -8,13 +8,8 @@
<body>
<input type="button" onclick="loadData()" value="load data"/>
<input type="button" onclick="deleteData()" value="delete data"/>
<div class="fjs-placeholder-container" style="width: 2000px;">
<div style="width: 1000px;">
<div style="height: 50%; width: 50%">
<div id="placeholder1"></div>
</div>
<div style="width: 1000px;">
<div id="placeholder2"></div>
</div>
</div>
</body>
......@@ -91,12 +86,8 @@
}
fjs.setChart({chart: 'boxplot', selector: '#placeholder1'})
fjs.setChart({chart: 'correlation-analysis', selector: '#placeholder2'})
</script>
<style>
.fjs-placeholder-container {
display: flex;
flex-direction: row;
}
</style>
......@@ -8,12 +8,9 @@
<body>
<input type="button" onclick="loadData()" value="load data"/>