javascript - 同一页面上的多个响应式 D3 图表重用图表脚本

标签 javascript d3.js

我正在尝试使用具有不同数据的相同脚本在同一页面上创建 3 个响应式条形图。

当窗口大小调整时,我的问题就出现了。我不断遇到仅在要渲染的最后一个图表中更新的元素。

我很抱歉没有提供 jsfiddle,但我无法让 fiddle 渲染我的代码(fiddle - newbee)

以下代码片段仅生成轴'。我遇到的第一个问题是 d3.axisBottom(scale) - 作为我遇到的示例。

页面:

<!DOCTYPE html>
<html lang="en">
<head>
  <title>AgeReport 1.3</title>

    <script src="jquery-1.11.2.js"></script>
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script 
  src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js">
  </script>`

    <link rel=stylesheet type=text/css 
href="https://cdnjs.cloudflare.com/ajax/libs/twitter-
bootstrap/3.3.5/css/bootstrap.min.css">

   <style>
       body {
           background-color: #e6e6e6;
           font-family: sans-serif;
           font-size: 12px;
       }
        section {
            position: relative;
            padding: 24px;
            height: 100%;
        }
                   .section-body:first-child {
            margin-top: 24px;
        }
                   .col-md-3, .col-lg-3, .col-md-4, .col-lg-4, .col-md-6, 
 .col-lg-6 {
            padding: 0;
        }
       .card {
          position: relative;
          background-color: #F5F5F5;
          color: #212121;
          -webkit-border-radius: 2px;
          -moz-border-radius: 2px;
          border-radius: 2px;
          border: 1px solid #BDBDBD;
          box-shadow: none;
          height: 100%;
        }
        .card-head.card-head-xs {
          line-height: 32px;
          min-height: 36px;
        }
        .card-head {
          position: relative;
          line-height: 40px;
          min-height: 44px;
          vertical-align: middle;
          border-radius: 2px 2px 0 0;
        }
       section {
           background-repeat: no-repeat;
       }
       .row {
           margin-left: 0;
       }
       .col-md-4 {
           padding-left: 5px;
           padding-right: 5px;
       }
       .card-head {
           background-color: #bdbdbd;
       }
       .card-body {
           padding: 10px 10px 10px 10px;
       }

       /*-- Age Chart --*/

       #age-chart-row {
           position: relative;
           height: 345px;
       }
       #age-chart-row .card {
           border-width: 1px 1px 0 1px;
       }
       .chart-container {
           height: 288px;
           border: 1px solid #bcbcbc;
           background-color: white;
       }
       .age-chart-canvas {
           position: absolute;
           width: 100%;
            height: 100%;
       }
        .axis--y .tick line {
            stroke: lightgray;
        }

    </style>

    <script type="text/javascript">

        var ageDistributionData = {....}'

        $(document).ready(function() {

            var vData = ageDistributionData;
            var dData = ageDistributionData;
            var mData = ageDistributionData;

            var vChart = new AgeChart("#vChart", vData);
            var dChart = new AgeChart("#dChart", dData);
            var mChart = new AgeChart("#mChart", mData);

        });

    </script>
</head>

<body>
    <section>
        <div class="section-body">
            <div id="age-chart-row" class="row">
                <div class="col-md-4">
                    <div class="card">
                        <div class="card-head card-head-xs"></div>
                        <div class="card-body">
                            <div id="vChart" class="chart-container"></div>
                        </div>
                    </div>
                </div>
                <div class="col-md-4">
                    <div class="card">
                        <div class="card-head card-head-xs"></div>
                        <div class="card-body">
                            <div id="dChart" class="chart-container"></div>
                        </div>
                    </div>
                </div>
                <div class="col-md-4">
                    <div class="card">
                        <div class="card-head card-head-xs"></div>
                        <div class="card-body">
                            <div id="mChart" class="chart-container"></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>
</body>
</html>

图表脚本:

function AgeChart(container, data) {

var containerW, containerH, chartW, chartH, svg, chartG,
    xScale, x, y, gAxis, xAxis, yAxis, xBottom, bars;
var margin = {top: 20, right: 10, bottom: 50, left: 60};

//-- axis labels -> will need translating --
var yLabelStr = "Anzahl",
    xLabelStr = "Alter";

// parse raw data
var agedData = parseAgedData(data),
    sizeMax = data.AgeDistribution.DataOwnerSizeMax,
    countMax = 0;
    for (var i = 0; i < agedData.length; i++) {
        if(agedData[i].doCount > countMax) {
            countMax = agedData[i].doCount;
        }
    };

// init scales
var xScale = d3.scaleBand()
    .paddingInner(0.16)
    .paddingOuter(0.1);
xScale.domain(agedData.map(function (d) {
    return d.label;
}));
x = d3.scaleBand()
    .paddingInner(0.16)
    .paddingOuter(0.1);
x.domain(agedData.map(function (d, i) {
    return i + 1;
}));
y = d3.scaleLinear();
y.domain([0, countMax]);

// init containers
svg = d3.select(container)
    .append("svg")
    .attr("id", container.substring(1) + "Svg")
    .classed("age-chart-canvas", true);
chartG = svg.append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// init axis lines
yAxis = chartG.append("g")
    .attr("class", "axis axis--y");
gAxis = chartG.append("g")
    .attr("class", "axis axis--x");
xAxis = gAxis.append("line")
    .style("stroke", "black")
    .attr("x1", 0)
    .attr("x2", 0)
    .classed("x-domain", true);

// render chart
render();

function render() {

    updateDimensions();

    // set tick lines
    yAxis.call(d3.axisLeft(y))
        .append("text")
        .attr("transform", "rotate(-90)")
        .attr("y", 6)
        .attr("dy", "0.71em")
        .attr("text-anchor", "end")
        .text(function(d) {
            return d;
        });
    d3.selectAll("g.axis--y g.tick line")
        .attr("x1", function(d) {
            return chartW;
        });
    gAxis.attr("transform", "translate(0," + chartH + ")")
        .call(new d3.axisBottom(xScale));
    gAxis.selectAll(".domain").remove();
    d3.selectAll(".x-domain")
        .attr("x2", function(d) {
            return chartW;
        });

    d3.selectAll("g.axis--x g.tick line")
        .attr("y2", function(d, i) {
            if(i%2 == 0)
                return 6;
            else
                return 16;
        })
        .style("fill", "#bdbdbd");
    d3.selectAll("g.axis--x g.tick text")
        .attr("y", function(d, i) {
            if(i%2 == 0)
                return 9;
            else
                return 20;
        });

};

function updateDimensions() {
    containerW = getDimension(container, "width");
    containerH = getDimension(container, "height");
    chartW = containerW - margin.left - margin.right;
    chartH = containerH - margin.top - margin.bottom;

    // set axis scales
    xScale.rangeRound([0, chartW]);
    x.rangeRound([0, chartW]);
    y.rangeRound([chartH, 0]);
};

d3.select(window).on("resize", render);

};

谢谢!

最佳答案

我也被同样的问题困扰。我知道您找到了解决方案,但我想我会提供我发现的内容,以防它对最终访问此页面的其他人有所帮助,因为这个问题比我发现的其他问题更准确地描述了我的问题。

我的解决方案最终来自以下 Stack Overflow 帖子。那里的答案解释说您需要为监听器添加命名空间,否则在添加新监听器时现有监听器将被删除。

How to have multiple d3 window resize events

对于这个例子,我必须更改此代码:

    d3.select(window).on("resize", render);

    var resizeId = "resize." + scope.chartId
    d3.select(window).on(resizeId, render);

其中scope.chartId是每个图表的唯一ID,因此监听器也是唯一的,并且在添加新图表时不会被删除。

关于javascript - 同一页面上的多个响应式 D3 图表重用图表脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45215084/

相关文章:

javascript - 如何将 d3js 中的拖动行为与 Leapjs 结合使用

Javascript D3.js 从其 svg 元素中拖出一个图表

javascript - 如何向 dc.js 图表添加自定义数据注释?

php - CKEDITOR 和 javascript 函数出现问题

javascript - 如何在我的网页上附加 div 后初始化 jquery 插件?

javascript - 一旦 [ ] 被 < > 替换,文本将变为空白

javascript - 可点击图表数据点以打开新页面

javascript - 是否可以为 dimple.js 中的条形图上的堆栈指定特定颜色?

javascript - AngularJS Controller 中的单元测试 promise

javascript - Bootstrap 工具提示不会被破坏