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.
...@@ -24,10 +24,10 @@ ...@@ -24,10 +24,10 @@
"deep-freeze-strict": "^1.1.1", "deep-freeze-strict": "^1.1.1",
"gsap": "^1.20.2", "gsap": "^1.20.2",
"jquery": "^3.2.1", "jquery": "^3.2.1",
"tippy.js": "^1.1.3", "tippy.js": "github:atomiks/tippyjs",
"uuid": "^3.1.0", "uuid": "^3.1.0",
"vue": "^2.4.1", "vue": "^2.4.2",
"vue-template-compiler": "^2.4.1", "vue-template-compiler": "^2.4.2",
"vuex": "^2.3.1" "vuex": "^2.3.1"
}, },
"devDependencies": { "devDependencies": {
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
"eslint-plugin-promise": "^3.5.0", "eslint-plugin-promise": "^3.5.0",
"eslint-plugin-standard": "^2.1.1", "eslint-plugin-standard": "^2.1.1",
"file-loader": "^0.11.1", "file-loader": "^0.11.1",
"jasmine-core": "^2.6.4", "jasmine-core": "^2.7.0",
"jsdoc": "^3.5.3", "jsdoc": "^3.5.3",
"karma": "^1.5.0", "karma": "^1.5.0",
"karma-chrome-launcher": "^2.2.0", "karma-chrome-launcher": "^2.2.0",
...@@ -56,7 +56,7 @@ ...@@ -56,7 +56,7 @@
"url-loader": "^0.5.8", "url-loader": "^0.5.8",
"vue-loader": "^12.2.2", "vue-loader": "^12.2.2",
"webpack": "^2.7.0", "webpack": "^2.7.0",
"webpack-dev-server": "^2.5.1", "webpack-dev-server": "^2.6.1",
"yargs": "^7.0.2" "yargs": "^7.0.2"
} }
} }
<template> <template>
<div :class="`fjs-boxplot fjs-vm-uid-${this._uid}`"> <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" <data-box class="fjs-data-box"
header="Numerical Variables" header="Numerical Variables"
dataType="numerical" dataType="numerical"
...@@ -11,16 +12,18 @@ ...@@ -11,16 +12,18 @@
dataType="categorical" dataType="categorical"
v-on:update="update_catData"> v-on:update="update_catData">
</data-box> </data-box>
</div> <hr class="fjs-seperator"/>
<div class="fjs-parameter-container">
<div class="fjs-parameter-container"> <input id="fjs-show-data-check" type="checkbox" v-model="params.showData"/>
<label for="fjs-show-data-check">Show Points</label> <label for="fjs-show-data-check">Show Points</label>
<input id="fjs-show-data-check" type="checkbox" v-model="params.showData"/> <br/>
<label for="fjs-jitter-data-check">Jitter Data</label> <input id="fjs-jitter-data-check" type="checkbox" v-model="params.jitter"/>
<input id="fjs-jitter-data-check" type="checkbox" v-model="params.jitter"/> <label for="fjs-jitter-data-check">Jitter Data</label>
<label for="fjs-show-kde-check">Show Density Est.</label> <br/>
<input id="fjs-show-kde-check" type="checkbox" v-model="params.showKDE"/> <input id="fjs-show-kde-check" type="checkbox" v-model="params.showKDE"/>
</div> <label for="fjs-show-kde-check">Show Density Est.</label>
</div>
</control-panel>
<div class="fjs-vis-container"> <div class="fjs-vis-container">
<svg :width="width" <svg :width="width"
...@@ -99,7 +102,7 @@ ...@@ -99,7 +102,7 @@
v-tooltip="{arrow: true, theme: 'light'}" v-tooltip="{arrow: true, theme: 'light'}"
:cx="point.jitter" :cx="point.jitter"
:cy="scales.y(point.value)" :cy="scales.y(point.value)"
r="4" r="0.4%"
v-for="point in points[label]" v-for="point in points[label]"
v-if="params.showData"> v-if="params.showData">
</circle> </circle>
...@@ -125,6 +128,7 @@ ...@@ -125,6 +128,7 @@
import deepFreeze from 'deep-freeze-strict' import deepFreeze from 'deep-freeze-strict'
import { truncateTextUntil } from '../mixins/utils' import { truncateTextUntil } from '../mixins/utils'
import tooltip from '../directives/tooltip' import tooltip from '../directives/tooltip'
import ControlPanel from '../components/ControlPanel.vue'
export default { export default {
name: 'boxplot', name: 'boxplot',
data () { data () {
...@@ -272,7 +276,7 @@ ...@@ -272,7 +276,7 @@
axis () { axis () {
const x = d3.axisBottom(this.scales.x).tickFormat(d => { const x = d3.axisBottom(this.scales.x).tickFormat(d => {
// noinspection JSSuspiciousNameCombination // 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) const y = d3.axisLeft(this.scales.y)
return { x, y } return { x, y }
...@@ -296,7 +300,7 @@ ...@@ -296,7 +300,7 @@
} }
}, },
'args': { 'args': {
handler: function (newArgs, oldArgs) { handler: function () {
if (this.validArgs) { if (this.validArgs) {
this.runAnalysisWrapper(this.args) this.runAnalysisWrapper(this.args)
} }
...@@ -360,6 +364,7 @@ ...@@ -360,6 +364,7 @@
} }
}, },
components: { components: {
ControlPanel,
DataBox, DataBox,
TaskView TaskView
}, },
...@@ -387,12 +392,10 @@ ...@@ -387,12 +392,10 @@
width: 100% width: 100%
display: flex display: flex
flex-direction: column flex-direction: column
.fjs-control-panel
.fjs-data-box-container hr
height: 160px width: 100%
display: flex margin: 10% 0 10% 0
justify-content: space-around
.fjs-vis-container .fjs-vis-container
flex: 1 flex: 1
display: flex display: flex
...@@ -406,7 +409,7 @@ ...@@ -406,7 +409,7 @@
.fjs-lower-whisker, .fjs-upper-whisker, .fjs-antenna .fjs-lower-whisker, .fjs-upper-whisker, .fjs-antenna
shape-rendering: crispEdges shape-rendering: crispEdges
stroke: black stroke: black
stroke-width: 2px stroke-width: 1px
.fjs-below-median-box .fjs-below-median-box
stroke: none stroke: none
fill: rgb(205, 232, 254) fill: rgb(205, 232, 254)
...@@ -423,7 +426,7 @@ ...@@ -423,7 +426,7 @@
.fjs-kde .fjs-kde
fill: none fill: none
stroke: black stroke: black
stroke-width: 2px stroke-width: 0.2%
</style> </style>
...@@ -431,16 +434,15 @@ ...@@ -431,16 +434,15 @@
<style lang="sass"> <style lang="sass">
.fjs-boxplot-axis .fjs-boxplot-axis
shape-rendering: crispEdges shape-rendering: crispEdges
stroke-width: 2px
.tick .tick
shape-rendering: crispEdges shape-rendering: crispEdges
text text
font-size: 18px font-size: 1rem
line line
stroke: #999 stroke: #999
.fjs-x-axis .fjs-x-axis
.tick .tick
text text
text-anchor: start text-anchor: start
font-size: 14px font-size: 1rem
</style> </style>
<template> <template>
<div :class="`fjs-correlation-analysis fjs-vm-uid-${this._uid}`"> <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" <data-box class="fjs-data-box"
header="X and Y variables" header="X and Y variables"
dataType="numerical" dataType="numerical"
...@@ -11,20 +12,19 @@ ...@@ -11,20 +12,19 @@
dataType="categorical" dataType="categorical"
v-on:update="update_categoryData"> v-on:update="update_categoryData">
</data-box> </data-box>
</div> <hr class="fjs-seperator"/>
<div class="fjs-parameter-container">
<span>{{ error }}</span>
<fieldset class="fjs-correlation-method"> <fieldset class="fjs-correlation-method">
<legend>Correlation Method</legend> <legend>Correlation Method</legend>
<input type="radio" id="fjs-param-method-1" value="pearson" v-model="params.method"> <input type="radio" id="fjs-param-method-1" value="pearson" v-model="params.method">
<label for="fjs-param-method-1">Pearson</label> <label for="fjs-param-method-1">Pearson</label>
<br/>
<input type="radio" id="fjs-param-method-2" value="spearman" v-model="params.method"> <input type="radio" id="fjs-param-method-2" value="spearman" v-model="params.method">
<label for="fjs-param-method-2">Spearman</label> <label for="fjs-param-method-2">Spearman</label>
<br/>
<input type="radio" id="fjs-param-method-3" value="kendall" v-model="params.method"> <input type="radio" id="fjs-param-method-3" value="kendall" v-model="params.method">
<label for="fjs-param-method-3">Kendall</label> <label for="fjs-param-method-3">Kendall</label>
</fieldset> </fieldset>
</div> </control-panel>
<div class="fjs-vis-container"> <div class="fjs-vis-container">
<svg :height="height" :width="width"> <svg :height="height" :width="width">
...@@ -36,21 +36,19 @@ ...@@ -36,21 +36,19 @@
<g class="fjs-brush"></g> <g class="fjs-brush"></g>
<text :x="padded.width / 2" <text :x="padded.width / 2"
y="-10" y="-10"
text-anchor="middle" text-anchor="middle">
font-size="16">
{{ shownResults.x_label }} {{ shownResults.x_label }}
</text> </text>
<text :x="padded.width + 10" <text :x="padded.width + 10"
:y="padded.height / 2" :y="padded.height / 2"
text-anchor="middle" text-anchor="middle"
font-size="16"
:transform="`rotate(90 ${padded.width + 10} ${padded.height / 2})`"> :transform="`rotate(90 ${padded.width + 10} ${padded.height / 2})`">
{{ shownResults.y_label }} {{ shownResults.y_label }}
</text> </text>
<circle class="fjs-scatterplot-point" <circle class="fjs-scatterplot-point"
:cx="scales.x(point.x)" :cx="scales.x(point.x)"
:cy="scales.y(point.y)" :cy="scales.y(point.y)"
r="4" r="0.4%"
:fill="categoryColors[categories.indexOf(point.category) % categoryColors.length]" :fill="categoryColors[categories.indexOf(point.category) % categoryColors.length]"
:stroke="subsetColors[point.subset]" :stroke="subsetColors[point.subset]"
:title="point.tooltip" :title="point.tooltip"
...@@ -74,11 +72,11 @@ ...@@ -74,11 +72,11 @@
<caption>Selected points</caption> <caption>Selected points</caption>
<tr> <tr>
<td>Coefficient</td> <td>Coefficient</td>
<td>{{ tmpResults.coef }}</td> <td>{{ parseFloat(tmpResults.coef).toFixed(4) }}</td>
</tr> </tr>
<tr> <tr>
<td>p-value</td> <td>p-value</td>
<td>{{ tmpResults.p_value }}</td> <td>{{ parseFloat(tmpResults.p_value).toFixed(4) }}</td>
</tr> </tr>
<tr> <tr>
<td>Method</td> <td>Method</td>
...@@ -94,11 +92,11 @@ ...@@ -94,11 +92,11 @@
<caption>Subset: {{ i + 1 }}</caption> <caption>Subset: {{ i + 1 }}</caption>
<tr> <tr>
<td>Coefficient</td> <td>Coefficient</td>
<td>{{ stats.coef }}</td> <td>{{ parseFloat(stats.coef).toFixed(4) }}</td>
</tr> </tr>
<tr> <tr>
<td>p-value</td> <td>p-value</td>
<td>{{ stats.p_value }}</td> <td>{{ parseFloat(stats.p_value).toFixed(4) }}</td>
</tr> </tr>
<tr> <tr>
<td>Method</td> <td>Method</td>
...@@ -111,7 +109,6 @@ ...@@ -111,7 +109,6 @@
</table> </table>
</div> </div>
</div> </div>
<task-view></task-view>
</div> </div>
</template> </template>
...@@ -122,8 +119,8 @@ ...@@ -122,8 +119,8 @@
import * as d3 from 'd3' import * as d3 from 'd3'
import { TweenLite } from 'gsap' import { TweenLite } from 'gsap'
import tooltip from '../directives/tooltip.js' import tooltip from '../directives/tooltip.js'
import TaskView from '../components/TaskView.vue'
import deepFreeze from 'deep-freeze-strict' import deepFreeze from 'deep-freeze-strict'
import ControlPanel from '../components/ControlPanel.vue'
export default { export default {
name: 'correlation-analysis', name: 'correlation-analysis',
data () { data () {
...@@ -144,7 +141,7 @@ ...@@ -144,7 +141,7 @@
p_value: 0, p_value: 0,
slope: 0, slope: 0,
intercept: 0, intercept: 0,
method: '', method: 'pearson',
x_label: '', x_label: '',
y_label: '', y_label: '',
data: [] data: []
...@@ -154,7 +151,7 @@ ...@@ -154,7 +151,7 @@
p_value: 0, p_value: 0,
slope: 0, slope: 0,
intercept: 0, intercept: 0,
method: '', method: 'pearson',
x_label: '', x_label: '',
y_label: '', y_label: '',
data: [] data: []
...@@ -455,8 +452,8 @@ ...@@ -455,8 +452,8 @@
window.removeEventListener('resize', this.handleResize) window.removeEventListener('resize', this.handleResize)
}, },
components: { components: {
DataBox, ControlPanel,
TaskView DataBox
}, },
directives: { directives: {
tooltip tooltip
...@@ -507,30 +504,25 @@ ...@@ -507,30 +504,25 @@
width: 100% width: 100%
display: flex display: flex
flex-direction: column flex-direction: column
.fjs-control-panel
.fjs-data-box-container hr
height: 160px width: 100%
display: flex margin: 10% 0 10% 0
justify-content: space-around .fjs-correlation-method
white-space: nowrap
.fjs-parameter-container border: solid 1px #fff
text-align: center text-align: left
.fjs-correlation-method border-radius: 8px
width: 0 margin: 1%
white-space: nowrap
border: solid 1px #bbb
text-align: left
border-radius: 8px
margin: 10px
.fjs-vis-container .fjs-vis-container
flex: 1 flex: 1
display: flex display: flex
svg svg
flex: 1 flex: 4
.fjs-lin-reg-line .fjs-lin-reg-line
stroke: #ff5e00 stroke: #ff5e00
stroke-width: 4px stroke-width: 0.4%
.fjs-lin-reg-line:hover .fjs-lin-reg-line:hover
opacity: 0.4 opacity: 0.4
.fjs-histogram-polyline .fjs-histogram-polyline
...@@ -545,24 +537,24 @@ ...@@ -545,24 +537,24 @@
.fjs-brush .fjs-brush
stroke-width: 0 stroke-width: 0
.fjs-table-container .fjs-table-container
width: 200px flex: 1
display: flex display: flex
flex-direction: column flex-direction: column
.fjs-stats-table .fjs-stats-table
margin: 5px width: 100%
margin: 1%
border-spacing: 0 border-spacing: 0
border-collapse: collapse border-collapse: collapse
font-size: 14px font-size: 0.875rem
tr:nth-child(even) tr:nth-child(even)
background-color: #ddd background-color: #ddd
td, th td, th
max-width: 100px
overflow: hidden overflow: hidden
text-overflow: ellipsis text-overflow: ellipsis
white-space: nowrap white-space: nowrap
border: 1px #ccc solid border: 1px #ccc solid
border-collapse: collapse border-collapse: collapse
padding: 5px padding: 2%
</style> </style>
<!--CSS for dynamically created components--> <!--CSS for dynamically created components-->
...@@ -574,5 +566,5 @@ ...@@ -574,5 +566,5 @@
line line
stroke: #999 stroke: #999
text text
font-size: 10px font-size: 0.875rem
</style> </style>
<template> <template>
<div :class="`fjs-heatmap fjs-vm-uid-${this._uid}`"> <div :class="`fjs-heatmap fjs-vm-uid-${this._uid}`">
<div class="fjs-data-box-container"> <control-panel>
<data-box class="fjs-data-box" <data-box class="fjs-data-box"
header="Numerical Array Data" header="Numerical Array Data"
dataType="numerical_array" dataType="numerical_array"
v-on:update="update_numericArrayData"> v-on:update="update_numericArrayData">
</data-box> </data-box>
</div> </control-panel>
<div class="fjs-parameter-container">
</div>
<div class="fjs-vis-container"> <div class="fjs-vis-container">
<svg height="100%" width="100%"> <svg height="100%" width="100%">
...@@ -62,6 +59,7 @@ ...@@ -62,6 +59,7 @@
import TaskView from '../components/TaskView.vue' import TaskView from '../components/TaskView.vue'
import deepFreeze from 'deep-freeze-strict' import deepFreeze from 'deep-freeze-strict'
import { truncateTextUntil } from '../mixins/utils' import { truncateTextUntil } from '../mixins/utils'
import ControlPanel from '../components/ControlPanel.vue'
export default { export default {
name: 'heatmap', name: 'heatmap',
data () { data () {
...@@ -126,7 +124,7 @@ ...@@ -126,7 +124,7 @@
return this.results.stats.map(d => d[this.selectedSigMes]) return this.results.stats.map(d => d[this.selectedSigMes])
}, },
sigScales () { sigScales () {
const x = d3.scaleLinear() const x = d3.scaleLinear()
.domain(d3.extent(this.currentStats)) .domain(d3.extent(this.currentStats))
.range([0, this.margin.left]) .range([0, this.margin.left])
const y = this.scales.y // has the same y scale than the heatmap grid const y = this.scales.y // has the same y scale than the heatmap grid
...@@ -154,7 +152,7 @@ ...@@ -154,7 +152,7 @@
sigBars () { sigBars () {
return this.results.stats.map(d => { return this.results.stats.map(d => {
return { return {
x: - this.sigScales.x(d[this.selectedSigMes]), x: -this.sigScales.x(d[this.selectedSigMes]),
y: this.sigScales.y(d.variable), y: this.sigScales.y(d.variable),
width: this.sigScales.x(d[this.selectedSigMes]), width: this.sigScales.x(d[this.selectedSigMes]),
height: this.gridBox.height, height: this.gridBox.height,
...@@ -210,7 +208,7 @@ ...@@ -210,7 +208,7 @@
}, },
watch: { watch: {
'args': { 'args': {
handler: function (newArgs, oldArgs) { handler: function () {
if (this.validArgs) { if (this.validArgs) {
this.runAnalysisWrapper(this.args) this.runAnalysisWrapper(this.args)
} }
...@@ -225,6 +223,7 @@ ...@@ -225,6 +223,7 @@
window.removeEventListener('resize', this.handleResize) window.removeEventListener('resize', this.handleResize)
}, },