/////////////////////////////////////////////////////////////////////////// //////////////////// Set up and initiate svg containers /////////////////// /////////////////////////////////////////////////////////////////////////// var margin = { top: 70, right: 20, bottom: 120, left: 20 }; var width = window.innerWidth - margin.left - margin.right - 20; var height = window.innerHeight - margin.top - margin.bottom - 20; //SVG container var svg = d3.select("#weatherRadial") .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + (margin.left + width/2) + "," + (margin.top + height/2) + ")"); /////////////////////////////////////////////////////////////////////////// //////////////////////////// Create scales //////////////////////////////// /////////////////////////////////////////////////////////////////////////// //Parses a string into a date var parseDate = d3.timeParse("%Y%m%d"); var parseDateNY = d3.timeParse("%d-%b") d3.json("myfile.json", function(error, weatherSF) { console.log(weatherSF.data) weatherSF.newyork.forEach(function(d) { d.date = parseDateNY(d.date); d.min = +d.min d.max = +d.max // d.meantempi = +d.meantempi // console.log(d.date) }) //Turn strings into actual numbers/dates weatherSF.data.forEach(function(d) { d.date = parseDate(d.date); d.mintempi = +d.mintempi d.maxtempi = +d.maxtempi d.meantempi = +d.meantempi // console.log(d.date) }) //Set the minimum inner radius and max outer radius of the chart var outerRadius = Math.min(width, height, 500)/2, innerRadius = outerRadius * 0.4; //Scale for the heights of the bar, not starting at zero to give the bars an initial offset outward var barScale = d3.scaleLinear() .range([innerRadius, outerRadius]) .domain([30,80]); //Scale to turn the date into an angle of 360 degrees in total //With the first datapoint (Jan 1st) on top var angle = d3.scaleLinear() .range([-180, 180]) .domain(d3.extent(weatherSF.data, function(d) { return d.date; })); var angleNY = d3.scaleLinear() .range([-180, 180]) .domain(d3.extent(weatherSF.newyork, function(d) { return d.date; })); // console.log(angle.domain) //create title var textWrapper = svg.append("g").attr("class", "textWrapper") .attr("transform", "translate(" + Math.max(-width/2, -outerRadius - 170) + "," + 0 + ")"); //Append title to the top textWrapper.append("text") .attr("class", "title") .attr("x", 0) .attr("y", -outerRadius - 40) .text("Daily Temperatures in San Francisco and New York"); textWrapper.append("text") .attr("class", "subtitle") .attr("x", 0) .attr("y", -outerRadius - 20) .text("2015"); //Append credit at bottom textWrapper.append("text") .attr("class", "credit") .attr("x", 0) .attr("y", outerRadius + 120) .text("Based on weather-radials.com"); //create axes //Wrapper for the bars and to position it downward var barWrapper = svg.append("g") .attr("transform", "translate(" + 0 + "," + 0 + ")"); //Draw gridlines below the bars var axes = barWrapper.selectAll(".gridCircles") .data([30,40,50,60,70,80]) .enter().append("g"); var tooltip = d3.select("body") .append("div") .attr("class", "tooltip") .style("position", "absolute") .style("z-index", "10") .style("visibility", "hidden"); //Draw the circles axes.append("circle") .attr("class", "axisCircles") .attr("r", function(d) { return barScale(d); }); //Draw the axis labels axes.append("text") .attr("class", "axisText") .attr("y", function(d) { return barScale(d); }) .attr("dy", "0.3em") .text(function(d) { return d + "°F"}); //Add January for reference barWrapper.append("text") .attr("class", "january") .attr("x", -17) .attr("y", -outerRadius * 1.15) .attr("dy", "0.9em") .text("January"); barWrapper.append("text") .attr("class", "january") .attr("x", outerRadius * 1.1) .attr("y", -7) .attr("dy", "0.9em") .text("April"); barWrapper.append("text") .attr("class", "january") .attr("x", -15) .attr("y", outerRadius * 1.1) .attr("dy", "0.9em") .text("June"); barWrapper.append("text") .attr("class", "january") .attr("x", -outerRadius * 1.32) .attr("y", -10) .attr("dy", "0.9em") .text("October"); //Add a line to split the year barWrapper.append("line") .attr("class", "yearLine") .attr("x1", 0) .attr("y1", -outerRadius ) .attr("x2", 0) .attr("y2", -outerRadius * 1.1); barWrapper.append("line") .attr("class", "yearLine") .attr("x1", outerRadius ) .attr("y1", 0) .attr("x2", outerRadius * 1.1) .attr("y2", 0); barWrapper.append("line") .attr("class", "yearLine") .attr("x1", -outerRadius) .attr("y1", 0) .attr("x2", -outerRadius * 1.1) .attr("y2", 0); barWrapper.append("line") .attr("class", "yearLine") .attr("x1", 0) .attr("y1", outerRadius) .attr("x2", 0) .attr("y2", outerRadius * 1.1); //drew bars //Draw a bar per day were the height is the difference between the minimum and maximum temperature //And the color is based on the mean temperature barWrapper.selectAll(".tempBar") .data(weatherSF.data) .enter().append("rect") .attr("class", "tempBar") .attr("transform", function(d,i) { return "rotate(" + (angle(d.date)) + ")"; }) .attr("width", 1.5) .attr("height", function(d,i) { return barScale(d.maxtempi) - barScale(d.mintempi); }) .attr("x", -0.75) .attr("y", function(d,i) {return barScale(d.mintempi); }) .style("fill", '#dd1c77') .on("mouseover", function(d,i) { tooltip.append("h3").attr("class", "tooltip_title"); tooltip.append("pre").attr("class", "tooltip_body"); tooltip.select(".tooltip_title") .text('San Francisco') tooltip.select(".tooltip_body") .text( "Date: " + d.date + "\n" + "Min Temp: " + d.mintempi + " °F\n" + "Max Temp: " + d.maxtempi + " °F\n" ); return tooltip.style("visibility", "visible"); }) .on("mousemove", function() { return tooltip.style("top", (d3.event.pageY-52) + "px").style("left", (d3.event.pageX+18) + "px"); }) .on("mouseout", function() { return tooltip.style("visibility", "hidden"); }); // .style("fill", function(d) { return colorScale(d.mean_temp); }); // barWrapper.selectAll("circle") // .data(weatherSF.data) // .enter().append("circle") // .attr("class", "circle") // .attr("transform", function(d,i) { return "rotate(" + (angle(d.date)) + ")"; }) // // .attr("width", 1.5) // // .attr("height", function(d,i) { return barScale(d.maxtempi) - barScale(d.mintempi); }) // .attr("cx", -0.75) // .attr("cy", function(d,i) {return barScale(d.meantempi); }) // .attr('r', 2) // .style("fill", '#e34a33') // .style('opacity', '0.4') barWrapper.selectAll(".nytempBar") .data(weatherSF.newyork) .enter().append("rect") .attr("class", "nytempBar") .attr("transform", function(d,i) { return "rotate(" + (angleNY(d.date)) + ")"; }) .attr("width", 1.5) .attr("height", function(d,i) { return barScale(d.max) - barScale(d.min); }) .attr("x", -0.75) .attr("y", function(d,i) {return barScale(d.min); }) .style("fill", '#43a2ca') .style('opacity', '.5') }) //Base the color scale on average temperature extremes // var colorScale = d3.scaleLinear() // .domain([-15, 7.5, 30]) // .range(["#2c7bb6", "#ffff8c", "#d7191c"]) // .interpolate(d3.interpolateHcl); /////////////////////////////////////////////////////////////////////////// //////////////// Create8the gradient for the legend /////////////////////// /////////////////////////////////////////////////////////////////////////// //Extra scale since the color scale is interpolated // var tempScale = d3.scaleLinear() // .domain([-15, 30]) // .range([0, width]); //Calculate the variables for the temp gradient // var numStops = 10; // tempRange = tempScale.domain(); // tempRange[2] = tempRange[1] - tempRange[0]; // tempPoint = []; // for(var i = 0; i < numStops; i++) { // tempPoint.push(i * tempRange[2]/(numStops-1) + tempRange[0]); // }//for i //Create the gradient // svg.append("defs") // .append("linearGradient") // .attr("id", "legend-weather") // .attr("x1", "0%").attr("y1", "0%") // .attr("x2", "100%").attr("y2", "0%") // .selectAll("stop") // .data(d3.range(numStops)) // .enter().append("stop") // .attr("offset", function(d,i) { return tempScale( tempPoint[i] )/width; }) // .attr("stop-color", function(d,i) { return colorScale( tempPoint[i] ); }); /////////////////////////////////////////////////////////////////////////// ////////////////////////// Draw the legend //////////////////////////////// /////////////////////////////////////////////////////////////////////////// // var legendWidth = Math.min(outerRadius*2, 400); //Color Legend container // var legendsvg = svg.append("g") // .attr("class", "legendWrapper") // .attr("transform", "translate(" + 0 + "," + (outerRadius + 70) + ")"); //Draw the Rectangle // legendsvg.append("rect") // .attr("class", "legendRect") // .attr("x", -legendWidth/2) // .attr("y", 0) // .attr("rx", 8/2) // .attr("width", legendWidth) // .attr("height", 8) // .style("fill", "url(#legend-weather)"); //Append title // legendsvg.append("text") // .attr("class", "legendTitle") // .attr("x", 0) // .attr("y", -10) // .style("text-anchor", "middle") // .text("Average Daily Temperature"); //Set scale for x-axis // var xScale = d3.scaleLinear() // .range([-legendWidth/2, legendWidth/2]) // .domain([-15,30] ); //Define x-axis // var xAxis = d3.axisBottom() // // d3.svg.axis() // // .orient("bottom") // .ticks(5) // .tickFormat(function(d) { return d + "°C"; }) // .scale(xScale); //Set up X axis // legendsvg.append("g") // .attr("class", "axis") // .attr("transform", "translate(0," + (10) + ")") // .call(xAxis);