Skip to content

Instantly share code, notes, and snippets.

@zanarmstrong
Last active November 8, 2015 20:05
Show Gist options
  • Save zanarmstrong/c9bb2842647140265d57 to your computer and use it in GitHub Desktop.
Save zanarmstrong/c9bb2842647140265d57 to your computer and use it in GitHub Desktop.
adding waves
body {
background-color: #393939;
font-family: 'Raleway', sans-serif;
}
.area {
fill: lightsteelblue;
stroke-width: 0;
}
rect {
stroke-width: .4px;
stroke: #393939;
}
.topLine {
fill: red;
}
.mainWave {
fill: white;
}
.mainWaveHighlight {
fill: gray;
}
svg {
shape-rendering:"crisp-edges";
}
/* slider stuff */
.axis {
fill: gray;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.slider {
width: 50px;
}
.slider .handle .mainVertical {
stroke-width: 3px;
stroke-linecap: round;
stroke: white;
}
.slider .handle .halo {
stroke-width: 50px;
stroke-linecap: round;
opacity: 0;
}
.slider .handle text {
text-align: center;
font-size: 14px;
fill: white;
}
"use strict";
// parameters
if(window.innerWidth > 500){
var margin = {
top: 50,
right: 50,
bottom: 50,
left: 50
};
} else {
var margin = {
top: 5,
right: 5,
bottom: 5,
left: 5
};
}
var width = window.innerWidth - margin.left - margin.right,
height = window.innerHeight - margin.bottom - margin.top;
// for graphing parameters
var amp = 50,
period = width/6,
verticalShift = 200,
numWaves = 3,
offShift = period * numWaves,
floor = amp + verticalShift,
constantHeightWave2 = 20,
capHeight = 2,
barWidth = 4;
// check for mobile
if(window.innerWidth < 500){
barWidth = 1;
capHeight = 1;
}
/* set up major elements */
var sineArea = d3.svg.area();
// function for wave 1
function sineY(d) {
return amp * Math.cos(((d) * 2 * Math.PI) / period)
};
// function for wave 2
function sineY2(d) {
return amp * Math.cos(((d + period / 2) * 2 * Math.PI) / period)
};
// height from baseline for wave 1
function sineYheight(d) {
return sineY(d) - amp;
}
// height to add to wave 2, based on wave 1 and if they overlap
function addWave(d) {
// check for overlap of waves, return 0 if not overlapping or return wave height
if (d + offShift > period * numWaves) {
return 0;
} else {
return (sineYheight(d + offShift));
}
}
// define x, y0, and y1 for left wave
sineArea
.x(function(d) {
return d;
})
.y0(function(d) {
return sineY(d) + verticalShift
})
.y1(amp + verticalShift);
// standard svg intro
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// set up data to use with d3
// wave 1
var k1 = [];
for (var i = 0; i < period * numWaves; i++) {
k1.push(i)
}
// wave 2
var k2 = [];
for (var i = 0; i < period * numWaves / barWidth; i++) {
k2.push(i * barWidth)
}
// x and y functions
var positionFunctions = {
x: function(d) {
return d + offShift - barWidth / 2
},
y: function(d) {
return verticalShift - sineY2(d) + addWave(d) - constantHeightWave2;
}
};
function highlight() {
this.classList.toggle('mainWaveHighlight')
}
// set up function for rectangles
function drawRectBody(z) {
z
.attr("x", positionFunctions.x)
.attr("height", function(d) {
return amp + sineY2(d) + constantHeightWave2;
})
.attr("y", positionFunctions.y)
.attr("width", barWidth)
.on("click", highlight)
.attr("class", 'mainWave');
};
function drawRectCap(z) {
z.attr("x", positionFunctions.x)
.attr("height", capHeight)
.attr("y", positionFunctions.y)
.attr("width", barWidth)
.attr('class', 'topLine');
};
function updateRects() {
d3.selectAll(".mainWave").data(k2)
.attr("x", positionFunctions.x)
.attr("y", positionFunctions.y)
d3.selectAll(".topLine").data(k2)
.attr("x", positionFunctions.x)
.attr("y", positionFunctions.y)
}
// set up brush
// sets scale for slider
var x = d3.scale.linear()
.domain([0, (period * numWaves)])
.range([0, (period * numWaves)])
.clamp(true);
// defines brush
var brush = d3.svg.brush()
.x(x)
.extent([offShift, offShift])
.on("brush", brushed);
// axis for brushing
var brushAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickFormat(function(d) {
return d;
})
.tickSize(0)
.tickPadding(12)
.tickValues([])
// start drawing
// draw wave 1
var myPath = svg.append("path")
.datum(k1)
.attr("class", "area")
.attr("d", sineArea);
// draw wave 2
drawRectBody(svg.append("g").selectAll(".mainWave")
.data(k2)
.enter()
.append('rect'))
drawRectCap(svg.append("g").selectAll(".topLine")
.data(k2)
.enter()
.append('rect'))
// add axis, for brush
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (verticalShift + amp) + ")")
// inroduce axis
.call(brushAxis)
.select(".domain")
.select(function() {
return this.parentNode.appendChild(this.cloneNode(true));
});
// create slider to call "brush"
var slider = svg.append("g")
.attr("class", "slider")
.call(brush);
slider.selectAll(".extent,.resize")
.remove();
// create handle for slider
var handle = slider.append("g")
.attr("class", "handle");
handle.append("path")
.attr("transform", "translate(0," + verticalShift + ")")
.attr("d", "M 0 -115 V 130")
.attr("class", "mainVertical")
handle.append("path")
.attr("transform", "translate("+ (-20) +"," + verticalShift + ")")
.attr("d", "M 0 -115 V 130")
.attr("class", "halo")
handle.append('text')
.text("slide me")
.attr("transform", "translate(" + (-60) + " ," + (verticalShift - 105) + ")");
slider
.call(brush.event)
// to do on brush
function brushed() {
var value = brush.extent()[0];
if (d3.event.sourceEvent) { // not a programmatic event
value = x.invert(d3.mouse(this)[0]);
brush.extent([value, value]);
}
offShift = value;
updateRects();
handle.attr("transform", "translate(" + x(value) + ",0)");
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Adding Waves</title>
<link href='http://fonts.googleapis.com/css?family=Raleway' rel='stylesheet' type='text/css'>
<!-- standard meyer reset -->
<link rel="stylesheet" href="http://meyerweb.com/eric/tools/css/reset/reset.css">
<link rel="stylesheet" href="addingWaves.css">
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<section id="wave1">
</section>
<!-- call JS files -->
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="addingWaves.js"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment