雷达图颜色过渡和边框平滑问题

问题描述 投票:0回答:1

“我正在尝试使用雷达图在图形中进行平滑的颜色过渡。同时,我希望线条平滑,但无法得到我想要的结果。颜色过渡平滑,但线条不合适好吧,角落看起来很难。有人有有用的解决方案建议吗?在此处输入图像描述

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Radar Chart with Smooth Color Transitions</title>
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
  <style>
    body {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      background-color: #252c37;
      margin: 0;
      font-family: Arial, sans-serif;
    }

    .chart-container {
      position: relative;
      width: 400px;
      height: 400px;
    }

    .center-text {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      text-align: center;
    }

    .main-number {
      font-size: 3em;
      color: #4CAF50;
    }

    .sub-text {
      font-size: 1.2em;
      color: #999;
    }
  </style>
</head>
<body>
  
  <div class="chart-container">
    <canvas id="radarChart"></canvas>
    <div class="center-text">
      <span class="main-number">87</span>
      <br />
      <span class="sub-text">Ad Liked</span>
    </div>
  </div>

  <script>
    // Özel plugin ile segmentleri renklendirme ve geçiş sağlama
    const multiColorPlugin = {
      id: 'multiColorPlugin',
      afterDatasetDraw(chart) {
        const { ctx } = chart;
        const meta = chart.getDatasetMeta(0);
        const points = meta.data;
        const tension = 0.3; // Daha yumuşak geçişler için tension

        const borderColors = [
          'rgba(255, 99, 132, 1)', // Pembe
          'rgba(54, 162, 235, 1)', // Mavi
          'rgba(255, 206, 86, 1)', // Sarı
          'rgba(75, 192, 192, 1)', // Turkuaz
          'rgba(153, 102, 255, 1)', // Mor
          'rgba(255, 159, 64, 1)'   // Turuncu
        ];

        ctx.save();
        for (let i = 0; i < points.length; i++) {
          const currentPoint = points[i];
          const nextPoint = points[(i + 1) % points.length];
          const prevPoint = points[(i - 1 + points.length) % points.length];

          // Kontrol noktaları hesaplanarak daha yumuşak geçiş sağlanıyor
          const cp1x = currentPoint.x + tension * (nextPoint.x - prevPoint.x);
          const cp1y = currentPoint.y + tension * (nextPoint.y - prevPoint.y);

          const gradient = ctx.createLinearGradient(currentPoint.x, currentPoint.y, nextPoint.x, nextPoint.y);
          gradient.addColorStop(0, borderColors[i]);
          gradient.addColorStop(1, borderColors[(i + 1) % points.length]);

          ctx.beginPath();
          ctx.moveTo(currentPoint.x, currentPoint.y);
          ctx.bezierCurveTo(cp1x, cp1y, nextPoint.x, nextPoint.y, nextPoint.x, nextPoint.y); // Daha yumuşak geçiş için bezierCurve
          ctx.strokeStyle = gradient;
          ctx.lineWidth = 3;
          ctx.stroke();
          ctx.closePath();
        }
        ctx.restore();
      }
    };

    // Radar grafiği verileri ve ayarları
    const data = {
      labels: ['Creativity', 'Originality', 'Emotion', 'Believable', 'Uniqueness', 'Different'],
      datasets: [{
        label: 'Ad Liked',
        data: [47, 91, 42, 88, 63, 83],
        fill: true,
        backgroundColor: 'rgba(0, 0, 0, 0.5)', // İç kısım siyah ve şeffaf
        pointBackgroundColor: 'rgba(0, 0, 0, 0)', // Noktaları gizle
        pointBorderColor: 'rgba(0, 0, 0, 0)', // Nokta kenarlarını gizle
        tension: 0.5 // Çizgilerin yumuşaklığı için tension
      }]
    };

    const config = {
      type: 'radar',
      data: data,
      options: {
        elements: {
          line: {
            borderWidth: 0 // Çizgi rengi plugin ile belirlenecek
          }
        },
        scales: {
          r: {
            angleLines: {
              display: false
            },
            suggestedMin: 0,
            suggestedMax: 100,
            ticks: {
              display: false // Etrafındaki sayıları gizler
            }
          }
        }
      },
      plugins: [multiColorPlugin] // Özel plugin kullanımı
    };

    // Radar grafiğini oluştur
    const radarChart = new Chart(
      document.getElementById('radarChart'),
      config
    );
  </script>

</body>
</html> Even though I made the transitions 0.5 to 0.5, it doesn't work.
javascript chart.js
1个回答
0
投票

一个简单的解决方案是使用已经可用的贝塞尔参数,这些参数是针对周期曲线计算的,该曲线非常平滑 角,使用 Chart.js 源代码 这将用于默认隐藏 (

borderWidth: 0
) 曲线:

ctx.bezierCurveTo(currentPoint.cp2x, currentPoint.cp2y, nextPoint.cp1x, nextPoint.cp1y, nextPoint.x, nextPoint.y);

经过此修改的原始代码,摘录如下:

const multiColorPlugin = {
   id: 'multiColorPlugin',
   afterDatasetDraw(chart) {
      const { ctx } = chart;
      const meta = chart.getDatasetMeta(0);
      const points = meta.data;
      const tension = 0.3; // set tension through regular options

      const borderColors = [
         'rgba(255, 99, 132, 1)',
         'rgba(54, 162, 235, 1)',
         'rgba(255, 206, 86, 1)',
         'rgba(75, 192, 192, 1)',
         'rgba(153, 102, 255, 1)',
         'rgba(255, 159, 64, 1)'
      ];

      ctx.save();
      for (let i = 0; i < points.length; i++) {
         const currentPoint = points[i];
         const nextPoint = points[(i + 1) % points.length];

         const gradient = ctx.createLinearGradient(currentPoint.x, currentPoint.y, nextPoint.x, nextPoint.y);
         gradient.addColorStop(0, borderColors[i]);
         gradient.addColorStop(1, borderColors[(i + 1) % points.length]);

         ctx.beginPath();
         ctx.moveTo(currentPoint.x, currentPoint.y);
         ctx.bezierCurveTo(currentPoint.cp2x, currentPoint.cp2y, nextPoint.cp1x, nextPoint.cp1y, nextPoint.x, nextPoint.y);
         ctx.strokeStyle = gradient;
         ctx.lineWidth = 3;
         ctx.stroke();
         ctx.closePath();
      }
      ctx.restore();
   }
};

const data = {
   labels: ['Creativity', 'Originality', 'Emotion', 'Believable', 'Uniqueness', 'Different'],
   datasets: [{
      label: 'Ad Liked',
      data: [47, 91, 42, 88, 63, 83],
      fill: true,
      backgroundColor: 'rgba(0, 0, 0, 0.5)',
      pointBackgroundColor: 'rgba(0, 0, 0, 0)',
      pointBorderColor: 'rgba(0, 0, 0, 0)',
      tension: 0.5
   }]
};

const config = {
   type: 'radar',
   data: data,
   options: {
      elements: {
         line: {
            borderWidth: 0
         }
      },
      scales: {
         r: {
            angleLines: {
               display: false
            },
            suggestedMin: 0,
            suggestedMax: 100,
            ticks: {
               display: false
            }
         }
      }
   },
   plugins: [multiColorPlugin]
};

new Chart(
   'radarChart',
   config
);
<div style="width: 250px">
    <canvas id="radarChart" style="background-color:rgb(64,64,78)">
    </canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

© www.soinside.com 2019 - 2024. All rights reserved.