Introduction to D3js: making histogram

D3js official website: https://d3js.org/
Recently, I was studying D3js. I simply summarized some documents to summarize my learning experience in the past week.
The official website of D3js is all in English. Compared with the detailed documents on the official website of Echarts, students with poor English may have to work harder to learn. However, if there is a partner with a Chinese translation version, please attach the link: https://github.com/d3/d3/wiki/CN-Home

What is D3Js

D3.js is a JavaScript function library based on the working mode of data-driven documents. It is mainly used for web page drawing and generating interactive graphics. It is one of the most popular visualization libraries. It is used by many other form plug-ins. D3 enables you to use HTML, SVG and CSS to visualize all kinds of data vividly. D3 does not need you to use a specific framework. It focuses on compatibility with modern mainstream browsers, and combines powerful visualization components to operate DOM in a data-driven way.

Browser support

D3js and ECharts are both JS libraries for data visualization. Compare d3js and ECharts

  • The mainstream browsers supported by D3 do not include IE8 and previous versions. D3 tested Firefox, Chrome, Safari, Opera, and IE9. Most components of D3 can run in old browsers.
  • ECharts, an open source visual library implemented by JavaScript, can run smoothly on PC and mobile devices, compatible with most of the current browsers (IE8/9/10/11, Chrome, Firefox, Safari, etc.), and the underlying layer relies on lightweight vector graphics library ZRender It can provide data visualization charts that are intuitive, interactive and highly customized.

install

Common import methods:

  • script tag introduction

 

<script src="http://d3js.org/d3.v3.min.js"></script>
  • npm command installation

 

npm install d3

Due to the great changes in v5 and v4/v3 of D3 version, this article mainly focuses on v3, and then discusses the specific use of d3js from simple to deep.

How to use D3

api official website https://github.com/d3/d3/wiki/API--%E4%B8%AD%E6%96%87%E6%89%8B%E5%86%8C
For a brief understanding, the following demo is used:

selector

 

<body>
    <p>Hello World!</p>
    <p>Hello World!</p>
    <script src="http://d3js.org/d3.v3.min.js"></script>
    <script>
        var p = d3.select('body')
                  .selectAll('p')
                  .text('Hello!')
        p.style("color", "red")
         .style("font-size", "72px")
    </script>
</body>

d3 provides rich dom operations, similar to the usage of jQuery.
d3.select() selects the first element that meets the conditions. It specifies one element;
You can write tags, class names and id names in parentheses, which is similar to jQuery

 

d3.select('body') //Within the specified body label
//or
d3.select('.red') //Specify the first label with the label class name red
//or
d3.select('#Blue ') / / specifies the first label with the label ID of blue

D3. Select all ('p ') selects all the elements of the P tag, which specifies a set;
. text('Hello ') specifies the content of the document

p.style() is to define css style for P element
The whole code execution results in two lines of red font Hello!

Many of d3's writing methods are similar to jQuery, not so strange.

datum

 

<body>
    <p>Hello World!</p>
    <p>Hello World!</p>

    <script src="../js/d3.v3.js"></script>
    <script>

        var str = "china"

        var body = d3.select('body')
        var p = body.selectAll('p')

        p.datum(str);

        p.text(function(d, i) {
            return "The first" + i + "The data bound by elements is" + d
        })


    </script>
</body>

Where is the source of data visualization? dataset is the data source;

  • selection.datum -Gets or sets the data for a single element without calculating the connection.

p. The element of the datum() / / P tag is set to str as the external source

p.text() / / receive a function callback in parentheses, d is the value of str, i is the index
Final output:

 

The data bound by the 0 th element is china

The data bound by the first element is china

data

 

<body>
    <p>Hello World!</p>
    <p>Hello World!</p>

    <script src="../js/d3.v3.js"></script>
    <script>

        var dataset = ["I like dogs","I like cats","I like snakes"];

        var body = d3.select('body')
        var p = body.selectAll('p')

        p.data(dataset);

        p.text(function(d, i) {
            return d
        })


    </script>
</body>
  • selection.data -Gets or sets the data for a set of elements when calculating related connections.
    There are three data sources, while the p tag has only two elements, so the output result to the page is:

 

I like dogs

I like cats

svg

 

<script>
        var width = 400;
        var height = 400;
        var svg = d3.select('body')
                    .append('svg')
                    .attr('width', width)
                    .attr('height', height)
</script>

append add svg tag
attr svg set width and height

Histogram

 

<script>
    var dataset = [ 250 , 210 , 170 , 130 , 90 ];  //Data (indicates the width of the rectangle)
    var width = 400;
    var height = 400;
    var svg = d3.select('body')
                .append('svg')
                .attr('width', width)
                .attr('height', height)
    var rectHeight = 25;   //Pixel height per rectangle (including white space)
    svg.selectAll("rect")
        .data(dataset)
        .enter()
        .append("rect")
        .attr("x", 20)
        .attr("y", function(d, i){
             return i * rectHeight;
        })
        .attr("width", function(d){
             return d;
        })
        .attr("height", rectHeight-2)
        .attr("fill", "steelblue");
</script>

Operation result:

 

image.png

 

Notice that
. enter() is used to return placeholders for missing elements

Linear scale

 

<script>
    // Linear scale
    var dataset = [1.2, 2.3, 0.9, 1.5, 3.3];

    var min = d3.min(dataset);
    var max = d3.max(dataset);

    var linear = d3.scale.linear()
                   .domain([min, max])
                   .range([0, 300])
    linear(0.9)
    console.log(linear(2.3)) // 175
</script>

d3.min() returns the minimum value
d3.max() returns the maximum value

d3.scale.linear() to build a linear scale
. domain() gets or sets the definition domain of the scale bar
. range() gets or sets the output range of the scale bar

Ordinal scale

 

<script>
    // Ordinal scale
    var index = [0, 1, 2, 3, 4];
    var color = ["red", "blue", "green", "yellow", "black"];
    var ordinal = d3.scale.ordinal() // Constructing an ordinal scale
                    .domain(index)  // Gets or specifies the input field for the scale bar
                    .range(color); // Gets or specifies the output range of the scale bar
    console.log(ordinal(2)) // 175
</script>

Histogram of linear scale

 

<script>
    var dataset = [ 2.5 , 2.1 , 1.7 , 1.3 , 0.9 ];

    var linear = d3.scale.linear()
            .domain([0, d3.max(dataset)])
            .range([0, 250])
    var rectHeight = 25;   //Pixel height per rectangle (including white space)

    var svg = d3.select("body")
                .append('svg')
                
    svg.selectAll("rect")
        .data(dataset)
        .enter()
        .append("rect")
        .attr("x",20)
        .attr("y",function(d,i){
             return i * rectHeight;
        })
        .attr("width",function(d){
             return linear(d);   //Use the scale here
        })
        .attr("height",rectHeight-2)
        .attr("fill","steelblue");
</script>

Histogram with x axis

 

<style>
    .axis path,
    .axis line{
        fill: none;
        stroke: black;
        shape-rendering: crispEdges;
    }
    .axis text {
        font-family: sans-serif;
        font-size: 11px;
    }
</style>
<script>
    var dataset = [ 2.5 , 2.1 , 1.7 , 1.3 , 0.9 ];

    var linear = d3.scale.linear()
            .domain([0, d3.max(dataset)])
            .range([0, 250])
    var rectHeight = 25;   //Pixel height per rectangle (including white space)

    var svg = d3.select("body")
                .append('svg')
                
    svg.selectAll("rect")
        .data(dataset)
        .enter()
        .append("rect")
        .attr("x",20)
        .attr("y",function(d,i){
             return i * rectHeight;
        })
        .attr("width",function(d){
             return linear(d);   //Use the scale here
        })
        .attr("height",rectHeight-2)
        .attr("fill","steelblue");
</script>

The output result is:

 

image.png

Histogram with xy axis

 

<style>
    .axis path,
    .axis line{
        fill: none;
        stroke: black;
        shape-rendering: crispEdges;
    }

    .axis text {
        font-family: sans-serif;
        font-size: 11px;
    }

    .MyRect {
        fill: steelblue;
    }

    .MyText {
        fill: white;
        text-anchor: middle;
    }

</style>
<script>
    //canvas size
    var width = 400;
    var height = 400;

    //Add an SVG canvas to the body   
    var svg = d3.select("body")
        .append("svg")
        .attr("width", width)
        .attr("height", height);

    //White space around canvas
    var padding = {left:30, right:30, top:20, bottom:20};

    //Define an array
    var dataset = [10, 20, 30, 40, 33, 24, 12, 5];
        
    //Scale of x-axis
    var xScale = d3.scale.ordinal()
        .domain(d3.range(dataset.length))
        .rangeRoundBands([0, width - padding.left - padding.right]);

    //Scale of y-axis
    var yScale = d3.scale.linear()
        .domain([0,d3.max(dataset)])
        .range([height - padding.top - padding.bottom, 0]);

    //Define x axis
    var xAxis = d3.svg.axis()
        .scale(xScale)
        .orient("bottom");
        
    //Define y axis
    var yAxis = d3.svg.axis()
        .scale(yScale)
        .orient("left");

    //White space between rectangles
    var rectPadding = 4;

    //Add rectangle element
    var rects = svg.selectAll(".MyRect")
        .data(dataset)
        .enter()
        .append("rect")
        .attr("class","MyRect")
        .attr("transform","translate(" + padding.left + "," + padding.top + ")")
        .attr("x", function(d,i){
            return xScale(i) + rectPadding/2;
        } )
        .attr("y",function(d){
            return yScale(d);
        })
        .attr("width", xScale.rangeBand() - rectPadding )
        .attr("height", function(d){
            return height - padding.top - padding.bottom - yScale(d);
        });

    //Add text element
    var texts = svg.selectAll(".MyText")
        .data(dataset)
        .enter()
        .append("text")
        .attr("class","MyText")
        .attr("transform","translate(" + padding.left + "," + padding.top + ")")
        .attr("x", function(d,i){
            return xScale(i) + rectPadding/2;
        } )
        .attr("y",function(d){
            return yScale(d);
        })
        .attr("dx",function(){
            return (xScale.rangeBand() - rectPadding)/2;
        })
        .attr("dy",function(d){
            return 20;
        })
        .text(function(d){
            return d;
        });

    //Add x axis
    svg.append("g")
        .attr("class","axis")
        .attr("transform","translate(" + padding.left + "," + (height - padding.bottom) + ")")
        .call(xAxis); 
        
    //Add y axis
    svg.append("g")
        .attr("class","axis")
        .attr("transform","translate(" + padding.left + "," + padding.top + ")")
        .call(yAxis);

</script>

image.png

Histogram with animation

 

<script>
    //canvas size
    var width = 400;
    var height = 400;

    //Add an SVG canvas to the body   
    var svg = d3.select("body")
        .append("svg")
        .attr("width", width)
        .attr("height", height);

    //White space around canvas
    var padding = {left:30, right:30, top:20, bottom:20};

    //Define an array
    var dataset = [10, 20, 30, 40, 33, 24, 12, 5];
        
    //Scale of x-axis
    var xScale = d3.scale.ordinal()
        .domain(d3.range(dataset.length))
        .rangeRoundBands([0, width - padding.left - padding.right]);

    //Scale of y-axis
    var yScale = d3.scale.linear()
        .domain([0,d3.max(dataset)])
        .range([height - padding.top - padding.bottom, 0]);

    //Define x axis
    var xAxis = d3.svg.axis()
        .scale(xScale)
        .orient("bottom");
        
    //Define y axis
    var yAxis = d3.svg.axis()
        .scale(yScale)
        .orient("left");

    //White space between rectangles
    var rectPadding = 4;

    //Add rectangle element
    var rects = svg.selectAll(".MyRect")
        .data(dataset)
        .enter()
        .append("rect")
        .attr("class","MyRect")
        .attr("transform","translate(" + padding.left + "," + padding.top + ")")
        .attr("x", function(d,i){
            return xScale(i) + rectPadding/2;
        } )
        .attr("y",function(d){
            return yScale(d);
        })
        .attr("width", xScale.rangeBand() - rectPadding)
        .attr("y",function(d){
            var min = yScale.domain()[0];
            return yScale(min);
        })
        .attr("height", function(d){
            return 0;
        })
        .transition()
        .delay(function(d,i){
            return i * 200;
        })
        .duration(2000)
        .ease("bounce")
        .attr("y",function(d){
            return yScale(d);
        })
        .attr("height", function(d){
            return height - padding.top - padding.bottom - yScale(d);
        })

    //Add text element
    var texts = svg.selectAll(".MyText")
        .data(dataset)
        .enter()
        .append("text")
        .attr("class","MyText")
        .attr("transform","translate(" + padding.left + "," + padding.top + ")")
        .attr("x", function(d,i){
            return xScale(i) + rectPadding/2;
        } )
        .attr("dx",function(){
            return (xScale.rangeBand() - rectPadding)/2;
        })
        .attr("dy",function(d){
            return 20;
        })
        .text(function(d){
            return d;
        })
        .attr("y",function(d){
            var min = yScale.domain()[0];
            return yScale(min);
        })
        .transition()
        .delay(function(d,i){
            return i * 200;
        })
        .duration(2000)
        .ease("bounce")
        .attr("y",function(d){
            return yScale(d);
        });

    //Add x axis
    svg.append("g")
        .attr("class","axis")
        .attr("transform","translate(" + padding.left + "," + (height - padding.bottom) + ")")
        .call(xAxis); 
        
    //Add y axis
    svg.append("g")
        .attr("class","axis")
        .attr("transform","translate(" + padding.left + "," + padding.top + ")")
        .call(yAxis);

</script>

 

19 original articles published, praised 101, 1.4 million visitors+
His message board follow

Tags: JQuery github Javascript Firefox

Posted on Tue, 14 Jan 2020 23:46:45 -0800 by ojav