Built with blockbuilder.org
Last active
July 12, 2017 20:01
-
-
Save kalpanavaidya/dbf4fad564b4b4b317ac02d716db0f9a to your computer and use it in GitHub Desktop.
addElements
This file contains 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
license: mit |
This file contains 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
<!DOCTYPE html> | |
<!-- Allows creating new values outside the normal scale | |
Then updates axis, scales, and circle attributes --> | |
<html> | |
<head> | |
<!-- Load D3 from site --> | |
<!-- CSS (Styling) --> | |
<style type="text/css"> | |
body { | |
margin: 0; | |
font-family: sans-serif; | |
font-size: 11px; | |
} | |
.axis path, .axis line { | |
fill: none; | |
stroke: black; | |
shape-rendering: crispEdges; /* Round any decimal pixels so it'll render nicely */ | |
} | |
/* | |
//Can use CSS3 Transitions, but not for everything (e.g. change radius size) | |
circle:hover{ | |
fill: green; | |
} | |
*/ | |
</style> | |
</head> | |
<body> | |
<!-- Begin Javascript --> | |
<script src="http://d3js.org/d3.v4.min.js"></script> | |
<script type="text/javascript"> | |
var w = window.innerWidth, | |
h = window.innerHeight, | |
margin = { top: 40, right: 20, bottom: 20, left: 40 }, | |
radius = 6; | |
var svg = d3.select("body").append("svg").attr({ | |
width: w, | |
height: h | |
}); | |
var dataset = [ | |
{ x: 100, y: 110 }, | |
{ x: 83, y: 43 }, | |
{ x: 92, y: 28 }, | |
{ x: 49, y: 74 }, | |
{ x: 51, y: 10 }, | |
{ x: 25, y: 98 }, | |
{ x: 77, y: 30 }, | |
{ x: 20, y: 83 }, | |
{ x: 11, y: 63 }, | |
{ x: 4, y: 55 }, | |
{ x: 0, y: 0 }, | |
{ x: 85, y: 100 }, | |
{ x: 60, y: 40 }, | |
{ x: 70, y: 80 }, | |
{ x: 10, y: 20 }, | |
{ x: 40, y: 50 }, | |
{ x: 25, y: 31 } | |
]; | |
// We're passing in a function in d3.max to tell it what we're maxing (x value) | |
var xScale = d3.scaleLinear() | |
.domain([0, d3.max(dataset, function (d) { return d.x + 10; })]) | |
.range([margin.left, w - margin.right]); // Set margins for x specific | |
// We're passing in a function in d3.max to tell it what we're maxing (y value) | |
var yScale = d3.scaleLinear() | |
.domain([0, d3.max(dataset, function (d) { return d.y + 10; })]) | |
.range([margin.top, h - margin.bottom]); // Set margins for y specific | |
// Add a X and Y Axis (Note: orient means the direction that ticks go, not position) | |
var xAxis = d3.axisBottom(xScale).tickFormat(function (d) { return d.x; }); | |
var yAxis = d3.axisLeft(yScale); | |
// Sets circles attributes | |
var circleAttrs = { | |
cx: function(d) { return xScale(d.x); }, | |
cy: function(d) { return yScale(d.y); }, | |
r: radius | |
}; | |
// Adds X-Axis as a 'g' element | |
var xAxisGroup = svg.append("g").attr({ | |
"class": "axis", // Give class so we can style it | |
transform: "translate(" + [0, margin.top] + ")" // Translate just moves it down into position (or will be on top) | |
}).call(xAxis); // Call the xAxis function on the group | |
// Adds Y-Axis as a 'g' element | |
var yAxisGroup = svg.append("g").attr({ | |
"class": "axis", | |
transform: "translate(" + [margin.left, 0] + ")" | |
}).call(yAxis); // Call the yAxis function on the group | |
var drag = d3.drag() | |
.on('dragstart', function(d, i) { | |
d3.event.sourceEvent.stopPropagation(); | |
d3.select("#t" + d.x + "-" + d.y + "-" + i).remove(); | |
}) | |
.on('drag', dragged) | |
.on('dragend', dragended); | |
var circles = svg.selectAll("circle") | |
.data(dataset) | |
.enter() | |
.append("circle") | |
.attr(circleAttrs) // Get attributes from circleInitialAttrs var | |
.on("mouseover", handleMouseOver) | |
.on("mouseout", handleMouseOut) | |
.call(drag); | |
// On Click, we want to add data to the array and chart | |
svg.on("click", function() { | |
if(d3.event.defaultPrevented) return; | |
var coords = d3.mouse(this); | |
// Normally we go from data to pixels, but here we're doing pixels to data | |
var newData= { | |
x: Math.round( xScale.invert(coords[0])), // Takes the pixel number to convert to number | |
y: Math.round( yScale.invert(coords[1])) | |
}; | |
dataset.push(newData); // Push data to our array | |
xScale.domain([0, d3.max(dataset, function (d) { return d.x + 10; })]) | |
yScale.domain([0, d3.max(dataset, function (d) { return d.y + 10; })]) | |
// Update Axis (e.g. might increase if new higher value added) | |
xAxisGroup.transition().call(xAxis); // Update X-Axis | |
yAxisGroup.transition().call(yAxis); // Update Y-Axis | |
// When adding new items, goes from 0,0 and transition to place | |
var c = svg.selectAll("circle") // For new circle, go through the update process | |
.data(dataset); | |
// Updates existing circles to new positions by just adding attr | |
c.transition() | |
.ease("elastic") | |
.attr(circleAttrs) | |
c.enter() | |
.append("circle") | |
.attr(circleAttrs) | |
.on("mouseover", handleMouseOver) | |
.on("mouseout", handleMouseOut) | |
.call(drag); | |
}) | |
// Create Event Handlers for mouse | |
function handleMouseOver(d, i) { // Add interactivity | |
// Use D3 to select element, change color and size | |
d3.select(this).attr({ | |
fill: "orange", | |
r: radius * 2 | |
}); | |
// Specify where to put label of text | |
svg.append("text").attr({ | |
id: "t" + d.x + "-" + d.y + "-" + i, // Create an id for text so we can select it later for removing on mouseout | |
x: function() { return xScale(d.x) - 30; }, | |
y: function() { return yScale(d.y) - 15; } | |
}) | |
.text(function() { | |
return [d.x, d.y]; // Value of the text | |
}); | |
} | |
function handleMouseOut(d, i) { | |
// Use D3 to select element, change color back to normal | |
d3.select(this).attr({ | |
fill: "black", | |
r: radius | |
}); | |
// Select text by id and then remove | |
d3.select("#t" + d.x + "-" + d.y + "-" + i).remove(); // Remove text location | |
} | |
function dragged(d,i) { | |
if(d3.event.x >= margin.left && d3.event.y >= margin.top | |
&& d3.event.x <= w | |
&& d3.event.y <= h) { | |
d.x = d3.event.x; | |
d.y = d3.event.y; | |
console.log(d3.event.x + " " + d3.event.y); | |
d3.select(this) | |
.attr("cx", d.x ) | |
.attr("cy", d.y ); | |
} | |
} | |
function dragended(d, i) { | |
console.log("end"); | |
var newX = Math.round(xScale.invert(d.x)), | |
newY = Math.round(yScale.invert(d.y)); | |
dataset[i].x = newX; | |
dataset[i].y = newY; | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment