parent
e4080bcb25
commit
a51d44d123
Binary file not shown.
Binary file not shown.
@ -1,86 +0,0 @@ |
||||
<template> |
||||
<div> |
||||
<label id="data" for="param-dataset" data-toggle="tooltip" data-placement="right" title="Tip: use one of the data sets already provided or upload a new file.">{{ dataset }}</label> |
||||
<select id="selectFile" @change="selectDataSet()"> |
||||
<option value="HeartC.csv">Heart Disease</option> |
||||
<option value="IrisC.csv" selected>Iris</option> |
||||
<option value="local">Upload New File</option> |
||||
</select> |
||||
<button class="btn-outline-success" |
||||
id="initializeID" |
||||
v-on:click="initialize"> |
||||
<font-awesome-icon icon="search" /> |
||||
{{ searchText }} |
||||
</button> |
||||
<button class="btn-outline-danger" |
||||
id="resetID" |
||||
v-on:click="reset"> |
||||
<font-awesome-icon icon="trash" /> |
||||
{{ resetText }} |
||||
</button> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import Papa from 'papaparse' |
||||
import { EventBus } from '../main.js' |
||||
import {$,jQuery} from 'jquery'; |
||||
import * as d3Base from 'd3' |
||||
|
||||
// attach all d3 plugins to the d3 library |
||||
const d3 = Object.assign(d3Base) |
||||
|
||||
export default { |
||||
name: 'DataSetExecController', |
||||
data () { |
||||
return { |
||||
defaultDataSet: 'IrisC', // default value for the first data set |
||||
searchText: 'Exploration of Features', |
||||
resetText: 'Reset', |
||||
dataset: 'Data set' |
||||
} |
||||
}, |
||||
methods: { |
||||
selectDataSet () { |
||||
const fileName = document.getElementById('selectFile') |
||||
this.defaultDataSet = fileName.options[fileName.selectedIndex].value |
||||
this.defaultDataSet = this.defaultDataSet.split('.')[0] |
||||
|
||||
if (this.defaultDataSet == "DiabetesC" || this.defaultDataSet == "HeartC" || this.defaultDataSet == "IrisC" || this.defaultDataSet == "StanceC") { // This is a function that handles a new file, which users can upload. |
||||
this.dataset = "Data set" |
||||
d3.select("#data").select("input").remove(); // Remove the selection field. |
||||
EventBus.$emit('SendToServerDataSetConfirmation', this.defaultDataSet) |
||||
} else { |
||||
EventBus.$emit('SendToServerDataSetConfirmation', this.defaultDataSet) |
||||
d3.select("#data").select("input").remove(); |
||||
this.dataset = "" |
||||
var data |
||||
d3.select("#data") |
||||
.append("input") |
||||
.attr("type", "file") |
||||
.style("font-size", "18.5px") |
||||
.style("width", "200px") |
||||
.on("change", function() { |
||||
var file = d3.event.target.files[0]; |
||||
Papa.parse(file, { |
||||
header: true, |
||||
dynamicTyping: true, |
||||
skipEmptyLines: true, |
||||
complete: function(results) { |
||||
data = results.data; |
||||
EventBus.$emit('SendToServerLocalFile', data) |
||||
} |
||||
}); |
||||
}) |
||||
} |
||||
}, |
||||
reset () { |
||||
EventBus.$emit('reset') |
||||
EventBus.$emit('alternateFlagLock') |
||||
}, |
||||
initialize () { |
||||
EventBus.$emit('ConfirmDataSet') |
||||
} |
||||
} |
||||
} |
||||
</script> |
@ -0,0 +1,156 @@ |
||||
<template> |
||||
<div> |
||||
<div class="row align-items-center"> |
||||
<div class="col-lg-1"><p>Separate classified incorrectly (predict %)</p></div> |
||||
<div class="col-lg-2"><div id="slider-stepNeg"></div></div> |
||||
<div class="col-lg-1"><p id="value-stepNeg"></p></div> |
||||
<div class="col-lg-4"> |
||||
<label id="data" for="param-dataset" data-toggle="tooltip" data-placement="right" title="Tip: use one of the data sets already provided or upload a new file.">{{ dataset }}</label> |
||||
<select id="selectFile" @change="selectDataSet()"> |
||||
<option value="HeartC.csv">Heart disease</option> |
||||
<option value="IrisC.csv" selected>Iris flower</option> |
||||
<option value="local">Upload file</option> |
||||
</select> |
||||
<button class="btn-outline-success" |
||||
id="initializeID" |
||||
v-on:click="initialize"> |
||||
<font-awesome-icon icon="search" /> |
||||
{{ searchText }} |
||||
</button> |
||||
<button class="btn-outline-danger" |
||||
id="resetID" |
||||
v-on:click="reset"> |
||||
<font-awesome-icon icon="trash" /> |
||||
{{ resetText }} |
||||
</button> |
||||
</div> |
||||
<div class="col-lg-1"><p>Separate classified correctly (predict %)</p></div> |
||||
<div class="col-lg-2"><div id="slider-stepPos"></div></div> |
||||
<div class="col-lg-1"><p id="value-stepPos"></p></div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import Papa from 'papaparse' |
||||
import { EventBus } from '../main.js' |
||||
import {$,jQuery} from 'jquery'; |
||||
import * as d3Base from 'd3' |
||||
import { sliderBottom } from 'd3-simple-slider' |
||||
|
||||
// attach all d3 plugins to the d3 library |
||||
const d3 = Object.assign(d3Base, { sliderBottom }) |
||||
|
||||
export default { |
||||
name: 'DataSetSlider', |
||||
data () { |
||||
return { |
||||
defaultDataSet: 'IrisC', // default value for the first data set |
||||
searchText: 'Feature exploration', |
||||
resetText: 'Factory reset', |
||||
dataset: 'Data set' |
||||
} |
||||
}, |
||||
methods: { |
||||
selectDataSet () { |
||||
const fileName = document.getElementById('selectFile') |
||||
this.defaultDataSet = fileName.options[fileName.selectedIndex].value |
||||
this.defaultDataSet = this.defaultDataSet.split('.')[0] |
||||
|
||||
if (this.defaultDataSet == "DiabetesC" || this.defaultDataSet == "HeartC" || this.defaultDataSet == "IrisC" || this.defaultDataSet == "StanceC") { // This is a function that handles a new file, which users can upload. |
||||
this.dataset = "Data set" |
||||
d3.select("#data").select("input").remove(); // Remove the selection field. |
||||
EventBus.$emit('SendToServerDataSetConfirmation', this.defaultDataSet) |
||||
} else { |
||||
EventBus.$emit('SendToServerDataSetConfirmation', this.defaultDataSet) |
||||
d3.select("#data").select("input").remove(); |
||||
this.dataset = "" |
||||
var data |
||||
d3.select("#data") |
||||
.append("input") |
||||
.attr("type", "file") |
||||
.style("font-size", "18.5px") |
||||
.style("width", "200px") |
||||
.on("change", function() { |
||||
var file = d3.event.target.files[0]; |
||||
Papa.parse(file, { |
||||
header: true, |
||||
dynamicTyping: true, |
||||
skipEmptyLines: true, |
||||
complete: function(results) { |
||||
data = results.data; |
||||
EventBus.$emit('SendToServerLocalFile', data) |
||||
} |
||||
}); |
||||
}) |
||||
} |
||||
}, |
||||
reset () { |
||||
EventBus.$emit('reset') |
||||
EventBus.$emit('alternateFlagLock') |
||||
}, |
||||
initialize () { |
||||
EventBus.$emit('ConfirmDataSet') |
||||
}, |
||||
InitSliders () { |
||||
var dataCorrect = [55.0, 60.0, 65.0, 70.0, 75.0, 80.0, 85.0, 90.0, 95.0]; |
||||
var dataWrong = [5.0, 10.0, 15.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0]; |
||||
|
||||
var sliderStepPos = d3 |
||||
.sliderBottom() |
||||
.min(d3.min(dataCorrect)) |
||||
.max(d3.max(dataCorrect)) |
||||
.width(300) |
||||
.tickFormat(d3.format(".0f")) |
||||
.ticks(9) |
||||
.step(5) |
||||
.default(75.0) |
||||
.on('onchange', val => { |
||||
d3.select('p#value-stepPos').text(d3.format(".0f")(val)); |
||||
EventBus.$emit('SendtheChangeinRangePos', d3.format(".0f")(val)) |
||||
}); |
||||
|
||||
var gStepPos = d3 |
||||
.select('div#slider-stepPos') |
||||
.append('svg') |
||||
.attr('width', 400) |
||||
.attr('height', 80) |
||||
.append('g') |
||||
.attr('transform', 'translate(30,30)'); |
||||
|
||||
gStepPos.call(sliderStepPos); |
||||
|
||||
d3.select('p#value-stepPos').text(d3.format(".0f")(sliderStepPos.value())); |
||||
|
||||
var sliderStepNeg = d3 |
||||
.sliderBottom() |
||||
.min(d3.min(dataWrong)) |
||||
.max(d3.max(dataWrong)) |
||||
.width(300) |
||||
.tickFormat(d3.format(".0f")) |
||||
.ticks(9) |
||||
.step(5) |
||||
.default(25.0) |
||||
.on('onchange', val => { |
||||
d3.select('p#value-stepNeg').text(d3.format(".0f")(val)); |
||||
EventBus.$emit('SendtheChangeinRangeNeg', d3.format(".0f")(val)) |
||||
}); |
||||
|
||||
var gStepNeg = d3 |
||||
.select('div#slider-stepNeg') |
||||
.append('svg') |
||||
.attr('width', 400) |
||||
.attr('height', 80) |
||||
.append('g') |
||||
.attr('transform', 'translate(30,30)'); |
||||
|
||||
gStepNeg.call(sliderStepNeg); |
||||
|
||||
d3.select('p#value-stepNeg').text(d3.format(".0f")(sliderStepNeg.value())); |
||||
}, |
||||
}, |
||||
mounted () { |
||||
this.InitSliders() |
||||
}, |
||||
} |
||||
</script> |
@ -0,0 +1,226 @@ |
||||
<template> |
||||
<div> |
||||
<div id="BeeSwarm"></div> |
||||
<div id="tooltip"> |
||||
<strong class="system"> </strong> |
||||
<span class="label"> </span> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
|
||||
import { EventBus } from '../main.js' |
||||
import * as Plotly from 'plotly.js' |
||||
|
||||
export default { |
||||
name: 'DataSpace', |
||||
data () { |
||||
return { |
||||
dataInstances: '', |
||||
PositiveValue: 75, |
||||
NegativeValue: 25, |
||||
} |
||||
}, |
||||
methods: { |
||||
initializeBeeSwarm () { |
||||
var tooltip = d3.select("#tooltip") |
||||
|
||||
var width = 2500 |
||||
var height = 125 |
||||
var rectWidth = 20 |
||||
var rectHeight = 10 |
||||
|
||||
var nodeR = 8 |
||||
var nodeStrokeW = 1.5 |
||||
|
||||
var scale = 1 |
||||
|
||||
var predictions = JSON.parse(this.dataInstances[2]) |
||||
|
||||
var len = predictions.length; |
||||
var instances = new Array(len); |
||||
for (var i = 0; i < len; ++i) instances[i] = i |
||||
instances.sort(function (a, b) { return predictions[a] < predictions[b] ? -1 : predictions[a] > predictions[b] ? 1 : 0; }) |
||||
console.log(instances) |
||||
|
||||
predictions.sort() |
||||
console.log(predictions) |
||||
|
||||
var colorInstances = [] |
||||
for (let i = 0; i < predictions.length; i++) { |
||||
if (predictions[i] > 50 && predictions[i] > this.PositiveValue) { |
||||
colorInstances.push("#33a02c") |
||||
} else if (predictions[i] > 50 && predictions[i] <= this.PositiveValue) { |
||||
colorInstances.push("#b2df8a") |
||||
} else if (predictions[i] <= 50 && predictions[i] > this.NegativeValue) { |
||||
colorInstances.push("#fb9a99") |
||||
} else { |
||||
colorInstances.push("#e31a1c") |
||||
} |
||||
} |
||||
|
||||
var data = d3.range(instances.length).map(function(d, i) { |
||||
return { |
||||
x : predictions[i], |
||||
y : 0, // doesn't matter, will be reset before it matters |
||||
r : nodeR, |
||||
col: colorInstances[i], |
||||
system : 'Predicted Probability', |
||||
label : '(%)' |
||||
} |
||||
}) |
||||
|
||||
var dx = function(d) { return d.x } |
||||
var dy = function(d) { return d.y } |
||||
var dr = function(d) { return d.r } |
||||
var colorX = function(d) { return d.col } |
||||
|
||||
var extent = d3.extent(data, dx) |
||||
|
||||
// the range is set in such a way that portions of nodes are not drawn outside the g |
||||
var xScale = d3.scale.linear() |
||||
.domain(extent) |
||||
.range([0, width]) |
||||
|
||||
var norm = d3.random.normal(0, 4.0) |
||||
|
||||
var chart = d3.select("#BeeSwarm").append("svg") |
||||
.attr("width", 2500) |
||||
.attr("height", 125) |
||||
.attr("pointer-events", "all") |
||||
.append("g") |
||||
.attr("transform", "translate(0,0)") |
||||
.on("mousemove", function() { |
||||
var x = d3.event.pageX - 24 // subtract translation |
||||
followMe.transition() |
||||
.duration(10) |
||||
.attr("x1", x).attr("x2", x) |
||||
}) |
||||
.call(d3.behavior.zoom().x(xScale).scaleExtent([0.8, 10]).on("zoom", zoom)) |
||||
.append('g'); |
||||
|
||||
// append a background rectangle to receive the pointer events |
||||
// (otherwise zoom only works when the pointer is over a node) |
||||
chart.append('rect') |
||||
.attr('width', width) |
||||
.attr('height', height) |
||||
.attr('fill', 'white'); |
||||
|
||||
var axis = d3.svg.axis().scale(xScale) |
||||
chart.append("g").attr("class", "xAxis").call(axis) |
||||
|
||||
var followMe = chart.append("line") |
||||
.attr("x1", 0).attr("x2", 0) |
||||
.attr("y1", 0).attr("y2", 400) |
||||
.style("stroke", "red") |
||||
|
||||
function zoom() { |
||||
chart.select(".xAxis").call(axis); |
||||
|
||||
if(scale != d3.event.scale) |
||||
beeswarm() |
||||
scale = d3.event.scale |
||||
|
||||
chart.selectAll("circle.node") |
||||
.transition(10) |
||||
.attr("cx", function(d) { return xScale(d.x) }) |
||||
.attr("cy", dy) |
||||
} |
||||
|
||||
var nodes = chart.selectAll("circle.node") |
||||
.data(data) |
||||
|
||||
beeswarm() |
||||
|
||||
nodes.enter().append("circle") |
||||
.attr("class", "node") |
||||
.attr("cx", function(d) { return xScale(d.x) }) |
||||
.attr("cy", dy) |
||||
.attr("r", dr) |
||||
.attr("fill", colorX) |
||||
.style("stroke", "black") |
||||
.style("stroke-width", 4) |
||||
.on("mouseover", function(d) { |
||||
tooltip.select(".system").html(d.system) |
||||
return tooltip.select(".label").html(d.label) |
||||
}) |
||||
.on("mouseout", function(d) { |
||||
tooltip.select(".system").html(" ") |
||||
return tooltip.select(".label").html(" ") |
||||
}) |
||||
.on("click", function(d, i) { |
||||
var inRange = function(dPrime, iPrime) { |
||||
return Math.pow(i-iPrime, 2) <= 4 |
||||
} |
||||
|
||||
d3.selectAll("circle.node").filter(inRange).style("stroke", "yellow") |
||||
d3.selectAll("circle.node").filter(function(dPrime, iPrime) { return !inRange(dPrime, iPrime) }) |
||||
.style("stroke", "black") |
||||
}) |
||||
|
||||
function beeswarm() { |
||||
// reset vertical position |
||||
data.map(function(d) { |
||||
d.y = height / 2 |
||||
}) |
||||
for(var iter = 0; iter < 10; iter++) { |
||||
var q = d3.geom.quadtree(data) |
||||
for(var i = 0; i < data.length; i++) |
||||
q.visit(collide(data[i])) |
||||
} |
||||
} |
||||
|
||||
function collide(node) { |
||||
var r = node.r + 16, |
||||
nx1 = xScale(node.x) - r, |
||||
nx2 = xScale(node.x) + r, |
||||
ny1 = node.y - r, |
||||
ny2 = node.y + r; |
||||
return function(quad, x1, y1, x2, y2) { |
||||
if (quad.point && (quad.point !== node)) { |
||||
var x = xScale(node.x) - xScale(quad.point.x), |
||||
y = node.y - quad.point.y, |
||||
l = Math.sqrt(x * x + y * y), |
||||
r = node.r + quad.point.r; |
||||
if (l < r) |
||||
node.y += norm() |
||||
} |
||||
return xScale(x1) > nx2 |
||||
|| xScale(x2) < nx1 |
||||
|| y1 > ny2 |
||||
|| y2 < ny1 |
||||
} |
||||
} |
||||
}, |
||||
reset () { |
||||
var svg = d3.select("#BeeSwarm"); |
||||
svg.selectAll("*").remove(); |
||||
}, |
||||
}, |
||||
mounted () { |
||||
EventBus.$on('SendtheChangeinRangePos', data => {this.PositiveValue = data}) |
||||
EventBus.$on('SendtheChangeinRangeNeg', data => {this.NegativeValue = data}) |
||||
EventBus.$on('quad', data => { this.dataInstances = data }) |
||||
EventBus.$on('quad', this.initializeBeeSwarm) |
||||
|
||||
EventBus.$on('reset', this.reset) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style> |
||||
|
||||
text { |
||||
font-family: sans-serif; |
||||
} |
||||
|
||||
svg { |
||||
display: block; |
||||
} |
||||
|
||||
.nodeHighlighted { |
||||
stroke: 'orange' |
||||
} |
||||
|
||||
</style> |
@ -1,684 +0,0 @@ |
||||
<template> |
||||
<div class="column"> |
||||
<div id="FeatureGraph1"></div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import { EventBus } from '../main.js' |
||||
import * as greadability from '../greadability.js' |
||||
import * as d3Base from 'd3' |
||||
|
||||
// attach all d3 plugins to the d3 library |
||||
const d3 = Object.assign(d3Base) |
||||
|
||||
export default { |
||||
name: 'FeatureSpace1', |
||||
data () { |
||||
return { |
||||
dataFS1: [], |
||||
dataFS1Trans: [], |
||||
jsonData: [], |
||||
corrMatrixComb: [], |
||||
corrMatrixCombTotal: [], |
||||
VIFRemaining: [], |
||||
MIRemaining: [], |
||||
computeNodes: 0 |
||||
} |
||||
}, |
||||
methods: { |
||||
initializeNetwork () { |
||||
|
||||
var listofNodes = this.dataFS1[0] |
||||
var dataLoc = JSON.parse(this.dataFS1[2]) |
||||
var pushEachFinal = [] |
||||
var pushEach |
||||
var oldVal |
||||
var newVal |
||||
var outcome |
||||
var countLoc |
||||
|
||||
var corrMatrixCombLoc =[] |
||||
var corrMatrixCombTotalLoc = [] |
||||
var VIFRemainingLoc = [] |
||||
var MIRemainingLoc = [] |
||||
|
||||
this.dataFS1Trans.forEach(function(element, index) { |
||||
var round = element.round |
||||
corrMatrixCombLoc.push(Object.values(JSON.parse(round[4]))) |
||||
corrMatrixCombTotalLoc.push(Object.values(JSON.parse(round[8]))[0] * 100) |
||||
VIFRemainingLoc.push(Object.values(JSON.parse(round[12]))[0]) |
||||
MIRemainingLoc.push(JSON.parse(round[16])) |
||||
round = JSON.parse(round[0]) |
||||
oldVal = 0 |
||||
newVal = 0 |
||||
outcome = 0 |
||||
countLoc = 0 |
||||
pushEach = [] |
||||
Object.entries(round).forEach( |
||||
function ([feature, value]) { |
||||
var key = Object.keys(value) |
||||
var search = Object.values(dataLoc[key]) |
||||
oldVal = Math.abs(search[countLoc]) + oldVal |
||||
newVal = Math.abs(Object.values(value)[0]) + newVal |
||||
countLoc++ |
||||
}) |
||||
oldVal = oldVal / listofNodes.length |
||||
newVal = newVal / listofNodes.length |
||||
outcome = oldVal - newVal |
||||
pushEach.push({keyIns: "round", valueIns: outcome}) |
||||
|
||||
var roundLogE = element.roundLogE |
||||
corrMatrixCombLoc.push(Object.values(JSON.parse(roundLogE[4]))) |
||||
corrMatrixCombTotalLoc.push(Object.values(JSON.parse(roundLogE[8]))[0] * 100) |
||||
VIFRemainingLoc.push(Object.values(JSON.parse(roundLogE[12]))[0]) |
||||
MIRemainingLoc.push(JSON.parse(roundLogE[16])) |
||||
roundLogE = JSON.parse(roundLogE[0]) |
||||
oldVal = 0 |
||||
newVal = 0 |
||||
outcome = 0 |
||||
countLoc = 0 |
||||
Object.entries(roundLogE).forEach( |
||||
function ([feature, value]) { |
||||
var key = Object.keys(value) |
||||
var search = Object.values(dataLoc[key]) |
||||
oldVal = Math.abs(search[countLoc]) + oldVal |
||||
newVal = Math.abs(Object.values(value)[0]) + newVal |
||||
countLoc++ |
||||
}) |
||||
oldVal = oldVal / listofNodes.length |
||||
newVal = newVal / listofNodes.length |
||||
outcome = oldVal - newVal |
||||
pushEach.push({keyIns: "roundLogE", valueIns: outcome}) |
||||
|
||||
var roundLog2 = element.roundLog2 |
||||
corrMatrixCombLoc.push(Object.values(JSON.parse(roundLog2[4]))) |
||||
corrMatrixCombTotalLoc.push(Object.values(JSON.parse(roundLog2[8]))[0] * 100) |
||||
VIFRemainingLoc.push(Object.values(JSON.parse(roundLog2[12]))[0]) |
||||
MIRemainingLoc.push(JSON.parse(roundLog2[16])) |
||||
roundLog2 = JSON.parse(roundLog2[0]) |
||||
oldVal = 0 |
||||
newVal = 0 |
||||
outcome = 0 |
||||
countLoc = 0 |
||||
Object.entries(roundLog2).forEach( |
||||
function ([feature, value]) { |
||||
var key = Object.keys(value) |
||||
var search = Object.values(dataLoc[key]) |
||||
oldVal = Math.abs(search[countLoc]) + oldVal |
||||
newVal = Math.abs(Object.values(value)[0]) + newVal |
||||
countLoc++ |
||||
}) |
||||
oldVal = oldVal / listofNodes.length |
||||
newVal = newVal / listofNodes.length |
||||
outcome = oldVal - newVal |
||||
pushEach.push({keyIns: "roundLog2", valueIns: outcome}) |
||||
|
||||
var roundLog10 = element.roundLog10 |
||||
corrMatrixCombLoc.push(Object.values(JSON.parse(roundLog10[4]))) |
||||
corrMatrixCombTotalLoc.push(Object.values(JSON.parse(roundLog10[8]))[0] * 100) |
||||
VIFRemainingLoc.push(Object.values(JSON.parse(roundLog10[12]))[0]) |
||||
MIRemainingLoc.push(JSON.parse(roundLog10[16])) |
||||
roundLog10 = JSON.parse(roundLog10[0]) |
||||
oldVal = 0 |
||||
newVal = 0 |
||||
outcome = 0 |
||||
countLoc = 0 |
||||
Object.entries(roundLog10).forEach( |
||||
function ([feature, value]) { |
||||
var key = Object.keys(value) |
||||
var search = Object.values(dataLoc[key]) |
||||
oldVal = Math.abs(search[countLoc]) + oldVal |
||||
newVal = Math.abs(Object.values(value)[0]) + newVal |
||||
countLoc++ |
||||
}) |
||||
oldVal = oldVal / listofNodes.length |
||||
newVal = newVal / listofNodes.length |
||||
outcome = oldVal - newVal |
||||
pushEach.push({keyIns: "roundLog10", valueIns: outcome}) |
||||
pushEachFinal.push({key: listofNodes[index], value: pushEach}) |
||||
}) |
||||
|
||||
this.corrMatrixComb = [...corrMatrixCombLoc] |
||||
this.corrMatrixCombTotal = [...corrMatrixCombTotalLoc] |
||||
this.VIFRemaining = [...VIFRemainingLoc] |
||||
this.MIRemaining = [...MIRemainingLoc] |
||||
|
||||
var nodes = [] |
||||
var groupID = 0 |
||||
|
||||
listofNodes.forEach( function(element) { |
||||
groupID++ |
||||
nodes.push({"name": element, "group": groupID+"_root"}) |
||||
}) |
||||
|
||||
var links = [] |
||||
|
||||
Object.entries(dataLoc).forEach( |
||||
function ([feature, value]) { |
||||
Object.entries(value).forEach( function ([featureInside, value]) { |
||||
if (feature != featureInside) { |
||||
if (value >= 0) { |
||||
links.push({"source": listofNodes.indexOf(feature), "target": listofNodes.indexOf(featureInside), "value": Math.abs(value) * 30, "lin_color": "#D3D3D3"}) |
||||
} |
||||
} |
||||
}) |
||||
}) |
||||
|
||||
groupID = 0 |
||||
listofNodes.forEach( function(element) { |
||||
groupID++ |
||||
nodes.push( |
||||
{"name": element+"_r", "group": groupID}, |
||||
{"name": element+"_r_E", "group": groupID}, |
||||
{"name": element+"_r_2", "group": groupID}, |
||||
{"name": element+"_r_10", "group": groupID}, |
||||
) |
||||
}) |
||||
|
||||
this.computeNodes = nodes.length |
||||
EventBus.$emit('countNodes1', this.computeNodes) |
||||
|
||||
Object.entries(pushEachFinal).forEach( |
||||
function ([index, feature]) { |
||||
feature.value.forEach(function (element, indexIns) { |
||||
if (element.valueIns > 0) { |
||||
links.push({"source": index, "target": index*feature.value.length+feature.value.length+indexIns, "value": Math.abs(element.valueIns) * 30, "lin_color": "#4393c3"}) |
||||
} |
||||
else { |
||||
links.push({"source": index, "target": index*feature.value.length+feature.value.length+indexIns, "value": Math.abs(element.valueIns) * 30, "lin_color": "#d6604d"}) |
||||
} |
||||
}) |
||||
}) |
||||
|
||||
this.jsonData = {"nodes": nodes, "links": links}; |
||||
|
||||
this.graphVizualization() |
||||
|
||||
}, |
||||
graphVizualization () { |
||||
|
||||
var listofNodes = this.dataFS1[0] |
||||
var uniqueTarget = JSON.parse(this.dataFS1[14]) |
||||
var corrTarget = JSON.parse(this.dataFS1[6]) |
||||
var corrGlob = JSON.parse(this.dataFS1[10]) |
||||
var VIFVar = JSON.parse(this.dataFS1[18]) |
||||
var MIVar = JSON.parse(this.dataFS1[22]) |
||||
MIVar = MIVar.concat(this.MIRemaining) |
||||
var colorCateg = d3.scaleOrdinal(d3.schemeAccent) |
||||
|
||||
var corrTargetFormatted = [] |
||||
for (let i = 0; i < Object.keys(corrTarget).length; i++) { |
||||
var corrTargetFormattedLoc = [] |
||||
for (let j = 0; j < Object.keys(corrTarget[i]).length; j++) { |
||||
if (j > uniqueTarget.length - 1) { |
||||
corrTargetFormattedLoc.push(Math.round(Object.values(corrTarget[i])[j] * 100)) |
||||
} |
||||
} |
||||
corrTargetFormatted.push(corrTargetFormattedLoc) |
||||
} |
||||
|
||||
for (let j = 0; j < uniqueTarget.length; j++) { |
||||
for (let i = 0; i < Object.keys(this.corrMatrixComb).length; i++) { |
||||
if (Math.round(Object.values((Object.values(this.corrMatrixComb[i])[j]))[0] * 100) == null) { |
||||
corrTargetFormatted[j].push(0) |
||||
} else { |
||||
corrTargetFormatted[j].push(Math.round(Object.values((Object.values(this.corrMatrixComb[i])[j]))[0] * 100)) |
||||
} |
||||
} |
||||
} |
||||
|
||||
var corrGlobFormatted = [] |
||||
for (let i = 0; i < Object.keys(corrGlob).length; i++) { |
||||
if (i != 0) { |
||||
corrGlobFormatted.push(Math.round(Object.values(corrGlob)[i]['0'] * 100)) |
||||
} |
||||
} |
||||
|
||||
for (let i = 0; i < this.corrMatrixCombTotal.length; i++) { |
||||
corrGlobFormatted.push(Math.round(this.corrMatrixCombTotal[i])) |
||||
} |
||||
|
||||
var VIFVarFormatted = [] |
||||
for (let i = 0; i < Object.keys(VIFVar).length; i++) { |
||||
if (i != 0) { |
||||
if (Object.values(VIFVar)[i] > 10) { |
||||
VIFVarFormatted.push(4) |
||||
} else if (Object.values(VIFVar)[i] > 5) { |
||||
VIFVarFormatted.push(2) |
||||
} else { |
||||
VIFVarFormatted.push(0) |
||||
} |
||||
} |
||||
} |
||||
|
||||
for (let i = 0; i < this.VIFRemaining.length; i++) { |
||||
if (this.VIFRemaining[i] > 10) { |
||||
VIFVarFormatted.push(4) |
||||
} else if (this.VIFRemaining[i] > 5) { |
||||
VIFVarFormatted.push(2) |
||||
} else { |
||||
VIFVarFormatted.push(0) |
||||
} |
||||
} |
||||
|
||||
function min(input) { |
||||
if (toString.call(input) !== "[object Array]") |
||||
return false; |
||||
return Math.min.apply(null, input); |
||||
} |
||||
|
||||
function max(input) { |
||||
if (toString.call(input) !== "[object Array]") |
||||
return false; |
||||
return Math.max.apply(null, input); |
||||
} |
||||
|
||||
function normalize(min, max) { |
||||
var delta = max - min; |
||||
return function (val) { |
||||
return (val - min) / delta; |
||||
}; |
||||
} |
||||
|
||||
var MIMin = min(MIVar) |
||||
var MIMax = max(MIVar) |
||||
|
||||
MIVar = MIVar.map(normalize(MIMin, MIMax)) |
||||
|
||||
var colorsScaleNodes = d3.scaleOrdinal() |
||||
.domain(d3.ticks([MIMin, MIMax, 10])) |
||||
.range(['#67001f','#b2182b','#d6604d','#f4a582','#fddbc7','#d1e5f0','#92c5de','#4393c3','#2166ac','#053061']); |
||||
|
||||
var svg = d3.select("#FeatureGraph1"); |
||||
svg.selectAll("*").remove(); |
||||
|
||||
var width = 1000; |
||||
var height = 500; |
||||
|
||||
var numTicks = 200; |
||||
|
||||
var selectedParams; |
||||
var bestParams; |
||||
|
||||
var dispatch = d3.dispatch('layoutend'); |
||||
|
||||
svg = d3.select("#FeatureGraph1").append("svg") |
||||
.attr("width", width) |
||||
.attr("height", height); |
||||
|
||||
var graph = this.jsonData |
||||
|
||||
var link = svg.append('g') |
||||
.attr('class', 'links') |
||||
.selectAll('line') |
||||
.data(graph.links) |
||||
.enter().append('line') |
||||
.attr("stroke", function(d) { return d.lin_color; }) |
||||
.attr("stroke-width", function(d) { return Math.sqrt(d.value); }); |
||||
|
||||
|
||||
var node = svg.append('g') |
||||
.attr('class', 'nodes') |
||||
.selectAll('g') |
||||
.data(graph.nodes) |
||||
.enter().append('g') |
||||
.on("click", function(id, index) { |
||||
var groupLoc = index + 1 |
||||
var items = document.getElementsByClassName(groupLoc) |
||||
items.forEach( function (it) { |
||||
if (it.style.visibility == "hidden") { |
||||
it.style.visibility = "visible"; |
||||
} else { |
||||
it.style.visibility = "hidden"; |
||||
} |
||||
}) |
||||
}); |
||||
|
||||
var paramGroups = [ |
||||
{name: 'chargeStrength', values: [-30, -80]}, |
||||
{name: 'linkDistance', values: [30, -80]}, |
||||
{name: 'linkStrength', values: [0, 1]}, |
||||
{name: 'gravity', values: [0, 0.5]}, |
||||
{name: 'iterations', values: [1, 2]}, |
||||
{name: 'alphaDecay', values: [0, 0.0228, 0.05]}, |
||||
{name: 'velocityDecay', values: [0.4, 0.8]} |
||||
]; |
||||
|
||||
var paramList = generateParams(paramGroups); |
||||
|
||||
var bestSoFar = d3.select('.best').selectAll('li') |
||||
.data(paramGroups.map(function (d) { return d.name; })) |
||||
.enter().append('li') |
||||
.text(function (d) { return d; }); |
||||
|
||||
dispatch.on('layoutend', function (params, i) { |
||||
if (!bestParams || params.graphReadability > bestParams.graphReadability) { |
||||
bestParams = params; |
||||
selectedParams = bestParams; |
||||
|
||||
bestSoFar |
||||
.data(d3.map(bestParams).keys().filter(function (d) { return d !== 'positions' && d !== 'graphReadability'; })) |
||||
.text(function (d) { return d + ' = ' + bestParams[d]; }); |
||||
} |
||||
|
||||
}); |
||||
|
||||
var i = 0; |
||||
var stepper = d3.timer(function () { |
||||
var p = paramList[i]; |
||||
var forceSim = getForceSimFromParams(p); |
||||
|
||||
// Reset node attributes. |
||||
graph.nodes.forEach(function (n) { |
||||
n.x = n.y = n.vx = n.vy = 0; |
||||
}); |
||||
|
||||
forceSim.nodes(graph.nodes) |
||||
.stop(); |
||||
|
||||
forceSim.force('link') |
||||
.links(graph.links); |
||||
|
||||
for (var t = 0; t < numTicks; ++t) { |
||||
forceSim.tick(); |
||||
} |
||||
|
||||
p.graphReadability = greadability.greadability(graph.nodes, graph.links); |
||||
p.graphReadability = (p.graphReadability.crossing + p.graphReadability.crossingAngle + |
||||
p.graphReadability.angularResolutionMin + p.graphReadability.angularResolutionDev) / 4 |
||||
|
||||
p.positions = graph.nodes.map(function (n) { return {x: n.x, y: n.y}; }); |
||||
|
||||
dispatch.call('layoutend', forceSim, p, i); |
||||
|
||||
++i; |
||||
if (i >= paramList.length) { |
||||
|
||||
var widthLoc = 100; |
||||
var arcSize = (6 * widthLoc / 100); |
||||
var innerRadius = arcSize * 2; |
||||
|
||||
var svgLoc = node.append('svg').attr('width', widthLoc).attr('height', widthLoc).attr("class", function(d, i) { return d.group; }) |
||||
.attr("id", function(d, i) { return "svg" + (i); }) |
||||
|
||||
graph.nodes.forEach(function(itemVal, indexNode) { |
||||
|
||||
var data = [] |
||||
|
||||
for(let k = 0; k < uniqueTarget.length; k++) { |
||||
data.push({value: corrTargetFormatted[k][indexNode], label: '', color: colorCateg(uniqueTarget[k]), lcolor: ''}) |
||||
} |
||||
|
||||
var length = data.length |
||||
data.push({value: 100, label: corrGlobFormatted[indexNode], color: '#000000', lcolor: colorsScaleNodes(MIVar[indexNode])}) |
||||
|
||||
|
||||
var border = VIFVarFormatted[indexNode] |
||||
|
||||
var arcs = data.map(function (obj, i) { |
||||
if (i == length) { |
||||
return d3.arc().innerRadius(i * arcSize + innerRadius).outerRadius((i + 1) * arcSize - (widthLoc / 100) + innerRadius + border); |
||||
} else { |
||||
return d3.arc().innerRadius(i * arcSize + innerRadius).outerRadius((i + 1) * arcSize - (widthLoc / 100) + innerRadius); |
||||
} |
||||
}); |
||||
|
||||
var arcsGrey = data.map(function (obj, i) { |
||||
return d3.arc().innerRadius(i * arcSize + (innerRadius + ((arcSize / 2) - 2))).outerRadius((i + 1) * arcSize - ((arcSize / 2)) + (innerRadius)); |
||||
}); |
||||
|
||||
var pieData = data.map(function (obj, i) { |
||||
return [ |
||||
{value: obj.value, arc: arcs[i], object: obj}, |
||||
{value: (100 - obj.value), arc: arcsGrey[i], object: obj}, |
||||
{value: 0, arc: arcs[i], object: obj}]; |
||||
}); |
||||
|
||||
var pie = d3.pie().sort(null).value(function (d) { |
||||
return d.value; |
||||
}); |
||||
var id = indexNode |
||||
var g = d3.select('#svg'+id).selectAll('g').data(pieData).enter() |
||||
.append('g') |
||||
.attr('transform', 'translate(' + widthLoc / 2 + ',' + widthLoc / 2 + ') rotate(180)'); |
||||
var gText = d3.select('#svg'+id).selectAll('g.textClass').data([{}]).enter() |
||||
.append('g') |
||||
.classed('textClass', true) |
||||
.attr('transform', 'translate(' + widthLoc / 2 + ',' + widthLoc / 2 + ') rotate(180)'); |
||||
|
||||
g.selectAll('path').data(function (d) { |
||||
return pie(d); |
||||
}).enter().append('path') |
||||
.attr('id', function (d, i) { |
||||
if (i == 1) { |
||||
return "Text" + d.data.object.label |
||||
} |
||||
}) |
||||
.attr('d', function (d) { |
||||
return d.data.arc(d); |
||||
}).attr('fill', function (d, i) { |
||||
return i == 0 ? d.data.object.color : i == 1 ? '#D3D3D3' : 'none'; |
||||
}); |
||||
|
||||
g.each(function (d, index) { |
||||
|
||||
var el = d3.select(this); |
||||
var path = el.selectAll('path').each(function (r, i) { |
||||
if (i === 1) { |
||||
var centroid = r.data.arc.centroid({ |
||||
startAngle: r.startAngle + 0.05, |
||||
endAngle: r.startAngle + 0.001 + 0.05 |
||||
}); |
||||
var lableObj = r.data.object; |
||||
g.append('text') |
||||
.attr('font-size', ((2 * width) / 100)) |
||||
.attr('dominant-baseline', 'central') |
||||
.append("textPath") |
||||
.attr("textLength", function (d, i) { |
||||
return 0; |
||||
}) |
||||
.attr("startOffset", '5') |
||||
.attr("dy", '-3em') |
||||
.text(lableObj.value + '%'); |
||||
} |
||||
if (i === 0) { |
||||
var centroidText = r.data.arc.centroid({ |
||||
startAngle: r.startAngle, |
||||
endAngle: r.startAngle |
||||
}); |
||||
var lableObj = r.data.object; |
||||
gText.append('text') |
||||
.attr('font-size', ((2 * width) / 100)) |
||||
.text(lableObj.label) |
||||
.style('fill', lableObj.lcolor) |
||||
.attr('transform', "translate(" + (10) + "," + (0 + ") rotate(" + (180) + ")")) |
||||
.attr('dominant-baseline', 'central'); |
||||
} |
||||
}); |
||||
|
||||
}); |
||||
|
||||
}) |
||||
|
||||
var drag_handler = d3.drag() |
||||
.on("start", drag_start) |
||||
.on("drag", drag_drag) |
||||
.on("end", drag_end); |
||||
|
||||
drag_handler(node); |
||||
|
||||
var labels = node.append("text") |
||||
.text(function(d) { |
||||
return d.name; |
||||
}) |
||||
.attr('x', 20) |
||||
.attr('y', 8); |
||||
|
||||
node.append('title').text(function (d) { return d.name; }); |
||||
|
||||
//add zoom capabilities |
||||
var zoom_handler = d3.zoom() |
||||
.on("zoom", zoom_actions); |
||||
|
||||
zoom_handler(svg); |
||||
|
||||
drawGraph(); |
||||
|
||||
for (let i = 0; i < listofNodes.length; i++) { |
||||
var numb = graph.nodes[i]['group'].match(/\d/g) |
||||
numb = parseInt(numb.join("")) |
||||
var items = document.getElementsByClassName(numb) |
||||
items.forEach( function (it) { |
||||
it.style.visibility = "hidden"; |
||||
}) |
||||
} |
||||
|
||||
//Zoom functions |
||||
function zoom_actions(){ |
||||
svg.attr("transform", d3.event.transform) |
||||
} |
||||
|
||||
function drag_start(d) { |
||||
if (!d3.event.active) forceSim.alphaTarget(0.3).restart(); |
||||
d.fx = d.x; |
||||
d.fy = d.y; |
||||
} |
||||
|
||||
//make sure you can't drag the circle outside the box |
||||
function drag_drag(d) { |
||||
d.fx = d3.event.x; |
||||
d.fy = d3.event.y; |
||||
tickActions(); |
||||
} |
||||
|
||||
function drag_end(d) { |
||||
if (!d3.event.active) forceSim.alphaTarget(0); |
||||
d.fx = null; |
||||
d.fy = null; |
||||
} |
||||
|
||||
stepper.stop(); |
||||
} |
||||
|
||||
}); |
||||
|
||||
function tickActions() { |
||||
link |
||||
.attr('x1', function (d) { return d.source.x; }) |
||||
.attr('x2', function (d) { return d.target.x; }) |
||||
.attr('y1', function (d) { return d.source.y; }) |
||||
.attr('y2', function (d) { return d.target.y; }); |
||||
|
||||
node |
||||
.attr("id", function(d, i) { return "g" + (i); }) |
||||
.attr("transform", function(d, i) { |
||||
d.x = d.x - 50 |
||||
d.y = d.y - 50 |
||||
return "translate(" + d.x + "," + d.y + ")"; |
||||
}) |
||||
}; |
||||
|
||||
function drawGraph () { |
||||
graph.nodes.forEach(function (n, i) { |
||||
n.x = selectedParams.positions[i].x; |
||||
n.y = selectedParams.positions[i].y; |
||||
}); |
||||
|
||||
var xDistance = d3.extent(graph.nodes, function (n) { return n.x; }); |
||||
var xMin = xDistance[0]; |
||||
xDistance = xDistance[1] - xDistance[0]; |
||||
|
||||
var yDistance = d3.extent(graph.nodes, function (n) { return n.y; }); |
||||
var yMin = yDistance[0]; |
||||
yDistance = yDistance[1] - yDistance[0]; |
||||
|
||||
graph.nodes.forEach(function (n, i) { |
||||
n.x = (height - 10) * (n.x - xMin) / Math.max(xDistance, yDistance); |
||||
n.y = (height - 10) * (n.y - yMin) / Math.max(xDistance, yDistance); |
||||
}); |
||||
|
||||
xDistance = d3.extent(graph.nodes, function (n) { return n.x; }); |
||||
var xMid = (xDistance[1] + xDistance[0]) / 2; |
||||
yDistance = d3.extent(graph.nodes, function (n) { return n.y; }); |
||||
var yMid = (yDistance[1] - yDistance[0]) / 2; |
||||
|
||||
graph.nodes.forEach(function (n, i) { |
||||
n.x = n.x + width/2 - xMid; |
||||
n.y = n.y + height/2 - yMid; |
||||
}); |
||||
|
||||
tickActions(); |
||||
} |
||||
|
||||
function generateParams (paramGroups, paramList, currParam) { |
||||
var p = paramGroups[0]; |
||||
|
||||
if (!paramList) paramList = []; |
||||
|
||||
if (!currParam) currParam = {}; |
||||
|
||||
p.values.forEach(function (v) { |
||||
var setting = {}; |
||||
setting[p.name] = v; |
||||
if (paramGroups.length === 1) { |
||||
paramList.push(Object.assign(setting, currParam)); |
||||
} else { |
||||
generateParams(paramGroups.slice(1), paramList, Object.assign(setting, currParam)); |
||||
} |
||||
}); |
||||
|
||||
return paramList; |
||||
} |
||||
|
||||
function getForceSimFromParams (params) { |
||||
var forceSim = d3.forceSimulation() |
||||
.force('link', d3.forceLink().iterations(params.iterations)) |
||||
.force('charge', d3.forceManyBody().strength(params.chargeStrength)) |
||||
.force('x', d3.forceX(0).strength(params.gravity)) |
||||
.force('y', d3.forceY(0).strength(params.gravity)) |
||||
.force('center', d3.forceCenter(0, 0)) |
||||
.alphaDecay(params.alphaDecay) |
||||
.velocityDecay(params.velocityDecay); |
||||
|
||||
if (params.linkStrength !== null) { |
||||
forceSim.force('link').strength(params.linkStrength); |
||||
} |
||||
|
||||
return forceSim; |
||||
} |
||||
|
||||
}, |
||||
reset () { |
||||
var svg = d3.select("#FeatureGraph1"); |
||||
svg.selectAll("*").remove(); |
||||
}, |
||||
}, |
||||
mounted () { |
||||
EventBus.$on('quadTrans1', data => { this.dataFS1Trans = data }) |
||||
EventBus.$on('quad1', data => { this.dataFS1 = data }) |
||||
EventBus.$on('quad1', this.initializeNetwork) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style> |
||||
|
||||
text { |
||||
font-family: sans-serif; |
||||
} |
||||
|
||||
svg { |
||||
display: block; |
||||
} |
||||
|
||||
.links line { |
||||
stroke-opacity: 0.6; |
||||
} |
||||
|
||||
.column { |
||||
float: left; |
||||
margin: 0 10px; |
||||
} |
||||
|
||||
</style> |
@ -1,686 +0,0 @@ |
||||
<template> |
||||
<div class="column"> |
||||
<div id="FeatureGraph3"></div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import { EventBus } from '../main.js' |
||||
import * as greadability from '../greadability.js' |
||||
import * as d3Base from 'd3' |
||||
|
||||
// attach all d3 plugins to the d3 library |
||||
const d3 = Object.assign(d3Base) |
||||
|
||||
export default { |
||||
name: 'FeatureSpace1', |
||||
data () { |
||||
return { |
||||
dataFS3: [], |
||||
dataFS3Trans: [], |
||||
jsonData: [], |
||||
corrMatrixComb: [], |
||||
corrMatrixCombTotal: [], |
||||
VIFRemaining: [], |
||||
MIRemaining: [], |
||||
computeNodes: 0 |
||||
} |
||||
}, |
||||
methods: { |
||||
initializeNetwork () { |
||||
|
||||
var listofNodes = this.dataFS3[0] |
||||
var dataLoc = JSON.parse(this.dataFS3[4]) |
||||
var pushEachFinal = [] |
||||
var pushEach |
||||
var oldVal |
||||
var newVal |
||||
var outcome |
||||
var countLoc |
||||
|
||||
var corrMatrixCombLoc =[] |
||||
var corrMatrixCombTotalLoc = [] |
||||
var VIFRemainingLoc = [] |
||||
var MIRemainingLoc = [] |
||||
|
||||
this.dataFS3Trans.forEach(function(element, index) { |
||||
var round = element.round |
||||
corrMatrixCombLoc.push(Object.values(JSON.parse(round[6]))) |
||||
corrMatrixCombTotalLoc.push(Object.values(JSON.parse(round[10]))[0] * 100) |
||||
VIFRemainingLoc.push(Object.values(JSON.parse(round[14]))[0]) |
||||
MIRemainingLoc.push(JSON.parse(round[18])) |
||||
round = JSON.parse(round[2]) |
||||
oldVal = 0 |
||||
newVal = 0 |
||||
outcome = 0 |
||||
countLoc = 0 |
||||
pushEach = [] |
||||
Object.entries(round).forEach( |
||||
function ([feature, value]) { |
||||
var key = Object.keys(value) |
||||
var search = Object.values(dataLoc[key]) |
||||
oldVal = Math.abs(search[countLoc]) + oldVal |
||||
newVal = Math.abs(Object.values(value)[0]) + newVal |
||||
countLoc++ |
||||
}) |
||||
oldVal = oldVal / listofNodes.length |
||||
newVal = newVal / listofNodes.length |
||||
outcome = oldVal - newVal |
||||
pushEach.push({keyIns: "round", valueIns: outcome}) |
||||
|
||||
var roundLogE = element.roundLogE |
||||
corrMatrixCombLoc.push(Object.values(JSON.parse(roundLogE[6]))) |
||||
corrMatrixCombTotalLoc.push(Object.values(JSON.parse(roundLogE[10]))[0] * 100) |
||||
VIFRemainingLoc.push(Object.values(JSON.parse(roundLogE[14]))[0]) |
||||
MIRemainingLoc.push(JSON.parse(roundLogE[18])) |
||||
roundLogE = JSON.parse(roundLogE[2]) |
||||
oldVal = 0 |
||||
newVal = 0 |
||||
outcome = 0 |
||||
countLoc = 0 |
||||
Object.entries(roundLogE).forEach( |
||||
function ([feature, value]) { |
||||
var key = Object.keys(value) |
||||
var search = Object.values(dataLoc[key]) |
||||
oldVal = Math.abs(search[countLoc]) + oldVal |
||||
newVal = Math.abs(Object.values(value)[0]) + newVal |
||||
countLoc++ |
||||
}) |
||||
oldVal = oldVal / listofNodes.length |
||||
newVal = newVal / listofNodes.length |
||||
outcome = oldVal - newVal |
||||
pushEach.push({keyIns: "roundLogE", valueIns: outcome}) |
||||
|
||||
var roundLog2 = element.roundLog2 |
||||
corrMatrixCombLoc.push(Object.values(JSON.parse(roundLog2[6]))) |
||||
corrMatrixCombTotalLoc.push(Object.values(JSON.parse(roundLog2[10]))[0] * 100) |
||||
VIFRemainingLoc.push(Object.values(JSON.parse(roundLog2[14]))[0]) |
||||
MIRemainingLoc.push(JSON.parse(roundLog2[18])) |
||||
roundLog2 = JSON.parse(roundLog2[2]) |
||||
oldVal = 0 |
||||
newVal = 0 |
||||
outcome = 0 |
||||
countLoc = 0 |
||||
Object.entries(roundLog2).forEach( |
||||
function ([feature, value]) { |
||||
var key = Object.keys(value) |
||||
var search = Object.values(dataLoc[key]) |
||||
oldVal = Math.abs(search[countLoc]) + oldVal |
||||
newVal = Math.abs(Object.values(value)[0]) + newVal |
||||
countLoc++ |
||||
}) |
||||
oldVal = oldVal / listofNodes.length |
||||
newVal = newVal / listofNodes.length |
||||
outcome = oldVal - newVal |
||||
pushEach.push({keyIns: "roundLog2", valueIns: outcome}) |
||||
|
||||
var roundLog10 = element.roundLog10 |
||||
corrMatrixCombLoc.push(Object.values(JSON.parse(roundLog10[6]))) |
||||
corrMatrixCombTotalLoc.push(Object.values(JSON.parse(roundLog10[10]))[0] * 100) |
||||
VIFRemainingLoc.push(Object.values(JSON.parse(roundLog10[14]))[0]) |
||||
MIRemainingLoc.push(JSON.parse(roundLog10[18])) |
||||
roundLog10 = JSON.parse(roundLog10[2]) |
||||
oldVal = 0 |
||||
newVal = 0 |
||||
outcome = 0 |
||||
countLoc = 0 |
||||
Object.entries(roundLog10).forEach( |
||||
function ([feature, value]) { |
||||
var key = Object.keys(value) |
||||
var search = Object.values(dataLoc[key]) |
||||
oldVal = Math.abs(search[countLoc]) + oldVal |
||||
newVal = Math.abs(Object.values(value)[0]) + newVal |
||||
countLoc++ |
||||
}) |
||||
oldVal = oldVal / listofNodes.length |
||||
newVal = newVal / listofNodes.length |
||||
outcome = oldVal - newVal |
||||
pushEach.push({keyIns: "roundLog10", valueIns: outcome}) |
||||
pushEachFinal.push({key: listofNodes[index], value: pushEach}) |
||||
}) |
||||
|
||||
this.corrMatrixComb = [...corrMatrixCombLoc] |
||||
this.corrMatrixCombTotal = [...corrMatrixCombTotalLoc] |
||||
this.VIFRemaining = [...VIFRemainingLoc] |
||||
this.MIRemaining = [...MIRemainingLoc] |
||||
|
||||
var nodes = [] |
||||
var groupID = 0 |
||||
listofNodes.forEach( function(element) { |
||||
groupID++ |
||||
nodes.push({"name": element, "group": groupID+"_root"}) |
||||
}) |
||||
|
||||
var links = [] |
||||
|
||||
Object.entries(dataLoc).forEach( |
||||
function ([feature, value]) { |
||||
Object.entries(value).forEach( function ([featureInside, value]) { |
||||
if (feature != featureInside) { |
||||
if (value >= 0) { |
||||
links.push({"source": listofNodes.indexOf(feature), "target": listofNodes.indexOf(featureInside), "value": Math.abs(value) * 30, "lin_color": "#D3D3D3"}) |
||||
} |
||||
} |
||||
}) |
||||
}) |
||||
|
||||
groupID = 0 |
||||
listofNodes.forEach( function(element) { |
||||
groupID++ |
||||
nodes.push( |
||||
{"name": element+"_r", "group": groupID}, |
||||
{"name": element+"_r_E", "group": groupID}, |
||||
{"name": element+"_r_2", "group": groupID}, |
||||
{"name": element+"_r_10", "group": groupID}, |
||||
) |
||||
}) |
||||
|
||||
Object.entries(pushEachFinal).forEach( |
||||
function ([index, feature]) { |
||||
feature.value.forEach(function (element, indexIns) { |
||||
if (element.valueIns > 0) { |
||||
links.push({"source": index, "target": index*feature.value.length+feature.value.length+indexIns, "value": Math.abs(element.valueIns) * 30, "lin_color": "#4393c3"}) |
||||
} |
||||
else { |
||||
links.push({"source": index, "target": index*feature.value.length+feature.value.length+indexIns, "value": Math.abs(element.valueIns) * 30, "lin_color": "#d6604d"}) |
||||
} |
||||
}) |
||||
}) |
||||
|
||||
this.jsonData = {"nodes": nodes, "links": links}; |
||||
|
||||
this.graphVizualization() |
||||
|
||||
}, |
||||
graphVizualization () { |
||||
|
||||
var computeNodesVar = this.computeNodes |
||||
|
||||
var listofNodes = this.dataFS3[0] |
||||
var uniqueTarget = JSON.parse(this.dataFS3[16]) |
||||
var corrTarget = JSON.parse(this.dataFS3[8]) |
||||
var corrGlob = JSON.parse(this.dataFS3[12]) |
||||
var VIFVar = JSON.parse(this.dataFS3[20]) |
||||
var MIVar = JSON.parse(this.dataFS3[24]) |
||||
MIVar = MIVar.concat(this.MIRemaining) |
||||
var colorCateg = d3.scaleOrdinal(d3.schemeAccent) |
||||
|
||||
var corrTargetFormatted = [] |
||||
for (let i = 0; i < Object.keys(corrTarget).length; i++) { |
||||
var corrTargetFormattedLoc = [] |
||||
for (let j = 0; j < Object.keys(corrTarget[i]).length; j++) { |
||||
if (j > uniqueTarget.length - 1) { |
||||
corrTargetFormattedLoc.push(Math.round(Object.values(corrTarget[i])[j] * 100)) |
||||
} |
||||
} |
||||
corrTargetFormatted.push(corrTargetFormattedLoc) |
||||
} |
||||
|
||||
for (let j = 0; j < uniqueTarget.length; j++) { |
||||
for (let i = 0; i < Object.keys(this.corrMatrixComb).length; i++) { |
||||
if (Math.round(Object.values((Object.values(this.corrMatrixComb[i])[j]))[0] * 100) == null) { |
||||
corrTargetFormatted[j].push(0) |
||||
} else { |
||||
corrTargetFormatted[j].push(Math.round(Object.values((Object.values(this.corrMatrixComb[i])[j]))[0] * 100)) |
||||
} |
||||
} |
||||
} |
||||
|
||||
var corrGlobFormatted = [] |
||||
for (let i = 0; i < Object.keys(corrGlob).length; i++) { |
||||
if (i != 0) { |
||||
corrGlobFormatted.push(Math.round(Object.values(corrGlob)[i]['0'] * 100)) |
||||
} |
||||
} |
||||
|
||||
for (let i = 0; i < this.corrMatrixCombTotal.length; i++) { |
||||
corrGlobFormatted.push(Math.round(this.corrMatrixCombTotal[i])) |
||||
} |
||||
|
||||
var VIFVarFormatted = [] |
||||
for (let i = 0; i < Object.keys(VIFVar).length; i++) { |
||||
if (i != 0) { |
||||
if (Object.values(VIFVar)[i] > 10) { |
||||
VIFVarFormatted.push(4) |
||||
} else if (Object.values(VIFVar)[i] > 5) { |
||||
VIFVarFormatted.push(2) |
||||
} else { |
||||
VIFVarFormatted.push(0) |
||||
} |
||||
} |
||||
} |
||||
|
||||
for (let i = 0; i < this.VIFRemaining.length; i++) { |
||||
if (this.VIFRemaining[i] > 10) { |
||||
VIFVarFormatted.push(4) |
||||
} else if (this.VIFRemaining[i] > 5) { |
||||
VIFVarFormatted.push(2) |
||||
} else { |
||||
VIFVarFormatted.push(0) |
||||
} |
||||
} |
||||
|
||||
function min(input) { |
||||
if (toString.call(input) !== "[object Array]") |
||||
return false; |
||||
return Math.min.apply(null, input); |
||||
} |
||||
|
||||
function max(input) { |
||||
if (toString.call(input) !== "[object Array]") |
||||
return false; |
||||
return Math.max.apply(null, input); |
||||
} |
||||
|
||||
function normalize(min, max) { |
||||
var delta = max - min; |
||||
return function (val) { |
||||
return (val - min) / delta; |
||||
}; |
||||
} |
||||
|
||||
var MIMin = min(MIVar) |
||||
var MIMax = max(MIVar) |
||||
|
||||
MIVar = MIVar.map(normalize(MIMin, MIMax)) |
||||
|
||||
var colorsScaleNodes = d3.scaleOrdinal() |
||||
.domain(d3.ticks([MIMin, MIMax, 10])) |
||||
.range(['#67001f','#b2182b','#d6604d','#f4a582','#fddbc7','#d1e5f0','#92c5de','#4393c3','#2166ac','#053061']); |
||||
|
||||
var svg = d3.select("#FeatureGraph3"); |
||||
svg.selectAll("*").remove(); |
||||
|
||||
var width = 1000; |
||||
var height = 500; |
||||
|
||||
var numTicks = 200; |
||||
|
||||
var selectedParams; |
||||
var bestParams; |
||||
|
||||
var dispatch = d3.dispatch('layoutend'); |
||||
|
||||
svg = d3.select("#FeatureGraph3").append("svg") |
||||
.attr("width", width) |
||||
.attr("height", height); |
||||
|
||||
var graph = this.jsonData |
||||
|
||||
var link = svg.append('g') |
||||
.attr('class', 'links') |
||||
.selectAll('line') |
||||
.data(graph.links) |
||||
.enter().append('line') |
||||
.attr("stroke", function(d) { return d.lin_color; }) |
||||
.attr("stroke-width", function(d) { return Math.sqrt(d.value); }); |
||||
|
||||
|
||||
var node = svg.append('g') |
||||
.attr('class', 'nodes') |
||||
.selectAll('g') |
||||
.data(graph.nodes) |
||||
.enter().append('g') |
||||
.on("click", function(id, index) { |
||||
var groupLoc = index + 1 |
||||
var items = document.getElementsByClassName(groupLoc) |
||||
items.forEach( function (it) { |
||||
if (it.style.visibility == "hidden") { |
||||
it.style.visibility = "visible"; |
||||
} else { |
||||
it.style.visibility = "hidden"; |
||||
} |
||||
}) |
||||
}); |
||||
|
||||
var paramGroups = [ |
||||
{name: 'chargeStrength', values: [-30, -80]}, |
||||
{name: 'linkDistance', values: [30, -80]}, |
||||
{name: 'linkStrength', values: [0, 1]}, |
||||
{name: 'gravity', values: [0, 0.5]}, |
||||
{name: 'iterations', values: [1, 2]}, |
||||
{name: 'alphaDecay', values: [0, 0.0228, 0.05]}, |
||||
{name: 'velocityDecay', values: [0.4, 0.8]} |
||||
]; |
||||
|
||||
var paramList = generateParams(paramGroups); |
||||
|
||||
var bestSoFar = d3.select('.best').selectAll('li') |
||||
.data(paramGroups.map(function (d) { return d.name; })) |
||||
.enter().append('li') |
||||
.text(function (d) { return d; }); |
||||
|
||||
dispatch.on('layoutend', function (params, i) { |
||||
if (!bestParams || params.graphReadability > bestParams.graphReadability) { |
||||
bestParams = params; |
||||
selectedParams = bestParams; |
||||
|
||||
bestSoFar |
||||
.data(d3.map(bestParams).keys().filter(function (d) { return d !== 'positions' && d !== 'graphReadability'; })) |
||||
.text(function (d) { return d + ' = ' + bestParams[d]; }); |
||||
} |
||||
|
||||
}); |
||||
|
||||
var i = 0; |
||||
var stepper = d3.timer(function () { |
||||
var p = paramList[i]; |
||||
var forceSim = getForceSimFromParams(p); |
||||
|
||||
// Reset node attributes. |
||||
graph.nodes.forEach(function (n) { |
||||
n.x = n.y = n.vx = n.vy = 0; |
||||
}); |
||||
|
||||
forceSim.nodes(graph.nodes) |
||||
.stop(); |
||||
|
||||
forceSim.force('link') |
||||
.links(graph.links); |
||||
|
||||
for (var t = 0; t < numTicks; ++t) { |
||||
forceSim.tick(); |
||||
} |
||||
|
||||
p.graphReadability = greadability.greadability(graph.nodes, graph.links); |
||||
p.graphReadability = (p.graphReadability.crossing + p.graphReadability.crossingAngle + |
||||
p.graphReadability.angularResolutionMin + p.graphReadability.angularResolutionDev) / 4 |
||||
|
||||
p.positions = graph.nodes.map(function (n) { return {x: n.x, y: n.y}; }); |
||||
|
||||
dispatch.call('layoutend', forceSim, p, i); |
||||
|
||||
++i; |
||||
if (i >= paramList.length) { |
||||
|
||||
var widthLoc = 100; |
||||
var arcSize = (6 * widthLoc / 100); |
||||
var innerRadius = arcSize * 2; |
||||
|
||||
var svgLoc = node.append('svg').attr('width', widthLoc).attr('height', widthLoc).attr("class", function(d, i) { return d.group; }) |
||||
.attr("id", function(d, i) { return "svg" + (i+computeNodesVar); }) |
||||
|
||||
graph.nodes.forEach(function(itemVal, indexNode) { |
||||
|
||||
var data = [] |
||||
|
||||
for(let k = 0; k < uniqueTarget.length; k++) { |
||||
data.push({value: corrTargetFormatted[k][indexNode], label: '', color: colorCateg(uniqueTarget[k]), lcolor: ''}) |
||||
} |
||||
|
||||
var length = data.length |
||||
data.push({value: 100, label: corrGlobFormatted[indexNode], color: '#000000', lcolor: colorsScaleNodes(MIVar[indexNode])}) |
||||
|
||||
|
||||
var border = VIFVarFormatted[indexNode] |
||||
|
||||
var arcs = data.map(function (obj, i) { |
||||
if (i == length) { |
||||
return d3.arc().innerRadius(i * arcSize + innerRadius).outerRadius((i + 1) * arcSize - (widthLoc / 100) + innerRadius + border); |
||||
} else { |
||||
return d3.arc().innerRadius(i * arcSize + innerRadius).outerRadius((i + 1) * arcSize - (widthLoc / 100) + innerRadius); |
||||
} |
||||
}); |
||||
|
||||
var arcsGrey = data.map(function (obj, i) { |
||||
return d3.arc().innerRadius(i * arcSize + (innerRadius + ((arcSize / 2) - 2))).outerRadius((i + 1) * arcSize - ((arcSize / 2)) + (innerRadius)); |
||||
}); |
||||
|
||||
var pieData = data.map(function (obj, i) { |
||||
return [ |
||||
{value: obj.value, arc: arcs[i], object: obj}, |
||||
{value: (100 - obj.value), arc: arcsGrey[i], object: obj}, |
||||
{value: 0, arc: arcs[i], object: obj}]; |
||||
}); |
||||
|
||||
var pie = d3.pie().sort(null).value(function (d) { |
||||
return d.value; |
||||
}); |
||||
var id = indexNode + computeNodesVar |
||||
var g = d3.select('#svg'+id).selectAll('g').data(pieData).enter() |
||||
.append('g') |
||||
.attr('transform', 'translate(' + widthLoc / 2 + ',' + widthLoc / 2 + ') rotate(180)'); |
||||
var gText = d3.select('#svg'+id).selectAll('g.textClass').data([{}]).enter() |
||||
.append('g') |
||||
.classed('textClass', true) |
||||
.attr('transform', 'translate(' + widthLoc / 2 + ',' + widthLoc / 2 + ') rotate(180)'); |
||||
|
||||
g.selectAll('path').data(function (d) { |
||||
return pie(d); |
||||
}).enter().append('path') |
||||
.attr('id', function (d, i) { |
||||
if (i == 1) { |
||||
return "Text" + d.data.object.label |
||||
} |
||||
}) |
||||
.attr('d', function (d) { |
||||
return d.data.arc(d); |
||||
}).attr('fill', function (d, i) { |
||||
return i == 0 ? d.data.object.color : i == 1 ? '#D3D3D3' : 'none'; |
||||
}); |
||||
|
||||
g.each(function (d, index) { |
||||
|
||||
var el = d3.select(this); |
||||
var path = el.selectAll('path').each(function (r, i) { |
||||
if (i === 1) { |
||||
var centroid = r.data.arc.centroid({ |
||||
startAngle: r.startAngle + 0.05, |
||||
endAngle: r.startAngle + 0.001 + 0.05 |
||||
}); |
||||
var lableObj = r.data.object; |
||||
g.append('text') |
||||
.attr('font-size', ((2 * width) / 100)) |
||||
.attr('dominant-baseline', 'central') |
||||
.append("textPath") |
||||
.attr("textLength", function (d, i) { |
||||
return 0; |
||||
}) |
||||
.attr("startOffset", '5') |
||||
.attr("dy", '-3em') |
||||
.text(lableObj.value + '%'); |
||||
} |
||||
if (i === 0) { |
||||
var centroidText = r.data.arc.centroid({ |
||||
startAngle: r.startAngle, |
||||
endAngle: r.startAngle |
||||
}); |
||||
var lableObj = r.data.object; |
||||
gText.append('text') |
||||
.attr('font-size', ((2 * width) / 100)) |
||||
.text(lableObj.label) |
||||
.style('fill', lableObj.lcolor) |
||||
.attr('transform', "translate(" + (10) + "," + (0 + ") rotate(" + (180) + ")")) |
||||
.attr('dominant-baseline', 'central'); |
||||
} |
||||
}); |
||||
|
||||
}); |
||||
|
||||
}) |
||||
|
||||
var drag_handler = d3.drag() |
||||
.on("start", drag_start) |
||||
.on("drag", drag_drag) |
||||
.on("end", drag_end); |
||||
|
||||
drag_handler(node); |
||||
|
||||
var labels = node.append("text") |
||||
.text(function(d) { |
||||
return d.name; |
||||
}) |
||||
.attr('x', 20) |
||||
.attr('y', 8); |
||||
|
||||
node.append('title').text(function (d) { return d.name; }); |
||||
|
||||
//add zoom capabilities |
||||
var zoom_handler = d3.zoom() |
||||
.on("zoom", zoom_actions); |
||||
|
||||
zoom_handler(svg); |
||||
|
||||
drawGraph(); |
||||
|
||||
for (let i = 0; i < listofNodes.length; i++) { |
||||
var numb = graph.nodes[i]['group'].match(/\d/g) |
||||
numb = parseInt(numb.join("")) |
||||
var items = document.getElementsByClassName(numb) |
||||
items.forEach( function (it) { |
||||
it.style.visibility = "hidden"; |
||||
}) |
||||
} |
||||
|
||||
//Zoom functions |
||||
function zoom_actions(){ |
||||
svg.attr("transform", d3.event.transform) |
||||
} |
||||
|
||||
function drag_start(d) { |
||||
if (!d3.event.active) forceSim.alphaTarget(0.3).restart(); |
||||
d.fx = d.x; |
||||
d.fy = d.y; |
||||
} |
||||
|
||||
//make sure you can't drag the circle outside the box |
||||
function drag_drag(d) { |
||||
d.fx = d3.event.x; |
||||
d.fy = d3.event.y; |
||||
tickActions(); |
||||
} |
||||
|
||||
function drag_end(d) { |
||||
if (!d3.event.active) forceSim.alphaTarget(0); |
||||
d.fx = null; |
||||
d.fy = null; |
||||
} |
||||
|
||||
stepper.stop(); |
||||
} |
||||
|
||||
}); |
||||
|
||||
function tickActions() { |
||||
link |
||||
.attr('x1', function (d) { return d.source.x; }) |
||||
.attr('x2', function (d) { return d.target.x; }) |
||||
.attr('y1', function (d) { return d.source.y; }) |
||||
.attr('y2', function (d) { return d.target.y; }); |
||||
|
||||
node |
||||
.attr("id", function(d, i) { return "g" + (i+computeNodesVar); }) |
||||
.attr("transform", function(d, i) { |
||||
d.x = d.x - 50 |
||||
d.y = d.y - 50 |
||||
return "translate(" + d.x + "," + d.y + ")"; |
||||
}) |
||||
}; |
||||
|
||||
function drawGraph () { |
||||
graph.nodes.forEach(function (n, i) { |
||||
n.x = selectedParams.positions[i].x; |
||||
n.y = selectedParams.positions[i].y; |
||||
}); |
||||
|
||||
var xDistance = d3.extent(graph.nodes, function (n) { return n.x; }); |
||||
var xMin = xDistance[0]; |
||||
xDistance = xDistance[1] - xDistance[0]; |
||||
|
||||
var yDistance = d3.extent(graph.nodes, function (n) { return n.y; }); |
||||
var yMin = yDistance[0]; |
||||
yDistance = yDistance[1] - yDistance[0]; |
||||
|
||||
graph.nodes.forEach(function (n, i) { |
||||
n.x = (height - 10) * (n.x - xMin) / Math.max(xDistance, yDistance); |
||||
n.y = (height - 10) * (n.y - yMin) / Math.max(xDistance, yDistance); |
||||
}); |
||||
|
||||
xDistance = d3.extent(graph.nodes, function (n) { return n.x; }); |
||||
var xMid = (xDistance[1] + xDistance[0]) / 2; |
||||
yDistance = d3.extent(graph.nodes, function (n) { return n.y; }); |
||||
var yMid = (yDistance[1] - yDistance[0]) / 2; |
||||
|
||||
graph.nodes.forEach(function (n, i) { |
||||
n.x = n.x + width/2 - xMid; |
||||
n.y = n.y + height/2 - yMid; |
||||
}); |
||||
|
||||
tickActions(); |
||||
} |
||||
|
||||
function generateParams (paramGroups, paramList, currParam) { |
||||
var p = paramGroups[0]; |
||||
|
||||
if (!paramList) paramList = []; |
||||
|
||||
if (!currParam) currParam = {}; |
||||
|
||||
p.values.forEach(function (v) { |
||||
var setting = {}; |
||||
setting[p.name] = v; |
||||
if (paramGroups.length === 1) { |
||||
paramList.push(Object.assign(setting, currParam)); |
||||
} else { |
||||
generateParams(paramGroups.slice(1), paramList, Object.assign(setting, currParam)); |
||||
} |
||||
}); |
||||
|
||||
return paramList; |
||||
} |
||||
|
||||
function getForceSimFromParams (params) { |
||||
var forceSim = d3.forceSimulation() |
||||
.force('link', d3.forceLink().iterations(params.iterations)) |
||||
.force('charge', d3.forceManyBody().strength(params.chargeStrength)) |
||||
.force('x', d3.forceX(0).strength(params.gravity)) |
||||
.force('y', d3.forceY(0).strength(params.gravity)) |
||||
.force('center', d3.forceCenter(0, 0)) |
||||
.alphaDecay(params.alphaDecay) |
||||
.velocityDecay(params.velocityDecay); |
||||
|
||||
if (params.linkStrength !== null) { |
||||
forceSim.force('link').strength(params.linkStrength); |
||||
} |
||||
|
||||
return forceSim; |
||||
} |
||||
|
||||
this.computeNodes = this.computeNodes + graph.nodes.length |
||||
EventBus.$emit('countNodes3', this.computeNodes) |
||||
|
||||
}, |
||||
reset () { |
||||
var svg = d3.select("#FeatureGraph3"); |
||||
svg.selectAll("*").remove(); |
||||
}, |
||||
}, |
||||
mounted () { |
||||
EventBus.$on('quadTrans3', data => { this.dataFS3Trans = data }) |
||||
EventBus.$on('quad3', data => { this.dataFS3 = data }) |
||||
EventBus.$on('quad3', this.initializeNetwork) |
||||
EventBus.$on('countNodes2', data => { this.computeNodes = data }) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style> |
||||
|
||||
text { |
||||
font-family: sans-serif; |
||||
} |
||||
|
||||
svg { |
||||
display: block; |
||||
} |
||||
|
||||
.links line { |
||||
stroke-opacity: 0.6; |
||||
} |
||||
|
||||
.column { |
||||
float: left; |
||||
margin: 0 10px; |
||||
} |
||||
|
||||
</style> |
@ -1,685 +0,0 @@ |
||||
<template> |
||||
<div class="column"> |
||||
<div id="FeatureGraph4"></div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import { EventBus } from '../main.js' |
||||
import * as greadability from '../greadability.js' |
||||
import * as d3Base from 'd3' |
||||
|
||||
// attach all d3 plugins to the d3 library |
||||
const d3 = Object.assign(d3Base) |
||||
|
||||
export default { |
||||
name: 'FeatureSpace1', |
||||
data () { |
||||
return { |
||||
dataFS4: [], |
||||
dataFS4Trans: [], |
||||
jsonData: [], |
||||
corrMatrixComb: [], |
||||
corrMatrixCombTotal: [], |
||||
VIFRemaining: [], |
||||
MIRemaining: [], |
||||
computeNodes: 0 |
||||
} |
||||
}, |
||||
methods: { |
||||
initializeNetwork () { |
||||
|
||||
var listofNodes = this.dataFS4[0] |
||||
var dataLoc = JSON.parse(this.dataFS4[5]) |
||||
var pushEachFinal = [] |
||||
var pushEach |
||||
var oldVal |
||||
var newVal |
||||
var outcome |
||||
var countLoc |
||||
|
||||
var corrMatrixCombLoc =[] |
||||
var corrMatrixCombTotalLoc = [] |
||||
var VIFRemainingLoc = [] |
||||
var MIRemainingLoc = [] |
||||
|
||||
this.dataFS4Trans.forEach(function(element, index) { |
||||
var round = element.round |
||||
corrMatrixCombLoc.push(Object.values(JSON.parse(round[7]))) |
||||
corrMatrixCombTotalLoc.push(Object.values(JSON.parse(round[11]))[0] * 100) |
||||
VIFRemainingLoc.push(Object.values(JSON.parse(round[15]))[0]) |
||||
MIRemainingLoc.push(JSON.parse(round[19])) |
||||
round = JSON.parse(round[3]) |
||||
oldVal = 0 |
||||
newVal = 0 |
||||
outcome = 0 |
||||
countLoc = 0 |
||||
pushEach = [] |
||||
Object.entries(round).forEach( |
||||
function ([feature, value]) { |
||||
var key = Object.keys(value) |
||||
var search = Object.values(dataLoc[key]) |
||||
oldVal = Math.abs(search[countLoc]) + oldVal |
||||
newVal = Math.abs(Object.values(value)[0]) + newVal |
||||
countLoc++ |
||||
}) |
||||
oldVal = oldVal / listofNodes.length |
||||
newVal = newVal / listofNodes.length |
||||
outcome = oldVal - newVal |
||||
pushEach.push({keyIns: "round", valueIns: outcome}) |
||||
|
||||
var roundLogE = element.roundLogE |
||||
corrMatrixCombLoc.push(Object.values(JSON.parse(roundLogE[7]))) |
||||
corrMatrixCombTotalLoc.push(Object.values(JSON.parse(roundLogE[11]))[0] * 100) |
||||
VIFRemainingLoc.push(Object.values(JSON.parse(roundLogE[15]))[0]) |
||||
MIRemainingLoc.push(JSON.parse(roundLogE[19])) |
||||
roundLogE = JSON.parse(roundLogE[3]) |
||||
oldVal = 0 |
||||
newVal = 0 |
||||
outcome = 0 |
||||
countLoc = 0 |
||||
Object.entries(roundLogE).forEach( |
||||
function ([feature, value]) { |
||||
var key = Object.keys(value) |
||||
var search = Object.values(dataLoc[key]) |
||||
oldVal = Math.abs(search[countLoc]) + oldVal |
||||
newVal = Math.abs(Object.values(value)[0]) + newVal |
||||
countLoc++ |
||||
}) |
||||
oldVal = oldVal / listofNodes.length |
||||
newVal = newVal / listofNodes.length |
||||
outcome = oldVal - newVal |
||||
pushEach.push({keyIns: "roundLogE", valueIns: outcome}) |
||||
|
||||
var roundLog2 = element.roundLog2 |
||||
corrMatrixCombLoc.push(Object.values(JSON.parse(roundLog2[7]))) |
||||
corrMatrixCombTotalLoc.push(Object.values(JSON.parse(roundLog2[11]))[0] * 100) |
||||
VIFRemainingLoc.push(Object.values(JSON.parse(roundLog2[15]))[0]) |
||||
MIRemainingLoc.push(JSON.parse(roundLog2[19])) |
||||
roundLog2 = JSON.parse(roundLog2[3]) |
||||
oldVal = 0 |
||||
newVal = 0 |
||||
outcome = 0 |
||||
countLoc = 0 |
||||
Object.entries(roundLog2).forEach( |
||||
function ([feature, value]) { |
||||
var key = Object.keys(value) |
||||
var search = Object.values(dataLoc[key]) |
||||
oldVal = Math.abs(search[countLoc]) + oldVal |
||||
newVal = Math.abs(Object.values(value)[0]) + newVal |
||||
countLoc++ |
||||
}) |
||||
oldVal = oldVal / listofNodes.length |
||||
newVal = newVal / listofNodes.length |
||||
outcome = oldVal - newVal |
||||
pushEach.push({keyIns: "roundLog2", valueIns: outcome}) |
||||
|
||||
var roundLog10 = element.roundLog10 |
||||
corrMatrixCombLoc.push(Object.values(JSON.parse(roundLog10[7]))) |
||||
corrMatrixCombTotalLoc.push(Object.values(JSON.parse(roundLog10[11]))[0] * 100) |
||||
VIFRemainingLoc.push(Object.values(JSON.parse(roundLog10[15]))[0]) |
||||
MIRemainingLoc.push(JSON.parse(roundLog10[19])) |
||||
roundLog10 = JSON.parse(roundLog10[3]) |
||||
oldVal = 0 |
||||
newVal = 0 |
||||
outcome = 0 |
||||
countLoc = 0 |
||||
Object.entries(roundLog10).forEach( |
||||
function ([feature, value]) { |
||||
var key = Object.keys(value) |
||||
var search = Object.values(dataLoc[key]) |
||||
oldVal = Math.abs(search[countLoc]) + oldVal |
||||
newVal = Math.abs(Object.values(value)[0]) + newVal |
||||
countLoc++ |
||||
}) |
||||
oldVal = oldVal / listofNodes.length |
||||
newVal = newVal / listofNodes.length |
||||
outcome = oldVal - newVal |
||||
pushEach.push({keyIns: "roundLog10", valueIns: outcome}) |
||||
pushEachFinal.push({key: listofNodes[index], value: pushEach}) |
||||
}) |
||||
|
||||
this.corrMatrixComb = [...corrMatrixCombLoc] |
||||
this.corrMatrixCombTotal = [...corrMatrixCombTotalLoc] |
||||
this.VIFRemaining = [...VIFRemainingLoc] |
||||
this.MIRemaining = [...MIRemainingLoc] |
||||
|
||||
var nodes = [] |
||||
var groupID = 0 |
||||
listofNodes.forEach( function(element) { |
||||
groupID++ |
||||
nodes.push({"name": element, "group": groupID+"_root"}) |
||||
}) |
||||
|
||||
var links = [] |
||||
|
||||
Object.entries(dataLoc).forEach( |
||||
function ([feature, value]) { |
||||
Object.entries(value).forEach( function ([featureInside, value]) { |
||||
if (feature != featureInside) { |
||||
if (value >= 0) { |
||||
links.push({"source": listofNodes.indexOf(feature), "target": listofNodes.indexOf(featureInside), "value": Math.abs(value) * 30, "lin_color": "#D3D3D3"}) |
||||
} |
||||
} |
||||
}) |
||||
}) |
||||
|
||||
groupID = 0 |
||||
listofNodes.forEach( function(element) { |
||||
groupID++ |
||||
nodes.push( |
||||
{"name": element+"_r", "group": groupID}, |
||||
{"name": element+"_r_E", "group": groupID}, |
||||
{"name": element+"_r_2", "group": groupID}, |
||||
{"name": element+"_r_10", "group": groupID}, |
||||
) |
||||
}) |
||||
|
||||
Object.entries(pushEachFinal).forEach( |
||||
function ([index, feature]) { |
||||
feature.value.forEach(function (element, indexIns) { |
||||
if (element.valueIns > 0) { |
||||
links.push({"source": index, "target": index*feature.value.length+feature.value.length+indexIns, "value": Math.abs(element.valueIns) * 30, "lin_color": "#4393c3"}) |
||||
} |
||||
else { |
||||
links.push({"source": index, "target": index*feature.value.length+feature.value.length+indexIns, "value": Math.abs(element.valueIns) * 30, "lin_color": "#d6604d"}) |
||||
} |
||||
}) |
||||
}) |
||||
|
||||
this.jsonData = {"nodes": nodes, "links": links}; |
||||
|
||||
this.graphVizualization() |
||||
|
||||
}, |
||||
graphVizualization () { |
||||
|
||||
var computeNodesVar = this.computeNodes |
||||
|
||||
var listofNodes = this.dataFS4[0] |
||||
var uniqueTarget = JSON.parse(this.dataFS4[17]) |
||||
var corrTarget = JSON.parse(this.dataFS4[9]) |
||||
var corrGlob = JSON.parse(this.dataFS4[13]) |
||||
var VIFVar = JSON.parse(this.dataFS4[21]) |
||||
var MIVar = JSON.parse(this.dataFS4[25]) |
||||
MIVar = MIVar.concat(this.MIRemaining) |
||||
var colorCateg = d3.scaleOrdinal(d3.schemeAccent) |
||||
|
||||
var corrTargetFormatted = [] |
||||
for (let i = 0; i < Object.keys(corrTarget).length; i++) { |
||||
var corrTargetFormattedLoc = [] |
||||
for (let j = 0; j < Object.keys(corrTarget[i]).length; j++) { |
||||
if (j > uniqueTarget.length - 1) { |
||||
corrTargetFormattedLoc.push(Math.round(Object.values(corrTarget[i])[j] * 100)) |
||||
} |
||||
} |
||||
corrTargetFormatted.push(corrTargetFormattedLoc) |
||||
} |
||||
|
||||
for (let j = 0; j < uniqueTarget.length; j++) { |
||||
for (let i = 0; i < Object.keys(this.corrMatrixComb).length; i++) { |
||||
if (Math.round(Object.values((Object.values(this.corrMatrixComb[i])[j]))[0] * 100) == null) { |
||||
corrTargetFormatted[j].push(0) |
||||
} else { |
||||
corrTargetFormatted[j].push(Math.round(Object.values((Object.values(this.corrMatrixComb[i])[j]))[0] * 100)) |
||||
} |
||||
} |
||||
} |
||||
|
||||
var corrGlobFormatted = [] |
||||
for (let i = 0; i < Object.keys(corrGlob).length; i++) { |
||||
if (i != 0) { |
||||
corrGlobFormatted.push(Math.round(Object.values(corrGlob)[i]['0'] * 100)) |
||||
} |
||||
} |
||||
|
||||
for (let i = 0; i < this.corrMatrixCombTotal.length; i++) { |
||||
corrGlobFormatted.push(Math.round(this.corrMatrixCombTotal[i])) |
||||
} |
||||
|
||||
var VIFVarFormatted = [] |
||||
for (let i = 0; i < Object.keys(VIFVar).length; i++) { |
||||
if (i != 0) { |
||||
if (Object.values(VIFVar)[i] > 10) { |
||||
VIFVarFormatted.push(4) |
||||
} else if (Object.values(VIFVar)[i] > 5) { |
||||
VIFVarFormatted.push(2) |
||||
} else { |
||||
VIFVarFormatted.push(0) |
||||
} |
||||
} |
||||
} |
||||
|
||||
for (let i = 0; i < this.VIFRemaining.length; i++) { |
||||
if (this.VIFRemaining[i] > 10) { |
||||
VIFVarFormatted.push(4) |
||||
} else if (this.VIFRemaining[i] > 5) { |
||||
VIFVarFormatted.push(2) |
||||
} else { |
||||
VIFVarFormatted.push(0) |
||||
} |
||||
} |
||||
|
||||
function min(input) { |
||||
if (toString.call(input) !== "[object Array]") |
||||
return false; |
||||
return Math.min.apply(null, input); |
||||
} |
||||
|
||||
function max(input) { |
||||
if (toString.call(input) !== "[object Array]") |
||||
return false; |
||||
return Math.max.apply(null, input); |
||||
} |
||||
|
||||
function normalize(min, max) { |
||||
var delta = max - min; |
||||
return function (val) { |
||||
return (val - min) / delta; |
||||
}; |
||||
} |
||||
|
||||
var MIMin = min(MIVar) |
||||
var MIMax = max(MIVar) |
||||
|
||||
MIVar = MIVar.map(normalize(MIMin, MIMax)) |
||||
|
||||
var colorsScaleNodes = d3.scaleOrdinal() |
||||
.domain(d3.ticks([MIMin, MIMax, 10])) |
||||
.range(['#67001f','#b2182b','#d6604d','#f4a582','#fddbc7','#d1e5f0','#92c5de','#4393c3','#2166ac','#053061']); |
||||
|
||||
var svg = d3.select("#FeatureGraph4"); |
||||
svg.selectAll("*").remove(); |
||||
|
||||
var width = 1000; |
||||
var height = 500; |
||||
|
||||
var numTicks = 200; |
||||
|
||||
var selectedParams; |
||||
var bestParams; |
||||
|
||||
var dispatch = d3.dispatch('layoutend'); |
||||
|
||||
svg = d3.select("#FeatureGraph4").append("svg") |
||||
.attr("width", width) |
||||
.attr("height", height); |
||||
|
||||
var graph = this.jsonData |
||||
|
||||
var link = svg.append('g') |
||||
.attr('class', 'links') |
||||
.selectAll('line') |
||||
.data(graph.links) |
||||
.enter().append('line') |
||||
.attr("stroke", function(d) { return d.lin_color; }) |
||||
.attr("stroke-width", function(d) { return Math.sqrt(d.value); }); |
||||
|
||||
|
||||
var node = svg.append('g') |
||||
.attr('class', 'nodes') |
||||
.selectAll('g') |
||||
.data(graph.nodes) |
||||
.enter().append('g') |
||||
.on("click", function(id, index) { |
||||
var groupLoc = index + 1 |
||||
var items = document.getElementsByClassName(groupLoc) |
||||
items.forEach( function (it) { |
||||
if (it.style.visibility == "hidden") { |
||||
it.style.visibility = "visible"; |
||||
} else { |
||||
it.style.visibility = "hidden"; |
||||
} |
||||
}) |
||||
}); |
||||
|
||||
var paramGroups = [ |
||||
{name: 'chargeStrength', values: [-30, -80]}, |
||||
{name: 'linkDistance', values: [30, -80]}, |
||||
{name: 'linkStrength', values: [0, 1]}, |
||||
{name: 'gravity', values: [0, 0.5]}, |
||||
{name: 'iterations', values: [1, 2]}, |
||||
{name: 'alphaDecay', values: [0, 0.0228, 0.05]}, |
||||
{name: 'velocityDecay', values: [0.4, 0.8]} |
||||
]; |
||||
|
||||
var paramList = generateParams(paramGroups); |
||||
|
||||
var bestSoFar = d3.select('.best').selectAll('li') |
||||
.data(paramGroups.map(function (d) { return d.name; })) |
||||
.enter().append('li') |
||||
.text(function (d) { return d; }); |
||||
|
||||
dispatch.on('layoutend', function (params, i) { |
||||
if (!bestParams || params.graphReadability > bestParams.graphReadability) { |
||||
bestParams = params; |
||||
selectedParams = bestParams; |
||||
|
||||
bestSoFar |
||||
.data(d3.map(bestParams).keys().filter(function (d) { return d !== 'positions' && d !== 'graphReadability'; })) |
||||
.text(function (d) { return d + ' = ' + bestParams[d]; }); |
||||
} |
||||
|
||||
}); |
||||
|
||||
var i = 0; |
||||
var stepper = d3.timer(function () { |
||||
var p = paramList[i]; |
||||
var forceSim = getForceSimFromParams(p); |
||||
|
||||
// Reset node attributes. |
||||
graph.nodes.forEach(function (n) { |
||||
n.x = n.y = n.vx = n.vy = 0; |
||||
}); |
||||
|
||||
forceSim.nodes(graph.nodes) |
||||
.stop(); |
||||
|
||||
forceSim.force('link') |
||||
.links(graph.links); |
||||
|
||||
for (var t = 0; t < numTicks; ++t) { |
||||
forceSim.tick(); |
||||
} |
||||
|
||||
p.graphReadability = greadability.greadability(graph.nodes, graph.links); |
||||
p.graphReadability = (p.graphReadability.crossing + p.graphReadability.crossingAngle + |
||||
p.graphReadability.angularResolutionMin + p.graphReadability.angularResolutionDev) / 4 |
||||
|
||||
p.positions = graph.nodes.map(function (n) { return {x: n.x, y: n.y}; }); |
||||
|
||||
dispatch.call('layoutend', forceSim, p, i); |
||||
|
||||
++i; |
||||
if (i >= paramList.length) { |
||||
|
||||
var widthLoc = 100; |
||||
var arcSize = (6 * widthLoc / 100); |
||||
var innerRadius = arcSize * 2; |
||||
|
||||
var svgLoc = node.append('svg').attr('width', widthLoc).attr('height', widthLoc).attr("class", function(d, i) { return d.group; }) |
||||
.attr("id", function(d, i) { return "svg" + (i+computeNodesVar); }) |
||||
|
||||
graph.nodes.forEach(function(itemVal, indexNode) { |
||||
|
||||
var data = [] |
||||
|
||||
for(let k = 0; k < uniqueTarget.length; k++) { |
||||
data.push({value: corrTargetFormatted[k][indexNode], label: '', color: colorCateg(uniqueTarget[k]), lcolor: ''}) |
||||
} |
||||
|
||||
var length = data.length |
||||
data.push({value: 100, label: corrGlobFormatted[indexNode], color: '#000000', lcolor: colorsScaleNodes(MIVar[indexNode])}) |
||||
|
||||
|
||||
var border = VIFVarFormatted[indexNode] |
||||
|
||||
var arcs = data.map(function (obj, i) { |
||||
if (i == length) { |
||||
return d3.arc().innerRadius(i * arcSize + innerRadius).outerRadius((i + 1) * arcSize - (widthLoc / 100) + innerRadius + border); |
||||
} else { |
||||
return d3.arc().innerRadius(i * arcSize + innerRadius).outerRadius((i + 1) * arcSize - (widthLoc / 100) + innerRadius); |
||||
} |
||||
}); |
||||
|
||||
var arcsGrey = data.map(function (obj, i) { |
||||
return d3.arc().innerRadius(i * arcSize + (innerRadius + ((arcSize / 2) - 2))).outerRadius((i + 1) * arcSize - ((arcSize / 2)) + (innerRadius)); |
||||
}); |
||||
|
||||
var pieData = data.map(function (obj, i) { |
||||
return [ |
||||
{value: obj.value, arc: arcs[i], object: obj}, |
||||
{value: (100 - obj.value), arc: arcsGrey[i], object: obj}, |
||||
{value: 0, arc: arcs[i], object: obj}]; |
||||
}); |
||||
|
||||
var pie = d3.pie().sort(null).value(function (d) { |
||||
return d.value; |
||||
}); |
||||
|
||||
var id = indexNode + computeNodesVar |
||||
|
||||
var g = d3.select('#svg'+id).selectAll('g').data(pieData).enter() |
||||
.append('g') |
||||
.attr('transform', 'translate(' + widthLoc / 2 + ',' + widthLoc / 2 + ') rotate(180)'); |
||||
var gText = d3.select('#svg'+id).selectAll('g.textClass').data([{}]).enter() |
||||
.append('g') |
||||
.classed('textClass', true) |
||||
.attr('transform', 'translate(' + widthLoc / 2 + ',' + widthLoc / 2 + ') rotate(180)'); |
||||
|
||||
g.selectAll('path').data(function (d) { |
||||
return pie(d); |
||||
}).enter().append('path') |
||||
.attr('id', function (d, i) { |
||||
if (i == 1) { |
||||
return "Text" + d.data.object.label |
||||
} |
||||
}) |
||||
.attr('d', function (d) { |
||||
return d.data.arc(d); |
||||
}).attr('fill', function (d, i) { |
||||
return i == 0 ? d.data.object.color : i == 1 ? '#D3D3D3' : 'none'; |
||||
}); |
||||
|
||||
g.each(function (d, index) { |
||||
|
||||
var el = d3.select(this); |
||||
var path = el.selectAll('path').each(function (r, i) { |
||||
if (i === 1) { |
||||
var centroid = r.data.arc.centroid({ |
||||
startAngle: r.startAngle + 0.05, |
||||
endAngle: r.startAngle + 0.001 + 0.05 |
||||
}); |
||||
var lableObj = r.data.object; |
||||
g.append('text') |
||||
.attr('font-size', ((2 * width) / 100)) |
||||
.attr('dominant-baseline', 'central') |
||||
.append("textPath") |
||||
.attr("textLength", function (d, i) { |
||||
return 0; |
||||
}) |
||||
.attr("startOffset", '5') |
||||
.attr("dy", '-3em') |
||||
.text(lableObj.value + '%'); |
||||
} |
||||
if (i === 0) { |
||||
var centroidText = r.data.arc.centroid({ |
||||
startAngle: r.startAngle, |
||||
endAngle: r.startAngle |
||||
}); |
||||
var lableObj = r.data.object; |
||||
gText.append('text') |
||||
.attr('font-size', ((2 * width) / 100)) |
||||
.text(lableObj.label) |
||||
.style('fill', lableObj.lcolor) |
||||
.attr('transform', "translate(" + (10) + "," + (0 + ") rotate(" + (180) + ")")) |
||||
.attr('dominant-baseline', 'central'); |
||||
} |
||||
}); |
||||
|
||||
}); |
||||
|
||||
}) |
||||
|
||||
var drag_handler = d3.drag() |
||||
.on("start", drag_start) |
||||
.on("drag", drag_drag) |
||||
.on("end", drag_end); |
||||
|
||||
drag_handler(node); |
||||
|
||||
var labels = node.append("text") |
||||
.text(function(d) { |
||||
return d.name; |
||||
}) |
||||
.attr('x', 20) |
||||
.attr('y', 8); |
||||
|
||||
node.append('title').text(function (d) { return d.name; }); |
||||
|
||||
//add zoom capabilities |
||||
var zoom_handler = d3.zoom() |
||||
.on("zoom", zoom_actions); |
||||
|
||||
zoom_handler(svg); |
||||
|
||||
drawGraph(); |
||||
|
||||
for (let i = 0; i < listofNodes.length; i++) { |
||||
var numb = graph.nodes[i]['group'].match(/\d/g) |
||||
numb = parseInt(numb.join("")) |
||||
var items = document.getElementsByClassName(numb) |
||||
items.forEach( function (it) { |
||||
it.style.visibility = "hidden"; |
||||
}) |
||||
} |
||||
|
||||
//Zoom functions |
||||
function zoom_actions(){ |
||||
svg.attr("transform", d3.event.transform) |
||||
} |
||||
|
||||
function drag_start(d) { |
||||
if (!d3.event.active) forceSim.alphaTarget(0.3).restart(); |
||||
d.fx = d.x; |
||||
d.fy = d.y; |
||||
} |
||||
|
||||
//make sure you can't drag the circle outside the box |
||||
function drag_drag(d) { |
||||
d.fx = d3.event.x; |
||||
d.fy = d3.event.y; |
||||
tickActions(); |
||||
} |
||||
|
||||
function drag_end(d) { |
||||
if (!d3.event.active) forceSim.alphaTarget(0); |
||||
d.fx = null; |
||||
d.fy = null; |
||||
} |
||||
|
||||
stepper.stop(); |
||||
} |
||||
|
||||
}); |
||||
|
||||
function tickActions() { |
||||
link |
||||
.attr('x1', function (d) { return d.source.x; }) |
||||
.attr('x2', function (d) { return d.target.x; }) |
||||
.attr('y1', function (d) { return d.source.y; }) |
||||
.attr('y2', function (d) { return d.target.y; }); |
||||
|
||||
node |
||||
.attr("id", function(d, i) { return "g" + (i+computeNodesVar); }) |
||||
.attr("transform", function(d, i) { |
||||
d.x = d.x - 50 |
||||
d.y = d.y - 50 |
||||
return "translate(" + d.x + "," + d.y + ")"; |
||||
}) |
||||
}; |
||||
|
||||
function drawGraph () { |
||||
graph.nodes.forEach(function (n, i) { |
||||
n.x = selectedParams.positions[i].x; |
||||
n.y = selectedParams.positions[i].y; |
||||
}); |
||||
|
||||
var xDistance = d3.extent(graph.nodes, function (n) { return n.x; }); |
||||
var xMin = xDistance[0]; |
||||
xDistance = xDistance[1] - xDistance[0]; |
||||
|
||||
var yDistance = d3.extent(graph.nodes, function (n) { return n.y; }); |
||||
var yMin = yDistance[0]; |
||||
yDistance = yDistance[1] - yDistance[0]; |
||||
|
||||
graph.nodes.forEach(function (n, i) { |
||||
n.x = (height - 10) * (n.x - xMin) / Math.max(xDistance, yDistance); |
||||
n.y = (height - 10) * (n.y - yMin) / Math.max(xDistance, yDistance); |
||||
}); |
||||
|
||||
xDistance = d3.extent(graph.nodes, function (n) { return n.x; }); |
||||
var xMid = (xDistance[1] + xDistance[0]) / 2; |
||||
yDistance = d3.extent(graph.nodes, function (n) { return n.y; }); |
||||
var yMid = (yDistance[1] - yDistance[0]) / 2; |
||||
|
||||
graph.nodes.forEach(function (n, i) { |
||||
n.x = n.x + width/2 - xMid; |
||||
n.y = n.y + height/2 - yMid; |
||||
}); |
||||
|
||||
tickActions(); |
||||
} |
||||
|
||||
function generateParams (paramGroups, paramList, currParam) { |
||||
var p = paramGroups[0]; |
||||
|
||||
if (!paramList) paramList = []; |
||||
|
||||
if (!currParam) currParam = {}; |
||||
|
||||
p.values.forEach(function (v) { |
||||
var setting = {}; |
||||
setting[p.name] = v; |
||||
if (paramGroups.length === 1) { |
||||
paramList.push(Object.assign(setting, currParam)); |
||||
} else { |
||||
generateParams(paramGroups.slice(1), paramList, Object.assign(setting, currParam)); |
||||
} |
||||
}); |
||||
|
||||
return paramList; |
||||
} |
||||
|
||||
function getForceSimFromParams (params) { |
||||
var forceSim = d3.forceSimulation() |
||||
.force('link', d3.forceLink().iterations(params.iterations)) |
||||
.force('charge', d3.forceManyBody().strength(params.chargeStrength)) |
||||
.force('x', d3.forceX(0).strength(params.gravity)) |
||||
.force('y', d3.forceY(0).strength(params.gravity)) |
||||
.force('center', d3.forceCenter(0, 0)) |
||||
.alphaDecay(params.alphaDecay) |
||||
.velocityDecay(params.velocityDecay); |
||||
|
||||
if (params.linkStrength !== null) { |
||||
forceSim.force('link').strength(params.linkStrength); |
||||
} |
||||
|
||||
return forceSim; |
||||
} |
||||
|
||||
}, |
||||
reset () { |
||||
var svg = d3.select("#FeatureGraph4"); |
||||
svg.selectAll("*").remove(); |
||||
}, |
||||
}, |
||||
mounted () { |
||||
EventBus.$on('quadTrans4', data => { this.dataFS4Trans = data }) |
||||
EventBus.$on('quad4', data => { this.dataFS4 = data }) |
||||
EventBus.$on('quad4', this.initializeNetwork) |
||||
EventBus.$on('countNodes3', data => { this.computeNodes = data }) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style> |
||||
|
||||
text { |
||||
font-family: sans-serif; |
||||
} |
||||
|
||||
svg { |
||||
display: block; |
||||
} |
||||
|
||||
.links line { |
||||
stroke-opacity: 0.6; |
||||
} |
||||
|
||||
.column { |
||||
float: left; |
||||
margin: 0 10px; |
||||
} |
||||
|
||||
</style> |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,595 @@ |
||||
<template> |
||||
<div> |
||||
<div id="Heatmap"></div> |
||||
<div id="LegendHeat" style="margin-left: 280px"></div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import * as d3Base from 'd3' |
||||
import { EventBus } from '../main.js' |
||||
import $ from 'jquery' |
||||
import * as colorbr from 'colorbrewer' |
||||
|
||||
// attach all d3 plugins to the d3 library |
||||
const d3 = Object.assign(d3Base) |
||||
const colorbrewer = Object.assign(colorbr) |
||||
|
||||
export default { |
||||
name: "Heatmap", |
||||
data () { |
||||
return { |
||||
GetResultsAll: '', |
||||
Toggles: '', |
||||
limitation: 0, |
||||
flag: false, |
||||
classesNumber: 10, |
||||
cellSize: 20, |
||||
ModelsIDHeatStack: [], |
||||
highlighted: [], |
||||
responsiveWidthHeight: [], |
||||
FeaturesAccuracyStore: [], |
||||
FeaturesStore: [], |
||||
PermImpEliStore: [], |
||||
featureUniStore: [], |
||||
modelIdsStore: [], |
||||
keyLocal: 0, |
||||
activeModels: 0, |
||||
flagLocal: false, |
||||
smallScreenMode: '0px' |
||||
} |
||||
}, |
||||
methods: { |
||||
Refresh () { |
||||
if (this.flagLocal) { |
||||
var tempFeatures = this.FeaturesStore.slice(this.activeModels,this.activeModels+1)[0] |
||||
var tempFeaturesTable = [] |
||||
var FeatureTemp = [] |
||||
var tempModelIds = this.modelIdsStore.slice(this.activeModels,this.activeModels+1)[0] |
||||
for (let i = 0; i < tempFeatures.length; i++) { |
||||
tempFeaturesTable.push(i) |
||||
} |
||||
for (let i = 0; i < tempModelIds.length; i++) { |
||||
FeatureTemp.push(tempFeaturesTable) |
||||
} |
||||
EventBus.$emit('SendSelectedFeaturesEvent', FeatureTemp) |
||||
} |
||||
}, |
||||
reset () { |
||||
var svg = d3.select("#Heatmap"); |
||||
svg.selectAll("*").remove(); |
||||
var svgLeg = d3.select("#LegendHeat"); |
||||
svgLeg.selectAll("*").remove(); |
||||
}, |
||||
Heatmap () { |
||||
// Clear Heatmap first |
||||
var svg = d3.select("#Heatmap"); |
||||
svg.selectAll("*").remove(); |
||||
|
||||
var dataAll = {"columns":[["R","F1"],["R","F2"],["R","F2"],["R","F1&F2"],["R","F2&F3"],["R","F1&F3"],["R","F1&F2&F3"],["R","F1+F2"],["R","F2+F3"],["R","F1+F3"],["R","F1+F2+F3"],["R","F1-F2"],["R","F2-F3"],["R","F1-F3"],["R","F1-F2-F3"],["R","F1*F2"],["R","F2*F3"],["R","F1*F3"],["R","F1*F2*F3"],["R","F1/F2"],["R","F2/F3"],["R","F1/F3"],["R","F1/F2/F3"]],"index":[["Information Gain"],["Fisher-Score"],["Relative Risk"],["Odds Ratio"]],"data":[[0.1178,0.4834,0.1647,0.1633,0.3355,0.1353,0.0556,0.9388,0.9354,0.8548,0.7037,0.6092,0.3835,0.7285,0.6405,0.424,0.6935,0.5766,0.2275,0.8309,0.972,0.9439,0.9366],[0.0372,-0.09,0.5015,0.5663,0.5126,-0.0274,0.4304,0.9518,0.9499,0.9216,-0.0278,0.6516,0.3019,-0.0936,0.6597,0.2323,-0.0833,0.4921,0.122,0.9275,0.96095,0.955,0.9501],[0.378,0.5514,0.378,0.3929,0.3271,0.3816,0.3647,0.9303,0.9372,0.8356,0.5314,0.4069,0.4288,0.5496,0.4156,0.427,0.5299,0.3454,0.4511,0.88235,0.9705,0.9468,0.9405],[0.4988,0.4149,0.5952,0.0628,-0.1015,0.497,0.58,0.9531,0.9572,0.8494,0.6262,0.3854,0.6904,0.5711,0.346,0.5132,0.583,0.3917,0.5305,0.7074,0.9763,0.9632,0.9582]]} |
||||
this.heatmap_display(dataAll, "#Heatmap"); |
||||
|
||||
}, |
||||
heatmap_display(data, heatmapId) { |
||||
var cellSize = this.cellSize |
||||
//########################################################################## |
||||
// Patrick.Brockmann@lsce.ipsl.fr |
||||
//########################################################################## |
||||
|
||||
//================================================== |
||||
// References |
||||
// http://bl.ocks.org/Soylent/bbff6cc507dca2f48792 |
||||
// http://bost.ocks.org/mike/selection/ |
||||
// http://bost.ocks.org/mike/join/ |
||||
// http://stackoverflow.com/questions/9481497/understanding-how-d3-js-binds-data-to-nodes |
||||
// http://bost.ocks.org/mike/miserables/ |
||||
// http://bl.ocks.org/ianyfchang/8119685 |
||||
|
||||
//================================================== |
||||
var tooltip = d3.select(heatmapId) |
||||
.append("div") |
||||
.style("position", "absolute") |
||||
.style("visibility", "hidden"); |
||||
// define the zoomListener which calls the zoom function on the "zoom" event constrained within the scaleExtents |
||||
const zoom = d3.zoom() |
||||
.scaleExtent([0.1, 3]) //zoom limit |
||||
.on('zoom', () => { |
||||
svg.attr('transform', d3.event.transform) // updated for d3 v4 |
||||
}) |
||||
|
||||
//================================================== |
||||
|
||||
|
||||
|
||||
var viewerWidth = 1250 |
||||
var viewerHeight = 180 |
||||
var widthHeatmap = 1250 |
||||
|
||||
var viewerPosTop = viewerHeight * 0.05; |
||||
var viewerPosTopHeat = viewerHeight * 0.15; |
||||
var viewerPosLeft = viewerWidth*0.1; |
||||
|
||||
var legendElementWidth = cellSize * 3; |
||||
|
||||
// http://bl.ocks.org/mbostock/5577023 |
||||
var colors = colorbrewer.RdYlGn[this.classesNumber]; |
||||
|
||||
// http://bl.ocks.org/mbostock/3680999 |
||||
var svg; |
||||
|
||||
//================================================== |
||||
var arr = data.data; |
||||
var row_number = arr.length; |
||||
var col_number = arr[0].length; |
||||
|
||||
var colorScale = d3.scaleQuantize() |
||||
.domain([0.0, 1.0]) |
||||
.range(colors); |
||||
|
||||
svg = d3.select(heatmapId).append("svg") |
||||
.attr("width", viewerWidth) |
||||
.attr("height", viewerHeight) |
||||
.call(zoom) |
||||
//.call(zoom.transform, d3.zoomIdentity.translate(200, 20).scale(0.25)) //initial size |
||||
.append('svg:g') |
||||
.attr("transform", "translate(" + viewerPosLeft + "," + viewerPosTopHeat + ")"); |
||||
|
||||
svg.append('defs') |
||||
.append('pattern') |
||||
.attr('id', 'diagonalHatch') |
||||
.attr('patternUnits', 'userSpaceOnUse') |
||||
.attr('width', 4) |
||||
.attr('height', 4) |
||||
.append('path') |
||||
.attr('d', 'M-1,1 l2,-2 M0,4 l4,-4 M3,5 l2,-2') |
||||
.attr('stroke', '#000000') |
||||
.attr('stroke-width', 1); |
||||
|
||||
var rowSortOrder = false; |
||||
var colSortOrder = false; |
||||
|
||||
var rowLabels = svg.append("g") |
||||
.attr("class", "rowLabels") |
||||
.selectAll(".rowLabel") |
||||
.data(data.index) |
||||
.enter().append("text") |
||||
.text(function(d) { |
||||
return d.count > 1 ? d.join("/") : d; |
||||
}) |
||||
.attr("x", 0) |
||||
.attr("y", function(d, i) { |
||||
return (i * cellSize); |
||||
}) |
||||
.style("text-anchor", "end") |
||||
.attr("transform", function(d, i) { |
||||
return "translate(-3," + cellSize / 1.5 + ")"; |
||||
}) |
||||
.attr("class", "rowLabel mono") |
||||
.attr("id", function(d, i) { |
||||
return "rowLabel_" + i; |
||||
}) |
||||
.on('mouseover', function(d, i) { |
||||
d3.select('#rowLabel_' + i).classed("hover", true); |
||||
}) |
||||
.on('mouseout', function(d, i) { |
||||
d3.select('#rowLabel_' + i).classed("hover", false); |
||||
}) |
||||
.on("click", function(d, i) { |
||||
rowSortOrder = !rowSortOrder; |
||||
sortByValues("r", i, rowSortOrder); |
||||
d3.select("#order").property("selectedIndex", 0); |
||||
//$("#order").jqxComboBox({selectedIndex: 0}); |
||||
}); |
||||
|
||||
var colLabels = svg.append("g") |
||||
.attr("class", "colLabels") |
||||
.selectAll(".colLabel") |
||||
.data(data.columns) |
||||
.enter().append("text") |
||||
.text(function(d) { |
||||
d.shift(); |
||||
return d.count > 1 ? d.reverse().join("/") : d.reverse(); |
||||
}) |
||||
.attr("x", 0) |
||||
.attr("y", function(d, i) { |
||||
return (i * cellSize); |
||||
}) |
||||
.style("text-anchor", "left") |
||||
.style('font-weight',function(d,i){ |
||||
/*if (d[0] === "Average") { |
||||
return "bold" |
||||
}*/ |
||||
}) |
||||
.attr("transform", function(d, i) { |
||||
return "translate(" + cellSize / 2 + ", -3) rotate(-90) rotate(45, 0, " + (i * cellSize) + ")"; |
||||
}) |
||||
.attr("class", "colLabel mono") |
||||
.attr("id", function(d, i) { |
||||
return "colLabel_" + i; |
||||
}) |
||||
.on('mouseover', function(d, i) { |
||||
d3.select('#colLabel_' + i).classed("hover", true); |
||||
}) |
||||
.on('mouseout', function(d, i) { |
||||
d3.select('#colLabel_' + i).classed("hover", false); |
||||
}) |
||||
.on("click", function(d, i) { |
||||
colSortOrder = !colSortOrder; |
||||
sortByValues("c", i, colSortOrder); |
||||
d3.select("#order").property("selectedIndex", 0); |
||||
}); |
||||
|
||||
var row = svg.selectAll(".row") |
||||
.data(data.data) |
||||
.enter().append("g") |
||||
.attr("id", function(d) { |
||||
return d.idx; |
||||
}) |
||||
.attr("class", "row"); |
||||
svg.append("text").attr("x", 150).attr("y", -40).text("Feature combination").style("font-size", "16px").attr("alignment-baseline","top") |
||||
svg.append("text").attr("transform", "rotate(-90)").attr("x", -42).attr("y", -90).style("text-anchor", "middle").style("font-size", "16px").text("Algorithm"); // -130 before for HeartC |
||||
var heatMap = row.selectAll(".cell") |
||||
.data(function(d) { |
||||
return d; |
||||
}) |
||||
.enter().append("svg:rect") |
||||
.attr("id", function(d, i, j){ |
||||
var k = Array.prototype.indexOf.call(j[i].parentNode.parentNode.childNodes,j[i].parentNode) - 3; |
||||
return k.toString()+i.toString(); |
||||
}) |
||||
.attr("x", function(d, i) { |
||||
return i * cellSize; |
||||
}) |
||||
.attr("y", function(d, i, j) { |
||||
var k = Array.prototype.indexOf.call(j[i].parentNode.parentNode.childNodes,j[i].parentNode) - 3; |
||||
return k * cellSize; |
||||
}) |
||||
.attr("rx", 4) |
||||
.attr("ry", 4) |
||||
.attr("class", function(d, i, j) { |
||||
var k = Array.prototype.indexOf.call(j[i].parentNode.parentNode.childNodes,j[i].parentNode) - 3; |
||||
return "cell bordered cr" + k + " cc" + i; |
||||
}) |
||||
.attr("row", function(d, i, j) { |
||||
var k = Array.prototype.indexOf.call(j[i].parentNode.parentNode.childNodes,j[i].parentNode) - 3; |
||||
return k; |
||||
}) |
||||
.attr("col", function(d, i, j) { |
||||
return i; |
||||
}) |
||||
.attr("width", cellSize) |
||||
.attr("height", cellSize) |
||||
.style("fill", function(d) { |
||||
if (d != null) return colorScale(d); |
||||
else return "url(#diagonalHatch)"; |
||||
}) |
||||
.on('mouseover', function(d, i, j) { |
||||
var k = Array.prototype.indexOf.call(j[i].parentNode.parentNode.childNodes,j[i].parentNode) - 3; |
||||
d3.select('#colLabel_' + i).classed("hover", true); |
||||
d3.select('#rowLabel_' + k).classed("hover", true); |
||||
if (d != null) { |
||||
tooltip.style("visibility", "visible"); |
||||
tooltip.html('<div class="heatmap_tooltip">' + d.toFixed(2) + '</div>'); |
||||
} else |
||||
tooltip.style("visibility", "hidden"); |
||||
}) |
||||
.on('mouseout', function(d, i, j) { |
||||
var k = Array.prototype.indexOf.call(j[i].parentNode.parentNode.childNodes,j[i].parentNode) - 3; |
||||
d3.select('#colLabel_' + i).classed("hover", false); |
||||
d3.select('#rowLabel_' + k).classed("hover", false); |
||||
tooltip.style("visibility", "hidden"); |
||||
}) |
||||
.on("mousemove", function(d, i) { |
||||
tooltip.style("top", (d3.mouse(this)[1] + 55) + "px").style("left", (d3.mouse(this)[0]) + "px"); |
||||
}) |
||||
.on('click', function(d, i, j) { |
||||
var rowsExtracted = svg.selectAll(".row")._groups[0] |
||||
var k = Array.prototype.indexOf.call(j[i].parentNode.parentNode.childNodes,j[i].parentNode) - 3; |
||||
d3.select(this).style("fill", function(d) { |
||||
if (d3.select(this).style("fill") === "url(\"#diagonalHatch\")"){ |
||||
return colorScale(d) |
||||
} else { |
||||
return "url(#diagonalHatch)" |
||||
} |
||||
}) |
||||
if (i+1 === j.length) { |
||||
if(d3.select(this).style("fill") === "url(\"#diagonalHatch\")") { |
||||
row.selectAll(".cr"+k).style("fill", "url(#diagonalHatch)") |
||||
} else { |
||||
row.selectAll(".cr"+k).style("fill", function(d) { |
||||
return colorScale(d) |
||||
}) |
||||
} |
||||
} |
||||
var finalresults = [] |
||||
for (let i = 0; i < rowsExtracted[0].childNodes.length - 1; i++) { |
||||
var results = [] |
||||
for (let j = 0; j < rowsExtracted.length; j++) { |
||||
if (rowsExtracted[j].childNodes[i].style.fill === "url(\"#diagonalHatch\")") { |
||||
} else { |
||||
results.push(j) |
||||
} |
||||
} |
||||
finalresults.push(results) |
||||
} |
||||
EventBus.$emit('flagLocal', true) |
||||
EventBus.$emit('sendSelectedFeaturestoPickle', finalresults) |
||||
EventBus.$emit('SendSelectedFeaturesEvent', finalresults) |
||||
}); |
||||
|
||||
var svgLeg = d3.select("#LegendHeat"); |
||||
svgLeg.selectAll("*").remove(); |
||||
|
||||
var svgLeg = d3.select("#LegendHeat").append("svg") |
||||
.attr("width", widthHeatmap) |
||||
.attr("height", viewerHeight*0.3) |
||||
|
||||
var legend = svgLeg.append('g') |
||||
.attr("class", "legend") |
||||
.attr("transform", "translate(0,0)") |
||||
.selectAll(".legendElement") |
||||
.data([0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]) |
||||
.enter().append("g") |
||||
.attr("class", "legendElement"); |
||||
|
||||
legend.append("svg:rect") |
||||
.attr("x", function(d, i) { |
||||
return legendElementWidth * i; |
||||
}) |
||||
.attr("y", viewerPosTop) |
||||
.attr("class", "cellLegend bordered") |
||||
.attr("width", legendElementWidth) |
||||
.attr("height", cellSize / 2) |
||||
.style("fill", function(d, i) { |
||||
return colors[i]; |
||||
}); |
||||
|
||||
legend.append("text") |
||||
.attr("class", "mono legendElement") |
||||
.text(function(d) { |
||||
return "≥" + Math.round(d * 100) / 100; |
||||
}) |
||||
.attr("x", function(d, i) { |
||||
return legendElementWidth * i; |
||||
}) |
||||
.attr("y", viewerPosTop + cellSize); |
||||
|
||||
svgLeg.append("text").attr("x", 200).attr("y", 50).text("Normalized feature importance").style("font-size", "16px").attr("alignment-baseline","top") |
||||
|
||||
//================================================== |
||||
// Change ordering of cells |
||||
function sortByValues(rORc, i, sortOrder) { |
||||
var t = svg.transition().duration(1000); |
||||
var values = []; |
||||
var sorted; |
||||
d3.selectAll(".c" + rORc + i) |
||||
.filter(function(d) { |
||||
if (d != null) values.push(d); |
||||
else values.push(-999); // to handle NaN |
||||
}); |
||||
if (rORc == "r") { // sort on cols |
||||
sorted = d3.range(col_number).sort(function(a, b) { |
||||
if (sortOrder) { |
||||
return values[b] - values[a]; |
||||
} else { |
||||
return values[a] - values[b]; |
||||
} |
||||
}); |
||||
t.selectAll(".cell") |
||||
.attr("x", function(d) { |
||||
var col = parseInt(d3.select(this).attr("col")); |
||||
return sorted.indexOf(col) * cellSize; |
||||
}); |
||||
t.selectAll(".colLabel") |
||||
.attr("y", function(d, i) { |
||||
return sorted.indexOf(i) * cellSize; |
||||
}) |
||||
.attr("transform", function(d, i) { |
||||
return "translate(" + cellSize / 2 + ", -3) rotate(-90) rotate(45, 0, " + (sorted.indexOf(i) * cellSize) + ")"; |
||||
}); |
||||
} else { // sort on rows |
||||
sorted = d3.range(row_number).sort(function(a, b) { |
||||
if (sortOrder) { |
||||
return values[b] - values[a]; |
||||
} else { |
||||
return values[a] - values[b]; |
||||
} |
||||
}); |
||||
t.selectAll(".cell") |
||||
.attr("y", function(d) { |
||||
var row = parseInt(d3.select(this).attr("row")); |
||||
return sorted.indexOf(row) * cellSize; |
||||
}); |
||||
t.selectAll(".rowLabel") |
||||
.attr("y", function(d, i) { |
||||
return sorted.indexOf(i) * cellSize; |
||||
}) |
||||
.attr("transform", function(d, i) { |
||||
return "translate(-3," + cellSize / 1.5 + ")"; |
||||
}); |
||||
} |
||||
} |
||||
|
||||
//================================================== |
||||
d3.select("#order").on("change", function() { |
||||
var newOrder = d3.select("#order").property("value"); |
||||
this.changeOrder(newOrder, heatmapId); |
||||
}); |
||||
|
||||
//================================================== |
||||
d3.select("#palette") |
||||
.on("keyup", function() { |
||||
var newPalette = d3.select("#palette").property("value"); |
||||
if (newPalette != null) // when interfaced with jQwidget, the ComboBox handles keyup event but value is then not available ? |
||||
this.changePalette(newPalette, heatmapId); |
||||
}) |
||||
.on("change", function() { |
||||
var newPalette = d3.select("#palette").property("value"); |
||||
this.changePalette(newPalette, heatmapId); |
||||
}); |
||||
|
||||
//================================================== |
||||
}, |
||||
changeOrder(newOrder, heatmapId) { |
||||
var svg = d3.select(heatmapId); |
||||
var cellSize = this.cellSize |
||||
var t = svg.transition().duration(1000); |
||||
if (newOrder == "sortinit_col") { // initial sort on cols (alphabetically if produced like this) |
||||
t.selectAll(".cell") |
||||
.attr("x", function(d) { |
||||
var col = parseInt(d3.select(this).attr("col")); |
||||
return col * cellSize; |
||||
}); |
||||
t.selectAll(".colLabel") |
||||
.attr("y", function(d, i) { |
||||
return i * cellSize; |
||||
}) |
||||
.attr("transform", function(d, i) { |
||||
return "translate(" + cellSize / 2 + ", -3) rotate(-90) rotate(45, 0, " + (i * cellSize) + ")"; |
||||
}); |
||||
} else if (newOrder == "sortinit_row") { // initial sort on rows (alphabetically if produced like this) |
||||
t.selectAll(".cell") |
||||
.attr("y", function(d) { |
||||
var row = parseInt(d3.select(this).attr("row")); |
||||
return row * cellSize; |
||||
}); |
||||
t.selectAll(".rowLabel") |
||||
.attr("y", function(d, i) { |
||||
return i * cellSize; |
||||
}) |
||||
.attr("transform", function(d, i) { |
||||
return "translate(-3," + cellSize / 1.5 + ")"; |
||||
}); |
||||
} else if (newOrder == "sortinit_col_row") { // initial sort on rows and cols (alphabetically if produced like this) |
||||
t.selectAll(".cell") |
||||
.attr("x", function(d) { |
||||
var col = parseInt(d3.select(this).attr("col")); |
||||
return col * cellSize; |
||||
}) |
||||
.attr("y", function(d) { |
||||
var row = parseInt(d3.select(this).attr("row")); |
||||
return row * cellSize; |
||||
}); |
||||
t.selectAll(".colLabel") |
||||
.attr("y", function(d, i) { |
||||
return i * cellSize; |
||||
}) |
||||
.attr("transform", function(d, i) { |
||||
return "translate(" + cellSize / 2 + ", -3) rotate(-90) rotate(45, 0, " + (i * cellSize) + ")"; |
||||
}); |
||||
t.selectAll(".rowLabel") |
||||
.attr("y", function(d, i) { |
||||
return i * cellSize; |
||||
}) |
||||
.attr("transform", function(d, i) { |
||||
return "translate(-3," + cellSize / 1.5 + ")"; |
||||
}); |
||||
} |
||||
}, |
||||
reset () { |
||||
var svg = d3.select("#Heatmap"); |
||||
svg.selectAll("*").remove(); |
||||
}, |
||||
brush () { |
||||
var columnLabels = document.getElementsByClassName('colLabels')[0]; |
||||
var modelIds = JSON.parse(this.GetResultsAll[13]) |
||||
|
||||
var selectedIds = [] |
||||
for (let i = 0; i < this.highlighted.length; i++) { |
||||
let looping = this.highlighted[i] |
||||
selectedIds.push(looping) |
||||
} |
||||
for (let i = 0; i < modelIds.length; i++) { |
||||
columnLabels.childNodes[i].style.fill = "#000"; |
||||
} |
||||
for (let i = 0; i < selectedIds.length; i++) { |
||||
let index = modelIds.indexOf(selectedIds[i]) |
||||
columnLabels.childNodes[index].style.fill = "#AF4427"; |
||||
} |
||||
} |
||||
}, |
||||
mounted () { |
||||
this.Heatmap() |
||||
EventBus.$on('reset', this.reset) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style> |
||||
.heatmap { |
||||
font-size: 8px; |
||||
font-family: monospace; |
||||
} |
||||
rect.bordered { |
||||
stroke: #E6E6E6; |
||||
stroke-width:2px; |
||||
} |
||||
text.mono { |
||||
font-size: 8px; |
||||
font-family: monospace; |
||||
fill: #000; |
||||
} |
||||
text.legendElement { |
||||
font-size: 10px; |
||||
} |
||||
text.hover { |
||||
font-weight: bold; |
||||
fill: #66F; |
||||
font-background: #000; |
||||
} |
||||
.heatmap_tooltip { |
||||
text-align: center; |
||||
font-family: monospace; |
||||
font-size: 14pt; |
||||
color: #000; |
||||
position: relative; |
||||
background: rgba(255, 255, 255, 0.8); |
||||
border: 4px solid #66F; |
||||
padding: 5px; |
||||
border-radius: 8px ; |
||||
-webkit-border-top-left-radius: 8px; |
||||
-webkit-border-top-right-radius: 8px; |
||||
-webkit-border-bottom-right-radius: 8px; |
||||
-webkit-border-bottom-left-radius: 8px; |
||||
-khtml-border-top-left-radius: 8px; |
||||
-khtml-border-top-right-radius: 8px; |
||||
-khtml-border-bottom-right-radius: 8px; |
||||
-khtml-border-bottom-left-radius: 8px; |
||||
-moz-border-radius-topleft: 8px; |
||||
-moz-border-radius-topright: 8px; |
||||
-moz-border-radius-bottomright: 8px; |
||||
-moz-border-radius-bottomleft: 8px; |
||||
border-top-left-radius: 8px; |
||||
border-top-right-radius: 8px; |
||||
border-bottom-right-radius: 8px; |
||||
border-bottom-left-radius: 8px; |
||||
width: 100px; |
||||
z-index:10000; |
||||
-webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.8); |
||||
-moz-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.8); |
||||
box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.8); |
||||
} |
||||
.heatmap_tooltip:after, .heatmap_tooltip:before { |
||||
top: 100%; |
||||
border: solid transparent; |
||||
content: " "; |
||||
height: 0; |
||||
width: 0; |
||||
position: absolute; |
||||
pointer-events: none; |
||||
} |
||||
.heatmap_tooltip:after { |
||||
border-color: rgba(236, 240, 241, 0); |
||||
border-top-color: #FFFFF; |
||||
border-width: 10px; |
||||
left: 50%; |
||||
margin-left: -10px; |
||||
} |
||||
.heatmap_tooltip:before { |
||||
border-color: rgba(44, 62, 80, 0); |
||||
border-top-color: #66F; |
||||
border-width: 16px; |
||||
left: 50%; |
||||
margin-left: -16px; |
||||
} |
||||
</style> |
@ -0,0 +1,141 @@ |
||||
<template> |
||||
<div id="LinePlot"></div> |
||||
</template> |
||||
|
||||
<script> |
||||
|
||||
import { EventBus } from '../main.js' |
||||
import * as Plotly from 'plotly.js' |
||||
|
||||
export default { |
||||
name: 'Results', |
||||
data () { |
||||
return { |
||||
dataInstances: '', |
||||
PositiveValue: 75, |
||||
NegativeValue: 25, |
||||
} |
||||
}, |
||||
methods: { |
||||
initializeLinePLot () { |
||||
|
||||
Plotly.purge('LinePlot') |
||||
|
||||
var trace1 = { |
||||
x: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1], |
||||
y: [12, 22, 32, 45, 56, 67, 77, 89, 98, 100, 99, 88, 78, 66, 55, 44, 33, 23, 18, 8], |
||||
fill: "tozerox", |
||||
fillcolor: "rgba(0,100,80,0.2)", |
||||
line: {color: "transparent"}, |
||||
name: "Accuracy", |
||||
showlegend: false, |
||||
type: "scatter" |
||||
}; |
||||
var trace2 = { |
||||
x: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1], |
||||
y: [55, 29, 63, 79, 59, 29, 79, 48, 58, 53, 50, 40, 40, 70, 24, 50, 77, 60, 25, 47], |
||||
fill: "tozerox", |
||||
fillcolor: "rgba(0,176,246,0.2)", |
||||
line: {color: "transparent"}, |
||||
name: "Precision", |
||||
showlegend: false, |
||||
type: "scatter" |
||||
}; |
||||
var trace3 = { |
||||
x: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1], |
||||
y: [100, 85, 68, 46, 25, 30, 29, 49, 27, 94, 87, 18, 30, 25, 25, 17, 30, 55, 77, 77], |
||||
fill: "tozerox", |
||||
fillcolor: "rgba(231,107,243,0.2)", |
||||
line: {color: "transparent"}, |
||||
name: "Recall", |
||||
showlegend: false, |
||||
type: "scatter" |
||||
}; |
||||
var trace4 = { |
||||
x: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], |
||||
y: [10, 20, 30, 40, 50, 60, 70, 80, 90, 100], |
||||
line: {color: "rgb(0,100,80)"}, |
||||
mode: "lines", |
||||
name: "Accuracy", |
||||
type: "scatter" |
||||
}; |
||||
var trace5 = { |
||||
x: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], |
||||
y: [50, 26, 59, 75, 50, 25, 75, 45, 55, 50], |
||||
line: {color: "rgb(0,176,246)"}, |
||||
mode: "lines", |
||||
name: "Precision", |
||||
type: "scatter" |
||||
}; |
||||
var trace6 = { |
||||
x: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], |
||||
y: [100, 80, 60, 40, 20, 28, 20, 40, 20, 90], |
||||
line: {color: "rgb(231,107,243)"}, |
||||
mode: "lines", |
||||
name: "Recall", |
||||
type: "scatter" |
||||
}; |
||||
var data = [trace1, trace2, trace3, trace4, trace5, trace6]; |
||||
var layout = { |
||||
height: '235', |
||||
margin: { |
||||
l: 55, |
||||
r: 20, |
||||
b: 45, |
||||
t: 5, |
||||
pad: 5 |
||||
}, |
||||
xaxis: { |
||||
title: "Execution step", |
||||
gridcolor: "rgb(230,230,230)", |
||||
range: [1, 10], |
||||
showgrid: true, |
||||
showline: false, |
||||
showticklabels: true, |
||||
tickcolor: "rgb(230,230,230)", |
||||
ticks: "outside", |
||||
zeroline: false |
||||
}, |
||||
yaxis: { |
||||
title: "Performance (%)", |
||||
gridcolor: "rgb(230,230,230)", |
||||
showgrid: true, |
||||
showline: false, |
||||
showticklabels: true, |
||||
tickcolor: "rgb(230,230,230)", |
||||
ticks: "outside", |
||||
zeroline: false |
||||
} |
||||
}; |
||||
Plotly.newPlot('LinePlot', data, layout); |
||||
}, |
||||
reset () { |
||||
Plotly.purge('LinePlot') |
||||
}, |
||||
}, |
||||
mounted () { |
||||
this.initializeLinePLot() |
||||
EventBus.$on('reset', this.reset) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style> |
||||
|
||||
text { |
||||
font-family: sans-serif; |
||||
} |
||||
|
||||
svg { |
||||
display: block; |
||||
} |
||||
|
||||
.nodeHighlighted { |
||||
stroke: 'orange' |
||||
} |
||||
|
||||
.modebar{ |
||||
display: none !important; |
||||
} |
||||
|
||||
</style> |
@ -1,99 +0,0 @@ |
||||
<template> |
||||
<div> |
||||
<div class="row align-items-center"> |
||||
<div class="col-lg-2"><p>Positive</p></div> |
||||
<div class="col-lg-8"><div id="slider-stepPos"></div></div> |
||||
<div class="col-lg-2"><p id="value-stepPos"></p></div> |
||||
</div> |
||||
<div class="row align-items-center"> |
||||
<div class="col-lg-2"><p>Negative</p></div> |
||||
<div class="col-lg-8"><div id="slider-stepNeg"></div></div> |
||||
<div class="col-lg-2"><p id="value-stepNeg"></p></div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import { EventBus } from '../main.js' |
||||
import { sliderBottom } from 'd3-simple-slider' |
||||
import * as d3Base from 'd3' |
||||
|
||||
// attach all d3 plugins to the d3 library |
||||
const d3 = Object.assign(d3Base, { sliderBottom }) |
||||
|
||||
export default { |
||||
name: 'Slider', |
||||
data () { |
||||
return { |
||||
} |
||||
}, |
||||
methods: { |
||||
InitSliders () { |
||||
var dataCorrect = [55.0, 60.0, 65.0, 70.0, 75.0, 80.0, 85.0, 90.0, 95.0]; |
||||
var dataWrong = [5.0, 10.0, 15.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0]; |
||||
|
||||
var sliderStepPos = d3 |
||||
.sliderBottom() |
||||
.min(d3.min(dataCorrect)) |
||||
.max(d3.max(dataCorrect)) |
||||
.width(300) |
||||
.tickFormat(d3.format(".0f")) |
||||
.ticks(9) |
||||
.step(5) |
||||
.default(75.0) |
||||
.on('onchange', val => { |
||||
d3.select('p#value-stepPos').text(d3.format(".0f")(val)); |
||||
EventBus.$emit('SendtheChangeinRangePos', d3.format(".0f")(val)) |
||||
}); |
||||
|
||||
var gStepPos = d3 |
||||
.select('div#slider-stepPos') |
||||
.append('svg') |
||||
.attr('width', 500) |
||||
.attr('height', 100) |
||||
.append('g') |
||||
.attr('transform', 'translate(30,30)'); |
||||
|
||||
gStepPos.call(sliderStepPos); |
||||
|
||||
d3.select('p#value-stepPos').text(d3.format(".0f")(sliderStepPos.value())); |
||||
|
||||
var sliderStepNeg = d3 |
||||
.sliderBottom() |
||||
.min(d3.min(dataWrong)) |
||||
.max(d3.max(dataWrong)) |
||||
.width(300) |
||||
.tickFormat(d3.format(".0f")) |
||||
.ticks(9) |
||||
.step(5) |
||||
.default(25.0) |
||||
.on('onchange', val => { |
||||
d3.select('p#value-stepNeg').text(d3.format(".0f")(val)); |
||||
EventBus.$emit('SendtheChangeinRangeNeg', d3.format(".0f")(val)) |
||||
}); |
||||
|
||||
var gStepNeg = d3 |
||||
.select('div#slider-stepNeg') |
||||
.append('svg') |
||||
.attr('width', 500) |
||||
.attr('height', 100) |
||||
.append('g') |
||||
.attr('transform', 'translate(30,30)'); |
||||
|
||||
gStepNeg.call(sliderStepNeg); |
||||
|
||||
d3.select('p#value-stepNeg').text(d3.format(".0f")(sliderStepNeg.value())); |
||||
}, |
||||
reset () { |
||||
EventBus.$emit('reset') |
||||
EventBus.$emit('alternateFlagLock') |
||||
}, |
||||
initialize () { |
||||
EventBus.$emit('ConfirmDataSet') |
||||
} |
||||
}, |
||||
mounted () { |
||||
this.InitSliders() |
||||
}, |
||||
} |
||||
</script> |
Loading…
Reference in new issue