

Data Visualization for Dummies: 3 Simple Charts with <70 Lines of Code
source link: https://hackernoon.com/data-visualization-for-dummies-3-simple-charts-with-less70-lines-of-code
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Data Visualization for Dummies: 3 Simple Charts with <70 Lines of Code

















Listen to this story

Software developer with expertise in JavaScript, Angular, AngularJs, D3
Here I would like to talk about converting large, complex data into an easy visual representation format. For that, I pick the most commonly used charts - line, bar, and pie.




Actually, there are plenty of charts, but you can find these three in most of the applications made for data analysis or representation. Next, I will explain how to build them by using the popular library D3.js.




I’ve created a small demo application. It is a simple dashboard with those charts. I did not use any framework, just HTML, CSS, and JavaScript.




Also, I added 3 separate files with data set for each of the charts. I think it is more than enough to begin drawing the charts. But first, let’s take a look at the HTML structure:




<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>D3 charts</title>
<link rel="stylesheet" href="styles.css">
<link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet">
<script src="https://d3js.org/d3.v7.min.js"></script>
<script type="module" src="charts/bar-chart.js" defer></script>
<script type="module" src="charts/line-chart.js" defer></script>
<script type="module" src="charts/pie-chart.js" defer></script>
</head>
<body>
<header>
<span>D3 Dashboard</span>
</header>
<section>
<div class="bar-line-charts">
<div class="chart-widget">
<div class="widget-header">
<span>Line chart</span>
</div>
<div id="line-chart" class="chart"></div>
</div>
<div class="chart-widget">
<div class="widget-header">
<span>Bar chart</span>
</div>
<div id="bar-chart" class="chart"></div>
</div>
</div>
<div class="pie-chart">
<div class="chart-widget">
<div class="widget-header">
<span>Pie chart</span>
</div>
<div id="d3-chart" class="chart" style="padding: 90px"></div>
</div>
</div>
</section>
</body>
</html>
Let’s draw the first chart, it is going to be a pie, then I will continue with the line and bar chart.




Pie Chart
import data from '../data/pie-data.js'
// Selecting the element
const element = document.getElementById('d3-chart');
// Setting dimensions
const margin = 10,
width = 400,
height = 400;
// Setting the radius of the pie
const radius = Math.min(width, height) / 2 - margin;
const svg = d3.select(element)
.append("svg")
.attr("width", width)
.attr("height", height)
.attr("style", "margin-top: -32px !important")
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
// Setting the color scale
const color = d3.scaleOrdinal()
.domain(data)
.range(["#43ab92", "#f75f00", "#512c62"]);
// Setting the position of each group on the pie
const pie = d3.pie()
.value(function (d) {
return d[1].value;
});
const data_ready = pie(Object.entries(data));
// Building arcs
const arcGenerator = d3.arc()
.innerRadius(0)
.outerRadius(radius);
// Building the pie chart
svg.selectAll('slices')
.data(data_ready)
.enter()
.append('path')
.attr('d', arcGenerator)
.attr('fill', function (d) {
return (color(d.data[1].name))
});
// Adding titles to pie slices
svg.selectAll('slices')
.data(data_ready)
.enter()
.append('text')
.text(function (d) {
return d.data[1].name
})
.attr("transform", function (d) {
return "translate(" + arcGenerator.centroid(d) + ")";
})
.style("text-anchor", "middle")
.style("font-size", 20);
Line Chart
import lineData from '../data/line-data.js'
// Selecting the element
const element = document.getElementById('line-chart');
// Setting dimensions
const margin = {top: 40, right: 30, bottom: 7, left: 50},
width = 900 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
// Adding helper functions to make the line look nice
// The <defs> element is used to store graphical objects that will be used at a later time.
const createGradient = function(select) {
const gradient = select
.select('defs')
.append('linearGradient')
.attr('id', 'gradient')
.attr('x1', '0%')
.attr('y1', '100%')
.attr('x2', '0%')
.attr('y2', '0%');
gradient.append('stop')
.attr('offset', '0%')
.attr('style', 'stop-color:#da6e2a;stop-opacity:0.05');
gradient.append('stop')
.attr('offset', '100%')
.attr('style', 'stop-color:#da6e2a;stop-opacity:.5');
}
const createGlowFilter = function(select) {
const filter = select
.select('defs')
.append('filter')
.attr('id', 'glow')
filter.append('feGaussianBlur')
.attr('stdDeviation', '4')
.attr('result', 'coloredBlur');
const femerge = filter
.append('feMerge');
femerge.append('feMergeNode')
.attr('in', 'coloredBlur');
femerge.append('feMergeNode')
.attr('in', 'SourceGraphic');
}
// Parsing timestamps
const parseTime = d3.timeParse('%Y/%m/%d');
const parsedData = lineData.map(item => (
{
values: item.values.map((val) => ({
total: val.total,
date: parseTime(val.date)
}))
}));
// Appending svg to a selected element
const svg = d3.select(element)
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', 300 + margin.top + margin.bottom)
.attr("viewBox", `0 40 ${width + 80} ${height}`)
.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`);
// Setting X,Y scale ranges
const xScale = d3.scaleTime()
.domain([
d3.min(parsedData, (d) => d3.min(d.values, (v) => v.date)),
d3.max(parsedData, (d) => d3.max(d.values, (v) => v.date))
])
.range([0, width]);
const yScale = d3.scaleLinear()
.domain([
d3.min(parsedData, (d) => d3.min(d.values, (v) => v.total)),
d3.max(parsedData, (d) => d3.max(d.values, (v) => v.total))
])
.range([height, 0]);
// Appending <defs>
svg.append('defs');
svg.call(createGradient);
svg.call(createGlowFilter);
// Drawing line with inner gradient
// Adding functionality to make line curved
const line = d3.line()
.x(function(d) {
return xScale(d.date);
})
.y(function(d) {
return yScale(d.total);
})
.curve(d3.curveCatmullRom.alpha(0.5));
// Drawing inner part of a line
svg.selectAll('.line')
.data(parsedData)
.enter()
.append('path')
.attr('d', function(d) {
const lineValues = line(d.values).slice(1);
const splitedValues = lineValues.split(',');
return `M0,${height},${lineValues},l0,${height - splitedValues[splitedValues.length - 1]}`
})
.style('fill', 'url(#gradient)');
// Drawing a line
svg.selectAll('.line')
.data(parsedData)
.enter()
.append('path')
.attr('d', function(d) {
return line(d.values)
})
.attr('stroke-width', '2')
.style('fill', 'none')
.style('filter', 'url(#glow)')
.attr('stroke', '#ff6f3c');
// Adding the x Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(xScale));
// Adding the y Axis
svg.append("g")
.call(d3.axisLeft(yScale));
Bar Chart
import barData from '../data/bar-data.js'
// Selecting the element
const element = document.getElementById('bar-chart');
// Setting dimensions
const margin = {top: 40, right: 20, bottom: 50, left: 50},
width = 900 - margin.left - margin.right,
height = 480 - margin.top - margin.bottom;
// Setting X,Y scale ranges
const xScale = d3.scaleBand()
.range([0, width])
.padding(0.1);
const yScale = d3.scaleLinear()
.range([height, 0]);
// Appending svg to a selected element
const svg = d3.select(element).append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("viewBox", `0 40 ${width + 80} ${height}`)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// Formatting the data
barData.forEach(function (d) {
d.value = +d.value;
});
// Scaling the range of the data in the domains
xScale.domain(barData.map(function (d) {
return d.name;
}));
yScale.domain([0, d3.max(barData, function (d) {
return d.value;
})]);
// Appending the rectangles for the bar chart
svg.selectAll(".bar")
.data(barData)
.enter().append("rect")
.attr("x", function (d) {
return xScale(d.name);
})
.attr("width", xScale.bandwidth())
.attr("y", function (d) {
return yScale(d.value);
})
.attr("height", function (d) {
return height - yScale(d.value);
})
.style("fill", "#ff6f3c");
// Adding the x Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(xScale));
// Adding the y Axis
svg.append("g")
.call(d3.axisLeft(yScale));
Wrapping up
As you can see, all these charts do not have difficult logic. It takes around 70 lines of code to implement it. That is how we can make complex data to be converted in easy visual representation format.




Try it yourself! The source code can be found on GitHub. I recommend inspecting charts in the DOM to understand how D3 renders the elements.




















Create your free account to unlock your custom reading experience.
Recommend
-
98
A quick tutorial on how to build a simple retweeting Twitter bot using twit and Node.js
-
50
Data Visualization is visual representation of quantitative information in the form of charts, graphs, plots and so on. There are so many libraries and frameworks available to visualize data, but the one that we are going...
-
63
Yes! It’s that simple. Let’s play around with datasets to visualize how the decision boundary changes as ‘k’ changes. Let’s h...
-
8
“A picture is worth a thousand words.” The 7.0.2 Couchbase Query Workbench (and the Analytics Workbench) introduces the charts tab, which allows users to create charts based on the results of the query. A Closer Look at Charts
-
8
Blooming bar charts: The growth of the data visualization industryExploring data visualization industry trends for 2022.
-
12
A Comprehensive List of the Best Data Visualization Charts for Your Business September 26, 2022
-
16
To get effective analyzing and communicating results, you may sift through lots of data for your jobs. When you manage multiple sources of data, it can get overwhelming and may make you frustrating. You'd better know wh...
-
9
Data Science For Dummies ($21 value)...
-
3
Angular Visualizations: Create Data Visualization with Kendo UI Charts ...
-
9
In today’s data-driven world, tracking multiple key metrics is crucial to understanding the relationships and trends in data.That is where the Syncfusion
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK