官术网_书友最值得收藏!

Creating the visualization

Now that we've got the data we want to work with, we can start creating the example. The files used in this example are the following:

  • <DVD3>/src/chapter-01/D01-02.html: The HTML template that loads the correct CSS and JavaScript files for this example
  • <DVD3>/src/chapter-01/js/D01-02.js: The JavaScript which uses the D3 APIs to draw the chart
  • <DVD3>/src/chapter-01/css/D01-02.css: Custom CSS to color the bars and format the text elements
  • <DVD3>/src/chapter-01/data/yob2015.txt: The data that is visualized

Let's start with the complete JavaScript file first. It might seem complex, and it introduces a couple of new concepts, but the general idea should be clear from the code (if you open the source file in your editor, you can also see inline comments for additional explanation):

 
function show() {
'use strict';

var margin = { top: 30, bottom: 20, right: 40, left: 40 },
width = 800 - margin.left - margin.right,
height = 600 - margin.top - margin.bottom;

var chart = d3.select('.chart')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ','
+ margin.top + ')');

var namesToShow = 10;
var barWidth = 20;
var barMargin = 5;

d3.csv('data/yob2015.txt', function (d) { return { name: d.name, sex: d.sex, amount: +d.amount }; }, function (data) {
var grouped = _.groupBy(data, 'sex');
var top10F = grouped['F'].slice(0, namesToShow);
var top10M = grouped['M'].slice(0, namesToShow);

var both = top10F.concat(top10M.reverse());

var bars = chart.selectAll("g").data(both)
.enter()
.append('g')
.attr('transform', function (d, i) {
var yPos = ((barWidth + barMargin) * i);
return 'translate( 0 ' + yPos + ')';
});

var yScale = d3.scaleLinear()
.domain([0, d3.max(both, function (d) { return d.amount; })])
.range([0, width]);

bars.append('rect')
.attr("height", barWidth)
.attr("width", function (d) { return yScale(d.amount); })
.attr("class", function (d) { return d.sex === 'F' ? 'female' : 'male'; });

bars.append("text")
.attr("x", function (d) { return yScale(d.amount) - 5 ; })
.attr("y", barWidth / 2)
.attr("dy", ".35em")
.text(function(d) { return d.name; });

var bottomAxis = d3.axisBottom().scale(yScale).ticks(20, "s");
var topAxis = d3.axisTop().scale(yScale).ticks(20, "s");

chart.append("g")
.attr('transform', 'translate( 0 ' + both.length * (barWidth + barMargin) + ')')
.call(bottomAxis);

chart.append("g")
.attr('transform', 'translate( 0 ' + -barMargin + ' )')
.call(topAxis);
});
}

In this JavaScript file, we perform the following steps:

  1. Set up the main chart element, like we did in the previous example.
  2. Load the data from the CSV file using d3.csv.
  3. Group the loaded data so we only have the top 10 names for both sexes. Note that we use the groupBy function from the lodash library (https://lodash.com/) for this. This library provides a lot of additional functions to deal with common array operations. Throughout this book, we'll use this library in places where the standard JavaScript APIs don't provide enough functionality.
  4. Add g elements that will hold the rect and text elements for each name.
  5. Create the rect elements with the correct width corresponding to the number of times the name was used.
  6. Create the text elements to show the name at the end of the rect elements.
  7. Add some CSS styles for the rect and text elements.
  8. Add an axis to the top and the bottom for easy referencing.

We'll skip the first step since we've already explained that before, and move on to the usage of the d3.csv API call. Before we do that, there are a couple of variables in the JavaScript that determine how the bars look, and how many we show:

var namesToShow = 10; 
var barWidth = 20;
var barMargin = 5;

These variables will be used throughout the explanation in the following sections. What this means is that we're going to show 10 (namesToShow) names, a bar is 20 (barWidth) pixels wide, and between each bar we put a five pixel margin.

主站蜘蛛池模板: 盐山县| 钦州市| 龙州县| 雷波县| 凤阳县| 林周县| 铁岭县| 宜黄县| 老河口市| 石河子市| 云浮市| 澎湖县| 安吉县| 平江县| 山阳县| 黄大仙区| 闸北区| 靖江市| 定远县| 丹棱县| 自治县| 兴业县| 台江县| 乌拉特中旗| 新乡县| 铁力市| 海安县| 育儿| 景泰县| 丘北县| 上饶县| 伊金霍洛旗| 济宁市| 寿宁县| 朝阳县| 体育| 阳江市| 乾安县| 马鞍山市| 黄大仙区| 新安县|