You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调整箱线图至400x800px并居中显示的技术求助

解决D3箱线图尺寸调整与居中显示问题

没问题,我帮你调整代码来实现400x800px的尺寸,同时让图表在页面居中,还能解决x轴标签被截断的问题。下面是修改后的完整代码,我会标注关键修改点:

关键修改说明

  • 互换宽高计算:把原代码中width和height的初始值互换,匹配400x800的要求
  • 添加居中CSS:给容器#boxplot添加样式让图表居中
  • 调整bottom边距:增大底部边距,确保x轴标签有足够显示空间
  • 修正x轴位置:根据新的高度调整x轴的垂直位置

修改后的完整代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>D3 Boxplot</title>
    <style>
        /* 添加这部分CSS让图表容器居中 */
        #boxplot {
            width: 450px; /* 比SVG宽度大一点,留出边距空间 */
            margin: 0 auto;
        }
        .box line, .box rect, .box circle {
            fill: #fff;
            stroke: #000;
            stroke-width: 1.5px;
        }
        .box .center {
            stroke-dasharray: 3,3;
        }
        .box .outlier {
            fill: none;
            stroke: #ccc;
        }
        .axis {
            font: 10px sans-serif;
        }
        .axis path, .axis line {
            fill: none;
            stroke: #000;
            shape-rendering: crispEdges;
        }
    </style>
    <script src="https://d3js.org/d3.v3.min.js"></script>
    <script src="https://rawgithub.com/jasondavies/d3-boxplot/master/d3.box.js"></script>
</head>
<body>
    <div id="boxplot"></div>
    <script>
        var labels = true; // show the text labels beside individual boxplots?
        // 修改1:互换width和height的基础值,匹配400x800需求,同时增大bottom边距
        var margin = {top: 25, right: 25, bottom: 50, left: 25};
        var width = 400 - margin.left - margin.right;
        var height = 800 - margin.top - margin.bottom;
        var min = 0, max = 10;

        // parse in the data
        d3.csv("boxplot_year.csv", function(error, csv) {
            var data = [];
            data[0] = [];
            data[1] = [];
            data[2] = [];
            data[3] = [];
            data[4] = [];
            data[5] = [];
            data[0][0] = "Y2010";
            data[1][0] = "Y2011";
            data[2][0] = "Y2012";
            data[3][0] = "Y2013";
            data[4][0] = "Y2014";
            data[5][0] = "Y2015";
            data[0][1] = [];
            data[1][1] = [];
            data[2][1] = [];
            data[3][1] = [];
            data[4][1] = [];
            data[5][1] = [];

            csv.forEach(function(x) {
                var v1 = Math.floor(x.Y2010),
                    v2 = Math.floor(x.Y2011),
                    v3 = Math.floor(x.Y2012),
                    v4 = Math.floor(x.Y2013),
                    v5 = Math.floor(x.Y2014),
                    v6 = Math.floor(x.Y2015);
                var rowMax = Math.max(Math.max(v1,v2), Math.max(Math.max(v3,v4), Math.max(v5,v6)));
                var rowMin = Math.min(Math.min(v1,v2), Math.min(Math.min(v3,v4), Math.min(v5,v6)));
                data[0][1].push(v1);
                data[1][1].push(v2);
                data[2][1].push(v3);
                data[3][1].push(v4);
                data[4][1].push(v5);
                data[5][1].push(v6);
                if (rowMax > max) max = rowMax;
                if (rowMin < min) min = rowMin;
            });

            var boxplot = d3.box()
                .whiskers(iqr(1.5))
                .height(height)
                .domain([min, max])
                .showLabels(labels);

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

            // the x-axis
            var x = d3.scale.ordinal()
                .domain( data.map(function(d) { return d[0]; } ) )
                .rangeRoundBands([0 , width], 0.7, 0.3);

            var xAxis = d3.svg.axis()
                .scale(x)
                .orient("bottom");

            // the y-axis
            var y = d3.scale.linear()
                .domain([min, max])
                .range([height + margin.top, 0 + margin.top]);

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

            // draw the boxplots
            svg.selectAll(".box")
                .data(data)
                .enter().append("g")
                .attr("transform", function(d) { return "translate(" + x(d[0]) + "," + margin.top + ")"; } )
                .call(boxplot.width(x.rangeBand()));

            // draw y axis
            svg.append("g")
                .attr("class", "y axis")
                .call(yAxis)
                .append("text") // and text1
                .attr("transform", "rotate(-90)")
                .attr("y", 6)
                .attr("dy", ".71em")
                .style("text-anchor", "middle")
                .style("font-size", "10px")
                .text("Grade");

            // 修改2:调整x轴的垂直位置和标签偏移,适配新高度和边距
            svg.append("g")
                .attr("class", "x axis")
                .attr("transform", "translate(0," + (height + margin.top) + ")")
                .call(xAxis)
                .append("text") // text label for the x axis
                .attr("x", (width / 2) )
                .attr("y", 30 )
                .attr("dy", ".71em")
                .style("text-anchor", "middle")
                .style("font-size", "10px")
                .text("Year");
        });

        // Returns a function to compute the interquartile range.
        function iqr(k) {
            return function(d, i) {
                var q1 = d.quartiles[0],
                    q3 = d.quartiles[2],
                    iqr = (q3 - q1) * k,
                    i = -1,
                    j = d.length;
                while (d[++i] < q1 - iqr);
                while (d[--j] > q3 + iqr);
                return [i, j];
            };
        }
    </script>
</body>
</html>

各修改点的作用

  1. CSS居中设置:给#boxplot容器设置固定宽度(略大于SVG宽度)和margin: 0 auto,让容器在页面水平居中,SVG自然跟着居中。
  2. 宽高互换与边距调整:原代码是宽800高400,现在改成宽400高800,同时把底部边距从25增大到50,给x轴标签留出足够的显示空间,避免被页面底部截断。
  3. x轴位置优化:调整x轴的垂直位置,并把x轴标签的垂直偏移量从10改成30,确保标签完全显示在SVG内部,不会被遮挡。

这样修改后,你的箱线图就会变成400x800px的尺寸,在页面居中显示,x轴标签也能完整看到了。

内容的提问来源于stack exchange,提问作者MTT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:04:02