Chart.js - несколько функций generateLegend () на одной странице - PullRequest
0 голосов
/ 15 декабря 2018

Итак, в последнее время я экспериментировал с Chart.js и работаю над проектом, в котором мне нужно динамически зациклить три графика, и мне нужно, чтобы у каждого из них была своя собственная пользовательская легенда, генерируемая функцией generateLegend ().Проблема в том, что функциональность легенд не верна.Нажатие любой из легенд, похоже, влияет только на последнюю итерацию Диаграммы, что означает, что последняя Диаграмма затрагивается только независимо от того, на какую легенду Диаграммы я нажимаю.Вот код:

jQuery(document).ready(function($) {

            if ($(".stats-content__chart__embed").length) {

                var chartCount = $(".stats-content__chart__embed").length;
                var chartCounter = 1;

                window.toggleVisibility = function(element) {
                    $(element).toggleClass("striken");
                }

                while (chartCounter <= chartCount) {

                    var statsChartOptions = {
                        responsive: true,
                        maintainAspectRatio: false,
                        scales: {
                            yAxes: [{
                                ticks: {
                                    stepSize: 1000
                                }
                            }]
                        },
                        legendCallback: function(chart) {
                            var legendHtml = [];
                            for (var i = 0; i < chart.data.datasets.length; i++) {                  
                                if (chart.data.datasets[i].label) {
                                    legendHtml.push('<li class="stats-content__chart__legend__item" onclick="toggleVisibility(this); updateDataset(event, ' + '\'' + chart.legend.legendItems[i].datasetIndex + '\'' + ')"><span>' + chart.data.datasets[i].label + '</span></li>');
                                }                                                                              
                            }                                                                                                                                        
                            return legendHtml.join("");                                                        
                        },                                                                                     
                        legend: {                                                                              
                            display: false                                                                     
                        }                                                                                 
                    };    

                    // You can ignore this
                    if ($(".stats-content").eq(chartCounter - 1).find(".stats-content__chart__datasets").length) {

                        var chartDatasets = $(".stats-content").eq(chartCounter - 1).find(".stats-content__chart__datasets");
                        var datasetsCount = chartDatasets.length;
                        var datasetsArray = [];
                        var datasetsLineColors = ["rgb(0,42,72)", "rgb(0,174,239)"];

                        for (var i = 0; i < datasetsCount; i++) {

                            var dataEntry = chartDatasets.eq(i).find("span").length;
                            var datasetLineColor;
                            var dataArrayString = [];

                            for (var x = 0; x < dataEntry; x++) {
                                var dataValue = chartDatasets.eq(i).find("span").eq(x).text();
                                dataArrayString.push(dataValue);
                                var dataArrayNumbers = dataArrayString.map(Number);
                            }

                            if ($(this).find("h6").length) {
                                var datasetLabel = chartDatasets.eq(i).find("h6").text();
                            }

                            if (i % 2 == 0) {
                                datasetLineColor = datasetsLineColors[0];
                            } else {
                                datasetLineColor = datasetsLineColors[1];
                            }

                            datasetsArray.push({
                                label: datasetLabel,
                                backgroundColor: "transparent",
                                lineTension: 0,
                                pointBackgroundColor: "transparent",
                                pointBorderColor: "transparent",
                                borderColor: datasetLineColor,
                                data: dataArrayNumbers,
                                borderWidth: 2
                            });

                        }

                    } 

                    if ($(".stats-content").eq(chartCounter - 1).find(".stats-content__chart__labels > span").length) {

                        var chartDatasetLabels = $(".stats-content").eq(chartCounter - 1).find(".stats-content__chart__labels > span");
                        var labelCount = chartDatasetLabels.length;
                        var labelsArray = [];

                        for (var i = 0; i < labelCount; i++) {
                            var labelText = chartDatasetLabels.eq(i).text();
                            labelsArray.push(labelText);
                        }

                    }
                    // Ignore all the way to here

                    var ctx = document.getElementById("stats-content__chart__embed-" + chartCounter).getContext("2d");
                    window.statsChart = new Chart(ctx, {
                        type: 'line',
                        data: {
                            labels: labelsArray,
                            datasets: datasetsArray
                        },
                        options: statsChartOptions
                    });

                    updateDataset = function(e, datasetIndex) {
                        var index = datasetIndex;
                        var ci = e.view.statsChart;
                        var meta = ci.getDatasetMeta(index);
                        meta.hidden = meta.hidden === null? !ci.data.datasets[index].hidden : null;
                        ci.update();
                    };

                    document.getElementById("stats-content__chart__legend-" + chartCounter).innerHTML = window.statsChart.generateLegend();

                    chartCounter++;

                }
            }

        });

Вы можете игнорировать код, который я поместил в комментарии, так как он не имеет отношения к проблеме (я получил комментарии, что он слишком большой, поэтому я стараюсьчтобы уменьшить нагрузку на вас, ребята, ха-ха).Пожалуйста, предложите мне любую помощь.Мне это действительно нужно.Вот также HTML-код для него, на случай, если он поможет каким-либо образом (фактический контент генерируется динамически с помощью плагина расширенных пользовательских полей Wordpress).

<?php if ( have_rows( 'stats_tabs' ) ) : ?>

                <div id="statsTabContent" class="tab-content stats-holder">

                    <?php while ( have_rows( 'stats_tabs' ) ) : the_row();

                        $index = get_row_index(); ?>

                        <div class="tab-pane fade <?php echo ( $index == 1 ) ? 'in active' : '' ?> stats-content" id="tab-<?php echo $index; ?>">

                            <ul id="stats-content__chart__legend-<?php echo $index; ?>" class="stats-content__chart__legend"></ul>

                            <div class="stats-content__description">
                                <?php the_sub_field( 'tab_description' ); ?>
                            </div>

                            <div class="stats-content__chart__holder">

                                <?php if ( have_rows( 'tab_dataset' ) ) :

                                    while ( have_rows( 'tab_dataset' ) ) : the_row(); ?>

                                        <div class="stats-content__chart__datasets">

                                            <h6><?php the_sub_field( 'dataset_label' ); ?></h6>

                                            <?php if ( have_rows( 'dataset_data' ) ) :

                                                while ( have_rows( 'dataset_data' ) ) : the_row(); ?>

                                                    <span><?php the_sub_field( 'dataset_value' ); ?></span>

                                                <?php endwhile;

                                            endif; ?>

                                        </div>

                                    <?php endwhile;

                                endif; ?>

                                <div class="stats-content__chart__labels">

                                    <?php if ( have_rows( 'tab_labels' ) ) :

                                        while ( have_rows( 'tab_labels' ) ) : the_row(); ?>

                                            <span><?php the_sub_field( 'tab_label' ); ?></span>

                                        <?php endwhile;

                                    endif; ?>

                                </div>

                            </div>

                            <div class="stats-content__chart">

                                <canvas id="stats-content__chart__embed-<?php echo $index; ?>"  class="stats-content__chart__embed"></canvas>

                            </div>

                        </div>

                    <?php endwhile; ?>

                </div>

            <?php endif; ?>

1 Ответ

0 голосов
/ 17 декабря 2018

Вы заменяете свою переменную на каждой итерации, поэтому, естественно, переменная ссылается на последнюю назначенную вещь (то есть на последнюю созданную диаграмму):

while (chartCounter <= chartCount) {
  ...
  window.statsChart = new Chart(ctx, {...});
  ...
}

Нажатие элемента легенды вызывает updateDataset, на который вы ссылаетесьвернуться к window.statsChart через строку:

var ci = e.view.statsChart;

Поскольку statsChart назначается последней итерированной диаграмме, ваш код влияет только на эту диаграмму.

Либо сделайте statsChart массивом, либопередайте соответствующий индекс через onclick или просто передайте сам объект chart в updateDataset (хотя это не сработает через встроенный onclick; вам необходимо привязать элемент).

...