1

I'am currently learning to code, and build a react-component with four charts, which are changing when the header is clicked. Everything is working fine, but the active header should have the className "open", which i have defined above in the styled-components. I tried to solve it with classList.add and classList.remove but it's not working. Thanks for your advice.

 import styled from "styled-components";
import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
import { coronadata_gesamt, coronadata_erst, coronadata_zweit, coronadata_auffrischung, coronaheader } from "../data";
import { useState } from "react";

const Container = styled.div`
    width:100%;
    padding:20px;
    position:relative;
    height:100%;
`;
const HeaderHolder = styled.div`
    display:flex;
    border-bottom: 1px solid var(--gray);
    width:30%;
    height:20px;
`;
const Header = styled.h3`
    margin-right: 10px;
    color: var(--gray);
    border: 1px solid var(--gray);
    padding:2px;
    background: var(--leightgray);
    opacity:0.5;
    cursor: pointer;

    & .open{
        border: 1px solid var(--gray);
        border-bottom: none;
        opacity:1;
        height:20px;
        background: var(--white);
        z-index:10;
    }
`;
const CardHolder = styled.div`
    width:100%;
    padding:10px;
    position:absolute;
    top:50px;
    left:0;
    & .responsive{
        width: 80%;
        aspect-ratio: 4 / 1;
`;

const Chart = () => {
    
        const [gesamtOpen, setGesamtOpen] = useState(true);
        const [erstOpen, setErstOpen] = useState(false);
        const [zweitOpen, setZweitOpen] = useState(false);
        const [auffrischungOpen, setAuffrischungOpen] = useState(false);

   const handleClick = (name)=>{
        if(name === "Gesamt"){
            setGesamtOpen(true);
            setErstOpen(false);
            setZweitOpen(false);
            setAuffrischungOpen(false);
        }
        else if(name === "Erst**"){
            setErstOpen(true);
            setGesamtOpen(false);
            setZweitOpen(false);
            setAuffrischungOpen(false);
        }
        else if(name === "Zweit"){
            setZweitOpen(true);
            setErstOpen(false);
            setGesamtOpen(false);
            setAuffrischungOpen(false);
        }
        else{
            setZweitOpen(false);
            setErstOpen(false);
            setGesamtOpen(false);
            setAuffrischungOpen(true);

        }
   }
  return (
    <Container>
    <HeaderHolder id="headerHolder">
    {
        coronaheader.map((header)=>(
            <Header key={header.id} onClick={()=>handleClick(header.name)}>{header.name}</Header>
        ))
    }
    </HeaderHolder>
       
        <CardHolder>
        {
            gesamtOpen &&
        <ResponsiveContainer className="responsive">
            <AreaChart data={coronadata_gesamt}>
                <CartesianGrid strokeDasharray="2 2"/>
                <XAxis dataKey="name" stroke="gray"/>
                <YAxis/>
                <Tooltip/>
                <Area
                    type="monotone"
                    dataKey="uv"
                    fill="green"
                />
                 <Area
                    type="monotone"
                    dataKey="pv"
                    fill="gray"
                />
            </AreaChart>
        </ResponsiveContainer>
        }
        {
            erstOpen &&
        <ResponsiveContainer className="responsive">
            <AreaChart data={coronadata_erst}>
                <CartesianGrid strokeDasharray="2 2"/>
                <XAxis dataKey="name" stroke="gray"/>
                <YAxis/>
                <Tooltip/>
                <Area
                    type="monotone"
                    dataKey="uv"
                    fill="green"
                />
               
            </AreaChart>
        </ResponsiveContainer>
        }
        {
            zweitOpen &&
        <ResponsiveContainer className="responsive">
            <AreaChart data={coronadata_zweit}>
                <CartesianGrid strokeDasharray="2 2"/>
                <XAxis dataKey="name" stroke="gray"/>
                <YAxis/>
                <Tooltip/>
                <Area
                    type="monotone"
                    dataKey="uv"
                    fill="green"
                />
                 <Area
                    type="monotone"
                    dataKey="pv"
                    fill="gray"
                />
            </AreaChart>
        </ResponsiveContainer>
        }
        {
            auffrischungOpen &&
        <ResponsiveContainer className="responsive">
            <AreaChart data={coronadata_auffrischung}>
                <CartesianGrid strokeDasharray="2 2"/>
                <XAxis dataKey="name" stroke="gray"/>
                <YAxis/>
                <Tooltip/>
                <Area
                    type="monotone"
                    dataKey="uv"
                    fill="green"
                />
                 <Area
                    type="monotone"
                    dataKey="pv"
                    fill="gray"
                />
            </AreaChart>
        </ResponsiveContainer>
        }
        </CardHolder>
    </Container>
  )
}

export default Chart
Roman
  • 137
  • 1
  • 14

1 Answers1

0

To achieve this you need to define the .open class in the styled-component Header with attrs. Then pass a boolean into the Header style to switch a .open class.

How to use it attrs Documentation

I created a simple example.

Edit dazziling-code

Anton
  • 8,058
  • 1
  • 9
  • 27
  • Thank you Anton for your engagement, that was new information for me. But it not really brings a solution for my problem, because, when I do it this way he changes the style from every header. I tried to fix this with switch case, and also with writing my script in another way, but nothing works. It is so, that the first Header should have per default the class "open" and when another Header is clicked should this have the class "open". – Roman Feb 16 '22 at 14:39
  • Now i understood what you need. The best way to solve this problem is, set a handler on the parent element to delegate it. In this case, we have one handler opposite handler for each elements. In **useState** i use a value instead boolean. When comparing value from array with state we get boolean and pass to the styled-component. I updated snippet. – Anton Feb 16 '22 at 16:11