Настройка Chart.js - PullRequest
       11

Настройка Chart.js

0 голосов
/ 12 ноября 2018

Итак, я пытался понять документацию для Chart.js, но для новых людей не совсем понятно, как можно настраивать определенные вещи.

Я установил плагин, но его нельзя настроить, так какЯ хочу получить его, я пытался использовать CSS, но, поскольку это холст, на самом деле вы ничего не можете сделать.

Я пытаюсь достичь этого дизайна, добавить данные из моей базы данных MySQL и отобразить ихЯ могу понять, как сделать все остальное, кроме разработки графика.

Чего я пытаюсь достичь.

Chart example

1 Ответ

0 голосов
/ 13 ноября 2018

Я думаю, что самый близкий результат, который вы можете получить с chart.js и закругленными границами, использует этот ответ: https://stackoverflow.com/a/43281198/10387396.

Но он не очень хорошо работает с отрицательными значениями.

Chart.helpers.drawRoundedTopRectangle = function(ctx, x, y, width, height, radius) {
  ctx.beginPath();
  ctx.moveTo(x + radius, y);
  // top right corner
  ctx.lineTo(x + width - radius, y);
  ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
  // bottom right   corner
  ctx.lineTo(x + width, y + height);
  // bottom left corner
  ctx.lineTo(x, y + height);
  // top left   
  ctx.lineTo(x, y + radius);
  ctx.quadraticCurveTo(x, y, x + radius, y);
  ctx.closePath();
};

Chart.elements.RoundedTopRectangle = Chart.elements.Rectangle.extend({
  draw: function() {
    var ctx = this._chart.ctx;
    var vm = this._view;
    var left, right, top, bottom, signX, signY, borderSkipped;
    var borderWidth = vm.borderWidth;

    if (!vm.horizontal) {
      // bar
      left = vm.x - vm.width / 2;
      right = vm.x + vm.width / 2;
      top = vm.y;
      bottom = vm.base;
      signX = 1;
      signY = bottom > top? 1: -1;
      borderSkipped = vm.borderSkipped || 'bottom';
    } else {
      // horizontal bar
      left = vm.base;
      right = vm.x;
      top = vm.y - vm.height / 2;
      bottom = vm.y + vm.height / 2;
      signX = right > left? 1: -1;
      signY = 1;
      borderSkipped = vm.borderSkipped || 'left';
    }

    // Canvas doesn't allow us to stroke inside the width so we can
    // adjust the sizes to fit if we're setting a stroke on the line
    if (borderWidth) {
      // borderWidth shold be less than bar width and bar height.
      var barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom));
      borderWidth = borderWidth > barSize? barSize: borderWidth;
      var halfStroke = borderWidth / 2;
      // Adjust borderWidth when bar top position is near vm.base(zero).
      var borderLeft = left + (borderSkipped !== 'left'? halfStroke * signX: 0);
      var borderRight = right + (borderSkipped !== 'right'? -halfStroke * signX: 0);
      var borderTop = top + (borderSkipped !== 'top'? halfStroke * signY: 0);
      var borderBottom = bottom + (borderSkipped !== 'bottom'? -halfStroke * signY: 0);
      // not become a vertical line?
      if (borderLeft !== borderRight) {
        top = borderTop;
        bottom = borderBottom;
      }
      // not become a horizontal line?
      if (borderTop !== borderBottom) {
        left = borderLeft;
        right = borderRight;
      }
    }

    // calculate the bar width and roundess
    var barWidth = Math.abs(left - right);
    var roundness = this._chart.config.options.barRoundness || 0.5;
    var radius = barWidth * roundness * 0.5;

    // keep track of the original top of the bar
    var prevTop = top;

    // move the top down so there is room to draw the rounded top
    top = prevTop + radius;
    var barRadius = top - prevTop;

    ctx.beginPath();
    ctx.fillStyle = vm.backgroundColor;
    ctx.strokeStyle = vm.borderColor;
    ctx.lineWidth = borderWidth;

    // draw the rounded top rectangle
    Chart.helpers.drawRoundedTopRectangle(ctx, left, (top - barRadius + 1), barWidth, bottom - prevTop, barRadius);

    ctx.fill();
    if (borderWidth) {
      ctx.stroke();
    }

    // restore the original top value so tooltips and scales still work
    top = prevTop;
  },
});

Chart.defaults.roundedBar = Chart.helpers.clone(Chart.defaults.bar);

Chart.controllers.roundedBar = Chart.controllers.bar.extend({
  dataElementType: Chart.elements.RoundedTopRectangle
});

//*********//
const d1=  [65, 59, 80, 81,-40, 56, 55, 40 ];
const setColor = data => data < 0 ? '#ff4433': '#3377ee';

var data = {
    labels: ["January", "February", "March", "April", "May", "June", "July", "August"],
    datasets: [
        {
            label: "My First dataset",
            backgroundColor: d1.map(setColor),
            borderColor: d1.map(setColor),
            data: d1
        },
    ],
};

var options = {
    scaleBeginAtZero: false,
    responsive: true,
    barRoundness: 1,
    scales: {
      yAxes: [{
        ticks: {
          suggestedMin: -70,
          suggestedMax: 100
        }
      }]
    }
};

const ctx = "myChart";
const chart = new Chart(ctx, { type: 'roundedBar', data, options });
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.min.js"></script>
<canvas id="myChart" width="250" height="100"></canvas>

С Echarts это сделать немного проще.

const chart = echarts.init(document.getElementById('main'));
const d1 =  [65, 59, 80, 81,-40, 56, 55, 40 ];

// specify chart configuration item and data
const option = {

  tooltip: {},
  legend: {
    data:['Sales']
  },
  xAxis: {
    data: ["January", "February", "March", "April", "May", "June", "July", "August"]
  },
  yAxis: {},
  series: [{
    name: 'Sales',
    type: 'bar',
    barWidth: 20,
    data: d1.map(item => {
      return {
        value: item,
        itemStyle: {
          color: item > 0 ? '#2196F3' : '#F44336',
          barBorderRadius: item > 0 ? [100, 100, 0 ,0] 
                                    : [0 ,0 ,100, 100]
        }
      }
    }),
  }]
};

// use configuration item and data specified to show chart
chart.setOption(option);
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/4.1.0/echarts.min.js"></script>
<div id="main" style="width: 100vw;height:400px;"></div>

Если вам не нужны закругленные границы, а только стилизация отрицательных значений, вы можете отобразить свои данные, чтобы создать массив цветов в зависимости отего значение:

const chartData = [65, 59, 80, 81,-40, 56, 55, 40 ];
const data = {
  labels: ["January", "February", "March", "April", "May", "June", "July", "August"],
  datasets: [
    {
        label: "My First dataset",
        backgroundColor: chartData.map(setColor),
        borderColor: chartData.map(setColor),
        data: chartData
    },
  ],
};
// If data < 0 return a red color.
const setColor = data => data < 0 ? '#ff4433': '#3377ee';

Результат:

const d1=  [65, 59, 80, 81,-40, 56, 55, 40 ];
const setColor = data => data < 0 ? '#ff4433': '#3377ee';

var data = {
    labels: ["January", "February", "March", "April", "May", "June", "July", "August"],
    datasets: [
        {
            label: "My First dataset",
            backgroundColor: d1.map(setColor),
            borderColor: d1.map(setColor),
            data: d1
        },
    ],
};

var options = {
    scaleBeginAtZero: false,
    responsive: true,
    scales: {
      yAxes: [{
        ticks: {
          suggestedMin: -60,
          suggestedMax: 100
        }
      }]
    }
};

const ctx = "myChart";
const chart = new Chart(ctx, { type: 'bar', data, options });
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.min.js"></script>
<canvas id="myChart" width="250" height="100"></canvas>
...