D3.js将圆点添加到折线图

时间:2020-04-01 22:24:59

标签: javascript d3.js

我是D3.js的新手,我试图在图形上的每个数据点所在的位置添加一个圆点。 这是原始数据的示例:

TIME,GEO,CITIZEN,GENDER,VALUE
2011M01,Germany (until 1990 former territory of the FRG),Belgium,Males,0

但是在代码中,我将其格式化为一个称为nestedData的变量,然后使用该绘图绘制了两个折线图UK.values和germany.values。

如何在两个折线图中分别添加圆点?

谢谢。

这是我目前拥有的:

<html>

<head>
    <script src="https://d3js.org/d3.v5.js"></script>
    <title> D3 Tutorial </title>

    <style>
        body {
            margin: 20px;
        }

        svg {
            padding: 50px;
        }

        .line {
            fill: none;
            stroke: black;
        }

        #UKLine {
            fill: none;
            stroke: red;
        }

        #germanyLine {
            fill: none;
            stroke: blue;
        }
    </style>
</head>

<body>
<h2>D3 Linegraph</h2>

<script>

    var dataPath = "data/migration.csv";

    var width = 800;                    //specifies the width, height and margins of our SVG element
    var height = 600;
    var margin = 100;

    var rowConverter = function (d) {
        var timeData = d.TIME;
        var datum = timeData.split("M");


        return {
            date: new Date(datum[0], datum[1] - 1),
            geo: d.GEO,
            value: d.VALUE
        }

    };
    d3.csv(dataPath, rowConverter)
        .then(function (data) {
            console.log(data);
            // console.table(data);     //loads table in a nice format - just to try it out (probably not super practical for this tutorial)


            var nestedData = d3.nest()
                .key(function (d) {
                    return d.geo;

                })
                .key(function (d) {
                    return d.date;
                })
                .rollup(function (leaves) {
                    return d3.sum(leaves, function (d) {
                        return parseInt(d.value);
                    });
                })
                .entries(data);

            console.log(nestedData);

            //work out time extent of ALL THE DATA NOT JUST THE NESTED ONES
            //work with unnested data

            var timeExtent = d3.extent(data, function (d) {
                return d.date;

            });

            console.log(timeExtent);

            var xScale = d3.scaleTime().domain(timeExtent).range([0, width]);

            var migrantCounts = new Array();
            nestedData.forEach(function (d) {
                (d.values).forEach(function (e) {
                    migrantCounts.push(e.value);

                });
            });
            console.log(migrantCounts);

            var migrantExtent = d3.extent(migrantCounts, function (d) {

                return parseInt(d);
            });
            console.log(migrantExtent);

            var yScale = d3.scaleLinear().domain(migrantExtent).range([height, 0]);

            var x_axis = d3.axisBottom(xScale);
            var y_axis = d3.axisLeft(yScale);

            var svg = d3.select("body")        //creates an SVG element in the body
                .append("svg")
                .attr("width", width + margin)
                .attr("height", height + margin);

            d3.select("svg")
                .append("g")
                .attr("class", "x axis")
                .attr("transform", "translate(" + margin + "," + height + ")")
                .call(x_axis
                    .tickFormat(d3.timeFormat("%y-%m-%d")))
                .selectAll("text")
                .style("text-anchor", "end")
                .attr("dx", "-0.8em")
                .attr("dy", "0.15em")
                .attr("transform", "rotate(-65)");

            d3.select("svg")
                .append("g")
                .attr("class", "y axis")
                .attr("transform", "translate(" + margin + ",0)")
                .call(y_axis);

            var germany = nestedData[0];
            var UK = nestedData[1];

            var lineGenerator = d3.line()
                .x(function (d) {
                    return margin + xScale(new Date(d.key));
                })
                .y(function (d) {
                    return yScale(parseInt(d.value));
                });


            svg.append("path")
                .datum(germany.values)
                .attr("class", "line")
                .attr("id", "germanyLine")
                .attr("d", lineGenerator);

            svg.append("path")
                .datum(UK.values)
                .attr("class", "line")
                .attr("id", "UKLine")
                .attr("d", lineGenerator);


        });



</script>

</body>

</html>

1 个答案:

答案 0 :(得分:1)

创建paths

后,您可能还需要添加两个步骤

// these two selections are adding paths
svg.append("path")
    .datum(germany.values)
    .attr("class","line")
    .attr("id","germanyLine")
    .attr("d",lineGenerator);

svg.append("path")
    .datum(UK.values)
    .attr("class","line")
    .attr("id", "UKLine")
    .attr("d", lineGenerator);

//you want to add circles

svg.selectAll(".circle-germany")
    .data(germany.values)
    .join("circle") // enter append
      .attr("class", "circle-germany")
      .attr("r", "1") // radius
      .attr("cx", d=> margin + xScale(new Date(d.key)))   // center x passing through your xScale
      .attr("cy", d=> yScale(parseInt(d.value)))   // center y through your yScale


svg.selectAll(".circle-uk")
    .data(UK.values)
    .join("circle") // enter append
      .attr("class", "circle-uk")
      .attr("r", "1") // radius
      .attr("cx", d=> margin + xScale(new Date(d.key)))   // center x passing through your xScale
      .attr("cy", d=> yScale(parseInt(d.value)))   // center y through your yScale