Skip to content

Instantly share code, notes, and snippets.

@timproDev
Created May 11, 2018 20:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timproDev/dac7d8bad4aa05411ed2bc40f0a08943 to your computer and use it in GitHub Desktop.
Save timproDev/dac7d8bad4aa05411ed2bc40f0a08943 to your computer and use it in GitHub Desktop.
Music Chart Ring V1
/**
* Foundation for Sites by ZURB
* Version 6.4.3
* foundation.zurb.com
* Licensed under MIT Open Source
*/
/* Global Styles and resets */
@media only screen and (min-width: 641px) {
body, html {
overflow-x: hidden; } }
@media only screen and (max-width: 40em) {
html {
-webkit-text-size-adjust: 100%; } }
body {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
height: auto;
display: block; }
article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary {
display: block; }
img {
border: none; }
button, input, optgroup, select, textarea {
color: inherit;
/* 1 */
font: inherit;
/* 2 */
margin: 0;
/* 3 */
-webkit-font-smoothing: antialiased; }
input, button, select {
outline: none; }
*,
*:before,
*:after {
box-sizing: border-box; }
line {
shape-rendering: crispEdges; }
.global-chart-container > section {
margin: 3rem auto;
width: 100%;
display: inline-block; }
.timp-dv-container {
text-align: center;
margin: 4rem auto;
max-width: 80%; }
.timp-dv-container .song-title {
font-family: 'Caveat', cursive;
color: #000000;
font-size: 2rem;
padding: 0;
margin: 0; }
.timp-dv-container .song-composer {
font-family: 'Caveat', cursive;
color: #000000;
font-size: 1rem;
padding: 0;
margin: 0; }
.timp-dv-container .plot-wrap.w-svg {
position: relative; }
.timp-dv-container .center-text {
font-family: 'Raleway', sans-serif;
font-size: 2rem;
width: 30.5%;
height: auto;
position: absolute;
left: 34.5%;
top: 22%; }
.timp-dv-container .center-text .lyrics-wrap {
width: 88%;
line-height: 1.15;
margin: 0 auto;
font-family: 'Caveat', cursive;
color: #000000; }
.timp-dv-container .center-text .section-wrap {
margin-bottom: 0;
padding-bottom: 0; }
.timp-dv-container .center-text .chords-wrap {
margin: .25rem;
border-radius: 3px;
letter-spacing: 3px;
text-align: center;
word-wrap: break-word;
display: block;
height: 85px; }
@media only screen and (max-width: 40em) {
.mx-dv-container .chart-ui-container {
display: none; }
.mx-dv-container .plot-wrap.no-svg {
display: block; }
.mx-dv-container .plot-wrap.w-svg {
display: none; } }
<!doctype html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Music Chart Ring</title>
<link href="https://fonts.googleapis.com/css?family=Raleway" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Caveat" rel="stylesheet">
<link rel="stylesheet" href="app.css">
</head>
<body>
<div class="global-chart-container">
<section>
<div class="timp-dv-container" id="musicChart">
<p class="song-title">"She Thinks I Still Care"</p>
<p class="song-composer">George Jones</p>
<div class="plot-wrap w-svg"></div>
</div>
</section>
</div>
<script src="music-chart.js"></script>
<script src="music-chart-init.js"></script>
<script src="https://rawgit.com/timproDev/d3-first-timer/master/js/d3v4-473-jetpack.js"></script>
</body>
</html>
document.addEventListener("DOMContentLoaded", function(){
// set global variables
var path = '';
var dataFile = 'stillcare-lyrics.csv';
var elemContainer = ['#musicChart'];
var uiEl = '.chart-ui-container input';
var cssFile = 'music-chart.css';
var strNumHeaders = ['bar number','beat']; // to convert to numbers
var musicChart = new MusicChart({
elem:document.querySelector(elemContainer[0]),
dataCount:'bar',
transSpeed:350
});
// fire chart and events
chartInit(musicChart, elemContainer[0], dataFile);
styleLink();
function chartInit(chartInst, elem, dataFile) {
d3.csv((path + dataFile), function(data) {
data.forEach(function(d) {
for (var i = 0; i < strNumHeaders.length; i++) {
d[strNumHeaders[i]] = +d[strNumHeaders[i]];
}
});
var lyricsData = d3.nest()
.key(function(d){ return d['section' ]; })
.key(function(d){ return d['lyrics' ]; })
.entries(data)
.map(function(d){
var obj = {}
obj['section'] = d.key;
obj['lyrics'] = d.values[0].key;
return obj;
});
var barsData = d3.nest()
.key(function(d) { return d['bar number']; })
.entries(data)
.map(function(d){
var obj = {}
obj['bar'] = d.key;
obj['section'] = d.values[0]['section'];
obj['beats'] = d.values.length;
obj['values'] = d.values;
obj['lyrics'] = d.values[0]['lyrics'];
return obj;
});
var sectionData = d3.nest() // section data for section arc
.key(function(d) { return d['section']; })
.entries(data);
chartInst.setData(barsData, sectionData, lyricsData);
});
}
// include resize event
d3.select(window).on('resize', function(){
musicChart.resize();
});
// inject custom chart css
function styleLink(){
var linkElem = document.createElement('link');
document.getElementsByTagName('head')[0].appendChild(linkElem);
linkElem.rel = 'stylesheet';
linkElem.type = 'text/css';
linkElem.href = (path + cssFile);
}
});
var MusicChart = function(opts){
this.transSpeed = opts.transSpeed;
this.dataCount = opts.dataCount;
this.colorScheme = d3.schemeCategory20b || this.colorScheme; // set up customize
this.element = opts.elem.querySelector('.plot-wrap.w-svg');
}
MusicChart.prototype.setData = function(newData, sectionData, lyricsData){
this.data = newData;
this.sectionData = sectionData;
this.lyricsData = lyricsData;
this.draw();
}
MusicChart.prototype.draw = function(){
var self = this
this.margin = {
top:0,
left:0,
right:0,
bottom:0
};
this.width = this.element.offsetWidth - this.margin.left - this.margin.right;
this.height = this.width / 2 - (this.margin.top - this.margin.bottom);
this.element.innerHTML = '';
var svg = d3.select(this.element).append('svg');
svg.attr('width', this.width + (this.margin.left + this.margin.right));
svg.attr('height', (this.height + this.margin.top + this.margin.bottom));
this.plot = svg.append('g')
.attr("transform", "translate(" + this.width / 2 + "," + this.height / 2 + ")");
this.createRadii()
this.createScales()
this.createArcs()
this.createPies()
this.createDonut()
}
MusicChart.prototype.createRadii = function() {
var self = this
this.radiusTwo = Math.min(this.width, this.height) / 2.25;
this.ringTwoSize = this.height / 35;
this.radiusOne = Math.min(this.width, this.height) / 2.5;
this.ringOneSize = this.height / 30;
}
MusicChart.prototype.createScales = function() {
var self = this
this.colorRange = ['#D15F8F', '#00B5CC', '#F2BA00', '#00B5CC', '#F2BA00', '#DB60E0', '#00B5CC', '#F2BA00', '#F2BA00'];
// ["intro", "verse 1", "chorus 1", "verse 2", "chorus 2", "bridge", "verse 3", "chorus 3", "chorus 4"]
this.sectionKeys = this.sectionData.map(function(d){
return d.key; // ["intro", "verse 1", "chorus 1", "verse 2", "chorus 2", "bridge", "verse 3", "chorus 3", "chorus 4"]
});
this.color = d3.scaleOrdinal()
.range(this.colorRange)
.domain(this.sectionKeys);
}
MusicChart.prototype.createArcs = function() {
var self = this
this.arcOne = d3.arc()
.innerRadius(this.radiusOne)
.outerRadius(this.radiusOne - this.ringOneSize);
this.outerArcOne = d3.arc() // for labels
.innerRadius(this.radiusOne * 0.9)
.outerRadius(this.radiusOne * 0.9);
this.arcTwo = d3.arc()
.innerRadius(this.radiusTwo)
.outerRadius(this.radiusTwo - this.ringTwoSize);
this.outerArcTwo = d3.arc() // for labels
.innerRadius(this.radiusTwo * 0.9)
.outerRadius(this.radiusTwo * 0.9);
}
MusicChart.prototype.createPies = function() {
var self = this
this.pie = d3.pie()
.value(function(d,i) {return d['beats'];})
.sort(null);
this.pieTwo = d3.pie()
.value(function(d,i) { return d.values.length; })
.sort(null);
}
MusicChart.prototype.createDonut = function() {
var self = this
this.barsPath = this.plot.selectAll("path.slice")
.data(this.pie(this.data));
this.sectionPath = this.plot.selectAll("path.slice")
.data(this.pieTwo(this.sectionData));
this.sectionPath
.enter()
.append("path")
.attr("class", "slice-two")
.attr("fill", function(d, i) {
return self.color(d.data.key);
})
.attr('stroke',"#ffffff")
.attr('stroke-width',function(){
return self.width / 200;
})
.attr('d', this.arcTwo)
.each(function(d){this._current = d;});
this.barsPath
.enter()
.append("path")
.attr("class", "slice")
.attr("fill", function(d, i) {
return self.color(d.data['section']);
})
.attr("opacity", function(d, i) {
return '0';
})
.attr('d', this.arcOne)
.attr('stroke','#ffffff')
.attr('stroke-width',function(){
return self.width / 150;
})
.each(function(d){this._current = d;});
this.textCard = d3.select(this.element).append('div.center-text');
this.sectionWrap = this.textCard.insert('p.section-wrap');
this.chordsWrap = this.textCard.insert('p.chords-wrap');
this.lyricsWrap = this.textCard.insert('p.lyrics-wrap');
// mouseover
this.plot.selectAll('path.slice-two')
.on('mouseenter', function(d){
var elem = this;
var section = [];
var chords = [];
var thisData = d3.nest()
.key(function(d){ return d['bar number']})
.key(function(d){ return d['chord']})
.key(function(d){ return d['section']})
.entries(d.data.values)
.map(function(d){
var obj = {}
chords.push(d.values[0].key)
section.push(d.values[0].values[0].key)
return obj;
})
chords = chords.toString().replace(/,/g , ' | ');
self.sectionWrap
.html(section[0])
.style('color', function(d, i) {
return self.color(section[0]);
})
.style('font-size', function(d){
return (self.height / 30) + "px";
});
self.chordsWrap
.html(chords)
.style('color', function(d, i) {
return self.color(section[0]);
})
.style('font-size', function(d){
return (self.height / 20) + "px";
})
.style('margin-top', function(d){
return (self.height / 80) + "px";
});
self.lyricsWrap
.html(function(){
var lyric;
self.lyricsData.forEach(function(l){
if (l['section'] === section[0]) {
lyric = l['lyrics'];
}
})
return '"' + lyric + '"';
})
.style('font-size', function(d){
return (self.height / 22) + "px";
})
.style('margin-top', function(d){
return (self.height / 40) + "px";
});
self.textCard.transition(50).style('opacity',1)
d3.selectAll('path.slice-two').transition(50).style('opacity',function(d){
if ( elem !== this ) {
return '.15';
}
d3.selectAll('.slice').transition(50).style('opacity',function(e){
return d.data.key === e.data['section'] ? '1' : '0';
})
});
})
.on('mouseleave', function(d){
d3.selectAll('.slice').transition(50).style('opacity',0);
self.textCard.transition(50).style('opacity',0);
d3.selectAll('path.slice-two').transition(50).style('opacity',function(d){
return '1';
});
});
}
MusicChart.prototype.resize = function(){
this.width = parseInt(d3.select(this.element).style('width'), 10);
this.draw();
}
bar number beat section chord lyrics
1 1 intro C she thinks I still care
1 2 intro C
1 3 intro C
1 4 intro C
2 1 intro G
2 2 intro G
2 3 intro G
2 4 intro G
3 1 intro C
3 2 intro C
3 3 intro C
3 4 intro C
4 1 intro C
4 2 intro C
4 3 intro C
4 4 intro C
5 1 verse 1 C just because I asked a friend about her, just because I spoke her name somewhere, just because I ran her number by mistake today
5 2 verse 1 C
5 3 verse 1 C
5 4 verse 1 C
6 1 verse 1 F
6 2 verse 1 F
6 3 verse 1 F
6 4 verse 1 F
7 1 verse 1 C
7 2 verse 1 C
7 3 verse 1 C
7 4 verse 1 C
8 1 verse 1 C
8 2 verse 1 C
8 3 verse 1 C
8 4 verse 1 C
9 1 verse 1 C
9 2 verse 1 C
9 3 verse 1 C
9 4 verse 1 C
10 1 verse 1 G
10 2 verse 1 G
10 3 verse 1 G
10 4 verse 1 G
11 1 verse 1 C
11 2 verse 1 C
11 3 verse 1 C
11 4 verse 1 C
12 1 verse 1 C
12 2 verse 1 C
12 3 verse 1 C
12 4 verse 1 C
13 1 verse 1 C
13 2 verse 1 C
13 3 verse 1 C
13 4 verse 1 C
14 1 verse 1 C7
14 2 verse 1 C7
14 3 verse 1 C7
14 4 verse 1 C7
15 1 verse 1 F
15 2 verse 1 F
15 3 verse 1 F
15 4 verse 1 F
16 1 verse 1 F
16 2 verse 1 F
16 3 verse 1 F
16 4 verse 1 F
17 1 chorus 1 C she thinks I still care
17 2 chorus 1 C
17 3 chorus 1 C
17 4 chorus 1 C
18 1 chorus 1 G
18 2 chorus 1 G
18 3 chorus 1 G
18 4 chorus 1 G
19 1 chorus 1 C
19 2 chorus 1 C
19 3 chorus 1 C
19 4 chorus 1 C
20 1 chorus 1 C
20 2 chorus 1 C
20 3 chorus 1 C
20 4 chorus 1 C
21 1 verse 2 C just because I haunt the same old places where the memory of her lingers everywhere, just because I'm not the happy guy I used to be
21 2 verse 2 C
21 3 verse 2 C
21 4 verse 2 C
22 1 verse 2 F
22 2 verse 2 F
22 3 verse 2 F
22 4 verse 2 F
23 1 verse 2 C
23 2 verse 2 C
23 3 verse 2 C
23 4 verse 2 C
24 1 verse 2 C
24 2 verse 2 C
24 3 verse 2 C
24 4 verse 2 C
25 1 verse 2 C
25 2 verse 2 C
25 3 verse 2 C
25 4 verse 2 C
26 1 verse 2 G
26 2 verse 2 G
26 3 verse 2 G
26 4 verse 2 G
27 1 verse 2 C
27 2 verse 2 C
27 3 verse 2 C
27 4 verse 2 C
28 1 verse 2 C
28 2 verse 2 C
28 3 verse 2 C
28 4 verse 2 C
29 1 verse 2 C
29 2 verse 2 C
29 3 verse 2 C
29 4 verse 2 C
30 1 verse 2 C7
30 2 verse 2 C7
30 3 verse 2 C7
30 4 verse 2 C7
31 1 verse 2 F
31 2 verse 2 F
31 3 verse 2 F
31 4 verse 2 F
32 1 verse 2 F
32 2 verse 2 F
32 3 verse 2 F
32 4 verse 2 F
33 1 chorus 2 C she thinks I still care
33 2 chorus 2 C
33 3 chorus 2 C
33 4 chorus 2 C
34 1 chorus 2 G
34 2 chorus 2 G
34 3 chorus 2 G
34 4 chorus 2 G
35 1 chorus 2 C
35 2 chorus 2 C
35 3 chorus 2 C
35 4 chorus 2 C
36 1 chorus 2 C
36 2 chorus 2 C
36 3 chorus 2 C
36 4 chorus 2 C
37 1 bridge 1 F but if she's happy thinking I still need her then let that silly notion bring her cheer. Oh, how could she ever be so foolish and where did she get such an idea
37 2 bridge 1 F
37 3 bridge 1 F
37 4 bridge 1 F
38 1 bridge 1 F
38 2 bridge 1 F
38 3 bridge 1 F
38 4 bridge 1 F
39 1 bridge 1 C
39 2 bridge 1 C
39 3 bridge 1 C
39 4 bridge 1 C
40 1 bridge 1 C
40 2 bridge 1 C
40 3 bridge 1 C
40 4 bridge 1 C
41 1 bridge 1 C
41 2 bridge 1 C
41 3 bridge 1 C
41 4 bridge 1 C
42 1 bridge 1 C
42 2 bridge 1 C
42 3 bridge 1 C
42 4 bridge 1 C
43 1 bridge 1 G
43 2 bridge 1 G
43 3 bridge 1 G
43 4 bridge 1 G
44 1 bridge 1 G
44 2 bridge 1 G
44 3 bridge 1 G
44 4 bridge 1 G
45 1 bridge 1 F
45 2 bridge 1 F
45 3 bridge 1 F
45 4 bridge 1 F
46 1 bridge 1 F
46 2 bridge 1 F
46 3 bridge 1 F
46 4 bridge 1 F
47 1 bridge 1 C
47 2 bridge 1 C
47 3 bridge 1 C
47 4 bridge 1 C
48 1 bridge 1 C
48 2 bridge 1 C
48 3 bridge 1 C
48 4 bridge 1 C
49 1 bridge 1 D
49 2 bridge 1 D
49 3 bridge 1 D
49 4 bridge 1 D
50 1 bridge 1 D
50 2 bridge 1 D
50 3 bridge 1 D
50 4 bridge 1 D
51 1 bridge 1 G
51 2 bridge 1 G
51 3 bridge 1 G
51 4 bridge 1 G
52 1 bridge 1 G
52 2 bridge 1 G
52 3 bridge 1 G
52 4 bridge 1 G
53 1 verse 3 C just because I asked a friend about her, just because I spoke her name somewhere, just because I saw her then went all to pieces
53 2 verse 3 C
53 3 verse 3 C
53 4 verse 3 C
54 1 verse 3 F
54 2 verse 3 F
54 3 verse 3 F
54 4 verse 3 F
55 1 verse 3 C
55 2 verse 3 C
55 3 verse 3 C
55 4 verse 3 C
56 1 verse 3 C
56 2 verse 3 C
56 3 verse 3 C
56 4 verse 3 C
57 1 verse 3 C
57 2 verse 3 C
57 3 verse 3 C
57 4 verse 3 C
58 1 verse 3 G
58 2 verse 3 G
58 3 verse 3 G
58 4 verse 3 G
59 1 verse 3 C
59 2 verse 3 C
59 3 verse 3 C
59 4 verse 3 C
60 1 verse 3 C
60 2 verse 3 C
60 3 verse 3 C
60 4 verse 3 C
61 1 verse 3 C
61 2 verse 3 C
61 3 verse 3 C
61 4 verse 3 C
62 1 verse 3 C7
62 2 verse 3 C7
62 3 verse 3 C7
62 4 verse 3 C7
63 1 verse 3 F
63 2 verse 3 F
63 3 verse 3 F
63 4 verse 3 F
64 1 verse 3 F
64 2 verse 3 F
64 3 verse 3 F
64 4 verse 3 F
65 1 chorus 3 C she thinks I still care
65 2 chorus 3 C
65 3 chorus 3 C
65 4 chorus 3 C
66 1 chorus 3 G
66 2 chorus 3 G
66 3 chorus 3 G
66 4 chorus 3 G
67 1 chorus 3 C
67 2 chorus 3 C
67 3 chorus 3 C
67 4 chorus 3 C
68 1 chorus 3 C
68 2 chorus 3 C
68 3 chorus 3 C
68 4 chorus 3 C
69 1 chorus 4 C she thinks I still care
69 2 chorus 4 C
69 3 chorus 4 C
69 4 chorus 4 C
70 1 chorus 4 G
70 2 chorus 4 G
70 3 chorus 4 G
70 4 chorus 4 G
71 1 chorus 4 F
71 2 chorus 4 F
71 3 chorus 4 F
71 4 chorus 4 F
72 1 chorus 4 C
72 2 chorus 4 C
72 3 chorus 4 C
72 4 chorus 4 C
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment