Как отобразить частную функцию прорисовки прототипа на графике js - PullRequest
0 голосов
/ 04 марта 2020

Я использую chartjs в angular и использую некоторые коды, чтобы сделать закругленные углы horizontalBar, но эти коды влияют на другие диаграммы. Я не хочу, чтобы те меняли другие. Я просто хочу, чтобы закругленные углы в tdfChart, как я могу это сделать?

<canvas #tdfChart style="height: 325px;"></canvas>
import * as Chart from 'chart.js';

Я использовал этот код для округления углов диаграммы в drawTdf, то есть:

Chart.elements.Rectangle.prototype.draw = function () {...}
@ViewChild("tdfChart", { static: true }) public tdfChart: ElementRef;
  private _tdf: any;
  public drawTDF(self) {
    this._tdf && this._tdf.destroy();
    this._tdf = new Chart(this.tdfChart.nativeElement.getContext('2d'), {
      type: 'horizontalBar',
      data: {
        datasets: [
          {
            label: 'Tdf chart',
            // data: [102, 56, 140, 200, 345, 80, 110, 20, 220, 112],
            data: this._dataForTDF(),
            backgroundColor: '#FFAD08',
            borderColor: '#f57c00',
          }
        ],

        labels: this._labelForTDF()
      },
      options: {
        barRoundness: .7,
        plugins: { labels: false },
        area: 'right',
        maintainAspectRatio: false,
        scales: {
          yAxes: [{
            ticks: {
              beginAtZero: true,
            }
          }],
          xAxes: [{
            scaleLineColor: 'transparent',
            ticks: {
              fontSize: 16
            }
          }]
        },
        legend: {
          labels: {
            fontSize: 16
          }
        },
        onClick: function (e, array) {
          let tdf_reason: string = "";
          if (array[0])
            tdf_reason = array[0]._model.label;
          if (self.actionPlan != 0)
            self._router.navigate(['parsian/dashboard/status'],
              {
                queryParams:
                {
                  agency: self.filters.agency_code,
                  year: self.filters.year,
                  month: self.filters.month,
                  week: self.filters.week,
                  status: self.selectedStatus == null ? '' : self.selectedStatus,
                  actionplan: self.actionPlan == null ? '' : self.actionPlan,
                  tdf_reason: tdf_reason,
                  totalPages: self.actionCount
                }
              });
          else
            self._router.navigate(['parsian/dashboard/status'],
              {
                queryParams:
                {
                  agency: self.filters.agency_code,
                  year: self.filters.year,
                  month: self.filters.month,
                  week: self.filters.week,
                  status: self.selectedStatus == null ? '' : self.selectedStatus,
                  tdf_reason: tdf_reason,
                  totalPages: self.statusCount
                }
              });
        }
      }
    });


Chart.elements.Rectangle.prototype.draw = function () {

      var ctx = this._chart.ctx;
      var vm = this._view;
      var left, right, top, bottom, signX, signY, borderSkipped, radius;
      var borderWidth = vm.borderWidth;
      // Set Radius Here
      // If radius is large enough to cause drawing errors a max radius is imposed
      var cornerRadius = 20;

      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;
        }
      }

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

      // Corner points, from bottom-left to bottom-right clockwise
      // | 1 2 |
      // | 0 3 |
      var corners = [
        [left, bottom],
        [left, top],
        [right, top],
        [right, bottom]
      ];

      // Find first (starting) corner with fallback to 'bottom'
      var borders = ['bottom', 'left', 'top', 'right'];
      var startCorner = borders.indexOf(borderSkipped, 0);
      if (startCorner === -1) {
        startCorner = 0;
      }

      function cornerAt(index) {
        return corners[(startCorner + index) % 4];
      }

      // Draw rectangle from 'startCorner'
      var corner = cornerAt(0);
      var width, height, x, y, nextCorner, nextCornerId
      var x_tl, x_tr, y_tl, y_tr;
      var x_bl, x_br, y_bl, y_br;
      ctx.moveTo(corner[0], corner[1]);

      for (var i = 1; i < 4; i++) {
        corner = cornerAt(i);
        nextCornerId = i + 1;
        if (nextCornerId == 4) {
          nextCornerId = 0
        }

        nextCorner = cornerAt(nextCornerId);

        width = corners[2][0] - corners[1][0];
        height = corners[0][1] - corners[1][1];
        x = corners[1][0];
        y = corners[1][1];

        radius = cornerRadius;

        // Fix radius being too large        
        if (radius > Math.abs(height) / 2) {
          radius = Math.floor(Math.abs(height) / 2);
        }
        if (radius > Math.abs(width) / 2) {
          radius = Math.floor(Math.abs(width) / 2);
        }

        if (height < 0) {
          // Negative values in a standard bar chart
          x_tl = x; x_tr = x + width;
          y_tl = y + height; y_tr = y + height;

          x_bl = x; x_br = x + width;
          y_bl = y; y_br = y;

          // Draw
          ctx.moveTo(x_bl + radius, y_bl);
          ctx.lineTo(x_br - radius, y_br);
          ctx.quadraticCurveTo(x_br, y_br, x_br, y_br - radius);
          ctx.lineTo(x_tr, y_tr + radius);
          ctx.quadraticCurveTo(x_tr, y_tr, x_tr - radius, y_tr);
          ctx.lineTo(x_tl + radius, y_tl);
          ctx.quadraticCurveTo(x_tl, y_tl, x_tl, y_tl + radius);
          ctx.lineTo(x_bl, y_bl - radius);
          ctx.quadraticCurveTo(x_bl, y_bl, x_bl + radius, y_bl);

        } else if (width < 0) {
          // Negative values in a horizontal bar chart
          x_tl = x + width; x_tr = x;
          y_tl = y; y_tr = y;

          x_bl = x + width; x_br = x;
          y_bl = y + height; y_br = y + height;

          // Draw
          ctx.moveTo(x_bl + radius, y_bl);
          ctx.lineTo(x_br - radius, y_br);
          ctx.quadraticCurveTo(x_br, y_br, x_br, y_br - radius);
          ctx.lineTo(x_tr, y_tr + radius);
          ctx.quadraticCurveTo(x_tr, y_tr, x_tr - radius, y_tr);
          ctx.lineTo(x_tl + radius, y_tl);
          ctx.quadraticCurveTo(x_tl, y_tl, x_tl, y_tl + radius);
          ctx.lineTo(x_bl, y_bl - radius);
          ctx.quadraticCurveTo(x_bl, y_bl, x_bl + radius, y_bl);

        } else {
          //Positive Value
          ctx.moveTo(x + radius, y);
          ctx.lineTo(x + width - radius, y);
          ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
          ctx.lineTo(x + width, y + height - radius);
          ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
          ctx.lineTo(x + radius, y + height);
          ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
          ctx.lineTo(x, y + radius);
          ctx.quadraticCurveTo(x, y, x + radius, y);
        }
      }

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