xxxxxxxxxx
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test</title>
<script src="https://d3js.org/d3.v3.min.js"></script>
<style type="text/css">
body {
background-color: #ddddff;
}
svg {
background-color: #C1C1CD;
background-color: rgb(52, 73, 89);
}
rect.followers:hover {
fill: #ADBFE5;
}
rect.friends:hover {
fill: #D8D8D8;
}
.axis path, .axis line {
fill: none;
stroke: grey;
shape-rendering: crispEdges;
}
text {
font-family: Verdana, Arial;
font-size: 13px;
font-weight: normal;
text-transform: uppercase;
color: black;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
color: black;
}
.axistitle {
color: white; !important
}
div.tooltip {
position: absolute;
text-align: left;
padding: 8px;
font: 10px Verdana;
background: lightsteelblue;
border: px;
border-radius: 8px;
pointer-events: none;
}
.tweep {
stroke: steelblue;
fill: lightblue;
}
.tweepSelected{
stroke: steelblue;
fill: orange;
}
</style>
</head>
<body>
<div id="main"></div>
<script>
Math.log10 = function(n) {
if (n==0) {
return 0
} else {
return (Math.log(n)) / (Math.log(10))
}}
//https://groups.google.com/forum/#!topic/d3-js/kVEcSdqsv30
var numberFormat = d3.format(",s");
function logFormat(d) {
var x = Math.log(d) / Math.log(10) + 1e-6;
if (Math.abs(x - Math.floor(x)) < .4) {
return numberFormat(d)
} else if (Math.abs(x - Math.floor(x)) > .5 && Math.abs(x - Math.floor(x)) < .65) {
return numberFormat(d)
} else if (Math.abs(x - Math.floor(x)) > .77 && Math.abs(x - Math.floor(x)) < .8) {
return numberFormat(d)
} else {
return ""
}};
accountAge = function(n) {
return d3.round((((new Date()).getTime() - date_format.parse(n).getTime())/(1000*3600*24*365)), 1)
}
var width = 700,
height = 600,
padding = [ 120, 70, 80, 100 ]; //Top, right, bottom, left
var svg = d3.select("#main").append("svg")
.attr("width", width)
.attr("height", height);
//Create tooltip element
var tooltip = d3.select("#main")
.append("div")
.attr("class", "tooltip")
.style("position", "absolute")
.style("z-index", "10")
.style("opacity", 0);
var xScale = d3.scale
.log()
.clamp(true)
.nice()
.range([padding[3] ,width - padding[1]]);
var yScale = d3.scale
.log()
.clamp(true)
.nice()
.range([padding[0], height - padding[2]]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(3)
//.tickFormat(d3.format('s'));
.tickFormat(logFormat);
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.ticks(6, "e")
.tickFormat(logFormat);
// .tickFormat(d3.format('s'));
var accountAgeScale = d3.scale.linear()
.range(["steelblue", "brown"])
.interpolate(d3.interpolateHcl);
var now = new Date()
var date_format = d3.time.format("%Y-%m-%d %X");
//Drag event declaration
var drag = d3.behavior.drag()
.origin(Object)
.on("drag", function(d){
if(Math.abs(d3.event.dx) > 3) //helps prevent accidental circle removal
{
d3.select(this).transition() //Remove dragged circle
.duration(300)
.attr("r", 0);
}
});
d3.csv("tweeps.csv", function(data) {
var max_followers_count = d3.max(data, function(d) { return parseInt(d.followers_count); });
var min_followers_count = d3.min(data, function(d) { return parseInt(d.followers_count); });
var max_friends_count = d3.max(data, function(d) { return parseInt(d.friends_count); });
var min_friends_count = d3.min(data, function(d) { return parseInt(d.friends_count); });
var max_fplusf = d3.max(data, function(d) { return parseInt(d.friends_count) + parseInt(d.followers_count); });
var max_fplusf_log = d3.max(data, function(d) { return Math.log10(parseInt(d.friends_count)) + Math.log10(parseInt(d.followers_count)); });
var max_status_count = d3.max(data, function(d) { return parseInt(d.statuses_count); });
//data.sort(function(a, b) {
// return d3.descending(+a.followers_count, +b.followers_count); // + signs because it makes ints from strrings
// });
yScale.domain([max_followers_count, min_followers_count]);
xScale.domain([min_friends_count+1, max_friends_count]);
// accountAgeScale.domain(
//console.log(max_followers_count);
//console.log(max_friends_count);
//console.log(max_fplusf);
//console.log(max_fplusf_log);
//console.log(Math.pow(10, max_fplusf_log));
//console.log(Math.log10(max_friends_count));
//console.log(Math.log10(max_followers_count));
//console.log(now);
var tweeps = svg.selectAll("g")
.data(data)
.enter()
.append("circle")
.sort(function(a, b){ //Sort by radius size, helps reduce obstruction of circles
return d3.descending(a.statuses_count, b.statuses_count)})
.attr("class", "tweep")
.attr("id", function(d) { return d.id; })
.attr("cx", function(d) { return xScale(d.friends_count) } )
.attr("cy", function(d) { return yScale(d.followers_count) || height - padding[2] } )
//.attr("fill", "blue")
//.attr("r", function(d) { return Math.log10(parseInt(d.statuses_count))*2} )
.attr("r", function(d) { return parseInt(d.statuses_count)/1900} )
//.style("opacity", 0.5)
.style("opacity", function(d) { if (parseInt(d.statuses_count)/max_status_count < 0.6 ) {
return 0.6
} else if (parseInt(d.statuses_count)/max_status_count > 0.9) {
return 0.9
} else {
return 0.5 + parseInt(d.statuses_count)/max_status_count - 0.4
}} )
// .append("title")
// .text(function(d) { return d.name + " has " + d.friends_count + " friends " + d.statuses_count + " tweets " + "is " + accountAge(d.created_at) + " years old" ;} )
.attr("tweepname", function(d){ return d.name; }) //Set tweepname for tooltip display
.attr("followers", function(d){ return d.followers_count; }) //Set followers for tooltip display
.attr("friends", function(d){ return d.friends_count; }) //Set friends for tooltip display
.attr("tweets", function(d){ return d.statuses_count; }) //Set tweets for tooltip display
.on("mousedown", mousedown)
.on("mouseover", mouseover)
.on("mousemove", mousemove)
.on("mouseout", mouseout)
.call(drag);
// Tooltip function from https://jsfiddle.net/kingernest/YDQR4/1/
function mousemove()
{ //Move tooltip to mouse location
return tooltip.style("top", (event.pageY-10)+"px").style("left",(event.pageX+10)+"px");
}
function mouseout()
{
d3.select(this)
.attr("class", "tweep"); //Recolor circle steel blue
tooltip.transition()
.delay(100)
.style("opacity", 0) //Make tooltip invisible
svg.selectAll("circle")
.transition()
.style("opacity", function(d) { if (parseInt(d.statuses_count)/max_status_count < 0.6 ) {
return 0.3
} else if (parseInt(d.statuses_count)/max_status_count > 0.9) {
return 0.7
} else {
return 0.5 + parseInt(d.statuses_count)/max_status_count - 0.7
}} ); //
}
//Mouseover function for circles, displays shortened tooltip and causes other circles to become opaque
function mouseover()
{
var myCircle = d3.select(this);
d3.select(this).attr("class", "tweepSelected"); //Color circle green
tooltip.html( //Populate tooltip text
"Tweep: " + d3.select(this).attr("tweepname") + "<br/>" +
"Followers: " + d3.select(this).attr("followers") + "<br/>" +
"Friend: " + d3.select(this).attr("friends")
)
.transition()
.duration(500)
.style("opacity", .7);
}
function mousedown()
{
tooltip.transition()
.duration(200)
.style("opacity", 1);
tooltip.html(
"Tweep: " + d3.select(this).attr("tweepname") + "<br/>" +
"Followers: " + d3.select(this).attr("followers") + "<br/>" +
"Friend: " + d3.select(this).attr("friends") + "<br/>" +
"Tweets: " + d3.select(this).attr("tweets")
)
}
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (height - padding[2] + 10) + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + (padding[3] - 10) + ",0)")
.call(yAxis);
svg.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0 + padding[3]-60 )
.attr("x", 0-(height/2)-padding[0]+100 )
.attr("class", "axistitle")
.style("text-anchor", "middle")
.text("# Followers of Tweep");
svg.append("text") // text label for the x axis
.attr("x", padding[3] + (width-padding[1]-padding[3])/2 )
.attr("y", height - padding[2]+ 60)
.attr("class", "axistitle")
.style("text-anchor", "middle")
.text("# Friends of Tweep");
});
</script>
</body>
</html>
Modified http://d3js.org/d3.v3.min.js to a secure url
https://d3js.org/d3.v3.min.js