Created
October 16, 2020 22:54
-
-
Save valex/708c17b011fea6c03b534b2a68ed5db4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"hand": "left", | |
"onPeriodStart": { | |
"thumb": 31.8, | |
"pointing": 15.4, | |
"middle": 25.4, | |
"ring": 10.4, | |
"pinky": 15.4 | |
}, | |
"onPeriodEnd": { | |
"thumb": 45.6, | |
"pointing": 22.4, | |
"middle": 15.3, | |
"ring": 17.4, | |
"pinky": 11.1 | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"hand": "right", | |
"onPeriodStart": { | |
"thumb": 31.8, | |
"pointing": 15.4, | |
"middle": 0.4, | |
"ring": 10.4, | |
"pinky": 15.4 | |
}, | |
"onPeriodEnd": { | |
"thumb": 45.6, | |
"pointing": 22.4, | |
"middle": 0.3, | |
"ring": 12.4, | |
"pinky": 11.1 | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<meta charset="utf-8"> | |
<link rel="stylesheet" href="styles.css"> | |
</head> | |
<body> | |
<div style="display: flex; | |
flex-direction: row;"> | |
<div id="chart"></div> | |
<div id="chart_right"></div> | |
</div> | |
</body> | |
<script src="https://code.jquery.com/jquery-3.5.1.min.js" ></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js" ></script> | |
<script src="scripts.js"></script> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// http://bl.ocks.org/chrisrzhou/2421ac6541b68c1680f8 | |
function CHART_4_class(selector, data_file){ | |
this.options = { | |
selector: selector, | |
data_file: data_file, | |
viewBox: [400, 300], | |
groups: ['onPeriodStart', 'onPeriodEnd'], | |
levels: 3, | |
radius: 0.28, // relative radius, max: 0.5 | |
legendRadius: 0.37 // relative radius, max: 0.5 | |
} | |
this.el = null, | |
this.aspect = null, | |
this.originalData = null, | |
this.data = null, | |
this.vis = { | |
svg: null, | |
axes: null, | |
levels: null, | |
vertices: null, | |
verticesData: {}, | |
allAxis:[], | |
axisScales: {}, | |
totalAxes:null, | |
radius: null, | |
legendRadius: null, | |
legend:null, | |
tooltip:null, | |
hand:null, | |
defs:null, | |
handDef: null | |
} | |
}; | |
CHART_4_class.prototype = { | |
init: function(){ | |
var that = this; | |
this.el = d3.select(this.options.selector); | |
this.aspect = this.options.viewBox[0] / this.options.viewBox[1]; | |
window.addEventListener("resize", this.onResize.bind(this), false); | |
d3.json(this.options.data_file) | |
.then((data) => { | |
this.originalData = data; | |
this.prepareData(this.originalData); | |
this.buildVisComponents(); | |
that.buildVis(); | |
}) | |
.catch((error) => { | |
throw error; | |
}); | |
}, | |
setData: function(data){ | |
this.originalData = data; | |
this.prepareData(this.originalData); | |
}, | |
prepareData: function(data){ | |
// calculate max | |
for(var i=0; i < this.options.groups.length; i++){ | |
var group = this.options.groups[i]; | |
for (var prop in data[group]) { | |
if( data[group].hasOwnProperty( prop ) ) { | |
if(typeof data['maxValue'] === 'undefined'){ | |
data['maxValue'] = +data[group][prop]; | |
}else{ | |
if(+data[group][prop] > data['maxValue']) | |
data['maxValue'] = +data[group][prop]; | |
} | |
} | |
} | |
} | |
// add 10% to max | |
// data['maxValue'] = Math.round(1.1 * data['maxValue'] * 100)/100; | |
for(var i=0; i < this.options.groups.length; i++){ | |
var group = this.options.groups[i]; | |
var j = 0; | |
for (var prop in data[group]) { | |
if( data[group].hasOwnProperty( prop ) ) { | |
data[group][prop] = { | |
value: data[group][prop], | |
axis: prop, | |
} | |
j++; | |
} | |
} | |
} | |
for(var i=0; i < this.options.groups.length; i++){ | |
var group = this.options.groups[i]; | |
this.vis.verticesData[group] = []; | |
for (var prop in data[group]) { | |
if( data[group].hasOwnProperty( prop ) ) { | |
var worse = false; | |
if(i === 1){ | |
if(data[group][prop].value - data[this.options.groups[0]][prop].value < 0){ | |
worse = true; | |
} | |
} | |
this.vis.verticesData[group].push(Object.assign({},{ | |
worse: worse | |
}, data[group][prop])); | |
} | |
} | |
} | |
this.data = data; | |
// build allAxes | |
for(var i=0; i < this.options.groups.length; i++){ | |
var group = this.options.groups[i]; | |
for (var prop in this.data[group]) { | |
if(this.vis.allAxis.indexOf(prop) === -1 ) | |
this.vis.allAxis.push(prop); | |
} | |
} | |
this.vis.totalAxes = this.vis.allAxis.length; | |
this.vis.radius = d3.min([this.options.radius * this.options.viewBox[0], this.options.radius * this.options.viewBox[1]]); | |
this.vis.legendRadius = d3.min([this.options.legendRadius * this.options.viewBox[0], this.options.legendRadius * this.options.viewBox[1]]); | |
this.vis.hand = this.data.hand.indexOf('right') === -1 ? 'left' : 'right'; | |
}, | |
buildMain: function(){ | |
}, | |
//build visualization using the other build helper functions | |
buildVis: function () { | |
// this.buildCoordinates(data); | |
this.buildLevels(); | |
// if (config.showLevelsLabels) buildLevelsLabels(); | |
this.buildAxes(); | |
this.buildAxesLabels(); | |
this.buildLegend(); | |
this.buildPolygons(); | |
this.buildVertices(); | |
}, | |
buildLegend: function(){ | |
var that = this; | |
var center = that.getCenter(); | |
var label = this.vis.legend | |
.selectAll('text') | |
.data([that.data.hand]) | |
.join("text") | |
.attr("x", function(){return center[0];}) | |
.attr("y", function(){return center[1] + 1.1 * that.vis.radius;}) | |
.attr("font-size", "1rem") | |
.attr("fill", "black") | |
.attr("text-anchor", "middle") | |
.attr("class", "noselect") | |
.text(function(d) { | |
switch(d){ | |
case 'left': | |
return "Левая рука" | |
break; | |
default: | |
return "Правая рука" | |
break; | |
} | |
}); | |
}, | |
buildPolygons: function(){ | |
var that = this; | |
var group_colors = ['#000000', '#4bc774']; | |
for(var i=0; i < this.options.groups.length; i++){ | |
var that = this; | |
var group = this.options.groups[i]; | |
var lines = []; | |
for (var j=0; j < this.vis.verticesData[group].length; j++){ | |
var vertex0 = this.vis.verticesData[group][j]; | |
var point0 = [ | |
that.vis.axisScales[vertex0.axis].x(vertex0.value), | |
that.vis.axisScales[vertex0.axis].y(vertex0.value) | |
]; | |
var vertex1 = this.vis.verticesData[group][0]; | |
if(typeof this.vis.verticesData[group][j+1] !== 'undefined'){ | |
vertex1 = this.vis.verticesData[group][j+1]; | |
} | |
var point1 = [ | |
that.vis.axisScales[vertex1.axis].x(vertex1.value), | |
that.vis.axisScales[vertex1.axis].y(vertex1.value) | |
]; | |
lines.push([point0, point1]); | |
} | |
this.vis.vertices | |
.selectAll('line.'+group) | |
.data(lines) | |
.join( | |
function(enter){ | |
return enter.append("svg:line") | |
.classed("polygon-areas", true) | |
.classed(group, true) | |
.attr("x1", function(d) { return d[0][0]; }) | |
.attr("y1", function(d) { return d[0][1]; }) | |
.attr("x2", function(d) { return d[1][0]; }) | |
.attr("y2", function(d) { return d[1][1]; }) | |
}, | |
function(update){ | |
return update | |
.call(function(update){ | |
return update.transition() | |
.duration(1000) | |
.ease(d3.easeLinear) | |
.attr("x1", function(d) { return d[0][0]; }) | |
.attr("y1", function(d) { return d[0][1]; }) | |
.attr("x2", function(d) { return d[1][0]; }) | |
.attr("y2", function(d) { return d[1][1]; }); | |
}); | |
}, | |
function(exit){return exit.remove();} | |
) | |
.attr("stroke", function() { | |
return group_colors[i]} | |
) | |
.attr("stroke-width", "1px"); | |
} | |
}, | |
buildVertices: function(){ | |
var that = this; | |
var group_colors = ['#000000', '#4bc774']; | |
var all_vertices = []; | |
for(var i=0; i < this.options.groups.length; i++){ | |
var that = this; | |
var group = this.options.groups[i]; | |
var color = group_colors[i]; | |
for(var j=0; j<this.vis.verticesData[group].length; j++){ | |
all_vertices.push(Object.assign({}, { | |
color: color | |
}, this.vis.verticesData[group][j])); | |
} | |
}// for | |
this.vis.vertices.selectAll('g.polygon-vertices') | |
.data(all_vertices) | |
.join( | |
function(enter){ | |
return enter.append("svg:g") | |
.classed("polygon-vertices ", true) | |
.each(function(d, fingerIndex){ | |
var outerCircle = d3.select(this).append("svg:circle") | |
.attr("class", "outer-circle") | |
.attr("r", 4.6) | |
.attr("cx", function(d) { return that.vis.axisScales[d.axis].x(d.value); }) | |
.attr("cy", function(d) { return that.vis.axisScales[d.axis].y(d.value); }) | |
.attr("fill", 'white') | |
.style("stroke", function(d){ | |
if(d.worse){ | |
return 'red'; | |
} | |
return d.color; | |
}) | |
.style("stroke-width", '1px') | |
if(d.worse){ | |
that.pulsate(outerCircle); | |
} | |
d3.select(this).append("svg:circle") | |
.attr("class", "inner-circle") | |
.attr("r", 3.2) | |
.attr("cx", function(d) { return that.vis.axisScales[d.axis].x(d.value); }) | |
.attr("cy", function(d) { return that.vis.axisScales[d.axis].y(d.value); }) | |
.attr("fill", function(d){ | |
if(d.worse){ | |
return 'red'; | |
} | |
return d.color; | |
}) | |
.style("opacity", 0.0) | |
}) | |
.on("click", function(event, d){ | |
event.stopPropagation(); | |
var clicked = d3.select(this); | |
// if click on active - hide tooltip | |
if(clicked.classed('active')){ | |
if( +that.vis.tooltip.style("opacity") > 0){ | |
that.vis.tooltip | |
.style("opacity", 0); | |
} | |
}else{ | |
that.vis.tooltip | |
.style("opacity", .9); | |
that.vis.tooltip.html("<span class=\"g-content noselect\">"+d.value+"°</span>") | |
.style("left", (event.pageX) + "px") | |
.style("top", (event.pageY) + "px"); | |
var tooltipRect = that.vis.tooltip.node().getBoundingClientRect(); | |
that.vis.tooltip | |
.style("left", (event.pageX - tooltipRect.width / 2) + "px") | |
.style("top", (event.pageY - 1.4 * tooltipRect.height) + "px"); | |
} | |
if(clicked.classed('active')){ | |
clicked.classed('active', false); | |
}else{ | |
that.el.selectAll(".polygon-vertices").classed('active', false); | |
clicked.classed('active', true) | |
} | |
}) | |
.on("mouseenter", function(event, d) { | |
// that.vis.tooltip | |
// //.transition() | |
// //.duration(100) | |
// .style("opacity", .9); | |
// that.vis.tooltip.html("<span class=\"g-content\">"+d.value+"°</span>") | |
// .style("left", (event.pageX) + "px") | |
// .style("top", (event.pageY) + "px"); | |
// var tooltipRect = that.vis.tooltip.node().getBoundingClientRect(); | |
// that.vis.tooltip | |
// .style("left", (event.pageX - tooltipRect.width / 2) + "px") | |
// .style("top", (event.pageY - 1.4 * tooltipRect.height) + "px"); | |
}) | |
.on("mousemove", function(event, d){ | |
// var tooltipRect = that.vis.tooltip.node().getBoundingClientRect(); | |
// that.vis.tooltip | |
// .style("left", (event.pageX - tooltipRect.width / 2) + "px") | |
// .style("top", (event.pageY - 1.4 * tooltipRect.height) + "px"); | |
}) | |
.on("mouseleave", function(event, d) { | |
//that.vis.tooltip | |
// .style("opacity", 0); | |
}); | |
}, | |
function(update){ | |
return update.each(function(d){ | |
d3.select(this).selectAll('circle').remove(); | |
var outerCircle = d3.select(this).append("svg:circle") | |
.attr("class", "outer-circle") | |
.attr("r", 4.6) | |
.attr("cx", function(d) { return that.vis.axisScales[d.axis].x(d.value); }) | |
.attr("cy", function(d) { return that.vis.axisScales[d.axis].y(d.value); }) | |
.attr("fill", 'white') | |
.style("stroke", function(d){ | |
if(d.worse){ | |
return 'red'; | |
} | |
return d.color; | |
}) | |
.style("stroke-width", '1px') | |
if(d.worse){ | |
that.pulsate(outerCircle); | |
} | |
d3.select(this).append("svg:circle") | |
.attr("class", "inner-circle") | |
.attr("r", 3.2) | |
.attr("cx", function(d) { return that.vis.axisScales[d.axis].x(d.value); }) | |
.attr("cy", function(d) { return that.vis.axisScales[d.axis].y(d.value); }) | |
.attr("fill", function(d){ | |
if(d.worse){ | |
return 'red'; | |
} | |
return d.color; | |
}) | |
.style("opacity", 0.0) | |
}); | |
}, | |
function(exit){ | |
return exit.remove(); | |
}, | |
) | |
// .enter() | |
// .append("svg:g").classed("polygon-vertices", true) | |
// .each(function(d, fingerIndex){ | |
// var outerCircle = d3.select(this).append("svg:circle") | |
// .attr("class", "outer-circle") | |
// .attr("r", 4.6) | |
// .attr("cx", function(d) { return that.vis.axisScales[d.axis].x(d.value); }) | |
// .attr("cy", function(d) { return that.vis.axisScales[d.axis].y(d.value); }) | |
// .attr("fill", 'white') | |
// .style("stroke", function(d){ | |
// if(d.worse){ | |
// return 'red'; | |
// } | |
// return group_colors[i] | |
// }) | |
// .style("stroke-width", '1px') | |
// if(d.worse){ | |
// that.pulsate(outerCircle); | |
// } | |
// d3.select(this).append("svg:circle") | |
// .attr("class", "inner-circle") | |
// .attr("r", 3.2) | |
// .attr("cx", function(d) { return that.vis.axisScales[d.axis].x(d.value); }) | |
// .attr("cy", function(d) { return that.vis.axisScales[d.axis].y(d.value); }) | |
// .attr("fill", function(d){ | |
// if(d.worse){ | |
// return 'red'; | |
// } | |
// return group_colors[i] | |
// }) | |
// .style("opacity", 0.0) | |
// }) | |
// .on("click", function(event, d){ | |
// event.stopPropagation(); | |
// var clicked = d3.select(this); | |
// // if click on active - hide tooltip | |
// if(clicked.classed('active')){ | |
// if( +that.vis.tooltip.style("opacity") > 0){ | |
// that.vis.tooltip | |
// .style("opacity", 0); | |
// } | |
// }else{ | |
// that.vis.tooltip | |
// .style("opacity", .9); | |
// that.vis.tooltip.html("<span class=\"g-content noselect\">"+d.value+"°</span>") | |
// .style("left", (event.pageX) + "px") | |
// .style("top", (event.pageY) + "px"); | |
// var tooltipRect = that.vis.tooltip.node().getBoundingClientRect(); | |
// that.vis.tooltip | |
// .style("left", (event.pageX - tooltipRect.width / 2) + "px") | |
// .style("top", (event.pageY - 1.4 * tooltipRect.height) + "px"); | |
// } | |
// if(clicked.classed('active')){ | |
// clicked.classed('active', false); | |
// }else{ | |
// that.el.selectAll(".polygon-vertices").classed('active', false); | |
// clicked.classed('active', true) | |
// } | |
// }) | |
// .on("mouseenter", function(event, d) { | |
// // that.vis.tooltip | |
// // //.transition() | |
// // //.duration(100) | |
// // .style("opacity", .9); | |
// // that.vis.tooltip.html("<span class=\"g-content\">"+d.value+"°</span>") | |
// // .style("left", (event.pageX) + "px") | |
// // .style("top", (event.pageY) + "px"); | |
// // var tooltipRect = that.vis.tooltip.node().getBoundingClientRect(); | |
// // that.vis.tooltip | |
// // .style("left", (event.pageX - tooltipRect.width / 2) + "px") | |
// // .style("top", (event.pageY - 1.4 * tooltipRect.height) + "px"); | |
// }) | |
// .on("mousemove", function(event, d){ | |
// // var tooltipRect = that.vis.tooltip.node().getBoundingClientRect(); | |
// // that.vis.tooltip | |
// // .style("left", (event.pageX - tooltipRect.width / 2) + "px") | |
// // .style("top", (event.pageY - 1.4 * tooltipRect.height) + "px"); | |
// }) | |
// .on("mouseleave", function(event, d) { | |
// //that.vis.tooltip | |
// // .style("opacity", 0); | |
// }); | |
}, | |
pulsate: function(selection){ | |
var that = this; | |
recursive_transitions(); | |
function recursive_transitions() { | |
selection.transition() | |
.duration(1000) | |
.ease(d3.easeLinear) | |
.style('stroke-width', '3px') | |
.style('stroke-opacity', '0.4') | |
.attr("r", 5.4) | |
.transition() | |
.duration(1000) | |
.ease(d3.easeLinear) | |
.style('stroke-width', '1px') | |
.style('stroke-opacity', '1') | |
.attr("r", 4.6) | |
.on("end", recursive_transitions); | |
} | |
}, | |
buildVisComponents: function(){ | |
var that = this; | |
// create main vis svg | |
this.vis['svg'] = this.el | |
.append("svg") | |
.classed("svg-vis", true) | |
.attr('xmlns', 'http://www.w3.org/2000/svg') | |
.attr("viewBox", "0 0 "+this.options.viewBox[0]+" "+this.options.viewBox[1]) | |
.attr("perserveAspectRatio", "xMinYMid") | |
.on("click", function(event, d){ | |
// hide tooltips | |
if(that.vis.tooltip){ | |
that.vis.tooltip | |
.style("opacity", 0); | |
} | |
// deselect all vertices | |
that.el.selectAll(".polygon-vertices").classed('active', false); | |
}) | |
.append("svg:g") | |
// hand def | |
var active_fingers = [ | |
'left-thumb', | |
'left-pointing', | |
'left-middle', | |
'left-ring', | |
'left-pinky', | |
'right-thumb', | |
'right-pointing', | |
'right-middle', | |
'right-ring', | |
'right-pinky', | |
]; | |
// for left hand | |
var fingers = { | |
left: [ | |
{ | |
x1: 0, | |
y1: 14, | |
x2: 0, | |
y2: 32, | |
hand: 'left', | |
finger: 'thumb' | |
}, | |
{ | |
x1: 6, | |
y1: 6, | |
x2: 6, | |
y2: 32, | |
hand: 'left', | |
finger: 'pointing' | |
}, | |
{ | |
x1: 12, | |
y1: 0, | |
x2: 12, | |
y2: 32, | |
hand: 'left', | |
finger: 'middle' | |
}, | |
{ | |
x1: 18, | |
y1: 5, | |
x2: 18, | |
y2: 32, | |
hand: 'left', | |
finger: 'ring' | |
}, | |
{ | |
x1: 24, | |
y1: 20, | |
x2: 24, | |
y2: 32, | |
hand: 'left', | |
finger: 'pinky' | |
}, | |
], | |
right: [ | |
{ | |
x1: 24, | |
y1: 14, | |
x2: 24, | |
y2: 32, | |
hand: 'right', | |
finger: 'thumb' | |
}, | |
{ | |
x1: 18, | |
y1: 6, | |
x2: 18, | |
y2: 32, | |
hand: 'right', | |
finger: 'pointing' | |
}, | |
{ | |
x1: 12, | |
y1: 0, | |
x2: 12, | |
y2: 32, | |
hand: 'right', | |
finger: 'middle' | |
}, | |
{ | |
x1: 6, | |
y1: 5, | |
x2: 6, | |
y2: 32, | |
hand: 'right', | |
finger: 'ring' | |
}, | |
{ | |
x1: 0, | |
y1: 20, | |
x2: 0, | |
y2: 32, | |
hand: 'right', | |
finger: 'pinky' | |
}, | |
] | |
}; | |
this.vis['defs'] = this.vis['svg'].append("defs") | |
this.vis['handDef'] = this.vis['defs'].selectAll('g').data(active_fingers).enter() | |
.append('g') | |
.attr("id", function(d,i){return 'hand-'+d}) | |
.each(function(active_finger,i){ | |
d3.select(this).selectAll("line").data(function(){ | |
if(active_finger.indexOf('left') !== -1) | |
return fingers.left; | |
else | |
return fingers.right; | |
}).enter() | |
.append("line") | |
.attr("x1", function(d){return d.x1}) | |
.attr("y1", function(d){return d.y1}) | |
.attr("x2", function(d){return d.x2}) | |
.attr("y2", function(d){return d.y2}) | |
.style("stroke", function(d, i){ | |
if(active_finger == d.hand+'-'+d.finger) | |
return '#4bc774'; // green | |
else | |
return "#d7e5ec" | |
}) | |
.style("stroke-linecap", "round") | |
.style("stroke-width", "4") | |
}) | |
// TOOLTIP | |
this.vis.tooltip = this.el.append("div") | |
.attr("class", "g-tooltip") | |
// create levels | |
this.vis.levels = this.vis.svg | |
.append("svg:g").classed("levels", true); | |
// create axes | |
this.vis['axes'] = this.vis.svg | |
.append("svg:g").classed("axes", true); | |
// create vertices | |
this.vis['vertices'] = this.vis.svg.append("svg:g") | |
.classed("vertices", true); | |
//Initiate Legend | |
this.vis.legend = this.vis.svg.append("svg:g") | |
.classed("legend", true) | |
// .attr("height", config.h / 2) | |
// .attr("width", config.w / 2) | |
// .attr("transform", "translate(" + 0 + ", " + 1.1 * config.h + ")"); | |
}, | |
buildAxes: function(){ | |
var that = this; | |
var center = this.getCenter(); | |
this.vis['axes'].selectAll("line") | |
.data(this.vis.allAxis).enter() | |
.append("svg:line").classed("axis-lines", true) | |
.attr("x1", center[0]) | |
.attr("y1", center[1]) | |
.attr("x2", function(d, i) { return x(i); }) | |
.attr("y2", function(d, i) { return y(i); }) | |
.attr("stroke", "#d7e5ec") | |
.attr("stroke-width", "1px"); | |
for(var i=0; i < this.vis.allAxis.length; i++ ){ | |
this.vis.axisScales[this.vis.allAxis[i]] = { | |
x:d3.scaleLinear() | |
.domain([0, this.data['maxValue']]) | |
.range([center[0], x(i)]), | |
y:d3.scaleLinear() | |
.domain([0, this.data['maxValue']]) | |
.range([center[1], y(i)]), | |
}; | |
} | |
function x(i){ | |
return center[0] + that.vis.radius * Math.sin(i * 2 * Math.PI / that.vis.totalAxes); | |
} | |
function y(i){ | |
return center[1] + that.vis.radius * -Math.cos(i * 2 * Math.PI / that.vis.totalAxes); | |
} | |
}, | |
buildAxesLabels: function(){ | |
var that = this; | |
var center = this.getCenter(); | |
var boundings = this.vis['handDef'].node().getBBox(); | |
this.vis['axes'].selectAll('g.label').remove(); | |
this.vis['axes'].selectAll('g.label') | |
.data(this.vis.allAxis) | |
.enter() | |
.append("g") | |
.classed('label', true) | |
.attr("transform",function(d,i) { | |
var x = center[0] + that.vis.legendRadius * Math.sin(i * 2 * Math.PI / that.vis.totalAxes); | |
x -= boundings.width / 2; | |
var y = center[1] + that.vis.legendRadius * -Math.cos(i * 2 * Math.PI / that.vis.totalAxes) | |
y -= boundings.height / 2; | |
return "translate("+x+","+y+")"; | |
}) | |
.append("use") | |
.attr("xlink:href",function(d,i){return "#hand-"+that.vis.hand+"-"+d}) | |
}, | |
buildLevels: function(){ | |
var that = this; | |
var center = this.getCenter(); | |
this.vis.levels.selectAll('line').remove(); | |
var data = []; | |
for (var level = 0; level < this.options.levels; level++) { | |
var levelFactor = this.vis.radius * ((level + 1) / this.options.levels); | |
for (var j=0; j < this.vis.allAxis.length; j++){ | |
data.push({ | |
levelFactor: levelFactor, | |
index: j | |
}); | |
} | |
} | |
// build level-lines | |
this.vis.levels.selectAll('line') | |
.data(data).enter() | |
.append("svg:line").classed("level-lines", true) | |
.attr("x1", function(d, i) { return d.levelFactor * (1 - Math.sin(d.index * 2 * Math.PI / that.vis.totalAxes)); }) | |
.attr("y1", function(d, i) { return d.levelFactor * (1 - Math.cos(d.index * 2 * Math.PI / that.vis.totalAxes)); }) | |
.attr("x2", function(d, i) { return d.levelFactor * (1 - Math.sin((d.index + 1) * 2 * Math.PI / that.vis.totalAxes)); }) | |
.attr("y2", function(d, i) { return d.levelFactor * (1 - Math.cos((d.index + 1) * 2 * Math.PI / that.vis.totalAxes)); }) | |
.attr("transform", function(d){return "translate(" + (center[0] - d.levelFactor) + ", " + (center[1] - d.levelFactor) + ")" }) | |
.attr("stroke", "#d7e5ec") | |
.attr("stroke-width", "1px"); | |
}, | |
getCenter: function(){ | |
return [this.options.viewBox[0] / 2, this.options.viewBox[1] / 2]; | |
}, | |
onResize: function (){ | |
this.updateSvgWidthAndHeight(); | |
}, | |
updateSvgWidthAndHeight: function (){ | |
var chartElContainer = d3.select(this.options.selector); | |
var chartEl = d3.select(this.options.selector + " > svg"); | |
var chartContainerBounding = chartElContainer.node().getBoundingClientRect(); | |
var chartBounding = chartEl.node().getBoundingClientRect(); | |
var targetWidth = chartContainerBounding.width; | |
chartEl.attr("width", targetWidth); | |
chartEl.attr("height", Math.round(targetWidth / this.aspect)); | |
}, | |
}; | |
var chart_left = new CHART_4_class('#chart', 'chart4.json'); | |
var chart_right = new CHART_4_class('#chart_right', 'chart4_right.json'); | |
chart_left.init(); | |
chart_right.init(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#chart { | |
width: 49%; | |
background-color: #ffffff; | |
} | |
#chart_right { | |
width: 49%; | |
background-color: #ffffff; | |
} | |
.noselect { | |
-webkit-touch-callout: none; /* iOS Safari */ | |
-webkit-user-select: none; /* Safari */ | |
-khtml-user-select: none; /* Konqueror HTML */ | |
-moz-user-select: none; /* Old versions of Firefox */ | |
-ms-user-select: none; /* Internet Explorer/Edge */ | |
user-select: none; /* Non-prefixed version, currently | |
supported by Chrome, Edge, Opera and Firefox */ | |
} | |
.polygon-vertices{ | |
cursor: pointer; | |
} | |
.polygon-vertices.active .inner-circle{ | |
opacity: 1 !important; | |
} | |
.g-tooltip { | |
position: absolute; | |
text-align: center; | |
padding: 4px 8px; | |
font: 12px sans-serif; | |
background: white; | |
border: 2px solid #4bc774; | |
border-radius: 4px; | |
pointer-events: none; | |
opacity: 0; | |
} | |
.g-tooltip .g-content { | |
font-weight: bold; | |
font-size: 1.2rem; | |
} | |
.stop-left { | |
stop-color: #4bc774; /* Indigo */ | |
} | |
.stop-right { | |
stop-color:red; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment