Commit 45b36cee authored by Sascha Herzinger's avatar Sascha Herzinger
Browse files

Improved parameter API further (labels, callback)

parent b8d67217
Pipeline #6694 passed with stages
in 5 minutes and 48 seconds
......@@ -79,13 +79,26 @@ class FractalJS {
// }
// noinspection JSMethodCanBeStatic
getChartParameterDescription (vm) {
return store.getters.chartManager.getChartParamDescr(vm)
/**
* For a given chart register a callback that accepts exactly one argument (the parameterDescription object)
* The callback is called every time the parameters of the chart change
* Example for parameterDescriptionObject: {ignoreSubsets: {label: 'Ignore Subsets', type: Boolean, value: true}, ...}
* @param vm The chart VM (returned by setChart)
* @param callback The callback to register.
*/
getChartParameterDescription (vm, callback) {
store.getters.chartManager.getChartParamDescr(vm, callback)
}
// noinspection JSMethodCanBeStatic
setChartParameter (vm, parameter) {
store.getters.chartManager.setChartParams(vm, parameter)
/**
* Update the given vm with the given parameter object.
* Example for parameter object: {ignoreSubsets: false, ...}
* @param vm (returned by setChart)
* @param parameters (key:value pairs / parameterName:parameterValue pairs)
*/
setChartParameter (vm, parameters) {
store.getters.chartManager.setChartParams(vm, parameters)
}
}
......
import Vue from 'vue'
import _ from 'lodash'
export default class {
constructor () {
......@@ -48,19 +47,14 @@ export default class {
return Object.keys(this.availableCharts)
}
getChartParamDescr (vm) {
if (typeof vm.params === 'undefined') {
throw new Error('This chart does not expose any parameters. This is a bug that you should report.')
getChartParamDescr (vm, callback) {
if (typeof vm._parameterChangedCallback === 'undefined') {
throw new Error('Cannot get parameters for this chart. It does not implement the parameter-interface mixin.')
}
return _.cloneDeep(vm.params)
vm._setParameterChangedCallback(callback)
}
setChartParameter (vm, params) {
Object.keys(params).forEach(key => {
if (typeof vm.params[key] === 'undefined') {
throw new Error(`Parameter "${key}" does not exist for this chart.`)
}
vm.params[key].value = params[key]
})
vm._setParameters(params)
}
}
......@@ -18,7 +18,7 @@
<div class="fjs-parameter-container">
<div>
<label>
Data transformation:
{{ params.transformation.label }}:
<select class="fjs-transformation-select" v-model="params.transformation.value">
<option v-for="t in params.transformation.validValues">{{ t }}</option>
</select>
......@@ -27,31 +27,31 @@
<div>
<label>
<input type="checkbox" v-model="params.showOutliers.value"/>
Show Outliers
{{ params.showOutliers.label }}
</label>
</div>
<div>
<label>
<input type="checkbox" v-model="params.showData.value"/>
Show Points
{{ params.showData.label }}
</label>
</div>
<div>
<label>
<input type="checkbox" v-model="params.jitter.value"/>
Jitter Data
{{ params.jitter.label }}
</label>
</div>
<div>
<label>
<input type="checkbox" v-model="params.showKDE.value"/>
Show Density Est.
{{ params.showKDE.label }}
</label>
</div>
<div>
<label>
<input type="checkbox" v-model="params.ignoreSubsets.value"/>
Ignore Subsets
{{ params.ignoreSubsets.label }}
</label>
</div>
......@@ -174,7 +174,7 @@
import * as d3 from 'd3'
import deepFreeze from 'deep-freeze-strict'
import tooltip from '../directives/tooltip'
import StateSaver from '../mixins/state-saver'
import ParameterInterface from '../mixins/parameter-interface'
import getHDPICanvas from '../../utils/high-dpi-canvas'
export default {
name: 'boxplot',
......@@ -182,44 +182,50 @@
return {
params: {
numVars: {
label: 'Numerical Variables',
type: Array,
elementType: String,
label: 'Numerical Variables',
validValues: [],
minLength: 1,
maxLength: Infinity,
value: []
},
catVars: {
label: 'Categorical Variables',
type: Array,
elementType: String,
label: 'Categorical Variables',
validValues: [],
minLength: 0,
maxLength: Infinity,
value: []
},
showOutliers: {
label: 'Show Outliers',
type: Boolean,
value: true
},
showData: {
label: 'Show Points',
type: Boolean,
value: false
},
jitter: {
label: 'Jitter Data',
type: Boolean,
value: false
},
showKDE: {
label: 'Show Density Est.',
type: Boolean,
value: false
},
ignoreSubsets: {
label: 'Ignore Subsets',
type: Boolean,
value: false
},
transformation: {
label: 'Data transformation',
type: String,
value: 'identity',
validValues: ['identity', 'log2(x)', 'log10(x)', '2^x', '10^x']
......@@ -240,6 +246,9 @@
dataUrls: {}
}
},
mounted () {
this.registerParameterObjectInterface('params')
},
computed: {
idFilter () {
return store.getters.filter('ids')
......@@ -493,8 +502,8 @@
Chart
},
mixins: [
StateSaver,
RunAnalysis
RunAnalysis,
ParameterInterface
],
directives: {
tooltip
......
......@@ -10,9 +10,8 @@
<hr class="fjs-seperator"/>
<div class="fjs-ranking-params">
<span class="fjs-param-header">Ranking Criteria</span>
<span class="fjs-param-header">{{ params.rankingMethod.label }}</span>
<fieldset class="fjs-expression-ranking fjs-fieldset">
<legend>Expression Level</legend>
<div v-for="method in params.rankingMethod.validValues">
<label>
<input type="radio" :value="method" v-model="params.rankingMethod.value">
......@@ -23,7 +22,7 @@
</div>
<div class="fjs-clustering-params">
<span class="fjs-param-header">Heatmap Clustering</span>
<span class="fjs-param-header">{{ params.clusterAlgorithm.label }}</span>
<fieldset class="fjs-fieldset">
<legend>Algorithm</legend>
<div v-for="algorithm in params.clusterAlgorithm.validValues">
......@@ -38,7 +37,7 @@
<legend>Options</legend>
<div class="fjs-hclust-selects">
<select v-model="params.clusterMethod.value">
<option value="" selected disabled>-- Method --</option>
<option value="" selected disabled>--{{ params.clusterMethod.label }}--</option>
<option :value="value"
v-for="value in params.clusterMethod.validValues"
v-model="params.clusterMethod.value">
......@@ -46,7 +45,7 @@
</option>
</select>
<select v-model="params.clusterMetric.value">
<option value="" selected disabled>-- Metric --</option>
<option value="" selected disabled>--{{ params.clusterMetric.label }}--</option>
<option :value="value"
v-for="value in params.clusterMetric.validValues"
v-model="params.clusterMetric.value">
......@@ -59,7 +58,7 @@
<input type="range"
:min="params.nRowClusters.min" :max="params.nRowClusters.max"
v-model="params.nRowClusters.value"/>
{{ params.nRowClusters.value }} Row Clusters
{{ params.nRowClusters.value }} {{ params.nRowClusters.label }}
</label>
</div>
<div class="fjs-cluster-ranges">
......@@ -67,7 +66,7 @@
<input type="range"
:min="params.nColClusters.min" :max="params.nColClusters.max"
v-model="params.nColClusters.value"/>
{{ params.nColClusters.value }} Col Clusters
{{ params.nColClusters.value }} {{ params.nColClusters.label }}
</label>
</div>
</fieldset>
......@@ -79,7 +78,7 @@
<input type="range"
:min="params.nRowCentroids.min" :max="params.nRowCentroids.max"
v-model="params.nRowCentroids.value"/>
{{ params.nRowCentroids.value }} Row Centroids
{{ params.nRowCentroids.value }} {{ params.nRowCentroids.label }}
</label>
</div>
<div class="fjs-cluster-ranges">
......@@ -87,7 +86,7 @@
<input type="range"
:min="params.nColCentroids.min" :max="params.nColCentroids.max"
v-model="params.nColCentroids.value"/>
{{ params.nColCentroids.value }} Col Centroids
{{ params.nColCentroids.value }} {{ params.nColCentroids.label }}
</label>
</div>
</fieldset>
......@@ -122,7 +121,7 @@
import tooltip from '../directives/tooltip.js'
import deepFreeze from 'deep-freeze-strict'
import getHDPICanvas from '../../utils/high-dpi-canvas'
import StateSaver from '../mixins/state-saver'
import ParameterInterface from '../mixins/parameter-interface'
import _ from 'lodash'
export default {
name: 'heatmap',
......@@ -134,53 +133,61 @@
subsetColors: d3.schemeCategory10,
params: {
numVars: {
label: 'Numerical Variables',
type: Array,
elementType: String,
label: 'Numerical Variables',
validValues: [],
minLength: 1,
maxLength: Infinity,
value: []
},
rankingMethod: {
label: 'Ranking Criteria',
type: String,
validValues: [],
value: 'mean'
},
clusterAlgorithm: {
label: 'Heatmap Clustering',
type: String,
validValues: ['hclust', 'kmeans'],
value: 'hclust'
},
clusterMethod: {
label: 'Cluster Method',
type: String,
validValues: ['single', 'complete', 'average', 'weighted', 'centroid', 'median', 'ward'],
value: ''
},
clusterMetric: {
label: 'Cluster Metric',
type: String,
validValues: ['euclidean', 'sqeuclidean', 'cityblock', 'correlation', 'cosine'],
value: ''
},
nRowClusters: {
label: 'Row Clusters',
type: Number,
min: 1,
max: 20,
value: 5
},
nColClusters: {
label: 'Col Clusters',
type: Number,
min: 1,
max: 20,
value: 5
},
nRowCentroids: {
label: 'Row Centroids',
type: Number,
min: 1,
max: 20,
value: 5
},
nColCentroids: {
label: 'Col Centroids',
type: Number,
min: 1,
max: 20,
......@@ -202,6 +209,9 @@
dataUrl: ''
}
},
mounted () {
this.registerParameterObjectInterface('params')
},
computed: {
mainArgs () {
return {
......@@ -500,7 +510,7 @@
tooltip
},
mixins: [
StateSaver,
ParameterInterface,
RunAnalysis
]
}
......
......@@ -16,11 +16,11 @@
<hr class="fjs-seperator"/>
<div class="fjs-params">
<label>
Bandwidth Factor:
{{ params.bwFactor.label }}:
<input type="number" :min="params.bwFactor.min" step="0.1" v-model.lazy.number="params.bwFactor.value"/>
</label>
<label>
Number of Bins:
{{ params.numBins.label }}:
<input type="number" :min="params.numBins.min" step="1" v-model.lazy.number="params.numBins.value"/>
</label>
</div>
......@@ -77,6 +77,7 @@
import Html2svg from '../components/HTML2SVG.vue'
import Draggable from '../components/Draggable.vue'
import tooltip from '../directives/tooltip'
import ParameterInterface from '../mixins/parameter-interface'
import _ from 'lodash'
export default {
name: 'histogram',
......@@ -89,7 +90,8 @@
Crosshair
},
mixins: [
RunAnalysis
RunAnalysis,
ParameterInterface
],
directives: {
tooltip
......@@ -100,30 +102,32 @@
width: 0,
params: {
numVars: {
label: 'Numerical Variables',
type: Array,
elementType: String,
label: 'Numerical Variables',
validValues: [],
minLength: 1,
maxLength: 1,
value: []
},
catVars: {
label: 'Categorical Variables',
type: Array,
elementType: String,
label: 'Categorical Variables',
validValues: [],
minLength: 0,
maxLength: Infinity,
value: []
},
bwFactor: {
label: 'Bandwidth Factor',
type: Number,
min: 0.1,
max: Infinity,
value: 0.5
},
numBins: {
label: 'Number of Bins',
type: Number,
min: 2,
max: 50,
......@@ -142,6 +146,9 @@
groupColors: d3.schemeCategory10
}
},
mounted () {
this.registerParameterObjectInterface('params')
},
computed: {
idFilter () {
return store.getters.filter('ids')
......
......@@ -33,13 +33,13 @@
<div>
<label>
<input type="checkbox" v-model="params.whiten.value"/>
Whiten Output
{{ params.whiten.label }}
</label>
</div>
<div>
<label>
<input type="checkbox" v-model="params.ignoreSubsets.value"/>
Ignore Subsets
{{ params.ignoreSubsets.label }}
</label>
</div>
</control-panel>
......@@ -131,7 +131,7 @@
import Html2svg from '../components/HTML2SVG.vue'
import Draggable from '../components/Draggable.vue'
import getHDPICanvas from '../../utils/high-dpi-canvas'
import StateSaver from '../mixins/state-saver'
import ParameterInterface from '../mixins/parameter-interface'
export default {
name: 'pca',
data () {
......@@ -140,28 +140,30 @@
width: 0,
params: {
numVars: {
label: 'Numerical Variables',
type: Array,
elementType: String,
label: 'Numerical Variables',
validValues: [],
minLength: 2,
maxLength: Infinity,
value: []
},
catVars: {
label: 'Categorical Variables',
type: Array,
elementType: String,
label: 'Categorical Variables',
validValues: [],
minLength: 0,
maxLength: Infinity,
value: []
},
whiten: {
label: 'Whiten Output',
type: Boolean,
value: false
},
ignoreSubsets: {
label: 'Ignore Subsets',
type: Boolean,
value: false
}
......@@ -194,6 +196,9 @@
}
}
},
mounted () {
this.registerParameterObjectInterface('params')
},
computed: {
idFilter () {
return store.getters.filter('ids')
......@@ -463,8 +468,8 @@
tooltip
},
mixins: [
StateSaver,
RunAnalysis
RunAnalysis,
ParameterInterface
]
}
</script>
......
......@@ -16,14 +16,14 @@
</data-box>
<hr class="fjs-seperator"/>
<fieldset class="fjs-fieldset">
<legend>Correlation Method</legend>
<legend>{{ params.method.label }}</legend>
<label v-for="method in params.method.validValues">
<input type="radio" :value="method" v-model="params.method.value">
Pearson
{{ method }}
</label>
</fieldset>
<label>
Ignore Subsets:
{{ params.ignoreSubsets.label }}:
<input type="checkbox" v-model="params.ignoreSubsets.value"/>
</label>
</control-panel>
......@@ -108,7 +108,7 @@
import Html2svg from '../components/HTML2SVG.vue'
import Draggable from '../components/Draggable.vue'
import getHDPICanvas from '../../utils/high-dpi-canvas'
import StateSaver from '../mixins/state-saver'
import ParameterInterface from '../mixins/parameter-interface'
import _ from 'lodash'
export default {
name: 'scatterplot',
......@@ -120,29 +120,31 @@
categoryColors: d3.schemeCategory10,
params: {
numVars: {
label: 'Numerical Variables',
type: Array,
elementType: String,
label: 'Numerical Variables',
validValues: [],
minLength: 2,
maxLength: 2,
value: []
},
catVars: {
label: 'Categorical Variables',
type: Array,
elementType: String,
label: 'Categorical Variables',
validValues: [],
minLength: 0,
maxLength: Infinity,
value: []
},
method: {
label: 'Correlation Method',
type: String,
validValues: ['pearson', 'kendall', 'spearman'],
value: 'pearson'
},
ignoreSubsets: {
label: 'Ignore Subsets',
type: Boolean,
value: false
}
......@@ -172,6 +174,9 @@
dataUrl: ''
}
},
mounted () {
this.registerParameterObjectInterface('params')
},
computed: {
idFilter () {
return store.getters.filter('ids')
......@@ -438,8 +443,8 @@
tooltip
},
mixins: [
StateSaver,
RunAnalysis
RunAnalysis,
ParameterInterface
],
methods: {
runAnalysisWrapper (init, args) {
......
......@@ -22,18 +22,18 @@
<hr class="fjs-seperator"/>
<div class="fjs-settings">
<fieldset class="fjs-fieldset">
<legend>Estimator</legend>
<div v-for="method in estimators">
<legend>{{ params.estimator.label }}</legend>
<div v-for="method in params.estimator.validValues">
<label>
<input type="radio" :value="method" v-model="estimator">
<input type="radio" :value="method" v-model="params.estimator.value">
{{ method }}
</label>
</div>
</fieldset>
<div>
<label>
Ignore Subsets
<input type="checkbox" v-model="ignoreSubsets"/>
{{ params.ignoreSubsets.label }}
<input type="checkbox" v-model="params.ignoreSubsets.value"/>
</label>
</div>
</div>
......@@ -84,6 +84,7 @@
import Chart from '../components/Chart.vue'
import DataBox from '../components/DataBox.vue'
import RunAnalysis from '../mixins/run-analysis'
import ParameterInterface from '../mixins/parameter-interface'
import store from '../../store/store'
import deepFreeze from 'deep-freeze-strict'
import * as d3 from 'd3'
......@@ -94,45 +95,47 @@
export default {
name: 'survivalplot',
components: {Draggable, Html2svg, Crosshair, DataBox, Chart, ControlPanel},
mixins: [RunAnalysis],
mixins: [RunAnalysis, ParameterInterface],
data () {
return {
height: 0,
width: 0,
params: {