朝活146日目 日付ごとに表示

んー
潮位をどこに表示するかで迷う。

現状はポイントを選ぶと7日分のデータが出てくる。
羅列されてるから見にくいっちゃ見にくいんだよなー

週間予報、各日付のタブとかで出し入れするかなー?

コパイロットにしつこく聞いてみたらそれっぽいコードが出てきた


既存のOrdersコンポーネントをMUIのタブで週間予報を表示するように書き換えることができます。以下にその方法を示します。

まず、必要なMUIコンポーネントをインポートします:

import Tabs from '@mui/material/Tabs';
import Tab from '@mui/material/Tab';
import Box from '@mui/material/Box';

次に、タブの状態を管理するためのuseStateフックを設定します:

const [value, setValue] = useState(0);

handleChange関数を作成して、タブが切り替えられたときに状態を更新します:

const handleChange = (event: React.SyntheticEvent, newValue: number) => {setValue(newValue);};

最後に、TabsとTabコンポーネントを使用してタブを作成し、Boxコンポーネントを使用して各タブの内容を表示します:

<Box sx={{ width: '100%' }}>
  <Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
    <Tabs value={value} onChange={handleChange} aria-label="basic tabs example">
      {waveData && 'time' in waveData && waveData.time.map((time, index) => (
        <Tab label={time} key={index} />
      ))}
    </Tabs>
  </Box>
  {waveData && 'time' in waveData && waveData.time.map((time, index) => (
    value === index && (
      <Box key={index}>
        {/* Day Content */}
        <Table size="small">
          <TableHead>
            <TableRow>
              <TableCell>時間</TableCell>
              <TableCell>波の向き</TableCell>
              <TableCell>うねりの高さ</TableCell>
              <TableCell>風速(m/s)</TableCell>
              <TableCell>風向き</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {/* Table Content */}
          </TableBody>
        </Table>
      </Box>
    )
  ))}
</Box>

このコードでは、タブが切り替えられるとhandleChange関数が呼び出され、value状態が更新されます。その結果、選択されたタブに対応する内容が表示されます。

この基本的な実装を、あなたのOrdersコンポーネントに適用することで、日付ごとの予報をタブで表示することが可能です。ただし、具体的な実装はあなたのデータ構造と要件によります。


これだと日付じゃなくて、時間ごとに出力されちゃってる。

さらに議論して、いい感じになった

<Box sx={{ width: '100%' }}>
      <Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
        <Tabs value={value} onChange={handleChange} aria-label="wave data tabs">
          {dates.map((date, index) => (
            <Tab label={date} key={index} />
          ))}
        </Tabs>
      </Box>
      {dates.map((date, index) => (
        <div role="tabpanel" hidden={value !== index} key={index}>
          <Table size="small">
            <TableHead>
              <TableRow>
                <TableCell>時間</TableCell>
                <TableCell>波の向き</TableCell>
                <TableCell>うねりの高さ</TableCell>
                <TableCell>風速(m/s)</TableCell>
                <TableCell>風向き</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {waveData && 'time' in waveData && waveData.time && waveData.time.map((time, idx) => {
                if (time.startsWith(date)) {
                  return (
                    <TableRow key={idx}>
                      <TableCell>{time.split('T')[1]}</TableCell>
                      <TableCell>{waveData.swell_wave_height[idx]}</TableCell>
                      <TableCell>{waveData.swell_wave_direction[idx]}</TableCell>
                      {windData && 'time' in windData && windData.time[idx] === time && (
                        <>
                          <TableCell>{windData.wind_speed_10m[idx]}</TableCell>
                          <TableCell>{getDirectionFromAngle(windData.wind_direction_10m[idx])}°</TableCell>
                        </>
                      )}
                    </TableRow>
                  );
                }
                return null;
              })}
            </TableBody>
          </Table>
        </div>
      ))}
    </Box>


ちゃんと表示されてる!!
本当に便利な世の中になったなぁー
ChatGPTなかったら多分1日以上掛かってるはず💦

ただ、ちゃんと理解せずに貼っつけちゃってる。。。
この日付ごとに区切る方法を紐解いてみる

   // 日付ごとのデータを抽出
  const dates: string[] = [];
// waveData が undefined でなく、WaveData 型のインスタンスであるかを確認
  if (waveData && 'time' in waveData) {  // 型ガードを追加
    for (const timestamp of waveData.time) {
      const date = timestamp.split('T')[0];
      if (!dates.includes(date)) {
        dates.push(date);
      }
    }
  }

waveData.timeをtimestampとして扱いますー
Tの文字で区切って、最初の要素をdateとしますー
datesの中にdateの値がなかったらPushする。

ちゃんと読んだらわかりやすかった。

後の説明は任せた!


このコードが特定の日付のデータのみを表示する理由は、`if (time.startsWith(date))` 条件によるフィルタリングにあります。この条件文は、各時刻データが選択された日付で始まるかどうかをチェックします。ここで使用される `startsWith` メソッドは、文字列が指定された文字列で始まるかどうかを確認し、それに基づいて真偽値を返します。

詳細解説:

  1. 日付のマッピング (`dates.map`):

    • `dates` 配列は、`time` 配列から取得されたすべてのユニークな日付を含みます。

    • `dates` 配列の各日付に対して、`map` 関数が繰り返し実行されます。この関数内で、各日付に関連するタブパネルが生成されます。

  2. 日付に基づいたデータのフィルタリング:

    • `waveData.time.map` は、`waveData` の `time` 配列を反復処理し、各時刻エントリに対して関数を適用します。

    • `if (time.startsWith(date))` は、`time` の値が現在処理中の `date` で始まるかどうかをチェックします。つまり、この条件はその日付に属するデータのみを処理するようにします。

  3. タイムスタンプの処理:

    • `time.split('T')[1]` は ISO 8601 形式のタイムスタンプ(例: "2024-05-03T00:00")を分割し、時間部分("00:00")のみを抽出します。

  4. 条件付きレンダリング:

    • `hidden={value !== index}` は、選択されているタブのインデックスが現在のインデックスと一致しない場合にコンテンツを非表示にします。これにより、アクティブなタブに対応するコンテンツのみが表示されます。

  5. 追加の風情報:

    • `{windData && 'time' in windData && windData.time[idx] === time && (...)}` は、`windData` オブジェクトが存在し、時間が一致する場合にのみ風速と風向きのデータを表示します。

この構造により、ユーザーがタブを切り替えるたびに、対応する日付の波情報が表示されるようになります。それぞれの日付ごとに異なるテーブルが生成され、適切なデータがその中に表示されるわけです。


今度は週間予報が見れなくなっちゃったので、週間予報のページにするか、タブにするか。。。

ページにしちゃうとなんかかさばる気がするんだよなー
また明日考えよっかな。

今日は数年ぶりの友達とドライブー

行ってきます!


この記事が気に入ったらサポートをしてみませんか?