To prepare

With that in mind, we need to look at a few more advanced concepts.

Scales

To scale a data set is to recalibrate it, for example to create a linear scale:

Var normalize = d3. Scale. Linear (). The domain ([0, 50]). The range ([0, 1])Copy the code

domain(..) Used to set the maximum and minimum values of input data, range(..) Used to set the maximum and minimum values for output data. This means that a linear scale will be created, mapping [0,50] to [0,1]. Verify:

Axes

The axes, which are a very important part of visualization, just give you an example:

Var svgElement = d3.select("body")
      .append("svg")
      .attr({"width" : 500, "height": 500}); // Create a linear scale, Domain (actual scale value displayed) is [0,50] range(real length) is [10,400] var xScale = d3.scale.linear().domain([0,50]).range([10,400]); Var xAxis = d3.svg.axis().scale(xScale).ticks(5).orient()"bottom"); G var x = svgelement.append ("g")
      .call(xAxis);
Copy the code

Style:

    path {
      stroke: steelblue;
      fill: none;
      stroke-width: 2;
    }
Copy the code

Display effect:

The d3.svg.axis() method is used to create the axes, and the ticks() method sets the number of ticks the axes have. The default is 10 if called.

The data load

D3 supports JSON, CSV, TSV, XML,HTML and other formatted data formats, and provides corresponding loading API, such as loading TSV data:

    d3.tsv("xxxx/data.tsv".function (error, data) {
      if (error)
        console.log(error);
      else
        console.table(data);
    });
Copy the code

Create basic diagrams and code reuse

The previous concept was to create a variety of classic visualizations, so let’s use line and area diagrams as a starting point.

Line diagram

Line charts are the most widely used type of chart, usually to show trends over time based on data series.

  • The data set

    The sample data set here is still in TSV format, which is a set of closing price data of a stock in a time span.

  • Data processing and format conversion

    Since data center date and close are both string formats, we need to convert them to usable formats before drawing, and process the data before loading it:

    //Create a date parser
    var ParseDate = d3.time.format("%d-%b-%y").parse;
    
    //Read TSV file
    d3.tsv("data.tsv".function(error, data){
        //Parse Data into useable format
        data.forEach(function(d){
        d.date = ParseDate(d.date);
        d.close = +d.close;
        //the + sign converts numeric string to number
        });
        
        //Print the data as a table in the console
        console.table(data);
    });
    Copy the code

    After processing, the data is converted into:

    hered3.time.format.parseThe local time () function converts time data in a specified format to the standard local time format. The ‘+’ sign casts a string to a numeric format.

  • Line drawing

    As we explained in the first tutorial, drawing lines in SVG requires the coordinates of each point, which is a very lengthy process. In D3 we just need to provide the data values and scales and D3 will automatically do the heavy lifting for us. The following code is a reusable line generator:

    //Create a line generator
    var valueline = d3.svg.line()
        .x(function(d){
            return xScale(d.date);
        })
        .y(function(d){
            return yScale(d.close);
        });
    Copy the code
  • Combination of code

    According to the step decomposition of the previous two parts, we can complete the whole drawing work by adding the creation of the scale. The complete code is as follows:

    <! DOCTYPE html> <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
      <title>line chart</title>
      <script src="https://d3js.org/d3.v3.js"></script> <style> path{ stroke: steelblue; fill: none; stroke-width: 2; } .axis path, .axis line { fill: none; stroke: grey; stroke-width: 1; /* Specify the rendering mode of SVG elements <path> */ shape-rendering: crispEdges; } </style> </head> <body> <script> //Set margins and sizes var margin = { top: 20, bottom: 50, right: 30, left: 50 }; var width = 700 - margin.left - margin.right; var height = 500 - margin.top - margin.bottom; //Create date parser var ParseDate = d3.time.format("%d-%b-%y").parse;
        //Create x and y scale to scale inputs
        var xScale = d3.time.scale().range([0, width]);
        var yScale = d3.scale.linear().range([height, 0]);
    
        //Create x and y axes
        var xAxis = d3.svg.axis().scale(xScale)
          .orient("bottom")
          .ticks(5);
        var yAxis = d3.svg.axis().scale(yScale)
          .orient("left")
          .ticks(5);
    
        //Create a line generator
        var valueline = d3.svg.line()
          .x(function (d) {
            return xScale(d.date);
          })
    
          .y(function (d) {
            return yScale(d.close);
          });
        //Create an SVG element and append it to the DOM
        var svgElement = d3.select("body").append("svg")
          .attr({ "width": width + margin.left + margin.right, "height": height + margin.top + margin.bottom })
          .append("g")
          .attr("transform"."translate(" + margin.left + "," + margin.top + ")");
        //Read TSV file
        d3.tsv("./data.tsv".function (data) {
          //Parse Data into useable format
          data.forEach(function (d) {
            d.date = ParseDate(d.date);
            d.close = +d.close;
            //the + sign converts string automagically to number
          });
    
          //Set the domains of our scales
          xScale.domain(d3.extent(data, function (d) { return d.date; })); // d3.extent - find the minimum and maximum value in an array.
          yScale.domain([0, d3.max(data, function (d) { return d.close; })]);
    
          //append the svg path
          var path = svgElement.append("path")
            .attr("d", valueline(data));
    
          //Add X Axis
          var x = svgElement.append("g")
            .attr("class"."x axis")
            .attr("transform"."translate(0," + height + ")")
            .call(xAxis);
    
          //Add Y Axis
          var y = svgElement.append("g")
            .attr("class"."y axis")
            .call(yAxis);
    
          //Add label to y axis
          y.append("text")
            .attr("fill"."# 000")
            .attr("transform"."rotate(-90)")
            .attr("y", 6)
            .attr("dy"."0.71 em")
            .attr("text-anchor"."end")
            .text("Price ($)");
        });
    
      </script>
    </body>
    
    </html>
    Copy the code

Regional figure

The only difference between an area diagram and a line diagram is that an area is marked below the line, so it can be turned into an area diagram with only a few code changes.

<! DOCTYPE html> <html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <title>area chart</title>
  <script src="https://d3js.org/d3.v3.js"></script>
  <style>
    .axis path,
    .axis line {
      fill: none;
      stroke: black;
      stroke-width: 1;
      shape-rendering: crispEdges;
    }
  </style>
</head>

<body>
  <script>
    //Set margins and sizes
    var margin = {
      top: 20,
      bottom: 50,
      right: 30,
      left: 50
    };

    var width = 960 - margin.left - margin.right;
    var height = 500 - margin.top - margin.bottom;
    //Create date parser
    var ParseDate = d3.time.format("%d-%b-%y").parse;
    //Create x and y scale to scale inputs
    var xScale = d3.time.scale().range([0, width]);
    var yScale = d3.scale.linear().range([height, 0]);

    //Create x and y axes
    var xAxis = d3.svg.axis().scale(xScale)
      .orient("bottom")
      .ticks(5);

    var yAxis = d3.svg.axis().scale(yScale)
      .orient("left");

    //Create a area generator
    var area = d3.svg.area()
      .x(function (d) {
        return xScale(d.date);
      })
      .y1(function (d) {
        return yScale(d.close);
      }); // area.y1 - get or set the y1-coordinate (topline) accessor.

    //Create an SVG element and append it to the DOM
    var svgElement = d3.select("body")
      .append("svg").attr({ "width": width + margin.left + margin.right, "height": height + margin.top + margin.bottom })
      .append("g")
      .attr("transform"."translate(" + margin.left + "," + margin.top + ")");

    //Read TSV file
    d3.tsv("./data.tsv".function (data) {
      //Parse Data into useable format
      data.forEach(function (d) {
        d.date = ParseDate(d.date);
        d.close = +d.close;
        //the + sign converts string automagically to number
      });

      //Set the domains of our scales
      xScale.domain(d3.extent(data, function (d) { return d.date; }));
      yScale.domain([0, d3.max(data, function (d) { return d.close; })]);
      area.y0(yScale(0));
      //append the svg path
      var path = svgElement.append("path")
        .attr("d", area(data))
        .attr("fill"."steelblue");
      //Add X Axis
      var x = svgElement.append("g")
        .attr("transform"."translate(0," + height + ")")
        .attr("class"."x axis")
        .call(xAxis);

      //Add Y Axis
      var y = svgElement.append("g")
        .call(yAxis)
        .attr("class"."y axis");

      //Add label to Y axis
      y.append("text")
        .attr("fill"."# 000")
        .attr("transform"."rotate(-90)")
        .attr("y", 6)
        .attr("dy"."0.71 em")
        .attr("text-anchor"."end")
        .text("Price ($)");
    });
  </script>
</body>

</html>
Copy the code

The main change is to replace the line generator with the region generator.

D3 Basic steps for drawing

Based on the above two types of chart creation, we can extract a relatively standard creation module, as follows:

  1. Basic HTML and CSS

  2. pretreatment

    A. Set the offset, size and variables of the chart in advance.

    B. Create scales, coordinates, color scales, etc.

    C. Create data processing functions such as time parser, percentage format processing, etc.

  3. Visual concrete design

    Specific code is done here based on different diagram types, such as line generator and region generator.

  4. Create SVG

  5. Loading external data

  6. Combination of code

  7. Additional processing

    This includes tags, effects, etc.

This is a recommended comparison of standard drawing steps, not strictly required, just a reference to form a fixed style for easy understanding and maintenance. In the next section, we use these lessons to draw a new chart type.

Give it a try

This section follows the steps above to make a bar chart with the data set in CSV format:

    1. Basic HTML and CSS
<! DOCTYPE html> <html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <title>bar chart</title>
  <script src="https://d3js.org/d3.v3.js"></script> <style> .axis path, .axis line { fill: none; stroke: grey; stroke-width: 1; /* Specify the rendering mode of SVG elements <path> */ shape-rendering: crispEdges; } </style> </head> <body> <script>Copy the code
    1. pretreatment
    //Set margins and sizes
    var margin = {
      top: 20,
      bottom: 70,
      right: 30,
      left: 50
    };

    var width = 700 - margin.left - margin.right;
    var height = 500 - margin.top - margin.bottom;
    //Create date parser
    var ParseDate = d3.time.format("%Y-%m").parse;
    //Create x and y scale to scale inputs
    var xScale = d3.scale.ordinal().rangeRoundBands([0, width], .05);
    var yScale = d3.scale.linear().range([height, 0]);

    //Create x and y axes
    var xAxis = d3.svg.axis().scale(xScale)
      .orient("bottom")
      .tickFormat(d3.time.format("%Y-%m"));
    var yAxis = d3.svg.axis().scale(yScale)
      .orient("left")
      .ticks(10);
Copy the code
    1. Visual concrete design

No special design is required for bar charts.

    1. Create SVG
    //Create an SVG element and append it to the DOM
    var svgElement = d3.select("body").append("svg")
      .attr({ "width": width + margin.left + margin.right, "height": height + margin.top + margin.bottom })
      .append("g")
      .attr("transform"."translate(" + margin.left + "," + margin.top + ")");
Copy the code
    1. Loading external data
    //Read CSV file
    d3.csv("./bar-data.csv".function (data) {
      //Parse Data into useable format
      data.forEach(function (d) {
        d.date = ParseDate(d.date);
        d.value = +d.value;
        //the + sign converts string automagically to number
      });

      //Set the domains of our scales
      xScale.domain(data.map(function(d) { return d.date; }));
      yScale.domain([0, d3.max(data, function (d) { return d.value; })]);
Copy the code
    1. Combination of code
<! DOCTYPE html> <html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <title>bar chart</title>
  <script src="https://d3js.org/d3.v3.js"></script> <style> .axis { font: 10px sans-serif; } .axis path, .axis line { fill: none; stroke: grey; stroke-width: 1; /* Specify the rendering mode of SVG elements <path> */ shape-rendering: crispEdges; } </style> </head> <body> <script> //Set margins and sizes var margin = { top: 20, bottom: 70, right: 30, left: 50 }; var width = 700 - margin.left - margin.right; var height = 500 - margin.top - margin.bottom; //Create date parser var ParseDate = d3.time.format("%Y-%m").parse;
    //Create x and y scale to scale inputs
    var xScale = d3.scale.ordinal().rangeRoundBands([0, width], .05);
    var yScale = d3.scale.linear().range([height, 0]);

    //Create x and y axes
    var xAxis = d3.svg.axis().scale(xScale)
      .orient("bottom")
      .tickFormat(d3.time.format("%Y-%m"));
    var yAxis = d3.svg.axis().scale(yScale)
      .orient("left")
      .ticks(10);

    //Create an SVG element and append it to the DOM
    var svgElement = d3.select("body").append("svg")
      .attr({ "width": width + margin.left + margin.right, "height": height + margin.top + margin.bottom })
      .append("g")
      .attr("transform"."translate(" + margin.left + "," + margin.top + ")");
    //Read CSV file
    d3.csv("./bar-data.csv".function (data) {
      //Parse Data into useable format
      data.forEach(function (d) {
        d.date = ParseDate(d.date);
        d.value = +d.value;
        //the + sign converts string automagically to number
      });

      //Set the domains of our scales
      xScale.domain(data.map(function(d) { return d.date; }));
      yScale.domain([0, d3.max(data, function (d) { return d.value; })]);

      //Add X Axis
      var x = svgElement.append("g")
        .attr("class"."x axis")
        .attr("transform"."translate(0," + height + ")")
        .call(xAxis)
        .selectAll("text")
        .style("text-anchor"."end")
        .attr("dx"."-.8em")
        .attr("dy"."-.55em")
        .attr("transform"."rotate(-90)" );

      //Add Y Axis
      var y = svgElement.append("g")
        .attr("class"."y axis")
        .call(yAxis);

      //Add label to y axis
      y.append("text")
        .attr("fill"."# 000")
        .attr("transform"."rotate(-90)")
        .attr("y", 6)
        .attr("dy"."0.71 em")
        .attr("text-anchor"."end")
        .text("Price ($)");
      
      svgElement.selectAll("rect")
        .data(data)
        .enter().append("rect")
        .style("fill"."steelblue")
        .attr("x".function(d) { return xScale(d.date); })
        .attr("width", xScale.rangeBand())
        .attr("y".function(d) { return yScale(d.value); })
        .attr("height".function(d) { return height - yScale(d.value); });
    });

  </script>
</body>

</html>
Copy the code

A simple bar chart is completed:

Other Common Graphics

Common graphs such as tree graphs and force guides have also changed a lot from the new VERSION of D3, which is summarized in the following tutorial.

The resources

  1. Reference Examples for this article
  2. V3 documentation