【问题标题】:Adding a label and path to a chart D3向图表 D3 添加标签和路径
【发布时间】:2014-06-30 11:44:45
【问题描述】:

希望你能帮上忙。我正在使用 D3 构建一个条形图,我需要添加标签以及附加路径以显示趋势和目标。我为路径添加了一条线,但它似乎没有生成。我的包含数据的 CSV 文件的结构如下:

date,projectCode,numberOfSchools,newSchools
2011-12-1,"PRJ2.1",1188,0

代码如下:

<!Doctype  html>
    <html>
        <head>
            <title>D3 bar and line chart for Aphellion</title>
            <meta charset="utf-8">
            <script type="text/javascript" src="js/d3.v3.js"></script>
            <!-- <script type="text/javascript" src"//cdnjs.cloudflare.com/ajax/libs/d3/3.4.8/d3.min.js"></script> -->
            <style type="text/css">
                /* the style for the page and charts goes here */
                .axis {
                    font: 10px sans-serif;
                }

                .axis path
                .axis line {
                    fill: none;
                    stroke: #000;
                    shape-rendering: crispEdges;

                }

                .rect:hover {
                fill: orange;
            }

            #tooltip {
                background-color: white;
                -webkit-border-radius: 10px;
                -moz-border-radius: 10px;
                border-radius: 10px;
                -webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
                -moz-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
                box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
                pointer-events: none;
            }

            #tooltip.hidden {
                display: none;
            }

            #tooltip p {
                margin: 0;
                font-family: sans-serif;
                font-size: 16px;
                line-height: 20px;
            }
            </style>

        </head>
        <body>
            <div id="lineChart"></div>

            <script type="text/javascript">
            "Use strict"

                //The script for the bar chart and line charts goes here
                var margin = {top: 20, right: 20, bottom: 70, left: 40},
                    width = 600 - margin.left - margin.right,
                    height = 300 - margin.top - margin.bottom
                    barPadding = 3;

                //parse the date / time
                var parseDate = d3.time.format("%Y-%m-%d").parse;

                //set up the scales
                var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);

                var y = d3.scale.linear().range([height, 0]); 

                //set up the axis
                var xAxis = d3.svg.axis()
                            .scale(x)
                            .orient("bottom")
                            .tickFormat(d3.time.format("%Y-%m"));

                var yAxis = d3.svg.axis()
                            .scale(y)
                            .orient("left")
                            .ticks(5);

                var svg = d3.select("body").append("svg")
                                .attr("class", "barChart")
                                .attr("width", width + margin.left + margin.right)
                                .attr("height", height + margin.top + margin.bottom)
                            .append("g")
                                .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

                d3.csv("Data/data.csv", function(error, data) {
                        data.forEach(function(d) {
                            d.date = parseDate(d.date.toString());
                            d.numberOfSchools = +d.numberOfSchools;
                        });

                        x.domain(data.map(function(d) {return d.date;}));
                        y.domain([0, d3.max(data, function(d) {return d.numberOfSchools;})]);


                        svg.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)");

                        svg.append("g")
                            .attr("class", "y axis")
                            .call(yAxis)
                        .append("text")
                            .attr("transform", "rotate(-90)")
                            .attr("y", 6)
                            .attr("dy", ".71em")
                            .style("text-anchor", "end")
                            .text("Schools");

                        svg.selectAll("bar")
                            .data(data)
                            .enter()
                            .append("rect")
                            .style("fill", function(d) {
                                if(d.numberOfSchools < 1200) {
                                    return "#ff0000";
                                } else if (d.numberOfSchools === 2000) {
                                    return "#33cc33";
                                } else {return "steelblue";}
                            })
                            .attr("class", "rect")
                            .attr("x", function(d) {return x(d.date);})
                            .attr("width", x.rangeBand() - barPadding)
                            .attr("y", function(d) {return y(d.numberOfSchools);})
                            .attr("height", function(d) {return height - y(d.numberOfSchools);})
                            .on("mouseover", function(d) {

                            //Get this bar's x/y values, then augment for the tooltip
                            var xPosition = parseFloat(d3.select(this).attr("x")) + x.rangeBand() / 2;
                            var yPosition = parseFloat(d3.select(this).attr("y")) + 14;

                            //Create the tooltip label
                            svg.append("text")
                                .attr("id", "tooltip")
                                .attr("x", xPosition)
                                .attr("y", yPosition)
                                .attr("text-anchor", "middle")
                                .attr("font-family", "sans-serif")
                                .attr("font-size", "11px")
                                .attr("font-weight", "bold")
                                .attr("fill", "black")
                                .text(d.numberOfSchools + " current schools.");

                                })
                            .on("mouseout", function() {

                            //Remove the tooltip
                            d3.select("#tooltip").remove();

                            });

                            svg.selectAll("text")
                                .data(data)
                                .enter()
                                .append("text")
                                .text(function(d) {
                                    return d.numberOfSchools;
                                })
                                .attr("x", function(d) {return x(d.date);})
                                .attr("y", function(d) {return y(d.numberOfSchools);});
             })


                //add a path to interpolate through the bars
                var line = d3.svg.line()
                            .x(function(d) {return x(d.date)})
                            .y(function(d) {return y(d.numberOfSchools)});

                //add the path
                /*d3.select("svg")
                    .append("path")
                        .attr("d", line(data.numberOfSchools))
                        .attr("class", "numberOfSchools");
                });*/



                    console.log("This code works");


            </script>
        </body>


    </html>

理论上我也可以使用相同的代码来创建带有条形的折线图吗?我尝试创建一个小提琴,但无法添加我的 CSV。不过这里是:http://jsfiddle.net/siyafrica/bfVHU/

【问题讨论】:

标签: javascript csv d3.js


【解决方案1】:

也许这会有所帮助:

jsFiddle: http://jsfiddle.net/reblace/bfVHU/7/

我必须进行大量更改才能使其正常工作,但基本上很难让 rangeBands 方法与使用时间数据的条形图一起工作。有很多关于这个主题的文章,这里有一个关于它的好(简短)convo:https://groups.google.com/forum/#!topic/d3-js/7GsDmnB4kdE

我将它切换为使用日期刻度,这通常可以使用,但您必须做一些工作才能使条形宽度和位置正确。

var x = d3.time.scale().range([0, width]);
x.domain(d3.extent(data, function(d) { return d.date; }));

另外,您的线生成器需要传递数据数组...

var line = d3.svg.line()
    .x(function(d) {return x(d.date)})
    .y(function(d) {return y(d.value)});

//add the path
svg.append("path")
    .attr("d", line(data))
    .attr("class", "numberOfSchools");

如果您想坚持使用序数 x 刻度并使用范围带,您可能需要一个辅助时间刻度来绘制路径,并且您需要在域范围内添加所有日期,否则“空”天将不会出现在您的图表上。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 2012-05-20
    • 1970-01-01
    • 1970-01-01
    • 2013-10-31
    相关资源
    最近更新 更多