Skip to content

Instantly share code, notes, and snippets.

@valex
Created December 13, 2017 21:14
Show Gist options
  • Save valex/1f8b0947acba6241ee4dfc8e7a659232 to your computer and use it in GitHub Desktop.
Save valex/1f8b0947acba6241ee4dfc8e7a659232 to your computer and use it in GitHub Desktop.
{
"RECORDS": [
{
"name": "Corey Goldfarb",
"exitvelo": "48.996",
"vlaunch": "25.093",
"distance": "119.232",
"hlaunch": "13.671"
},
{
"name": "Corey Goldfarb",
"exitvelo": "57.342",
"vlaunch": "10.642",
"distance": "109.205",
"hlaunch": "33.076"
},
{
"name": "Corey Goldfarb",
"exitvelo": "64.148",
"vlaunch": "21.460",
"distance": "158.060",
"hlaunch": "-22.891"
},
{
"name": "Corey Goldfarb",
"exitvelo": "68.694",
"vlaunch": "24.660",
"distance": "205.239",
"hlaunch": "-38.423"
},
{
"name": "Corey Goldfarb",
"exitvelo": "58.100",
"vlaunch": "1.216",
"distance": "29.927",
"hlaunch": "6.950"
},
{
"name": "Corey Goldfarb",
"exitvelo": "45.542",
"vlaunch": "-1.435",
"distance": "38.432",
"hlaunch": "1.412"
},
{
"name": "Corey Goldfarb",
"exitvelo": "69.515",
"vlaunch": "16.342",
"distance": "185.072",
"hlaunch": "-27.972"
},
{
"name": "Corey Goldfarb",
"exitvelo": "66.590",
"vlaunch": "26.978",
"distance": "217.268",
"hlaunch": "-4.834"
},
{
"name": "Corey Goldfarb",
"exitvelo": "54.215",
"vlaunch": "-6.854",
"distance": "17.304",
"hlaunch": "-30.127"
},
{
"name": "Corey Goldfarb",
"exitvelo": "66.806",
"vlaunch": "31.138",
"distance": "215.927",
"hlaunch": "4.282"
}
]
}
<!DOCTYPE html>
<meta charset='utf-8'>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet">
<link rel='stylesheet' href='style.css'>
</head>
<body>
<div id="page-container" class="row justify-content-center">
<div class="col-sm-4" id="distance-module"></div>
<div class="col-sm-4" id="exit-launch-angle-module"></div>
<div class="col-sm-4" id="exit-direction-module"></div>
</div>
<div class="row justify-content-center">
<div class="col-sm-4" id="table-module"></div>
</div>
<script type='text/javascript' src='script.js'></script>
</body>
</html>
var BASEBALL_ANIM_APP = {
url: 'batData.json',
data: [],
activeIndex: 0,
timer: null,
animation: {
duration: 1000,
delay: 4000
},
tableModuleOptions:{
id: 'baseball-app-table',
appendToSelector: '#table-module',
rowActiveClass:"active",
},
distanceModuleOptions: {
id: 'distance',
appendToSelector: '#distance-module',
margins: {top: 10, right: 10, bottom: 10, left: 10},
width: 300,
height: 300,
defaultBallColor:'#b3b3b3',
ballActiveClass:"active",
ballHoverClass:"hovered",
radii: [350, 250, 150],
mainGroup: null,
schemeRadius: 0,
schemeBasePoint: {x:0, y:0},
},
exitLaunchAngleModuleOptions: {
id: 'exit-angle',
appendToSelector: '#exit-launch-angle-module',
margins: {top: 10, right: 10, bottom: 10, left: 10},
width: 300,
height: 200,
mainGroup: null,
schemeRadius: 0,
vectorLength: 0,
vectorArcGenerator: null,
schemeBasePoint: {x:0, y:0},
},
exitDirectionModuleOptions: {
id: 'exit-dir',
appendToSelector: '#exit-direction-module',
margins: {top: 10, right: 10, bottom: 10, left: 10},
width: 300,
height: 200,
mainGroup: null,
schemeRadius: 0,
schemeBasePoint: {x:0, y:0},
vectorArcGenerator: null,
},
mainColor: '#005d80',
mainLightColor: '#3bafda',
start: function(){
this.loadData();
},
loadData: function(){
var that = this;
d3.json(this.url, function (error, rawData) {
if (error) throw error;
that.data = rawData['RECORDS'].map(function (d) {
return {
exitSpeed: +d["exitvelo"],
vAngle: +d["vlaunch"],
hAngle: +d["hlaunch"],
distance: +d["distance"]
}
});
that.initTableModule();
that.initDistanceModule();
that.initExitLaunchAngleModule();
that.initExitDirectionModule();
that.startTimer();
});
},
initTableModule: function() {
var options = this.tableModuleOptions;
var columns = [
{
key: 'exitSpeed',
label: 'Exit velocity'
},
{
key: 'vAngle',
label: 'Vertical Launch'
},
{
key: 'hAngle',
label: 'Horiztonal Launch'
},
{
key: 'distance',
label: 'Distance'
},
];
var table = d3.select(options.appendToSelector).append('table')
.attr('id', options.id)
.attr('class', 'table');
var thead = table.append('thead');
var tbody = table.append('tbody');
// append the header row
thead.append('tr')
.selectAll('th')
.data(columns)
.enter()
.append('th')
.text(function (column) { return column.label; });
// create a row for each object in the data
var rows = tbody.selectAll('tr')
.data(this.data)
.enter()
.append('tr')
.attr('id', function(d,i){ return 'ball-'+i;})
.on('click', function(d, i){
BASEBALL_ANIM_APP.ballManuallySelected(i);
});
// create a cell in each row for each column
var cells = rows.selectAll('td')
.data(function (row) {
return columns.map(function (column) {
return {value: row[column.key]};
});
})
.enter()
.append('td')
.text(function (d) { return d.value; });
return table;
},
initDistanceModule: function(){
var that = this;
var options = this.distanceModuleOptions;
var graphWidth = options.width - options.margins.left - options.margins.right,
graphHeight = options.height - options.margins.top - options.margins.bottom;
var svg = d3.select(options.appendToSelector)
.append("svg")
.attr("width", options.width)
.attr("height", options.height);
options.mainGroup = svg.append('g')
.attr('transform', 'translate(' + options.margins.left + ',' + options.margins.top + ')')
.attr('id', options.id);
// title text
options.mainGroup.append("text")
.attr("x", 0)
.attr("y", 0)
.attr("font-weight", "bold")
.attr("font-size", "14px")
.attr("alignment-baseline", "hanging")
.attr("dominant-baseline", "hanging") // for firefox
.attr("class", "title")
.style("fill", this.mainColor)
.text("DISTANCE");
// ft label
options.mainGroup.append("text")
.attr("x", graphWidth)
.attr("y", 28)
.attr("font-size", "18px")
.attr("alignment-baseline", "baseline")
.attr("dominant-baseline", "baseline") // for firefox
.attr("text-anchor", "end")
.style("fill", this.mainColor)
.html("ft");
// ft value
options.mainGroup.append("text")
.attr("id", "ft-value")
.attr("x", graphWidth - 14)
.attr("y", 28)
.attr("font-weight", "bold")
.attr("font-size", "28px")
.attr("alignment-baseline", "baseline")
.attr("dominant-baseline", "baseline") // for firefox
.attr("text-anchor", "end")
.style("fill", this.mainColor)
.html("0");
// Define the div for the tooltip
var tooltip = d3.select("body")
.append("div")
.attr("class", "tooltip")
.style("opacity", 0);
options.schemeRadius = Math.round(0.5 * graphWidth / Math.cos(45 * Math.PI / 180));
options.schemeBasePoint = {
x: Math.round(0.5 * graphWidth),
y: graphHeight
};
var arcGen = d3.arc()
.startAngle(-45 * Math.PI / 180)
.endAngle(45 * Math.PI / 180);
var scaleRadius = d3.scaleLinear()
.domain([0, d3.max(options.radii)])
.range([0, options.schemeRadius]);
// outfield
options.mainGroup.append('path')
.attr("d", arcGen({
innerRadius: 0,
outerRadius: scaleRadius(d3.max(options.radii))
}))
.attr("transform", 'translate('+options.schemeBasePoint.x+', '+options.schemeBasePoint.y+')')
.attr("fill", '#0a6d08');
// infield
options.mainGroup.append('path')
.attr("d", arcGen({
innerRadius: 0,
outerRadius: scaleRadius(d3.min(options.radii))
}))
.attr("transform", 'translate('+options.schemeBasePoint.x+', '+options.schemeBasePoint.y+')')
.attr("fill", '#5e3d0b');
var radii = options.radii;
var innerRadius, outerRadius;
for(var i=0; i < radii.length; i++){
innerRadius = scaleRadius(radii[i]);
outerRadius = innerRadius;
if(i == 0){
innerRadius = 0;
}
options.mainGroup.append('path')
.attr("d", arcGen({
innerRadius: innerRadius,
outerRadius: outerRadius
}))
.attr("transform", 'translate('+options.schemeBasePoint.x+', '+options.schemeBasePoint.y+')')
.attr("fill", 'none')
.attr("stroke", '#777777')
.attr("stroke-width", '1');
// labels left
options.mainGroup.append("text")
.attr("x", options.schemeBasePoint.x)
.attr("y", options.schemeBasePoint.y - scaleRadius(radii[i]))
.attr("transform", "translate(-3,0) rotate(-45,"+options.schemeBasePoint.x+", "+options.schemeBasePoint.y+")")
.attr("text-anchor", i == 0 ? "start" : "end")
.attr("font-size", "12px")
.attr("font-weight", "bold")
.attr("alignment-baseline", i == 0 ? "auto" : "middle")
.attr("dominant-baseline", i == 0 ? "auto" : "middle") // for firefox
.style("fill", '#777777')
.text(radii[i]);
// labels right
options.mainGroup.append("text")
.attr("x", options.schemeBasePoint.x)
.attr("y", options.schemeBasePoint.y - scaleRadius(radii[i]))
.attr("transform", "translate(3,0) rotate(45,"+options.schemeBasePoint.x+", "+options.schemeBasePoint.y+")")
.attr("text-anchor", i == 0 ? "end" : "start")
.attr("font-size", "12px")
.attr("font-weight", "bold")
.attr("alignment-baseline", i == 0 ? "auto" : "middle")
.attr("dominant-baseline", i == 0 ? "auto" : "middle") // for firefox
.style("fill", '#777777')
.text(radii[i]);
}
options.mainGroup.selectAll('circle')
.data(this.data)
.enter()
.append('circle')
.attr('id', function(d,i){return 'ball-'+i;})
.attr('class', 'ball')
.attr('fill', options.defaultBallColor)
.attr('stroke', 'none')
.attr('r', 5)
.attr('cx', function(d, i){return options.schemeBasePoint.x + scaleRadius(d.distance * Math.sin(d.hAngle * Math.PI / 180))})
.attr('cy', function(d, i){return options.schemeBasePoint.y - scaleRadius(d.distance * Math.cos(d.hAngle * Math.PI / 180))})
.on('click', function(d, i) {
var el = d3.select(this);
that.ballManuallySelected(i);
})
.on('mouseenter', function(d) {
var el = d3.select(this);
// tooltip
tooltip.transition()
.duration(200)
.style("opacity", .8);
tooltip.html(parseFloat(d.exitSpeed).toFixed(1)+' mph')
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
// classes
if(el.classed(options.ballActiveClass))
return;
el.classed(options.ballHoverClass, true);
})
.on('mouseout', function(d) {
var el = d3.select(this);
// tooltip
tooltip.transition()
.duration(500)
.style("opacity", 0);
// classes
if(el.classed(options.ballActiveClass))
return;
el.classed(options.ballHoverClass, false);
});
},
initExitLaunchAngleModule: function(){
var options = this.exitLaunchAngleModuleOptions;
var graphWidth = options.width - options.margins.left - options.margins.right,
graphHeight = options.height - options.margins.top - options.margins.bottom;
var svg = d3.select(options.appendToSelector)
.append("svg")
.attr("width", options.width)
.attr("height", options.height);
options.mainGroup = svg.append('g')
.attr('transform', 'translate(' + options.margins.left + ',' + options.margins.top + ')')
.attr('id', options.id);
// title text
options.mainGroup.append("text")
.attr("x", 0)
.attr("y", 0)
.attr("font-weight", "bold")
.attr("font-size", "14px")
.attr("alignment-baseline", "hanging")
.attr("dominant-baseline", "hanging") // for firefox
.attr("class", "title")
.style("fill", this.mainColor)
.text("EXIT LAUNCH ANGLE");
// angle text
options.mainGroup.append("text")
.attr("id", "angle-label")
.attr("x", graphWidth)
.attr("y", 0)
.attr("font-weight", "bold")
.attr("font-size", "28px")
.attr("alignment-baseline", "hanging")
.attr("dominant-baseline", "hanging") // for firefox
.attr("class", "angle")
.attr("text-anchor", "end")
.style("fill", this.mainColor)
.html("0&#176;");
options.schemeRadius = Math.round((graphHeight - 30) * 0.5);
options.vectorLength = Math.round(options.schemeRadius * 0.85);
options.schemeBasePoint = {
x: Math.round(1/3 * graphWidth),
y: graphHeight - options.schemeRadius
};
// outer arc
var outerArc = d3.arc()
.innerRadius(0)
.outerRadius(0.6 * options.schemeRadius)
.startAngle(0)
.endAngle(180 * Math.PI / 180);
options.mainGroup.append('path')
.attr("d", outerArc)
.attr("transform", 'translate('+options.schemeBasePoint.x+', '+options.schemeBasePoint.y+')')
.attr("fill", '#dee0df')
.attr("stroke-width", '0');
// inner arc
var innerArc = d3.arc()
.innerRadius(0)
.outerRadius(0.44 * options.schemeRadius)
.startAngle(0)
.endAngle(180 * Math.PI / 180);
options.mainGroup.append('path')
.attr("d", innerArc)
.attr("transform", 'translate('+options.schemeBasePoint.x+', '+options.schemeBasePoint.y+')')
.attr("fill", this.mainLightColor)
.attr("stroke", this.mainColor)
.attr("stroke-width", 0);
// vector arc
options.vectorArcGenerator = d3.arc()
.innerRadius(0)
.outerRadius(0.44 * options.schemeRadius)
.startAngle(90 * Math.PI / 180)
.endAngle(function(d) { return (90 - d) * Math.PI / 180; });
options.mainGroup.append('path')
.attr("id", "vector-arc")
.attr("d", options.vectorArcGenerator(0))
.attr("transform", 'translate('+options.schemeBasePoint.x+', '+options.schemeBasePoint.y+')')
.attr("fill", this.mainColor);
// vector
options.mainGroup.append("line")
.style("stroke", this.mainColor)
.attr("id", "vector")
.attr("x1", options.schemeBasePoint.x)
.attr("y1", options.schemeBasePoint.y)
.attr("x2", options.schemeBasePoint.x + options.vectorLength)
.attr("y2", options.schemeBasePoint.y)
.attr("stroke-width", 1.5);
// x axis
options.mainGroup.append("line")
.style("stroke", this.mainColor) // colour the line
.attr("x1", options.schemeBasePoint.x) // x position of the first end of the line
.attr("y1", options.schemeBasePoint.y) // y position of the first end of the line
.attr("x2", options.schemeBasePoint.x + options.schemeRadius) // x position of the second end of the line
.attr("y2", options.schemeBasePoint.y)
.attr("stroke-width", 3);
// y axis
options.mainGroup.append("line")
.style("stroke", this.mainColor) // colour the line
.attr("x1", options.schemeBasePoint.x) // x position of the first end of the line
.attr("y1", options.schemeBasePoint.y + options.schemeRadius) // y position of the first end of the line
.attr("x2", options.schemeBasePoint.x) // x position of the second end of the line
.attr("y2", options.schemeBasePoint.y - options.schemeRadius)
.attr("stroke-width", 3);
},
initExitDirectionModule: function(){
var options = this.exitDirectionModuleOptions;
var graphWidth = this.exitDirectionModuleOptions.width - this.exitDirectionModuleOptions.margins.left - this.exitDirectionModuleOptions.margins.right,
graphHeight = this.exitDirectionModuleOptions.height - this.exitDirectionModuleOptions.margins.top - this.exitDirectionModuleOptions.margins.bottom;
var svg = d3.select(options.appendToSelector)
.append("svg")
.attr("width", options.width)
.attr("height", options.height);
options.mainGroup = svg.append('g')
.attr('transform', 'translate(' + options.margins.left + ',' + options.margins.top + ')')
.attr('id', options.id);
// Add the Title
options.mainGroup.append("text")
.attr("x", 0)
.attr("y", 0)
.attr("font-weight", "bold")
.attr("font-size", "14px")
.attr("alignment-baseline", "hanging")
.attr("dominant-baseline", "hanging") // for firefox
.attr("class", "title")
.style("fill", this.mainColor)
.text("EXIT DIRECTION");
options.mainGroup.append("text")
.attr("id", "angle-label")
.attr("x", graphWidth)
.attr("y", 0)
.attr("font-weight", "bold")
.attr("font-size", "28px")
.attr("alignment-baseline", "hanging")
.attr("dominant-baseline", "hanging") // for firefox
.attr("class", "angle")
.attr("text-anchor", "end")
.style("fill", this.mainColor)
.html("0&#176;");
options.schemeRadius = Math.round(graphWidth * 0.5 * 0.66);
options.schemeBasePoint = {
x: Math.round(graphWidth / 2),
y: graphHeight
};
// outer arc
var outerArc = d3.arc()
.innerRadius(0)
.outerRadius(4/5 * options.schemeRadius)
.startAngle(-45 * Math.PI / 180)
.endAngle(45 * Math.PI / 180);
options.mainGroup.append('path')
.attr("d", outerArc)
.attr("transform", 'translate('+options.schemeBasePoint.x+', '+options.schemeBasePoint.y+')')
.attr("fill", '#dee0df')
.attr("stroke-width", '0');
// inner arc
var innerArc = d3.arc()
.innerRadius(0)
.outerRadius(4/7 * options.schemeRadius)
.startAngle(-45 * Math.PI / 180)
.endAngle(45 * Math.PI / 180);
options.mainGroup.append('path')
.attr("d", innerArc)
.attr("transform", 'translate('+options.schemeBasePoint.x+', '+options.schemeBasePoint.y+')')
.attr("fill", this.mainLightColor)
.attr("stroke", this.mainColor)
.attr("stroke-width", 2);
// vector arc
options.vectorArcGenerator = d3.arc()
.innerRadius(0)
.outerRadius(4/7 * options.schemeRadius)
.startAngle(0)
.endAngle(function(d) { return d * Math.PI / 180; });
options.mainGroup.append('path')
.attr("id", "vector-arc")
.attr("d", options.vectorArcGenerator(0))
.attr("transform", 'translate('+options.schemeBasePoint.x+', '+options.schemeBasePoint.y+')')
.attr("fill", this.mainColor);
options.mainGroup.append("line")
.style("stroke", this.mainColor) // colour the line
.attr("x1", options.schemeBasePoint.x) // x position of the first end of the line
.attr("y1", options.schemeBasePoint.y) // y position of the first end of the line
.attr("x2", options.schemeBasePoint.x + options.schemeRadius) // x position of the second end of the line
.attr("y2", options.schemeBasePoint.y - options.schemeRadius)
.attr("stroke-width", 3);
options.mainGroup.append("line")
.style("stroke", this.mainColor) // colour the line
.attr("x1", options.schemeBasePoint.x) // x position of the first end of the line
.attr("y1", options.schemeBasePoint.y) // y position of the first end of the line
.attr("x2", options.schemeBasePoint.x - options.schemeRadius) // x position of the second end of the line
.attr("y2", options.schemeBasePoint.y - options.schemeRadius)
.attr("stroke-width", 3);
// vector
options.mainGroup.append("line")
.style("stroke", this.mainColor) // colour the line
.attr("id", "vector") // x position of the first end of the line
.attr("x1", options.schemeBasePoint.x) // x position of the first end of the line
.attr("y1", options.schemeBasePoint.y) // y position of the first end of the line
.attr("x2", options.schemeBasePoint.x) // x position of the second end of the line
.attr("y2", options.schemeBasePoint.y - options.schemeRadius)
.attr("stroke-width", 1.5);
},
animateExitLaunchAngleModule: function(){
var options = this.exitLaunchAngleModuleOptions;
var data = this.data[this.activeIndex];
options.mainGroup
.select('#'+options.id+' #vector')
.datum(data)
.transition()
.duration(this.animation.duration)
.tween("animations", function(d){
var el = d3.select(this);
var angleLabel = d3.select('#'+options.id+' #angle-label');
var vectorArc = d3.select('#'+options.id+' #vector-arc');
var X2 = +el.attr("x2");
var Y2 = +el.attr("y2");
var fromAngle = 180 / Math.PI * Math.asin((options.schemeBasePoint.y - Y2) / options.vectorLength);
var toAngle = d['vAngle'];
var iAngle = d3.interpolateNumber(fromAngle, toAngle);
return function(t){
el.attr("x2", options.schemeBasePoint.x + (options.vectorLength * Math.cos(iAngle(t) * Math.PI / 180)));
el.attr("y2", options.schemeBasePoint.y - (options.vectorLength * Math.sin(iAngle(t) * Math.PI / 180)));
angleLabel.html(Math.round(iAngle(t)) + "&#176;");
vectorArc.attr("d", options.vectorArcGenerator(iAngle(t)))
}
})
},
animateExitDirectionModule: function(){
var options = this.exitDirectionModuleOptions;
var data = this.data[this.activeIndex];
options.mainGroup
.select('#'+options.id+' #vector')
.datum(data)
.transition()
.duration(this.animation.duration)
.tween("animations", function(d){
var el = d3.select(this);
var angleLabel = d3.select('#'+options.id+' #angle-label');
var vectorArc = d3.select('#'+options.id+' #vector-arc');
var X2 = +el.attr("x2");
var Y2 = +el.attr("y2");
var fromAngle = 180 / Math.PI * Math.asin((X2 - options.schemeBasePoint.x) / options.schemeRadius);
var toAngle = d['hAngle'];
var iAngle = d3.interpolateNumber(fromAngle, toAngle);
return function(t){
el.attr("x2", options.schemeBasePoint.x + (options.schemeRadius * Math.sin(iAngle(t) * Math.PI / 180)));
el.attr("y2", options.schemeBasePoint.y - (options.schemeRadius * Math.cos(iAngle(t) * Math.PI / 180)));
var suffix = "&#176;";
if(iAngle(t) >= 0){
suffix += 'R';
}else{
suffix += 'L';
}
angleLabel.html(Math.round(iAngle(t)) + suffix);
vectorArc.attr("d", options.vectorArcGenerator(iAngle(t)))
}
})
},
animateDistanceModule: function(){
var options = this.distanceModuleOptions;
var data = this.data[this.activeIndex];
this.setBallActive(this.activeIndex);
},
animateTableModule: function(){
this.setRowActive(this.activeIndex);
},
startTimer: function(){
var that = this;
var animationDelay = this.animation.duration + this.animation.delay;
var dataLength = this.dataLength();
var prevTickNum = null;
var tickNum;
this.timer = d3.timer(function(elapsed){
tickNum = Math.floor(elapsed / animationDelay);
if(prevTickNum !== tickNum){
prevTickNum = tickNum;
that.setActiveIndex(tickNum % dataLength);
that.updateModules();
}
})
},
stopTimer: function(){
this.timer.stop();
},
updateModules: function(){
this.animateExitLaunchAngleModule();
this.animateExitDirectionModule();
this.animateDistanceModule();
this.animateTableModule();
},
setActiveIndex:function(index){
this.activeIndex = index;
},
setRowActive: function(index){
var options = this.tableModuleOptions;
var table = d3.select('#'+options.id);
var tr = table.select('#ball-'+index);
// only one active
var alreadyIsActive = tr.classed(options.rowActiveClass);
if(alreadyIsActive)
return;
table.selectAll('#'+options.id+' tr')
.classed(options.rowActiveClass, false);
tr.classed(options.rowActiveClass, !alreadyIsActive);
},
ballManuallySelected: function(index){
this.setBallActive(index);
this.stopTimer();
this.setActiveIndex(index);
this.updateModules();
},
setBallActive:function(index){
var options = this.distanceModuleOptions;
var el = d3.select('#'+options.id+' #ball-'+index);
var datum = el.datum();
// update ft-value
options.mainGroup.select('#'+options.id+' #ft-value')
.text(Math.round(datum['distance']));
// only one active
var alreadyIsActive = el.classed(options.ballActiveClass);
if(alreadyIsActive)
return;
options.mainGroup.selectAll('#'+options.id+' .ball')
.classed(options.ballActiveClass, false);
el.classed(options.ballActiveClass, !alreadyIsActive);
el.classed(options.ballHoverClass, false);
},
isDataLoaded: function(){
return this.dataLength();
},
dataLength: function(){
return this.data.length;
}
};
BASEBALL_ANIM_APP.start();
circle.ball.active{
fill: #ffffff;
}
circle.ball.hovered{
fill: #c6c6c6;
}
table {
border-collapse: collapse;
}
.table {
width: 100%;
max-width: 100%;
margin-bottom: 1rem;
background-color: transparent;
font-size: 0.92rem;
}
.table thead th {
vertical-align: bottom;
border-bottom: 2px solid #e9ecef;
}
.table tr.active{
background-color: #c5e8f5;
}
.table td, .table th {
padding: .3rem;
vertical-align: top;
border-top: 1px solid #e9ecef;
text-align: center;
}
.table td, .table th {
padding: .3rem;
vertical-align: top;
border-top: 1px solid #e9ecef;
}
div.tooltip {
position: absolute;
text-align: center;
width: 60px;
height: 28px;
line-height: 28px;
padding: 6px 2px 2px 2px;
font: 12px sans-serif;
background: black;
border: 0px;
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;
pointer-events: none;
color:white;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment