https://opendata.resas-portal.go.jp/docs/api/v1/prefectures.html
現在こちらのAPIを使って県名のチェックボックスをチェックしたらその県名の県名コードから人口を取り出すAPIを叩いてグラフに表示させるwebページをReactを用いて開発をしております。
ビジュアルは以下の通りです。
そこで質問なのですが
ABCD…のように他の県名のボタンを押したらそのグラフを動的に表示してチェックボックスを外した箇所だけのデータを消す方法をご教授願いたいです。
おそらくチェックボックスのkeyによって消すデータを決定するしかないと思うのですが、何通りの方法も試したのですが答えにたどり着くことができませんでした。
index.tsx
1import React, { useEffect, useState } from "react"; 2import { getPrefectureData } from "./api/prefecture"; 3import { getPopulationData } from "./api/population"; 4import HighchartsReact from "highcharts-react-official"; 5 6interface PrefectureInfo { 7 prefCode: number; 8 prefName: string; 9} 10type PopulationInfo = { 11 year: number; 12 value: number; 13}; 14 15export default function index() { 16 const [prefectures, setPrefectures] = useState<PrefectureInfo[]>([]); 17 const [populations, setPopulations] = useState<PopulationInfo[]>([]); 18 const [selectedPopulations, setSelectedPopulations] = useState<number[]>([]); 19 const [checkedIds, setCheckedIds] = useState<number[]>([]); 20 const [checkedName, setCheckedName] = useState<string>(); 21 const [graphData, setGraphData] = useState< 22 { data: number[]; name: string | undefined }[] 23 >([]); 24 25 const options = { 26 chart: { 27 type: "spline", 28 }, 29 title: { 30 text: "人口グラフ", 31 }, 32 xAxis: { 33 categories: [ 34 "1960", 35 "1965", 36 "1970", 37 "1975", 38 "1980", 39 "1985", 40 "1990", 41 "1995", 42 "2000", 43 "2005", 44 "2010", 45 "2015", 46 "2020", 47 "2025", 48 "2030", 49 "2035", 50 "2040", 51 "2045", 52 ], 53 }, 54 series: graphData, 55 }; 56 57 //こちらで県名のuAPIを取得しております。 58 useEffect(() => { 59 const fetchPrefecture = async () => { 60 const res = getPrefectureData.FetchPrefecture(); 61 62 await res.then((data) => { 63 setPrefectures(data); 64 }); 65 }; 66 fetchPrefecture(); 67 }, []); 68 69 70 useEffect(() => { 71 const fetchPopulation = async () => { 72 //こちらで自分がチェックした値のcitycodeでresasのAPIを叩いて人口をgetします。 73 74 const res = await Promise.all( 75 checkedIds?.map( 76 async (id: number) => await getPopulationData.FetchPopulation(id) 77 ) 78 ); 79 //もしレスポンスがなかったら????にします 80 if (res.length === 0) { 81 setPopulations([]); 82 } 83 //こちらで人口のデータを最終的にstateで保管します。 84 await Promise.all(res.map((item) => setPopulations(item[0].data))); 85 }; 86 fetchPopulation(); 87 }, [checkedIds]); 88 89 useEffect(() => { 90 //保管した人口のstateのをhichartの形式(data:[11,22,33])のようなにするために人口データを加工します 91 const data = populations?.map((item) => { 92 return item.value; 93 }); 94 //もし加工してstateで管理します。こちらの値をグラフで表示します。 95 if (data && checkedName) { 96 setGraphData([...graphData, { data, name: checkedName }]); 97 } 98 99 if (populations.length === 0) { 100 setGraphData([]); 101 } 102 }, [populations]); 103 104 const handleChange = ( 105 e: React.FormEvent<HTMLInputElement>, 106 prefectureName: string 107 ) => { 108 if ((e.target as HTMLInputElement).checked === true) { 109 const deleteDuplicateId = new Set([...checkedIds]); 110 setCheckedIds([...deleteDuplicateId, Number(e.currentTarget.value)]); 111 112 setCheckedName(prefectureName); 113 114 } else if ((e.target as HTMLInputElement).checked === false) { 115 const removedId = Number(e.currentTarget.value); 116 const newIds = checkedIds.filter((value) => { 117 return value !== removedId; 118 }); 119 setCheckedIds(newIds); 120 121 setCheckedName(""); 122 } 123 }; 124 125 return ( 126 <div className="mt-10"> 127 <h1 className="w-9/12 m-auto"> 128 <span className="border-2 border-black">都道府県</span> 129 </h1> 130 <div className="flex flex-wrap w-9/12 m-auto"> 131 {prefectures?.map((item) => { 132 return ( 133 <label key={item.prefCode} className="flex mr-14 mt-4"> 134 <input 135 type="checkbox" 136 value={item.prefCode} 137 onChange={(e) => handleChange(e, item.prefName)} 138 /> 139 <div>{item.prefName}</div> 140 </label> 141 ); 142 })} 143 </div> 144 <div className="w-9/12 m-auto mt-28"> 145 <HighchartsReact constructorType={"chart"} options={options} /> 146 </div> 147 </div> 148 ); 149} 150
populationAPI
1import { PopulationInfo } from "./types"; 2 3class Population { 4 FetchPopulation = async (code: number) => { 5 const res = await fetch( 6 `https://opendata.resas-portal.go.jp/api/v1/population/composition/perYear?prefCode=${code}`, 7 { 8 method: "GET", 9 headers: { 10 "X-API-KEY": `${process.env.NEXT_PUBLIC_API_KEY}`, 11 }, 12 } 13 ); 14 return await res.json().then((item: PopulationInfo) => item.result.data); 15 }; 16} 17 18export const getPopulationData = new Population();
PrefecutureAPI
1import { PrefectureInfo } from "./types"; 2 3class Prefecutures { 4 FetchPrefecture = async () => { 5 const res = await fetch( 6 "https://opendata.resas-portal.go.jp/api/v1/prefectures", 7 { 8 method: "GET", 9 headers: { 10 "X-API-KEY": `${process.env.NEXT_PUBLIC_API_KEY}`, 11 }, 12 } 13 ); 14 return await res.json().then((item: PrefectureInfo) => item.result); 15 }; 16} 17 18export const getPrefectureData = new Prefecutures(); 19
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/02/28 22:25
2021/02/28 22:38