D3 v4:制图工具:如何在列后面发送水平网格线 [英] D3 v4: charting tool: How to send horizontal gridlines behind columns

查看:76
本文介绍了D3 v4:制图工具:如何在列后面发送水平网格线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用D3 charting tool绘制图表.问题是我无法在列后面发送水平网格线.请查看屏幕截图.

I am drawing a chart using D3 charting tool. The problem is I cannot send the horizontal gridlines behind the columns. Please see the screenshot.

此处的方法确实将网格线发送到条形后面,但是同时,所有列标签都消失了!请查看下面的屏幕截图:

This approach here does send the gridlines behind the bars but at the same time, all the column labels get disappeared! Please see the screenshot below:

代码

public function evd_unitary_growth_plan_chart( $data_str ){
        ob_start(); ?>

        <style> /* set the CSS */

            .line {
                fill: none;
                stroke: steelblue;
                stroke-width: 2px;
            }

            .grid line {
                stroke: lightgrey;
                stroke-opacity: 0.6;
                shape-rendering: crispEdges;
            }

            .grid path {
                stroke-width: 0;
            }

            .axis {
                font-size: 13px;
                font-family: 'Roboto';
                color: #394041;
            }

        </style>

        <script type="text/javascript">
            var h = 300;
            var w = 750;
            var barPadding = 2;

            function barColor(data_month, current_month) {
                if( parseInt(data_month) >= current_month)
                    return "#008600";
                else
                    return "#c4c4c4";
            }

            // set the dimensions and margins of the graph
            var margin = {top: 30, right: 20, bottom: 30, left: 40},
                width = w - margin.left - margin.right,
                height = h - margin.top - margin.bottom;

            var data = <?php echo $data_str ?>;

            // set the ranges
            var x = d3.scaleBand().range([0, width]).padding(0.2);
            var y = d3.scaleLinear().range([height, 0]);

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

            // Scale the range of the data in the domains
            x.domain(data.map(function(d) { return d.month; }));

            var y_domain_upperBound = d3.max(data, function(d) { return d.points; });
            y_domain_upperBound = Math.round(y_domain_upperBound / 10) * 10 + 10;
            y.domain([0, y_domain_upperBound]);

            // Create Y-Axis tick array to draw grid lines
            var yTicks = [];
            var tickInterval = 5;
            for(var i = 0; i <= y_domain_upperBound; i = i + 5) {
                yTicks.push(i);
            }

            // gridlines in y axis function
            function draw_yAxis_gridlines() {
                return d3.axisLeft(y)
                    .tickValues(yTicks);
            }

            // append the rectangles for the bar chart
            svg.selectAll("rect")
                .data(data)
                .enter().append("rect")
                .attr("x", function(d) {
                    return x(d.month);
                })
                .attr("width", x.bandwidth())
                .attr("y", function(d) { return y(d.points); })
                .attr("height", function(d) { return height - y(d.points); })
                .attr("fill", function(d){return barColor(d.data_month_number, d.current_month_number)});



            // column labels
            svg.selectAll("text")
                .data(data)
                .enter()
                .append("text")
                .text(function(d) {
                    return d.points;
                })
                .attr("text-anchor", "middle")
                .attr("x", function(d, i) {
                    return x(d.month) + x.bandwidth() / 2;
                })
                .attr("y", function(d) {
                    return y(d.points) - 10;
                })
                .attr("font-family", "Roboto")
                .attr("font-size", "13px")
                .attr("font-weight", "bold")
                .attr("fill", "#394041");

            // add the x Axis
            svg.append("g")
                .attr("class", "axis")
                .attr("transform", "translate(0," + height + ")")
                .call(d3.axisBottom(x));


            // add the Y gridlines
            svg.append("g")
                .attr("class", "grid axis")
                .call(draw_yAxis_gridlines()
                    .tickSize(-width)
                );

        </script>

        <?php return ob_get_clean();
    }

推荐答案

JDunken是正确的,您绘制事物的顺序将确定什么位于什么之上,因此您要在制作矩形之前做水平线它们出现在矩形后面.

JDunken is right, the order in which you draw things will determine what sits on top of what, so you want to do the horizontal lines before the rectangles to make them appear behind the rectangles.

如果那会弄乱您的标签,则可能与我在另一篇文章中提出的关于不只对列标签使用"text"选择的观点有关.

If that's then messing up your labels, it's probably related to one of the points I made in your other post about not using just a "text" selection for your column labels.

请记住,当在<svg>上添加轴时,这些轴通常包括<text>元素,因此当您以后调用svg.selectAll("text")准备绑定列标签时,很有可能该选择被拾取您轴上的某些<text>元素,结果无法预测! svg.selectAll("text")会做到这一点-选择svg中的所有<text>元素.

Remember that when you add axes on to your <svg> these axes typically include <text> elements, so when you later call svg.selectAll("text") ready to bind for your column labels, there's a good chance that this selection is picking up some <text> elements in your axes, with unpredictable results! svg.selectAll("text") will do just that - select all the <text> elements in svg.

您可以改为在为列标签保留的类上选择以下内容:

You can instead select on a class that you reserve for your column labels with something like:

svg.selectAll(".column-label")
                .data(data)
                .enter()
                .append("text")
                .attr("class","column-label")

希望有帮助

这篇关于D3 v4:制图工具:如何在列后面发送水平网格线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆