Skip to content

Instantly share code, notes, and snippets.

@nharrisanalyst
Last active May 10, 2016 19:08
Show Gist options
  • Save nharrisanalyst/8ecb2dfda6d9563422f0485d0f35d7e1 to your computer and use it in GitHub Desktop.
Save nharrisanalyst/8ecb2dfda6d9563422f0485d0f35d7e1 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF8">
<title>A real time data visualization</title>
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/1.10.0/d3-legend.js"></script>
<script src="https://d3js.org/d3-queue.v2.min.js"></script>
<script>
q=d3_queue.queue();
</script>
<style>
.title{
}
#g0 { fill: #eafeea; }
#g1 { fill: #d5fdd5; }
#g2 { fill: #c1fcc1; }
#g3 { fill: #acfbac; }
#g4 { fill: #88e188; }
#g5 { fill: #6aaf6a; }
#g6 { fill: #4c7d4c; }
#g7 { fill: #2d4b2d; }
.g0 { fill: #eafeea; }
.g1 { fill: #d5fdd5; }
.g2 { fill: #c1fcc1; }
.g3 { fill: #acfbac; }
.g4 { fill: #88e188; }
.g5 { fill: #6aaf6a; }
.g6 { fill: #4c7d4c; }
.g7 { fill: #2d4b2d; }
.zipcode{stroke:black;}
</style>
</head>
<body>
<h1 class="title"> Sacramento County 311 Calls by Zipcode Up to Date API call</h1>
<p>Sacramento County 311 handles all County municipal service requests that are not police and fire related.
this map and bar chart makes up to date request from http://data.saccounty.net/home api
the data automatically updates when the api is updated. If the website is left open the api is called every 15 min<p>
<script>
//??twitter real time api search
//https://api.twitter.com/1.1/search/tweets.json?q=donald%20trump&src=typd
// api key http://www.divvybikes.com/stations/json
(function(){
var rectData=[]
var scaleX
var data;
var dataGeo
var dataZipcode={};
var dataCalls={};
var h = 600;
var w = 550;
var width=400;
var svg =d3.select("body").append("svg")
.attr("width",w)
.attr("height",h)
.attr("id","svgone");
var projection= d3.geo.albers()
.scale(45000)
.rotate([120.5,.25,0]);
var path = d3.geo.path()
.projection(projection);
var quantize;
var newData;
var check;
var newDict={};
var mapDict={};
//ordinal scale
var ordinal=d3.scale.ordinal().domain(["#g0","#g1","#g2","#g3","#g4","#g5","#g6","#g7"])
.range(["#eafeea","#d5fdd5","#c1fcc1","#acfbac","#88e188","#6aaf6a","#4c7d4c","#2d4b2d"])
//mouseover mouseout
var selecetion;
var mouseover= function(d){
var z = this.getAttribute('class')
console.log(z)
if(z.slice(0,1)=="y"){
var z = this.getAttribute('class');
var y = z.slice(1,6);
d3.select("." + this.getAttribute('class'))
.style("fill","orange")
d3.select('.z'+y)
.style("fill","orange")
d3.select('#svgone')
.append("text")
.attr("class","text")
.attr({
x:5,
y:250,
"font-size": "12px",
"font-family":"Sans-Serif"
})
.text("Name: "+d.properties.PO_NAME)
d3.select('#svgone')
.append("text")
.attr("class","text")
.attr({
x:5,
y:260,
"font-size": "12px",
"font-family":"Sans-Serif"
})
.text("Zipcode: " +d.properties.ZIP5+ ", Calls: " +newDict[d.properties.ZIP5])}
else{
var z = this.getAttribute('class');
var y = z.slice(1,6);
d3.select("." + this.getAttribute('class'))
.style("fill","orange");
d3.select('.y'+y)
.style("fill","orange")
d3.select('#svgone')
.append("text")
.attr("class","text")
.attr({
x:5,
y:250,
"font-size": "12px",
"font-family":"Sans-Serif"
})
.text("Name: "+mapDict[d.zipcode].name)
d3.select('#svgone')
.append("text")
.attr("class","text")
.attr({
x:5,
y:260,
"font-size": "12px",
"font-family":"Sans-Serif"
})
.text("Zipcode: " +mapDict[d.zipcode].zipcode+ ", Calls: " +mapDict[d.zipcode].calls)}
};
var mouseout= function(d){
var z = this.getAttribute('class')
console.log(z.slice(0,1)=="y")
if(z.slice(0,1)=="y"){
var z = this.getAttribute('class');
var y = z.slice(1,6);
var color=ordinal('#'+quantize(newDict[d.properties.ZIP5]))
console.log(color)
d3.select("." + this.getAttribute('class'))
.style("fill",ordinal('#'+quantize(newDict[d.properties.ZIP5])))
d3.select('.z'+y)
.style("fill",ordinal('#'+quantize(newDict[d.properties.ZIP5])))
d3.selectAll(".text").remove()
}else{
console.log(d.calls)
console.log('#'+quantize(d.calls))
console.log(ordinal(quantize(d.calls)))
var z = this.getAttribute('class');
var y = z.slice(1,6);
d3.select("." + this.getAttribute('class'))
.style("fill",ordinal('#'+quantize(d.calls)));
d3.select('.y'+y)
.style("fill",ordinal('#'+quantize(d.calls)))}
d3.selectAll('.text').remove();
};
//defer double request
q.defer(d3.json,"http://saccounty.cloudapi.junar.com/api/v2/datastreams/311-CASES-BY-ZIPCO-SUMMA/data.json/?auth_key=77bf2351cdb42d68f577b6c54041550cf708b773")
.defer(d3.json,"saczipgeo.json")
.awaitAll(ready)
function ready(error,first){
if(error){alert("You had an error retrieving data");}
//preparing data and everything for first json file
data=first;
data=data[0];
data.result.fArray.forEach(function(value,i){
if(i%2==0){
dataZipcode[i]=data.result.fArray[i].fStr
}
if(i%2!=0){
dataCalls[i]=data.result.fArray[i].fStr
}
});
data=[];
for ( i=0;i<=108;i=i+2){
if(i==0){
data[i]={"zipcode":dataZipcode[i],"calls":dataCalls[i+1]};
}
data[i/2]={"zipcode":dataZipcode[i],"calls":dataCalls[i+1]};
};
//scale for data colors
var maxD=d3.max(data.slice(1,data.length-1),function(d){return parseInt(d.calls)});
console.log(maxD);
var minD=d3.min(data.slice(1,data.length-1),function(d){return d.calls});
quantize= d3.scale.quantize()
.domain([0,maxD])
.range(d3.range(8).map(function(i) { return "g"+i; }));
data.forEach(function(d){return newDict[d.zipcode]= +d.calls;});
//preparing for the second json
dataGeo=first[1];
dataGeo=dataGeo.features
//checking for zipcodes that had zero calls(will be undefined in the dataMap object
for(i=0;i<dataGeo.length;i++){
if (newDict[dataGeo[i].properties.ZIP5] === undefined){
newDict[dataGeo[i].properties.ZIP5]=0;
};
};
svg.selectAll("zipcode")
.data(dataGeo)
.enter().append("path")
.attr("d", path)
.attr("class",function(d){return 'y'+ d.properties.ZIP5})
.attr("id",function(d){return quantize(newDict[d.properties.ZIP5])})
.attr("stroke","black")
.on("mouseover",mouseover)
.on("mouseout",mouseout)
var svg2=d3.select("body")
.append("svg")
.attr({
width: width,
height:h,
id:"svgtwo"
});
scaleX = d3.scale.linear()
.domain([0,maxD])
.range([0,width]);
for(i=0;i<dataGeo.length;i++){
rectData[i] = {"zipcode":dataGeo[i].properties.ZIP5,"calls":newDict[dataGeo[i].properties.ZIP5]}
};
rectData.sort(function(a, b){
return b.calls-a.calls;
})
var barPadding=1;
svg2.selectAll("rect")
.data(rectData)
.enter()
.sort(function(a, b) {
return d3.ascending(a, b);
})
.append("rect")
.attr("width",function(d){return scaleX(d.calls)})
.attr("height", function(d,i){return (h/rectData.length)-barPadding;})
.attr("y",function(d,i){return (h/rectData.length)*i;})
.attr("id",function(d){return quantize(d.calls)})
.attr("class",function(d){return 'z'+d.zipcode;})
.on("mouseover",mouseover)
.on("mouseout",mouseout);
for(i=0;i<dataGeo.length;i++){
mapDict[dataGeo[i].properties.ZIP5]={'name':dataGeo[i].properties.PO_NAME,'zipcode':dataGeo[i].properties.ZIP5,'calls':newDict[dataGeo[i].properties.ZIP5]};
};
d3.select('#svgtwo')
.append('line')
.attr({
x1:0,
y1:0,
x2:0,
y2:h,
"stroke-width":"1px",
"stroke":"black",
});
//legend
svg.append("g")
.attr("class", "legendQuant")
.attr("transform", "translate(350,450)");
var legend = d3.legend.color()
.labelFormat(d3.format(".2f"))
.useClass(true)
.scale(quantize);
svg.select(".legendQuant")
.call(legend);
};})();
</script>
for more info or data vist <a href="http://data.saccounty.net/home">http://data.saccounty.net/home</a>
</body>
<html>
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment