Skip to content

Instantly share code, notes, and snippets.

@ValentinTT
Created March 31, 2018 04:07
Show Gist options
  • Save ValentinTT/f4bad2a7bc93df4cd7ab7b992b3b7822 to your computer and use it in GitHub Desktop.
Save ValentinTT/f4bad2a7bc93df4cd7ab7b992b3b7822 to your computer and use it in GitHub Desktop.
Visualize Data with a Bar Chart
<footer>
<a class="link" href="https://github.com/ValentinTapiaTorti" target="_blank">Valentin TT</a>
</footer>
const extractValues = (data, index = 0) => data
.reduce((acc, curr) => [...acc, curr[index]], []);
axios.get("https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/GDP-data.json")
.then((response) => drawBarChart(response.data.data));
const drawBarChart = (data) => {
let margin = {left: 70, right: 50, top: 50, bottom: 50},
barWidth = 3,
width = data.length * barWidth + (margin.left + margin.right),
height = 500,
xAxisLength = width - (margin.left + margin.right),
yAxisLength = height - (margin.top + margin.bottom),
tooltipWidth = 180,
tooltipHeight = 50;
let parseTime = d3.timeParse("%Y-%m-%d"),
formatTime = d3.timeFormat("%B %d, %Y"),
productDates = extractValues(data, 0).map(v => parseTime(v)),
productNumber = extractValues(data, 1);
let svgContainer = d3.select("body")
.append("div")
.classed("chart-container", true)
.append("svg")
.attr("width", width)
.attr("height", height);
svgContainer.append("text")
.classed("chart-title", true)
.text("US Gross Domestic Product");
let dim = d3.select(".chart-title").node().getBoundingClientRect();
d3.select(".chart-title")
.attr("x", (width/2) - (dim.width/2))
.attr("y", (margin.top / 2) + (dim.height/2));
let xScale = d3.scaleTime()
.domain(d3.extent(productDates))
.range([0, xAxisLength]);
let xAxis = d3.axisBottom(xScale);
svgContainer.append("g")
.classed("x-axis", true)
.attr("transform", "translate(" + margin.left + ", " + (height - margin.bottom) + ")")
.call(xAxis);
let yScale = d3.scaleLinear()
.domain(d3.extent(productNumber).reverse())
.range([0, yAxisLength]);
let yAxis = d3.axisLeft(yScale);
svgContainer.append("g")
.classed("y-axis", true)
.attr("transform", "translate(" + margin.left + ", " + margin.top + ")")
.call(yAxis);
let tooltip = d3.select('body')
.append("div")
.classed("tooltip", true)
.style("width", tooltipWidth + "px")
.style("height", tooltipHeight + "px")
.style("top", "0px")
.style("visibility", "hidden");
tooltip.append("p").classed("tooltip-date", true);
tooltip.append("p").classed("tooltip-data", true);
svgContainer.append("g")
.selectAll(".bar")
.data(data)
.enter()
.append("rect")
.classed("bar", true)
.attr("x", d => margin.left + xScale(parseTime(d[0])))
.attr("y", d => margin.top + yScale(d[1]))
.attr("width", barWidth)
.attr("height", d => yAxisLength - yScale(d[1]))
.on("mouseover", d => {
tooltip.transition();
tooltip
.style("left", d3.event.pageX - (tooltipWidth / 2)+ "px")
.style("top", d3.event.pageY - (tooltipHeight + 25) + "px")
.style("visibility", "visible")
.transition()
.duration(100)
.style("opacity", .7);
tooltip.select(".tooltip-date")
.text("Date: " + formatTime(parseTime(d[0])));
tooltip.select(".tooltip-data")
.text("$" + d[1] + " billion");
})
.on("mouseout", d => {
tooltip.transition();
tooltip.transition().duration(300)
.style("opacity", 0)
.style("left", d3.event.pageX - (tooltipWidth / 2)+ "px")
.style("top", d3.event.pageY - (tooltipHeight + 25) + "px")
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
$body-bg: #53B4F0;
$char-container-bg: #fff;
$tooltip-bg: #131313;
$tooltip-color: #fff;
$bar-bg: #B14647;
$bar-hover-bg: #B37D7D;
$link-color: #fff;
$footer-bg: #53B4F0;
$link-underline-color: #000;
@import url('https://fonts.googleapis.com/css?family=Abril+Fatface');
body {
box-sizing: border-box;
width: 100vw;
height: 100vh;
margin: 0;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr auto;
grid-template-areas: "chart-container" "footer";
background: $body-bg;
font-family: 'Abril Fatface', cursive;
}
footer {
grid-area: footer;
box-sizing: border-box;
padding: 10px 0;
display: flex;
align-items: center;
justify-content: center;
background: $footer-bg;
.link {
font-size: 20px;
color: $link-color;
text-decoration: none;
display: inline-block;
text-decoration: none;
transition: color 0.5s ease-out;
position: relative;
&::before, &::after {
content: "";
background: $link-color;
width: 0;
height: 3px;
position: absolute;
bottom: -5px;
transition: width 0.5s ease-out, background 0.5s ease-out;
}
&::after {
right: 0px;
}
&:hover{
color: $link-underline-color;
opacity: 0.9;
&::before, &::after {
background: $link-underline-color;
width: 100%;
}
}
}
}
.chart-container {
grid-area: chart-container;
box-sizing: border-box;
width: 100%;
height: 100%;
padding: 10px 0;
display: flex;
align-items: center;
justify-content: center;
svg {
background: $char-container-bg;
-webkit-box-shadow: -20px 10px 67px -2px rgba(0,0,0,0.6);
-moz-box-shadow: -20px 10px 67px -2px rgba(0,0,0,0.6);
box-shadow: -20px 10px 67px -2px rgba(0,0,0,0.6);
}
.chart-title {
font-size: 30px;
}
.bar {
fill: $bar-bg;
&:hover {
fill: $bar-hover-bg;
}
}
.x-axis, .y-axis {
text{
font-size: 14px;
}
}
}
.tooltip {
position: absolute;
text-align: center;
border-radius: 5px;
opacity: 0;
background: $tooltip-bg;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.tooltip-data, .tooltip-date {
color: $tooltip-color;
margin: 0;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment