以表格形状创建时间线

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

我正在尝试创建一个非常具体的组件,应该如下所示:

我给它一个包含 id、日期的数组,它应该以时间线方式显示事件,但也以表格方式显示事件,因为每个事件必须放置在月份内,根据日期具有不同的间距。最重要的是,表格下方应该有一个单选按钮与其事件对齐(onClick 事件应该使单选按钮处于活动状态)。

到目前为止,我成功地完成了时间线和事件,但它们是相等的,而不是在表格中。

这就是它的样子:

这就是代码的样子(使用 MUI 和 Minimal 模板):

import { useState } from 'react';
// mui
import { Box, Stack, Radio, FormControlLabel, FormControl, RadioGroup, Grid, Fab, Tooltip, Divider } from "@mui/material";
// components
import ScanCarousel from "./scan-carousel";

// ----------------------------------------------------------------------

const myObject = [
  {
    id: 1,
    date: "10/10/2021",
    label: "normal",
    scan: [
      '/assets/images/mock/front1.png',
      '/assets/images/mock/back1.png',
      '/assets/images/mock/lside1.png',
      '/assets/images/mock/rside1.png',
    ],
  },
  {
    id: 2,
    date: "11/10/2021",
    label: "critical",
    scan: [
      '/assets/images/mock/front2.png',
      '/assets/images/mock/back2.png',
      '/assets/images/mock/lside2.png',
      '/assets/images/mock/rside2.png',
    ],
  },
  {
    id: 3,
    label: "normal",
    date: "12/10/2021",
    scan: [
      '/assets/images/mock/front3.png',
      '/assets/images/mock/back3.png',
      '/assets/images/mock/lside3.png',
      '/assets/images/mock/rside3.png',
    ],
  },
];

// ----------------------------------------------------------------------

const ScanTimeline = () => {

  const [images, setImages] = useState(myObject[0].scan);
  const [value, setValue] = useState(myObject[2].date);
  const [openTooltips, setOpenTooltips] = useState({});

  const handleChange = (event) => {
    setValue(event.target.value);
  };

  const handleClick = (item) => {
    setOpenTooltips(prev => ({
      ...Object.keys(prev).reduce((acc, key) => {
        acc[key] = false;
        return acc;
      }, {}),
      [item.id]: !prev[item.id]
    })); setImages(item.scan);
    setValue(item.date);
  };

  return (
    <>
      <Stack direction='row'>
        <Box>
          <FormControl>
            <RadioGroup
              row
              value={value}
              onChange={handleChange}
            >
              {myObject.map((item) => (
                <Stack direction='column' key={item.id} alignItems='flex-start'>
                  <Stack direction='row' alignItems='center'>
                    <Fab
                      onClick={() => handleClick(item)}
                      aria-label="add"
                      size="small"
                      sx={{
                        color: 'grey',
                        backgroundColor: 'transparent',
                        border: `2px solid ${item.label === 'normal' ? '#0BE2CF' : "pink"}`,
                        boxShadow: 'none',
                        "&:hover": {
                          backgroundColor: "transparent"
                        }
                      }}>
                      {item.id}
                    </Fab>
                    <Divider sx={{ width: "40px", borderBottomWidth: 2 }} />
                  </Stack>
                  <FormControlLabel
                    labelPlacement="top"
                    value={item.date}
                    onClick={() => setImages(item.scan)}
                    sx={{ mr: 0, ml: "2px" }}
                    control={
                      <Tooltip
                        open={openTooltips[item.id] || false}
                        onOpen={() => setOpenTooltips(prev => ({ ...prev, [item.id]: true }))}
                        onClose={() => setOpenTooltips(prev => ({ ...prev, [item.id]: false }))}
                        title={item.date}
                      >
                        <Radio
                          sx={{
                            color: item.label === 'normal' ? '#0BE2CF' : "pink",
                            '&.Mui-checked': {
                              color: item.label === 'normal' ? '#0BE2CF ' : "pink",
                            },
                          }}
                        />
                      </Tooltip>}
                  />
                </Stack>
              ))
              }
            </RadioGroup>
          </FormControl>
        </Box>
      </Stack>
      <Grid container>
        <ScanCarousel previousScan={images} currentScan={myObject[2].scan} />
      </Grid>
    </>

  );
};

export default ScanTimeline;

其范围是,单击事件后,您还可以更改时间线下轮播/滑块的内容。

我不是在找人来编码整个事情,而是更多地寻找如何实现这个棘手组件的想法,一些方向,因为到目前为止,经过长时间的反思,我真的不知道从哪里开始。

谢谢你。

javascript reactjs html-table timeline
1个回答
0
投票

好吧,最终创建它的方法是调整定位,这是我根据自己的代码做到的:

    <div style={{ width: `${monthsBetween.length * 150}px` }}>
        <Stack direction='row' sx={{ width: `${monthsBetween.length * 150}px`, p: 1.5, pl: 0, border: '1px solid lightgrey', borderRadius: '5px', position: 'relative' }}>
          {monthsBetween.map((month, index) => (
            <Box key={index} >
              <Typography sx={{ position: 'absolute', top: '-35px', left: `calc(150px * ${index + 1})`, transform: 'translateX(-50%)', textTransform: 'uppercase' }}>{month}</Typography>
              <Divider orientation='vertical' sx={{ position: 'absolute', top: '0', left: `calc(150px * ${index + 1})` }} />
            </Box>
          ))}
          <Divider sx={{ width: "100%", backgroundColor: 'lightgray', position: 'absolute', top: '50%', left: 0 }} />
          <Box>
            <FormControl>
              <RadioGroup
                row
                value={value}
                onChange={handleChange}
              >
                {myObject.map((item, index) => (
                  <Stack
                    direction='column'
                    key={item.id}
                    alignItems='flex-start'
                    sx={{
                      left: `calc(500px * ${index + 1})`,
                      position: 'absolute',
                    }}>
                    <Stack direction='row' alignItems='center'>
                      <Fab
                        onClick={() => handleClick(item)}
                        aria-label="add"
                        size="small"
                        sx={{
                          minHeight: '30px',
                          minWidth: '30px',
                          width: '30px',
                          height: '30px',
                          color: 'grey',
                          backgroundColor: 'white',
                          border: `2px solid ${item.label === 'normal' ? '#0BE2CF' : "pink"}`,
                          boxShadow: 'none',
                          "&:hover": {
                            backgroundColor: "white"
                          }
                        }}>
                        {item.id}
                      </Fab>
                    </Stack>
                    <FormControlLabel
                      labelPlacement="top"
                      value={item.date}
                      onClick={() => setImages(item.scan)}
                      sx={{ mr: 0, ml: "-3px", bottom: "-50px", position: "absolute" }}
                      control={
                        <Tooltip
                          open={openTooltips[item.id] || false}
                          onOpen={() => setOpenTooltips(prev => ({ ...prev, [item.id]: true }))}
                          onClose={() => setOpenTooltips(prev => ({ ...prev, [item.id]: false }))}
                          title={item.date}
                        >
                          <Radio
                            sx={{
                              color: item.label === 'normal' ? '#0BE2CF' : "pink",
                              '&.Mui-checked': {
                                color: item.label === 'normal' ? '#0BE2CF ' : "pink",
                              },
                            }}
                          />
                        </Tooltip>}
                    />
                  </Stack>
                ))
                }
              </RadioGroup>
            </FormControl>
          </Box>
        </Stack >
      </div>

我只需要找出一个算法来确定时间线上每个按钮的确切位置,并找到一种方法使溢出工作(因为到目前为止它使月份文本消失..)

这是结果:

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