typescript - Hur gör jag så att linjen börjar i mitten istället för i början av kolumnen?


Jag skapar ett linjediagram med chartjs (v3) (och react-chartjs för att integrera) och jag har lite problem med att anpassa linjen så att den startar i mitten av den första kolumnen (och även slutar i mitten av den sista kolumnen) eftersom den första kolumnen alltid kommer att vara på en noll Y-position vilket gör att linjen startar helt till vänster. Så jag behöver lista ut hur man får linjerna att markeras i mitten av kolumnen istället för vid kanten.

Det här är resultatet jag har:

Och jag behöver något liknande detta:

Min konfiguration:

<Line
  data={data}
  height={440}
  width={480}
  options={{
    ...options,
    scales: {
      x: {
        grid: {
          color(context) {
            if (context.tick.value === 0) return '#B3B3B3';

            return '#E6E6E6';
          },
          tickWidth: 0,
          lineWidth: 1,
        },
        border: {
          dash(context) {
            if (context.tick.value === 0) return [0];

            return [5, 5];
          },
          width: 0,
        },
        ticks: {
          display: false,
        },
      },
      y: {
        grid: {
          color(context) {
            if ([0, 30, 70].includes(context.tick.value)) {
              return '#B3B3B3';
            }

            return '#E6E6E6';
          },
          lineWidth(context) {
            if ([30, 70].includes(context.tick.value)) {
              return 2;
            }

            return 1;
          },
          tickWidth: 0,
        },
        border: {
          dash(context) {
            if (context.tick.value === 0) return [0];

            return [5, 5];
          },
          width: 1,
        },
        min: 0,
        max: 100,
        ticks: {
          font: {
            weight: 'bold',
            size: 10,
            family: 'Open Sans',
          },
          color: '#000000',
        },
      },
    },
    animation: false,
    plugins: {
      legend: {
        display: false,
      },
      tooltip: {
        enabled: false,
      },
    },
  }}
/>

Svar #1

...      

      options: {
            scales: {
                x: {
                    type: 'linear', // Use linear scale for x-axis
                    ticks: {
                        stepSize: 0, // Set step size to 0
                        precision: 0
                        // No decimal places
                    }
                },
                y: {
                    ticks: {
                        stepSize: 1, // Set step size to 1
                        precision: 0 // No decimal places
                    }
                }
            },
...

eller

...

options: {
    scales: {
        x: {
            type: 'category', // Use category scale for x-axis
            labels: ['1', '1.5', '2', '2.5', '3', '3.5', '4', '4.5', '5'], // Custom labels
            ticks: {
                precision: 1, // No decimal places
                maxRotation: 0, // Disable label rotation
                autoSkip: false, // Do not skip any labels
                padding: 10 // Padding between ticks and chart area
            }
        },
        y: {
            ticks: {
                stepSize: 1, // Set step size to 1
                precision: 0 // No decimal places
            }
        }
    }
}

...
  • Vi ställer in typen av x-axelns skala till 'kategori'.
  • Anpassade etiketter tillhandahålls för varje punkt,
  • Vi inaktiverar etikettrotation (maxRotation: 0),
  • Vi förhindrar att etiketter hoppas över (autoSkip: false),
  • Ett mellanrum på 10 px läggs till mellan markeringarna och diagramytan för att ge plats åt etiketterna.

Här är en helt statisk sida som jag använde för proof of concept för den snabba lösning jag kom fram till:

<html lang="en"><head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Random Line Chart</title>
    <!-- Include Chart.js -->
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <style>
        #myChart
        {
            aspect-ratio: 1/1;
            display: block;
            height: 718px;
            width: 756px;
        }
    </style>
</head>
<body>
    <canvas id="myChart" width="1502" height="1378" style="display: block; box-sizing: border-box; height: 689px; width: 751px;"></canvas>
    <script>
        document.addEventListener('DOMContentLoaded', function () {
            var ctx = document.getElementById('myChart').getContext('2d');

            function generateRandomData(numLines, numPoints, maxY) {
                var data = [];
                var labels = Array.from({ length: numPoints }, (_, i) => (i + 1).toString());
                var colors = ['red', 'blue', 'green', 'orange', 'purple']; // Line colors

                // Generate random data for each line
                for (var i = 0; i < numLines; i++) {
                    var lineData = [];
                    for (var j = 0; j < numPoints; j++) {
                        // Generate random y values within the specified range
                        var randomY = Math.floor(Math.random() * (maxY)) + 1;
                        lineData.push({ x: (j + randomY - 0.5).toString(), y: randomY });
                    }
                    data.push({
                        label: 'Line ' + String.fromCharCode(65 + i), // A, B, C, D, E
                        data: lineData,
                        borderColor: colors[i % colors.length], // Cycle through colors
                        borderWidth: 2,
                        fill: false
                    });
                }

                return { labels: labels, datasets: data };
            }

            // Create the chart with random data
            var myChart = new Chart(ctx, {
                type: 'line',
                data: generateRandomData(5, 5, 10), // 5 lines, 5 points per line, maxY = 10
                options: {
                    scales: {
                        x: {
                            type: 'linear', // Use linear scale for x-axis
                            ticks: {
                                stepSize: 1, // Set step size to 1
                                precision: 0 // No decimal places
                            }
                        },
                        y: {
                            ticks: {
                                stepSize: 1, // Set step size to 1
                                precision: 0 // No decimal places
                            }
                        }
                    },
                    plugins: {
                        legend: {
                            display: true
                        }
                    }
                }
            });
        });
    </script>


</body></html>