Dos gráficos en uno Card
hay demasiada pequeña cosa, ¿no crees? Sería mejor si los gráficos se pudieran alternar haciendo clic en el encabezado. ¡Implementemos eso!
Primero agregue un estado. Debería gobernar, qué gráfico regalar. Utilizar el Lógica de gancho de estado para implementar el estado y establecer
"lineChart"
como valor predeterminado. No olvides importaruseState
de React, de lo contrario obtendrá un error.Importar el
useState
función en el encabezado delMyApp.jsx
archivo (reemplace la importación actual de React).import React, { useState } from "react";
Utilizar el
useState
ejercicio justo después de comenzar a definir elMyApp
función (antes del controlador de clic).const [toggleCharts, setToggleCharts] = useState("lineChart");
Al hacer clic en el
Card
un encabezado debe establecer el estado correspondiente al gráfico que se debe mostrar.Reescribe tu
handleHeaderClick
función para que maneje esta lógica.const handleHeaderClick = () => { if (toggleCharts === "lineChart") { setToggleCharts("barChart"); } else { setToggleCharts("lineChart"); } };
Para proporcionar el gráfico actual, agregue las siguientes líneas a la representación del componente:
<Card heading="Card" style={{ width: "300px" }} headerInteractive onHeaderClick={handleHeaderClick}> <Text style={spacing.sapUiContentPadding}> This is the content area of the Card </Text> {toggleCharts === "lineChart" ? ( <LineChart dimensions={[{ accessor: "month" }]} measures={[{ accessor: "data", label: "Stock Price" }]} dataset={dataset} /> ) : ( <BarChart dimensions={[{ accessor: "month" }]} measures={[{ accessor: "data" }]} dataset={dataset} /> )} </Card>
¡Hecho! Ahora puede alternar entre gráficos haciendo clic en el encabezado
Card
.Puedes mejorar aún más tu parte
Card
componente utilizando elavatar
prop
y agregandoIcon
él.Agregue la siguiente importación a su componente:
import { Card, Text, Icon } from "@ui5/webcomponents-react";
Y el
avatar
prop, quien obtiene elIcon
como valor, alCard
componente:<Card avatar={<Icon name="line-chart" />} ... </Card>
Para reducir el tamaño del paquete,
Icons
deben importarse manualmente. Como usamos unline-chart
agregue esto a sus importaciones.import '@ui5/webcomponents-icons/dist/line-chart.js';
El es
Icons
también debe darse condicionalmente. Afortunadamente esto es fácil. Pon elbar-chart
importar:import '@ui5/webcomponents-icons/dist/horizontal-bar-chart.js';
Entonces cambia el
name
apoyar unIcon
como sigue:<Card avatar={ <Icon name={ toggleCharts === "lineChart" ? "line-chart" : "horizontal-bar-chart" } /> } ... >
Ahora el
Card
cambia elIcon
haciendo clic en el encabezado.
Si algo salió mal, puede comparar su componente con esta barra de código:
import React, { useState } from "react";
import { Card, Text, Icon } from "@ui5/webcomponents-react";
import { spacing } from "@ui5/webcomponents-react-base";
import { BarChart, LineChart } from "@ui5/webcomponents-react-charts";
import "@ui5/webcomponents-icons/dist/line-chart.js";
import "@ui5/webcomponents-icons/dist/horizontal-bar-chart.js";
export function MyApp() {
const [toggleCharts, setToggleCharts] = useState("lineChart");
const handleHeaderClick = () => {
if (toggleCharts === "lineChart") {
setToggleCharts("barChart");
} else {
setToggleCharts("lineChart");
}
};
const dataset = [
{
month: "January",
data: 65
},
{
month: "February",
data: 59
},
{
month: "March",
data: 80
},
{
month: "April",
data: 81
},
{
month: "May",
data: 56
},
{
month: "June",
data: 55
},
{
month: "July",
data: 40
}
];
return (
<div>
<Card
avatar={
<Icon
name={
toggleCharts === "lineChart"
? "line-chart"
: "horizontal-bar-chart"
}
/>
}
heading="Card"
style={{ width: "300px" }}
headerInteractive
onHeaderClick={handleHeaderClick}
>
<Text style={spacing.sapUiContentPadding}>
This is the content area of the Card
</Text>
{toggleCharts === "lineChart" ? (
<LineChart
dimensions={[{ accessor: "month" }]}
measures={[{ accessor: "data", label: "Stock Price" }]}
dataset={dataset}
/>
) : (
<BarChart
dimensions={[{ accessor: "month" }]}
measures={[{ accessor: "data", label: "Stock Price" }]}
dataset={dataset}
/>
)}
</Card>
</div>
);
}