Tengo datos como los ejemplos. En lugar de Categoría, tengo tiempo para un día completo para cada trimestre. Si un trimestre no tiene datos, no tiene valor. Por ejemplo, las 08:30 no existen en la Serie 1. Por lo tanto, cuando el gráfico se muestre, las 08:30 vendrán después de las 08:45, ya que solo la Serie 2 tiene un valor para ello. Pero obviamente lo quiero justo después de las 08:15. Todo lo demás es correcto. La única solución en la que estoy pensando es completar el primer elemento (Serie 1) con cada período de tiempo faltante y con 0 como valor para él. Pero espero que haya una solución mejor para esto.
const series = [ { name: 'Series 1', data: [ { time: '08:00', value: Math.random() }, { category: '08:15', value: Math.random() }, { category: '08:45', value: Math.random() }, ], }, { name: 'Series 2', data: [ { category: '08:00', value: Math.random() }, { category: '08:15', value: Math.random() }, { category: '08:30', value: Math.random() }, ], }, ];Aquí está el código relevante según lo solicitado. Datakey es solo una cadena para seleccionar qué datos mostrar. Porque tengo varios campos de "valor" para el eje Y.
<ResponsiveContainer> <LineChart> <CartesianGrid strokeDasharray="2 2" /> <XAxis dataKey="endTime" type="category" allowDuplicatedCategory={false} /> <YAxis dataKey={dataKey} /> <Tooltip /> <Legend /> {chartData.map((irvMachine, i) => ( <Line data={irvMachine.data} name={irvMachine.irvMachine} dataKey={dataKey} stroke={colors[i]} activeDot={{ r: 4 }} type="monotone" /> ))} </LineChart> </ResponsiveContainer>Puede transformar un poco sus datos para obtener una sola serie de datos donde "Serie 1" y "Serie 2" serían las claves de valor y clasificar según la clave de "categoría". De esta forma, todas las categorías se muestran en el orden deseado y cualquier valor faltante para una sola subserie es solo una clave faltante para esa entrada.
Aquí hay una función de muestra:
function transformSeries(series) { const chartDataObj = {}; for (let i = 0; i < series.length; i++) { const seriesName = series[i].name; for (let j = 0; j < series[i].data.length; j++) { const category = series[i].data[j].category; const value = series[i].data[j].value; if (!chartDataObj.hasOwnProperty(category)) { chartDataObj[category] = { category: category }; } chartDataObj[category][seriesName] = value; if (!chartDataObj[category].hasOwnProperty("maxVal")) { chartDataObj[category].maxVal = value; } else { chartDataObj[category].maxVal = Math.max(chartDataObj[category].maxVal, value); } } } return Object.values(chartDataObj).sort((a, b) => (a.category > b.category ? 1 : -1)); }El resultado de llamar a esta función en los datos que proporcionó es:
[ {category: "08:00", "Series 1": 0.7467901762604093, "Series 2": 0.47855212989392215, maxVal: 0.7467901762604093}, {category: "08:15", "Series 1": 0.2311522761588818, "Series 2": 0.12893275264478166, maxVal: 0.2311522761588818}, {category: "08:30", "Series 2": 0.924208327780883, maxVal: 0.924208327780883}, {category: "08:45", "Series 1": 0.8633031302477523, maxVal: 0.8633031302477523} ] Esto también incluye una clave maxVal para proporcionar al componente YAxis (ya que actualmente no admite varias claves).
Entonces puedes renderizar así:
export function MyChart() { const chartData = transformSeries(series); return ( <LineChart width={800} height={450} data={chartData}> <CartesianGrid strokeDasharray="2 2" /> <XAxis dataKey="category" type="category" allowDuplicatedCategory={false} /> <YAxis dataKey="maxVal" /> <Tooltip /> <Legend /> {series.map((s) => ( <Line key={s.name} dataKey={s.name} /> ))} </LineChart> ); }El problema ocurre debido a que faltan algunas entradas de las etiquetas en la primera fuente de datos que tiene la segunda. La solución simple puede ser crear una fuente de datos adicional solo para etiquetas y no trazaremos una línea para esa fuente.
Un ejemplo de sandbox relevante está aquí
La explicación completa está aquí.
La siguiente solución puede resolver el problema.
const labelSeries = { data: [ { category: '08:00' }, { category: '08:15' }, { category: '08:30' }, { category: '08:45' } ] } <ResponsiveContainer> <LineChart> <CartesianGrid strokeDasharray="2 2" /> <XAxis dataKey="endTime" type="category" allowDuplicatedCategory={false} /> <YAxis dataKey={dataKey} /> <Tooltip /> <Legend /> <Line data={labelSeries.data} /> // This line will sort the x-axis label {chartData.map((irvMachine, i) => ( <Line data={irvMachine.data} name={irvMachine.irvMachine} dataKey={dataKey} stroke={colors[i]} activeDot={{ r: 4 }} type="monotone" /> ))} </LineChart> </ResponsiveContainer>