Built with blockbuilder.org
Last active
June 7, 2017 15:40
-
-
Save stevesong/4c0413987781619cc109c23fa0543924 to your computer and use it in GitHub Desktop.
spectrum-chart
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: gpl-3.0 | |
scrolling: yes | |
border: yes | |
height: 1000 |
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
var svg = d3.select("svg"), | |
margin = {top: 60, right: 50, bottom: 30, left: 90}, | |
width = +svg.attr("width") - margin.left - margin.right, | |
height = +svg.attr("height") - margin.top - margin.bottom; | |
var x = d3.scaleLinear().rangeRound([0, width]), | |
y = d3.scaleBand().rangeRound([0, height]).padding(0.1); | |
var g = svg.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
var infoBox = d3.select("body").append("div") | |
.attr("class", "tooltip") | |
.style("opacity", 0); | |
var f = d3.format(".1f"); | |
var totSpec = ""; | |
var sumSpec = 0; | |
/* Load data file */ | |
d3.csv("900MHz.csv", function(d) { | |
d.freqStart = +d.freqStart; | |
d.freqEnd = +d.freqEnd; | |
return d; | |
}, function(error, data) { | |
if (error) throw error; | |
x.domain([d3.min(data, function(d) { return d.freqStart; }), d3.max(data, function(d) { return d.freqEnd; })]); | |
y.domain(data.map(function(d) { return d.Country; })); | |
/* Set lower X-axis and legend */ | |
g.append("g") | |
.attr("class", "axis axis--x") | |
.attr("transform", "translate(0," + height + ")") | |
.call(d3.axisBottom(x).ticks(20).tickSize(-height)) | |
.append("text") | |
.attr("x", 20) | |
.attr("y", 30) | |
.text("Frequency (MHz)"); | |
/* Set X-axis at top and add title/legend */ | |
g.append("g") | |
.attr("class", "axis axis--x") | |
.call(d3.axisTop(x).ticks(20).tickSize(-height)) | |
.append("text") | |
.classed("FreqLegend", true) | |
.attr("x", 20) | |
.attr("y", -30) | |
.text("900 MHz Band"); | |
/* Set Y-axis */ | |
g.append("g") | |
.attr("class", "axis axis--y") | |
.call(d3.axisLeft(y).tickSize(5)) | |
.selectAll(".tick text") | |
.classed("countryName", true) | |
.call(wrap, margin.left) | |
/* Mouseover for Y axis elements */ | |
.on("mouseover", function(d) { | |
}) | |
.on("mouseout", function(d) { | |
}); | |
d3.xml("https://raw.githubusercontent.com/lipis/flag-icon-css/master/flags/4x3/za.svg").mimeType("image/svg+xml").get(function(error, xml) { | |
if (error) throw error; | |
document.body.appendChild(xml.documentElement); | |
}); | |
/* Iterate through data file */ | |
g.selectAll(".bar") | |
.data(data) | |
.enter().append("g") | |
.attr("class", "bars") | |
.append("rect") | |
.attr("class", function(d) { return d.Operator.replace(/\s+/g, '_').replace(/\W/g,'') + " " + d.Country.replace(/\s+/g, '_'); }) | |
.classed("bar", true) | |
.attr("y", function(d) { return y(d.Country); }) | |
.attr("x", function(d) { return x(d.freqStart); }) | |
.attr("width", function(d) { return x(d.freqEnd) - x(d.freqStart); }) | |
.attr("height", y.bandwidth()); | |
/* Add label to each spectrum assignments */ | |
var bars = svg.selectAll(".bars"); | |
bars.append("text") | |
.attr("class", "label") | |
.attr('transform', 'rotate(-90)') | |
.attr("y", function(d) { return x(d.freqStart) + (x(d.freqEnd) - x(d.freqStart))/2 + 5; }) | |
.attr("x", function(d) { return -y(d.Country) - y.bandwidth() + 10 ; }) | |
.text(function(d) { return d.Operator; }) | |
.call(wrap, y.bandwidth()) | |
/* ToolTip for spectrum assignments */ | |
.on("mouseover", function(d) { | |
/* calculate total spectrum assigned */ | |
g.selectAll("." + d.Operator.replace(/\s+/g, '_').replace(/\W/g,'') + "." + d.Country.replace(/\s+/g, '_')).each(function(d) { | |
totSpec = f(d.freqEnd - d.freqStart) + " + " + totSpec; | |
sumSpec = sumSpec + d.freqEnd - d.freqStart; | |
}); | |
g.selectAll("." + d.Operator.replace(/\s+/g, '_').replace(/\W/g,'') + "." + d.Country.replace(/\s+/g, '_')) | |
.classed("selected", true) | |
infoBox.transition() | |
.duration(200) | |
.style("opacity", ); | |
infoBox.html('<div class="tab-row"><div class="cell-right">Country:</div><div class="cell-left">' + d.Country + '</div></div><div class="tab-row"><div class="cell-right">Operator:</div><div class="cell-left">' + d.Operator + '</div></div><div class="tab-row"><div class="cell-right">Band:</div><div class="cell-left">' + d.Band + '</div></div><div class="tab-row"><div class="cell-right">Assignment:</div><div class="cell-left">' + totSpec.replace(/\s\+\s$/, '') + ' MHz</div></div><div class="tab-row"><div class="cell-right">Total:</div><div class="cell-left">' + f(sumSpec) + " MHz</div></div>") | |
.style("left", x(d.freqStart) - 20 + "px") | |
.style("top", y(d.Country) + 1.65*y.bandwidth() + "px"); | |
}) | |
.on("mouseout", function(d) { | |
totSpec = ""; | |
sumSpec = 0; | |
g.selectAll("." + d.Operator.replace(/\s+/g, '_').replace(/\W/g,'') + "." + d.Country.replace(/\s+/g, '_')) | |
.classed("selected", false) | |
infoBox.transition() | |
.duration(500) | |
.style("opacity", 0); | |
}); | |
}); | |
/* Wrap text function */ | |
function wrap (text, width) { | |
text.each(function() { | |
var breakChars = ['/', '&', '-'], | |
text = d3.select(this), | |
textContent = text.text(), | |
spanContent; | |
breakChars.forEach(char => { | |
// Add a space after each break char for the function to use to determine line breaks | |
textContent = textContent.replace(char, char + ' '); | |
}); | |
var words = textContent.split(/\s+/).reverse(), | |
word, | |
line = [], | |
lineNumber = 0, | |
lineHeight = 1.1, // ems | |
x = text.attr('x'), | |
y = text.attr('y'), | |
dy = parseFloat(text.attr('dy') || 0), | |
tspan = text.text(null).append('tspan').attr('x', x).attr('y', y).attr('dy', dy + 'em'); | |
while (word = words.pop()) { | |
line.push(word); | |
tspan.text(line.join(' ')); | |
if (tspan.node().getComputedTextLength() > width) { | |
line.pop(); | |
spanContent = line.join(' '); | |
breakChars.forEach(char => { | |
// Remove spaces trailing breakChars that were added above | |
spanContent = spanContent.replace(char + ' ', char); | |
}); | |
tspan.text(spanContent); | |
line = [word]; | |
tspan = text.append('tspan').attr('x', x).attr('y', y).attr('dy', ++lineNumber * lineHeight + dy + 'em').text(word); | |
} | |
} | |
}); | |
/* Import SVG flag */ | |
function flag (iso) { | |
} | |
} |
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
Country | Operator | Band | freqStart | freqEnd | |
---|---|---|---|---|---|
Botswana | BeMobile | 900 | 906.6 | 910.6 | |
Botswana | BeMobile | 900 | 951.6 | 955.6 | |
Botswana | Government | 900 | 911 | 914.8 | |
Botswana | Government | 900 | 956 | 959.8 | |
Botswana | Mascom | 900 | 890.2 | 898.2 | |
Botswana | Mascom | 900 | 935 | 943 | |
Botswana | Orange | 900 | 898.4 | 906.2 | |
Botswana | Orange | 900 | 943.4 | 951.2 | |
Burkina Faso | Onatel | 900 | 890.2 | 898.3 | |
Burkina Faso | Onatel | 900 | 935.2 | 943.3 | |
Burkina Faso | Orange | 900 | 898.3 | 906.6 | |
Burkina Faso | Orange | 900 | 943.3 | 951.6 | |
Burkina Faso | Telecel | 900 | 906.6 | 914.8 | |
Burkina Faso | Telecel | 900 | 951.6 | 959.8 | |
Egypt | Etisalat | 900 | 902.5 | 915 | |
Egypt | Etisalat | 900 | 947.5 | 960 | |
Egypt | Orange | 900 | 890 | 902.5 | |
Egypt | Orange | 900 | 935 | 947.5 | |
Egypt | Vodafone | 900 | 880 | 890 | |
Egypt | Vodafone | 900 | 925 | 935 | |
Ghana | Airtel | 900 | 885 | 890 | |
Ghana | Airtel | 900 | 930 | 935 | |
Ghana | Glo | 900 | 880 | 885 | |
Ghana | Glo | 900 | 925 | 930 | |
Ghana | MTN | 900 | 907 | 915 | |
Ghana | MTN | 900 | 952 | 960 | |
Ghana | Tigo | 900 | 890 | 898 | |
Ghana | Tigo | 900 | 935 | 943 | |
Ghana | Vodafone | 900 | 898 | 907 | |
Ghana | Vodafone | 900 | 943 | 952 | |
Kenya | Airtel | 900 | 905 | 915 | |
Kenya | Airtel | 900 | 950 | 960 | |
Kenya | Orange | 900 | 880 | 882.5 | |
Kenya | Orange | 900 | 900 | 905 | |
Kenya | Orange | 900 | 925 | 927.5 | |
Kenya | Orange | 900 | 945 | 950 | |
Kenya | Safaricom | 900 | 890 | 900 | |
Kenya | Safaricom | 900 | 935 | 945 | |
Kenya | Yu(Safaricom) | 900 | 882.5 | 890 | |
Kenya | Yu(Safaricom) | 900 | 927.5 | 935 | |
Namibia | MTC | 900 | 890 | 903 | |
Namibia | MTC | 900 | 935 | 948 | |
Namibia | Telecom Namibia | 900 | 905 | 915 | |
Namibia | Telecom Namibia | 900 | 950 | 960 | |
South Africa | CellC | 900 | 880.1 | 889.9 | |
South Africa | CellC | 900 | 903.7 | 905.9 | |
South Africa | CellC | 900 | 925.1 | 934.9 | |
South Africa | CellC | 900 | 948.7 | 950.9 | |
South Africa | MTN | 900 | 901.3 | 903.7 | |
South Africa | MTN | 900 | 905.9 | 914.7 | |
South Africa | MTN | 900 | 946.3 | 948.7 | |
South Africa | MTN | 900 | 950.9 | 959.7 | |
South Africa | Vodacom | 900 | 889.9 | 901.3 | |
South Africa | Vodacom | 900 | 934.9 | 946.3 | |
Uganda | UTL | 900 | 880 | 885 | |
Uganda | UTL | 900 | 925 | 930 | |
Uganda | WARID | 900 | 885 | 890 | |
Uganda | WARID | 900 | 930 | 935 | |
Uganda | Airtel | 900 | 890.2 | 898.0 | |
Uganda | Airtel | 900 | 935.2 | 943.0 | |
Uganda | Africell | 900 | 898.2 | 903.2 | |
Uganda | Africell | 900 | 943.2 | 948.2 | |
Uganda | iTEL | 900 | 903.2 | 906.4 | |
Uganda | iTEL | 900 | 948.2 | 951.4 | |
Uganda | MTN | 900 | 906.6 | 914.8 | |
Uganda | MTN | 900 | 951.6 | 959.8 |
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> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<link rel="stylesheet" href="spectrum-chart.css" /> | |
</head> | |
<svg width="800" height="1200"></svg> | |
<script type="text/javascript" src="900byCountry.js"></script> | |
</body> |
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
.bar { | |
fill: purple; | |
stroke: grey; | |
stroke-width: .5; | |
} | |
.bar text { | |
fill: #fff; | |
font: 10px sans-serif; | |
} | |
/* | |
.bar:hover { | |
fill: grey; | |
} | |
.label:hover { | |
fill: black; | |
} | |
*/ | |
.FreqLegend { | |
fill: #144667; | |
font-family: "Arial Black", Gadget, sans-serif; | |
font-size: 22px; | |
} | |
.label { | |
fill: white; | |
font-family: "Arial Black", Gadget, sans-serif; | |
font-size: 16px; | |
} | |
.axis--x path { | |
display: none; | |
} | |
.axis--y { | |
font-size: 14px; | |
border: 10px; | |
} | |
.axis--y path { | |
display: none; | |
} | |
.countryName { | |
fill: #144667; | |
font-family: "Arial Black", Gadget, sans-serif; | |
font-size: 14px; | |
} | |
text { | |
fill: steelblue; | |
font-family: sans-serif | |
} | |
.axis--x .tick line { | |
stroke-width: 1; | |
stroke: rgba(0, 0, 0, 0.5); | |
} | |
/* Operator colour assignments based on corporate colours */ | |
.Orange { | |
fill: #f16e00; | |
} | |
.Safaricom { | |
fill: #61a60e; | |
} | |
.Yu(Safaricom) { | |
fill: #61a60e; | |
} | |
.Airtel { | |
fill: #A7010A; | |
} | |
.CellC { | |
fill: #0b0b0b; | |
} | |
.MTN { | |
fill: #ffbe00; | |
} | |
.Vodacom { | |
fill: #e60000 | |
} | |
.Vodafone { | |
fill: #e60000; | |
} | |
.Mascom { | |
fill: #fee100; | |
} | |
.BeMobile { | |
fill: #65BD0F; | |
} | |
.Onatel { | |
fill: #E5418A; | |
} | |
.Telecel { | |
fill: #527B97; | |
} | |
.Etisalat { | |
fill: #719E19; | |
} | |
.Tigo { | |
fill: #162458; | |
} | |
.Glo { | |
fill: #45B649; | |
} | |
.MTC { | |
fill: #00AAF0; | |
} | |
.Telecom_Namibia { | |
fill: #FD8326; | |
} | |
.mcel { | |
fill: #FFCF1D; | |
} | |
.Movitel { | |
fill: #FE9413; | |
} | |
.ntel { | |
fill: #E6077C; | |
} | |
.Africell { | |
fill: #ff6220; | |
} | |
.UTL { | |
fill: #34479B; | |
} | |
.selected { | |
fill: #144667; | |
} | |
div.tooltip { | |
position: absolute; | |
text-align: left; | |
width: 320px; | |
height: 150px; | |
padding: 5px; | |
font-family: arial; | |
font-size: 1em; | |
line-height: 1.5; | |
padding: 1.5em; | |
background: #144667; | |
border: 2px; | |
color: white; | |
border-radius: 3px; | |
pointer-events: none; | |
-webkit-transform: translate3d(0,-0.5em,0); | |
transform: translate3d(0,-0.5em,0); | |
-webkit-transition: opacity 0.1s, -webkit-transform 0.1s; | |
transition: opacity 0.1s, transform 0.1s; | |
} | |
div.tooltip:hover:before{ | |
border: solid; | |
border-color: #333 transparent; | |
border-width: 6px 6px 0 6px; | |
bottom: 20px; | |
content: ""; | |
left: 50%; | |
position: absolute; | |
z-index: 99; | |
} | |
.div-table { | |
float: left; | |
padding: 10px; | |
width: auto; | |
} | |
.tab-row { | |
float: left; | |
width: 400px; | |
border-radius: 3px; | |
} | |
.cell-left { | |
border: 1px solid; | |
float: left; | |
padding: 3px; | |
width: 200px; | |
} | |
.cell-right { | |
border: 1px solid; | |
float: left; | |
text-align: right; | |
padding: 3px; | |
width: 100px; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment