如何使D3圆形条形图响应式?

问题描述 投票:0回答:1

我使用代码here创建了以下圆形条形图。它在笔记本电脑上运行良好,但在移动设备上运行不佳,我正在尝试找出原因。这是我在 d3 中的第一个项目,我尝试阅读文档,但标准条形图的示例似乎不适用于这种情况,所以我不知道如何去做。

PS:“不起作用”是指图表未居中,不完全可见,并且标签已消失。

作为参考,页面底部的此处有一个版本。

这是我的

index.html

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Page Title</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <link href="https://fonts.cdnfonts.com/css/gotham-6" rel="stylesheet">
    <link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
    <!-- D3 -->
    <script src="https://d3js.org/d3.v4.js"></script>
    <script src="https://cdn.jsdelivr.net/gh/holtzy/D3-graph-gallery@master/LIB/d3-scale-radial.js"></script>
</head>
<body>
    <header>
        <div class="main-title">Main Title</div>
    </header>

    <!-- Circular time distribution -->
    <h2 class="section-title" style="display: block; margin-bottom: 10px;">Circular BarPlot</h2>
    <div id="my_dataviz"></div>

    <!-- Circular time distribution histogram -->
    <script>

    // set the dimensions and margins of the graph
    var margin = {top: 0, right: 10, bottom: 30, left: 10},
        width = 460 - margin.left - margin.right,
        height = 460 - margin.top - margin.bottom,
        innerRadius = 90,
        outerRadius = Math.min(width, height) / 2;   // the outerRadius goes from the middle of the SVG area to the border

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

    d3.csv("static/time_distribution.csv", function(data) {

      var maxCount = d3.max(data, function(d) { return +d.count; });

      // Scales
      var x = d3.scaleBand()
          .range([0, 2 * Math.PI])    // X axis goes from 0 to 2pi = all around the circle. If I stop at 1Pi, it will be around a half circle
          .align(0)                  // This does nothing
          .domain(data.map(function(d) { return d.hour; })); // The domain of the X axis is the list of states.
      var y = d3.scaleRadial()
          .range([innerRadius, outerRadius])   // Domain will be define later.
          .domain([0, maxCount]); // Domain of Y is from 0 to the max seen in the data

      // Add the bars
      svg.append("g")
        .selectAll("path")
        .data(data)
        .enter()
        .append("path")
          .attr("fill", "#1DB954")
          .attr("stroke", "black")
          .attr("stroke-width", 3) // Set the border width
          .attr("d", d3.arc()     // imagine your doing a part of a donut plot
              .innerRadius(innerRadius)
              .outerRadius(function(d) { return y(d['count']); })
              .startAngle(function(d) { return x(d.hour); })
              .endAngle(function(d) { return x(d.hour) + x.bandwidth(); })
              .padAngle(0.01)
              .padRadius(innerRadius))

      // Add the labels
      svg.append("g")
          .selectAll("g")
          .data(data)
          .enter()
          .append("g")
            .attr("text-anchor", function(d) { return (x(d.hour) + x.bandwidth() / 2 + Math.PI) % (2 * Math.PI) < Math.PI ? "end" : "start"; })
            .attr("transform", function(d) { return "rotate(" + ((x(d.hour) + x.bandwidth() / 2) * 180 / Math.PI - 90) + ")"+"translate(" + (y(d['count'])+10) + ",0)"; })
          .append("text")
            .text(function(d){return(d.hour)})
            .attr("transform", function(d) { return (x(d.hour) + x.bandwidth() / 2 + Math.PI) % (2 * Math.PI) < Math.PI ? "rotate(180)" : "rotate(0)"; })
            .style("font-size", "15px")
            .style("font-family", "Gotham")
            .style("font-weight", "500")
            .attr("alignment-baseline", "middle")

    });

    </script>
</body>
</html>

CSS

这些是潜在相关的 CSS 样式

html {
  overflow-x: hidden;
  margin-right: calc(-1 * (100vw - 100%));
}
body {
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-height: 100vh; /* Set a minimum height for the page */
    align-items: center;
    margin: 0;
    font-family: 'Circular', sans-serif;
    background-color: #f3f3f3; /* Set a light background color */
    background-image: radial-gradient(circle at center center, #f5f5f5, #f5f5f5), repeating-radial-gradient(circle at center center, #f5f5f5, #f5f5f5 10px, transparent 20px, transparent 10px);
    background-blend-mode: multiply;
    background-attachment: fixed; /* Keep the background fixed while scrolling */
}
.section-title {
    display: block;
    font-family: 'Gotham', sans-serif;
    margin-bottom: 0px;
    text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.2);
    background: linear-gradient(45deg, #333, #000); /* Gradient background */
    -webkit-background-clip: text; /* Clip text to background */
    background-clip: text;
    -webkit-text-fill-color: transparent; /* Hide text fill to show gradient */
}
@media (max-width: 500px) { /* 500 should be enough for mobile */
    body {
        overflow-x: hidden;
        width: 100%;
        -webkit-box-sizing: border-box;
           -moz-box-sizing: border-box;
                box-sizing: border-box;
    }
    html {
      overflow-x: hidden;
    }

数据

这是我正在使用的数据,尽管我怀疑它会产生影响:

hour,count
1,3
2,0
3,0
4,0
5,0
6,0
7,0
8,0
9,0
10,0
11,0
12,0
13,0
14,0
15,10
16,0
17,7
18,7
19,0
20,0
21,0
22,0
23,0
24,5
javascript html css d3.js
1个回答
0
投票

长宽比必须保持相同的图表可能很难做出响应。你可以做的一件事就是缩小整个图表:

.mygraphic {
    transform:scale(0.5);
}
© www.soinside.com 2019 - 2024. All rights reserved.