Created
October 18, 2020 21:46
-
-
Save valex/d9ad843ba337664ee9d3d229c52ffae0 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://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
function CHART_4_class(selector){ | |
this.options = { | |
selector: selector, | |
viewBox: [400, 300], | |
colors: { | |
background: '#d7e5ec', | |
before: '#000000', | |
after: '#4bc774', | |
worse: 'red' | |
}, | |
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 | |
} | |
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); | |
}; | |
CHART_4_class.prototype = { | |
loadDataFromFile: function(path){ | |
var that = this; | |
d3.json(path) | |
.then(function(data) { | |
that.setData(data); | |
that.buildVis(); | |
}) | |
.catch(function(error) { | |
throw error; | |
}); | |
}, | |
setData: function(data){ | |
this.originalData = Object.assign({}, data); | |
this.data = null; | |
this.prepareData(); | |
}, | |
prepareData: function(){ | |
var that = this; | |
this.data = Object.assign({}, this.originalData); | |
// calculate max | |
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.data[group].hasOwnProperty( prop ) ) { | |
if(typeof this.data['maxValue'] === 'undefined'){ | |
this.data['maxValue'] = +this.data[group][prop]; | |
}else{ | |
if(+this.data[group][prop] > this.data['maxValue']) | |
this.data['maxValue'] = +this.data[group][prop]; | |
} | |
} | |
} | |
} | |
// add 10% to max | |
// this.data['maxValue'] = Math.round(1.1 * this.data['maxValue'] * 100)/100; | |
for(var i=0; i < this.options.groups.length; i++){ | |
var group = this.options.groups[i]; | |
var groupData = {}; | |
for (var prop in this.originalData[group]) { | |
if( this.originalData[group].hasOwnProperty( prop ) ) { | |
var value = this.originalData[group][prop]; | |
groupData[prop] = { | |
value: value, | |
axis: prop, | |
}; | |
} | |
} | |
that.data[group] = Object.assign({}, groupData); | |
} | |
for(var i=0; i < this.options.groups.length; i++){ | |
var group = this.options.groups[i]; | |
this.vis.verticesData[group] = []; | |
for (var prop in this.data[group]) { | |
if( this.data[group].hasOwnProperty( prop ) ) { | |
var worse = false; | |
if(i === 1){ | |
if(this.data[group][prop].value - this.data[this.options.groups[0]][prop].value < 0){ | |
worse = true; | |
} | |
} | |
this.vis.verticesData[group].push(Object.assign({},{ | |
worse: worse | |
}, this.data[group][prop])); | |
} | |
} | |
} | |
// 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'; | |
}, | |
//build visualization using the other build helper functions | |
buildVis: function () { | |
if( ! this.vis.svg ) this.buildVisComponents(); | |
this.buildLevels(); | |
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 = [that.options.colors.before, that.options.colors.after]; | |
var lines = []; | |
for(var i=0; i < this.options.groups.length; i++){ | |
var that = this; | |
var group = this.options.groups[i]; | |
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({ | |
x1: point0[0], | |
y1: point0[1], | |
x2: point1[0], | |
y2: point1[1], | |
color: group_colors[i] | |
}); | |
} | |
} | |
this.vis.vertices | |
.selectAll('line') | |
.data(lines) | |
.join( | |
function(enter){ | |
return enter.append("svg:line") | |
.classed("polygon-areas", true) | |
.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; }) | |
}, | |
function(update){ | |
return update | |
.call(function(update){ | |
return update.transition() | |
.duration(1000) | |
.ease(d3.easeLinear) | |
.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; }) | |
}); | |
}, | |
function(exit){return exit.remove();} | |
) | |
.attr("stroke", function(d) { | |
return d.color} | |
) | |
.attr("stroke-width", "1px"); | |
}, | |
buildVertices: function(){ | |
var that = this; | |
var group_colors = [that.options.colors.before, that.options.colors.after]; | |
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) | |
.selectAll('circle.outer-circle') | |
.data([d]) | |
.join("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 that.options.colors.worse; | |
} | |
return d.color; | |
}) | |
.style("stroke-width", '1px') | |
.style("stroke-opacity", '1') | |
if(d.worse){ | |
that.pulsate(outerCircle); | |
} | |
d3.select(this) | |
.selectAll('circle.inner-circle') | |
.data([d]) | |
.join("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 that.options.colors.worse; | |
} | |
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) | |
} | |
}); | |
}, | |
function(update){ | |
return update.each(function(d){ | |
// deselect all vertices | |
that.deselectAllAndHide(); | |
var outerCircle = d3.select(this) | |
.selectAll('circle.outer-circle') | |
.data([d]) | |
.join("svg:circle") | |
.call(function(selection){ | |
return selection | |
.interrupt() | |
.transition() | |
.duration(1000) | |
.ease(d3.easeLinear) | |
.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 that.options.colors.worse; | |
} | |
return d.color; | |
}) | |
.style("stroke-width", '1px') | |
.style("stroke-opacity", '1') | |
.on("end", function(){ | |
if(d.worse){ | |
that.pulsate(outerCircle); | |
} | |
}) | |
}) | |
d3.select(this) | |
.selectAll('circle.inner-circle') | |
.data([d]) | |
.join("svg:circle") | |
.call(function(selection){ | |
return selection.transition() | |
.duration(1000) | |
.ease(d3.easeLinear) | |
.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 that.options.colors.worse; | |
} | |
return d.color; | |
}) | |
.style("opacity", 0.0) | |
}) | |
}); | |
}, | |
function(exit){ | |
return exit.remove(); | |
}, | |
) | |
}, | |
deselectAllAndHide: function(){ | |
var that = this; | |
if(that.vis.tooltip){ | |
that.vis.tooltip | |
.style("opacity", 0); | |
} | |
// deselect all vertices | |
that.el.selectAll(".polygon-vertices").classed('active', false); | |
}, | |
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.selectAll('svg') | |
.data(["one"]) | |
.enter() | |
.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){ | |
that.deselectAllAndHide(); | |
}) | |
.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'].selectAll("defs") | |
.data(["one"]) | |
.enter() | |
.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 that.options.colors.after; | |
else | |
return that.options.colors.background | |
}) | |
.style("stroke-linecap", "round") | |
.style("stroke-width", "4") | |
}) | |
// TOOLTIP | |
this.vis.tooltip = this.el.selectAll("div.g-tooltip") | |
.data(["one"]) | |
.enter().append("div") | |
.attr("class", "g-tooltip") | |
// create levels | |
this.vis.levels = this.vis.svg.selectAll("g.levels") | |
.data(["one"]) | |
.enter() | |
.append("svg:g").classed("levels", true); | |
// create axes | |
this.vis['axes'] = this.vis.svg.selectAll("g.axes") | |
.data(["one"]) | |
.enter() | |
.append("svg:g").classed("axes", true); | |
// create vertices | |
this.vis['vertices'] = this.vis.svg.selectAll("g.vertices") | |
.data(["one"]) | |
.enter() | |
.append("svg:g") | |
.classed("vertices", true); | |
//Initiate Legend | |
this.vis.legend = this.vis.svg.selectAll("g.legend") | |
.data(["one"]) | |
.enter() | |
.append("svg:g") | |
.classed("legend", true) | |
}, | |
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", that.options.colors.background) | |
.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", that.options.colors.background) | |
.attr("stroke-width", "1px"); | |
}, | |
getCenter: function(){ | |
return [this.options.viewBox[0] / 2, this.options.viewBox[1] / 2]; | |
}, | |
onResize: function (){ | |
this.deselectAllAndHide(); | |
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 targetWidth = chartContainerBounding.width; | |
chartEl.attr("width", targetWidth); | |
chartEl.attr("height", Math.round(targetWidth / this.aspect)); | |
}, | |
}; | |
var chart_left = new CHART_4_class('#chart'); | |
chart_left.loadDataFromFile('chart4.json'); | |
var chart_right = new CHART_4_class('#chart_right'); | |
chart_right.loadDataFromFile('chart4_right.json'); | |
var newData = { | |
"hand": "right", | |
"onPeriodStart": { | |
"thumb": 15.8, | |
"pointing": 5.4, | |
"middle": 17.4, | |
"ring": 6.4, | |
"pinky": 11.4 | |
}, | |
"onPeriodEnd": { | |
"thumb": 21.6, | |
"pointing": 14.4, | |
"middle": 12.3, | |
"ring": 16.4, | |
"pinky": 18.1 | |
} | |
} | |
setTimeout(function(){ | |
chart_left.setData(newData); | |
chart_left.buildVis(); | |
}, 5000); | |
var newData2 = { | |
"hand": "left", | |
"onPeriodStart": { | |
"thumb": 34.8, | |
"pointing": 32.4, | |
"middle": 30.4, | |
"ring": 28.4, | |
"pinky": 26.4 | |
}, | |
"onPeriodEnd": { | |
"thumb": 24.6, | |
"pointing": 28.4, | |
"middle": 25.3, | |
"ring": 22.4, | |
"pinky": 18.1 | |
} | |
} | |
setTimeout(function(){ | |
chart_left.setData(newData2); | |
chart_left.buildVis(); | |
}, 12000) | |
var newData3 = { | |
"hand": "left", | |
"onPeriodStart": { | |
"thumb": 24.6, | |
"pointing": 28.4, | |
"middle": 25.3, | |
"ring": 22.4, | |
"pinky": 18.1 | |
}, | |
"onPeriodEnd": { | |
"thumb": 34.8, | |
"pointing": 32.4, | |
"middle": 30.4, | |
"ring": 28.4, | |
"pinky": 26.4 | |
} | |
} | |
setTimeout(function(){ | |
chart_left.setData(newData3); | |
chart_left.buildVis(); | |
}, 19000) | |
var newData4 = { | |
"hand": "left", | |
"onPeriodStart": { | |
"thumb": 12.6, | |
"pointing": 11.4, | |
"middle": 10.3, | |
"ring": 9.4, | |
"pinky": 8.1 | |
}, | |
"onPeriodEnd": { | |
"thumb": 8.8, | |
"pointing": 3.4, | |
"middle": 6.4, | |
"ring": 2.4, | |
"pinky": 3.4 | |
} | |
} | |
setTimeout(function(){ | |
chart_left.setData(newData4); | |
chart_left.buildVis(); | |
}, 26000) |
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