居中 D3 图表 + 增加响应能力

Centering D3 chart + adding responsiveness

本文关键字:响应 能力 增加 D3 图表 居中      更新时间:2023-09-26

一点背景,我对JS和一般开发仍然相当陌生,所以我可能错过了一些明显的东西。我使用 d3 让这个图表运行得很好,但无论我做什么我都无法获得正确的定位。我尝试过用CSS操作它,但它似乎没有以合乎逻辑的方式运行。我将显示设置为块,将边距设置为自动,它根本没有影响它。我可以更改定位的唯一方法是调整 d3 代码中的边距,但这对响应能力没有多大作用。我也尝试使用文本对齐,但也没有用。我试图做的是将其居中,并随着屏幕尺寸的增加而使其缩放更大。从理论上讲,这在CSS中应该很容易做到,但它似乎根本不起作用。感谢您的任何帮助。

这是JS代码:

            // Set the dimensions of the canvas / graph
            var margin = {top: 20, right: 0, bottom: 70, left: 70},
                width = 300 - margin.left - margin.right,
                height = 300 - margin.top - margin.bottom;
            // Parse the date / time
            var parseDate = d3.time.format("%-m/%-d/%Y").parse;
            // Set the ranges
            var x = d3.time.scale().range([0, width]);
            var y = d3.scale.linear().range([height, 0]);
            // Define the axes
            var xAxis = d3.svg.axis().scale(x)
                .orient("bottom").ticks(10);
            var yAxis = d3.svg.axis().scale(y)
                .orient("left").ticks(5);
            // chart area fill
            var area = d3.svg.area()
                .x(function(d) { return x(d.Date); })
                .y0(height)
                .y1(function(d) { return y(d.Forecast); });
            // Define the line
            var valueline = d3.svg.line()
                .interpolate("cardinal")
                .x(function(d) { return x(d.Date); })
                .y(function(d) { return y(d.Orders); });
            var valueline2 = d3.svg.line()
                .interpolate("cardinal")
                .x(function(d) { return x(d.Date); })
                .y(function(d) { return y(d.Forecast); });
            // Adds the svg canvas
            var svg = d3.select("body")
                .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 + ")");

            // Get the data
            d3.csv("csv/Forecast.csv", function(error, data) {
                data.forEach(function(d) {
                    d.Date = parseDate(d.Date);
                    d.Orders = +d.Orders;
                });
             // Scale the range of the data
                x.domain(d3.extent(data, function(d) { return d.Date; }));
                y.domain([0, d3.max(data, function(d) { return d.Orders; })]);

                // Area
                svg.append("path")
                    .datum(data)
                    .attr("class", "area")
                    .attr("d", area);
                // Add the valueline path.
                svg.append("path")
                    .attr("class", "line")
                    .attr("d", valueline2(data))
                    .style("stroke", "#A7A9A6");
                svg.append("path")
                    .attr("class", "line")
                    .attr("d", valueline(data));
                // Add the X Axis
                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", ".15em")
                        .attr("transform", "rotate(-65)");
                // Add the Y Axis
                svg.append("g")
                    .attr("class", "y axis")
                    .call(yAxis);
            });

JSFIDDLES

响应式和居中式:https://jsfiddle.net/sladav/6fyjhmne/3/

无响应:https://jsfiddle.net/sladav/7tp5vdkr/

为了提高响应能力,请利用 SVG viewBox:

一些链接:

  • https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/viewBox
  • 使用 ViewBox 根据窗口大小调整 svg 的大小

设置视图框:

var margin = {top: 100, right: 150, bottom: 100, left: 150}
var outerWidth  = 1600,
    outerHeight = 900;
var width  = outerWidth - margin.right - margin.left,
    height = outerHeight - margin.top - margin.bottom;

d3.select(".plot-div").append("svg")
    .attr("class", "plot-svg")
    .attr("width", "100%")
    .attr("viewBox", "0 0 " + outerWidth + " " + outerHeight)
    .append("g")
      .attr("class", "plot-space")
      .attr("transform", 
        "translate(" + margin.left + "," + margin.top + ")"
      );

上述注意事项:

  1. SVG 被放在一个div 中——我将调整div 的大小和位置,而不是 svg
  2. SVG 宽度设置为父/分区的百分比,而不是绝对值。
  3. 您现在在 SVG 中绘制的所有内容都与 outerWidth x outerHeight 有关,无单位参数由 viewBox 重新缩放。

看看我的 JSFIDDLE 示例中的矩形...

d3.select(".plot-svg").append("rect")
    .attr("x", 0)
    .attr("y", 3*outerHeight/4)
    .attr("width", 800)
    .attr("height", outerHeight/4)
    .attr("fill", "grey")

调整窗口大小,矩形将始终填充 svg 的 1/2,因为 800/1600(注意:1600 是 outerWidth)。

调整位置/居中:

操作包含 SVG/图表的div 以按您想要的方式定位它。在我的示例中,它占据了页面的 50%,并且由于边距而居中:auto。

.plot-div{
  width: 50%;
  display: block;
  margin: auto;
 }

无论您使用什么方法来缩放/定位div,您的图表都应该效仿。