Chart.js Выпадающий список для выбора 1 дня, вчерашнего дня и 7 дней

#javascript #chart.js

#javascript #chart.js

Вопрос:

 <script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js"
    integrity="sha256-R4pqcOYV8lt7snxMQO/HSbVCFRPMdrhAFMH vr9giYI=" crossorigin="anonymous"></script>
    
    <div class="chart" style="position: relative; height:50vh; width:100%;margin: 0 auto;;">
    <canvas id="myChart" width="400" height="400"></canvas></div>
    <select id="date-choose">
        <option value="Today">Today</option>
        <option value="Yesterday">Yesterday</option>
        <option value="7 Days">Last 7 Days</option>
      </select>

<script>
    function BuildChart(labels, values, chartTitle) {
        var data = {
            labels: labels,
            datasets: [{
                label: chartTitle, // Name the series
                data: values,
                backgroundColor: [
                    'rgba(50, 99, 231, 0.2)',
                    'rgba(50, 90, 231, 0.2)',
                    'rgba(50, 90, 231, 0.2)',
                    'rgba(50, 90, 231, 0.2)',
                    'rgba(50, 90, 231, 0.2)',
                    'rgba(50, 90, 231, 0.2)'
                ],
                borderColor: [
                    'rgba(50, 90, 231, 1)',
                    'rgba(54, 162, 235, 1)',
                    'rgba(50, 90, 231, 1)',
                    'rgba(50, 90, 231, 1)',
                    'rgba(50, 90, 231, 1)',
                    'rgba(50, 90, 231, 1)'
                ],
                borderWidth: 1
            }],
        };


        Chart.defaults.global.defaultFontColor = '#151515';
        var ctx = document.getElementById("myChart").getContext('2d');
        var myChart = new Chart(ctx, {
            type: 'line',
            data: data,
            options: {
                responsive: true, // Instruct chart js to respond nicely.
                maintainAspectRatio: false, // Add to prevent default behaviour of full-width/height 
                scales: {
                    xAxes: [{
                        scaleLabel: {
                            display: true,
                            labelString: ''
                        }
                    }],
                    yAxes: [{
                        ticks: {
            callback: function(value, index, values) {
                if (Math.floor(value) === value) {
                    return value;
                }
            }
      }
                    }]
                },
            }
        });
        //$('#legend').html(myChart.generateLegend());
        return myChart;
    }



    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function () {
        if (this.readyState == 4 amp;amp; this.status == 200) {
            var json = JSON.parse(this.response);
            console.log(json);

            // Map json labels  back to values array
            var labels = json.feed.entry.map(function (e) {
                return e.gsx$date.$t;
            });

            // Map json values back to values array
            var values = json.feed.entry.map(function (e) {
                return e.gsx$followers.$t;
            });
            for (i = 0; i < values.length; i  ) {
                if (values[i].charAt(0) == '-') {
                    values.length = values.length - 1;
                    labels.length = labels.length - 1;
                    
                } else if (values[i].charAt(0) == ' '){
                    values.length = values.length - 1;
                    labels.length = labels.length - 1;
                }
            }

            for (i = 0; i < values.length; i  ) {
                  values[i]= values[i].replace(/,/g, '');
            }

            BuildChart(labels.reverse(), values.reverse(), "Followers");
        }
    };
    xhttp.open("GET", "https://spreadsheets.google.com/feeds/list/1nLLfOhAD6PGcIPc5mttyBFi1maoveEYpsz4MiU7JNAA/od6/public/full?alt=json", false);
    xhttp.send();
</script>  

Я использую эту диаграмму, чтобы показать данные подписчика определенного человека, я хотел бы иметь выпадающий список, в котором человек может выбрать интервал, который он предпочитает видеть, или выпадающий список с «вчера», «последние 3 дня», «последние 7 дней». Заранее спасибо тем, кто потрудился мне помочь. Возможно ли сделать что-то подобное?
Заранее спасибо

Ответ №1:

Вы можете сделать это, изменив значения chart.config.options.scales.xAxes[0].ticks.max и chart.config.options.scales.xAxes[0].ticks.min .

В приведенном выше коде просто обратите внимание на одну вещь: я заметил, что метки находятся в обратном времени. Справа указана дата «сегодня», а значения слева — это дни в будущем.

введите описание изображения здесь

Я не очень хорошо понимаю, как вы пытаетесь представить данные, но в любом случае это не меняет того, как это делается. В приведенном выше фрагменте есть пример с числовым вводом, который добавляет определенное количество days к текущей дате. Таким образом, вам нужно будет только перевести это на ваш <select> .

 <script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js" integrity="sha256-R4pqcOYV8lt7snxMQO/HSbVCFRPMdrhAFMH vr9giYI=" crossorigin="anonymous"></script>

<div class="chart" style="position: relative; height:50vh; width:100%;margin: 0 auto;;">
  <canvas id="myChart" width="400" height="400"></canvas></div>
Days from now: <input id="days" value="0" type="number" />
<br/>
<select id="date-choose" disabled>
  <option value="1">Today</option>
  <option value="2">Yesterday</option>
  <option value="7">Last 7 Days</option>
</select>

<script>
  let chart; // 1
  let inp = document.getElementById("days");

  inp.oninput = function() { // 3
    const today = new Date().getTime()    inp.value * 1000 * 60 * 60 * 24; // 4
    const newMax = new Date(today).toISOString().split("T")[0]
    console.log("newMax", newMax)

    chart.config.options.scales.xAxes[0].ticks.max = newMax

    chart.update();
  };

  function BuildChart(labels, values, chartTitle) {
    var data = {
      labels: labels,
      datasets: [{
        label: chartTitle, // Name the series
        data: values,
        backgroundColor: [
          'rgba(50, 99, 231, 0.2)',
          'rgba(50, 90, 231, 0.2)',
          'rgba(50, 90, 231, 0.2)',
          'rgba(50, 90, 231, 0.2)',
          'rgba(50, 90, 231, 0.2)',
          'rgba(50, 90, 231, 0.2)'
        ],
        borderColor: [
          'rgba(50, 90, 231, 1)',
          'rgba(54, 162, 235, 1)',
          'rgba(50, 90, 231, 1)',
          'rgba(50, 90, 231, 1)',
          'rgba(50, 90, 231, 1)',
          'rgba(50, 90, 231, 1)'
        ],
        borderWidth: 1
      }],
    };


    Chart.defaults.global.defaultFontColor = '#151515';
    var ctx = document.getElementById("myChart").getContext('2d');
    var myChart = new Chart(ctx, {
      type: 'line',
      data: data,
      options: {
        responsive: true, // Instruct chart js to respond nicely.
        maintainAspectRatio: false, // Add to prevent default behaviour of full-width/height 
        scales: {
          xAxes: [{
            scaleLabel: {
              display: true,
              labelString: ''
            },
          }],
          yAxes: [{
            ticks: {
              callback: function(value, index, values) {
                if (Math.floor(value) === value) {
                  return value;
                }
              }
            }
          }]
        },
      }
    });
    return myChart;
  }

  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 amp;amp; this.status == 200) {
      var json = JSON.parse(this.response);
      //console.log(json);

      // Map json labels  back to values array
      var labels = json.feed.entry.map(function(e) {
        return e.gsx$date.$t;
      });

      // Map json values back to values array
      var values = json.feed.entry.map(function(e) {
        return e.gsx$followers.$t;
      });
      for (i = 0; i < values.length; i  ) {
        if (values[i].charAt(0) == '-') {
          values.length = values.length - 1;
          labels.length = labels.length - 1;

        } else if (values[i].charAt(0) == ' ') {
          values.length = values.length - 1;
          labels.length = labels.length - 1;
        }
      }

      for (i = 0; i < values.length; i  ) {
        values[i] = values[i].replace(/,/g, '');
      }

      chart = BuildChart(labels.reverse(), values.reverse(), "Followers"); // 2
    }
  };
  xhttp.open("GET", "https://spreadsheets.google.com/feeds/list/1nLLfOhAD6PGcIPc5mttyBFi1maoveEYpsz4MiU7JNAA/od6/public/full?alt=json", false);
  xhttp.send();
</script>  

В приведенном выше коде есть несколько важных моментов (найдите комментарий, чтобы сослаться на число). Это:

  1. chart создается так, чтобы он содержал экземпляр диаграммы
  2. BuildChart вывод сохраняется в chart
  3. Необходимо создать нового oninput слушателя, чтобы реагировать на изменения даты. Если вы используете a <select> , вы можете использовать onchange событие вместо этого.
  4. Здесь вычисление производится путем вычитания количества дней, которые мы хотим показать.