|
<!DOCTYPE html> |
|
<head> |
|
<meta charset="utf-8"> |
|
<script src="https://cdn.jsdelivr.net/npm/vega@4"></script> |
|
<script src="https://cdn.jsdelivr.net/npm/vega-embed@3"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script> |
|
</head> |
|
|
|
<body> |
|
<div id="vis"></div> |
|
|
|
<script> |
|
var respondents = 95, |
|
emptyPerc = 0.4, |
|
//How many "units" would define this empty percentage |
|
emptyStroke = Math.round(respondents * emptyPerc), |
|
//Calculate how far the chord diagram needs to be rotated clockwise |
|
//to make the dummy invisible chord center vertically |
|
offset = Math.PI * (emptyStroke/(respondents + emptyStroke)) / 2, |
|
startAngle = function(d) { return d.startAngle + offset; }, |
|
endAngle = function(d) { return d.endAngle + offset; }; |
|
|
|
var chord = d3.chord() |
|
.padAngle(0.05) |
|
.sortSubgroups(d3.descending); |
|
|
|
var innerRadius = 270, |
|
outerRadius = 290; |
|
|
|
var arc = d3.arc() |
|
.innerRadius(innerRadius) |
|
.outerRadius(outerRadius) |
|
.startAngle(startAngle) |
|
.endAngle(endAngle); |
|
|
|
var ribbon = d3.ribbon() |
|
.radius(innerRadius) |
|
.startAngle(startAngle) |
|
.endAngle(endAngle); |
|
|
|
|
|
var data = [ |
|
[0,0,0,0,10,5,15,0], //X |
|
[0,0,0,0,5,15,20,0], //Y |
|
[0,0,0,0,15,5,5,0], //Z |
|
[0,0,0,0,0,0,0,emptyStroke], //Dummy stroke |
|
[10,5,15,0,0,0,0,0], //C |
|
[5,15,5,0,0,0,0,0], //B |
|
[15,20,5,0,0,0,0,0], //A |
|
[0,0,0,emptyStroke,0,0,0,0] //Dummy stroke |
|
]; |
|
|
|
// TODO: |
|
// unharcode this |
|
var emptyStrokeIndexes = [4,8]; |
|
|
|
var chords = chord(data); |
|
|
|
var ribbonsPaths = chords.map(function(chord, index) { |
|
return { |
|
'path' : ribbon(chord), |
|
'sourceId' : chord.source.index, |
|
'targetId' : chord.target.index, |
|
} |
|
}); |
|
console.log('___ ribbonPaths ____'); |
|
console.log(JSON.stringify(ribbonsPaths)); |
|
|
|
console.log('___ chords.groups ____'); |
|
console.log(chords); |
|
console.log( |
|
JSON.stringify(chords.groups) |
|
); |
|
|
|
var view; |
|
|
|
vega.loader() |
|
.load('chords.vg.json') |
|
.then(function(data) { |
|
var spec = JSON.parse(data); |
|
|
|
// add signals |
|
spec.signals.push({ |
|
'name' : 'inner_radius', |
|
'value' : innerRadius |
|
}); |
|
spec.signals.push({ |
|
'name' : 'outer_radius', |
|
'value' : outerRadius |
|
}); |
|
spec.signals.push({ |
|
'name' : 'offset', |
|
'value' : offset |
|
}); |
|
spec.signals.push({ |
|
'name' : 'emptyStrokeIndexes', |
|
'value' : emptyStrokeIndexes |
|
}); |
|
|
|
// inject the data |
|
_.find(spec.data, ['name', 'chords']) |
|
.values = JSON.parse(JSON.stringify(chords.groups)); |
|
|
|
_.find(spec.data, ['name', 'ribbonsPaths']) |
|
.values = JSON.parse(JSON.stringify(ribbonsPaths)); |
|
|
|
console.log('___ spec ____'); |
|
console.log(spec); |
|
render(spec); |
|
}); |
|
|
|
function render(spec) { |
|
view = new vega.View(vega.parse(spec)) |
|
.renderer('canvas') // set renderer (canvas or svg) |
|
.initialize('#vis') // initialize view within parent DOM container |
|
.hover() // enable hover encode set processing |
|
.run(); |
|
} |
|
|
|
</script> |
|
</body> |