Как получить смешанную диаграмму из «горизонтальных» полос и линейной диаграммы с помощью Chart.js ?

#javascript #angular #typescript #chart.js #chart.js2

#javascript #угловой #typescript #chart.js #chart.js2

Вопрос:

С вертикальными полосами, по-видимому, вся смешанная диаграмма отображается нормально. Но когда я делаю это horizontally с two X Axes and one Y Axis помощью, будут отображаться только столбцы, а линейная диаграмма — нет. Я рассмотрел другие вопросы, но ни один из них не обсуждал это конкретно.

Это то, чего я хочу достичь, используя Chart.js

Также по какой-то причине мне type: 'linear' scales.xAxes по какой-то причине пришлось указать where id: 'maturity' (как показано в приведенном ниже коде), иначе строковые метки на оси Y также повторялись бы как метки оси X

 var ctx = document.getElementById("myChart");
let chart = new Chart(ctx, {
  type: 'horizontalBar',
  data: {
    labels: ['Information Security', 'Asset Management', 'Human Resource Security', 'Physical Security', 'Equipment Security', 'Access Management', 'Review', "Policy Governance", 'Security Coordination', 'label10', 'label11', 'label12', 'label13'],
    datasets: [{
        xAxisID: 'compliance', // X axis 1
        data: [25, 15, 25, 25, 45, 15, 25, 25, 25, 25, 80, 80, 80],
        label: "Compliance",
        backgroundColor: "#3367D6",
        borderColor: 'rgba(105,159,177,1)',
        categoryPercentage: 0.8,
      },
      {
        type: 'line', // line type dataset
        xAxisID: 'maturity', // X axis 2
        data: [4, 4, 3, 3, 4, 5, 4, 4, 3, 3, 4, 5, 4],
        label: "Threshold for Maturity",
        backgroundColor: "rgba(247, 148, 30, 1)",
        borderColor: 'rgba(247, 148, 30, 1)',
        fill: false,
      },
      {
        xAxisID: 'maturity', // X axis 2
        data: [2, 4, 3, 2, 4, 4, 3, 3, 4, 5, 4, 4, 3],
        label: "Maturity level",
        backgroundColor: "#F7941E",
        borderColor: 'rgba(77,20,96,1)',
        categoryPercentage: 0.8,
      }
    ]
  },
  options: {
    responsive: true,
    legend: {
      align: 'end',
      labels: {
        usePointStyle: true
      },
      position: 'top'
    },
    scales: {
      yAxes: [{
        fontStyle: 'bold',
        ticks: {
          fontSize: 11,
        },
        gridLines: {
          display: false
        },
        scaleLabel: {
          display: true,
          labelString: 'Domains',
          fontStyle: 'bold',
          fontSize: 15
        }
      }],
      xAxes: [{
        id: 'compliance',
        position: 'top',
        ticks: {
          beginsAtZero: true,
          min: 0,
          stepSize: 25
        },
        gridLines: {
          display: false
        },
        scaleLabel: {
          display: true,
          labelString: 'Compliance %',
          fontStyle: 'bold',
          fontSize: 15
        }
      }, {
        id: 'maturity',
        type: 'linear',
        position: 'bottom',
        ticks: {
          min: 1,
          max: 5,
          stepSize: 1,
          callback: function(value, index, values) {
            return 'L'   value;
          },
          fontStyle: 'bold'
        },
        scaleLabel: {
          display: true,
          labelString: 'Maturity Level',
          fontStyle: 'bold',
          fontSize: 15
        }
      }]
    }
  }
})  
 <canvas class="chart" height="250px" id="myChart"></canvas>  

Ответ №1:

Я думаю, проблема в том, что он пытается использовать метки для оси x и данные для оси y.

Для Chart.js v2.x вы могли бы попробовать предоставить данные для строки в виде массива объектов: [{x: 4, y: 'Information Security'}, {x: ... , Я думаю, это должно сработать.

В версии v3 (все еще в бета-версии) horizontalBar тип диаграммы отсутствует. Вместо этого есть новая опция indexAxis , которая работает для всех типов диаграмм. руководство по миграции на v3

Вот как вы могли бы это сделать, используя v3:

 var ctx = document.getElementById("myChart");
let chart = new Chart(ctx, {
  type: 'bar',
  data: {
    labels: ['Information Security', 'Asset Management', 'Human Resource Security', 'Physical Security', 'Equipment Security', 'Access Management', 'Review', "Policy Governance", 'Security Coordination', 'label10', 'label11', 'label12', 'label13'],
    datasets: [{
        xAxisID: 'compliance', // X axis 1
        data: [25, 15, 25, 25, 45, 15, 25, 25, 25, 25, 80, 80, 80],
        label: "Compliance",
        backgroundColor: "#3367D6",
        borderColor: 'rgba(105,159,177,1)',
        categoryPercentage: 0.8,
      },
      {
        type: 'line', // line type dataset
        xAxisID: 'compliance', // X axis 2
        data: [4, 4, 3, 3, 4, 5, 4, 4, 3, 3, 4, 5, 4],
        label: "Threshold for Maturity",
        backgroundColor: "rgba(247, 148, 30, 1)",
        borderColor: 'rgba(247, 148, 30, 1)',
        fill: false
      },
      {
        xAxisID: 'maturity', // X axis 2
        data: [2, 4, 3, 2, 4, 4, 3, 3, 4, 5, 4, 4, 3],
        label: "Maturity level",
        backgroundColor: "#F7941E",
        borderColor: 'rgba(77,20,96,1)',
        categoryPercentage: 0.8,
      }
    ]
  },
  options: {
    indexAxis: 'y', // this changes the orientation for all datasets in v3
    responsive: true,
    legend: {
      align: 'end',
      labels: {
        usePointStyle: true
      },
      position: 'top'
    },
    scales: {
      y: {
        fontStyle: 'bold',
        ticks: {
          fontSize: 11,
        },
        gridLines: {
          display: false
        },
        scaleLabel: {
          display: true,
          labelString: 'Domains',
          font: {
            style: 'bold',
            size: 15
          }
        }
      },
      compliance: {
        position: 'top',
        beginsAtZero: true,
        min: 0,
        ticks: {
          stepSize: 25
        },
        gridLines: {
          display: false
        },
        scaleLabel: {
          display: true,
          labelString: 'Compliance %',
          font: {
            style: 'bold',
            size: 15
          }
        }
      },
      matyrity: {
        type: 'linear',
        position: 'bottom',
        min: 1,
        max: 5,
        ticks: {
          stepSize: 1,
          callback: function(value, index, values) {
            return 'L'   value;
          },
          font: {
            style: 'bold'
          }
        },
        scaleLabel: {
          display: true,
          labelString: 'Maturity Level',
          font: {
            style: 'bold',
            size: 15
          }
        }
      }
    }
  }
})  
 <script src="https://cdn.jsdelivr.net/npm/chart.js@3.0.0-beta.6/dist/chart.min.js"></script>
<canvas class="chart" height="250px" id="myChart"></canvas>  

Комментарии:

1. Здравствуйте, добрый сэр, большое вам спасибо. Я рад, что вы нашли время ответить на мой запрос. Первое решение не сработало для меня. Если это помогает — внутри моего линейного data массива, x поступает из вызова службы и y поступает из другого вызова службы, но я думаю, что это не вызывает никаких проблем. Мне еще предстоит попробовать переход на v3

2. миграция на v3 вызывала проблемы. Я удалил стабильную версию и включил CDN в index.html файл моего проекта Angular, но он не будет принимать ctx в качестве допустимого аргумента и вызвал другие проблемы, поэтому я откатился к стабильной версии v2.9.4, и я все еще не получаю линейную диаграмму для рендеринга