首頁數據展示

排版

現在做首頁的排版,依舊是偷antd里面的東西

使用card包裹list的樣式

import React from 'react'
import 'axios'
import { Card, Col, Row, List } from 'antd'
import { EditOutlined, EllipsisOutlined, SettingOutlined } from '@ant-design/icons';
import { Avatar } from 'antd';
const { Meta } = Card;function Home() {return (<div><Row gutter={16}><Col span={8}><Card title="用戶最常瀏覽" variant="border"><Listsize="small"dataSource={['qq', 'wx', 'dy']}renderItem={(item) => <List.Item>{item}</List.Item>}/></Card></Col><Col span={8}><Card title="用戶點贊最多" variant="border"><Listsize="small"dataSource={['qq', 'wx', 'dy']}renderItem={(item) => <List.Item>{item}</List.Item>}/></Card></Col><Col span={8}><Cardcover={<imgalt="example"src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png"/>}actions={[<SettingOutlined key="setting" />,<EditOutlined key="edit" />,<EllipsisOutlined key="ellipsis" />,]}><Metaavatar={<Avatar src="https://api.dicebear.com/7.x/miniavs/svg?seed=8" />}title="Card title"description="This is the description"/></Card></Col></Row></div>)
}export default Home

數據

接下來就是寫數據請求之類的了

做后端數據請求+顯示:

import React, { useEffect } from 'react'
import 'axios'
import { Card, Col, Row, List } from 'antd'
import { EditOutlined, EllipsisOutlined, SettingOutlined } from '@ant-design/icons';
import { Avatar } from 'antd';
import axios from 'axios';
import { useState } from'react'
const { Meta } = Card;function Home() {const [viewList, setviewList] = useState([])const [starList, setstarList] = useState([])useEffect(()=>{axios.get("http://localhost:3000/news?publishState=2&_expand=category&_sort=view&_order=desc&_limit=6").then(res=>{setviewList(res.data)}).catch(err => {console.error('Request failed', err)})},[])useEffect(()=>{axios.get("http://localhost:3000/news?publishState=2&_expand=category&_sort=star&_order=desc&_limit=6").then(res=>{setstarList(res.data)}).catch(err => {console.error('Request failed', err)})},[])const {username,region,role:{roleName}} = JSON.parse(localStorage.getItem('token'))return (<div><Row gutter={16}><Col span={8}><Card title="用戶最常瀏覽" variant="border"><Listsize="small"dataSource={viewList}renderItem={(item) => <List.Item><a href={`#/news-manage/preview/${item.id}`}>{item.title}</a></List.Item>}/></Card></Col><Col span={8}><Card title="用戶點贊最多" variant="border"><Listsize="small"dataSource={starList}renderItem={(item) => <List.Item><a href={`#/news-manage/preview/${item.id}`}>{item.title}</a></List.Item>}/></Card></Col><Col span={8}><Cardcover={<imgalt="example"src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png"/>}actions={[<SettingOutlined key="setting" />,<EditOutlined key="edit" />,<EllipsisOutlined key="ellipsis" />,]}><Metaavatar={<Avatar src="https://api.dicebear.com/7.x/miniavs/svg?seed=8" />}title={username}description={<div><b>{region?region:'全球'}</b><span style={{paddingLeft:"30px" }}>{roleName}</span> </div>}/></Card></Col></Row></div>)
}export default Home

柱狀圖

要做柱狀圖,需要用到一個開源的可視化的庫:Apache EChartshttps://echarts.apache.org/zh/index.html

echarts也是需要下載的:

npm i --save echarts

使用相對來說簡單,先做好模塊的初始化,然后進行導入,復制粘貼就好了:

import React, { useEffect } from 'react'
import 'axios'
import { Card, Col, Row, List } from 'antd'
import { EditOutlined, EllipsisOutlined, SettingOutlined } from '@ant-design/icons';
import { Avatar } from 'antd';
import axios from 'axios';
import * as Echarts from 'echarts';
// 把所有東西都導進打模塊中
import { useState } from'react'
const { Meta } = Card;function Home() {const [viewList, setviewList] = useState([])const [starList, setstarList] = useState([])useEffect(()=>{axios.get("http://localhost:3000/news?publishState=2&_expand=category&_sort=view&_order=desc&_limit=6").then(res=>{setviewList(res.data)}).catch(err => {console.error('Request failed', err)})},[])useEffect(()=>{axios.get("http://localhost:3000/news?publishState=2&_expand=category&_sort=star&_order=desc&_limit=6").then(res=>{setstarList(res.data)}).catch(err => {console.error('Request failed', err)})},[])useEffect(()=>{var myChart = Echarts.init(document.getElementById('main'));// 指定圖表的配置項和數據var option = {title: {text: 'ECharts 入門示例'},tooltip: {},legend: {data: ['銷量']},xAxis: {data: ['襯衫', '羊毛衫', '雪紡衫', '褲子', '高跟鞋', '襪子']},yAxis: {},series: [{name: '銷量',type: 'bar',data: [5, 20, 36, 10, 10, 20]}]};// 使用剛指定的配置項和數據顯示圖表。myChart.setOption(option);},[])const {username,region,role:{roleName}} = JSON.parse(localStorage.getItem('token'))return (<div><Row gutter={16}><Col span={8}><Card title="用戶最常瀏覽" variant="border"><Listsize="small"dataSource={viewList}renderItem={(item) => <List.Item><a href={`#/news-manage/preview/${item.id}`}>{item.title}</a></List.Item>}/></Card></Col><Col span={8}><Card title="用戶點贊最多" variant="border"><Listsize="small"dataSource={starList}renderItem={(item) => <List.Item><a href={`#/news-manage/preview/${item.id}`}>{item.title}</a></List.Item>}/></Card></Col><Col span={8}><Cardcover={<imgalt="example"src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png"/>}actions={[<SettingOutlined key="setting" />,<EditOutlined key="edit" />,<EllipsisOutlined key="ellipsis" />,]}><Metaavatar={<Avatar src="https://api.dicebear.com/7.x/miniavs/svg?seed=8" />}title={username}description={<div><b>{region?region:'全球'}</b><span style={{paddingLeft:"30px" }}>{roleName}</span> </div>}/></Card></Col></Row><div id="main" style={{width:"100%",height:"400px",marginTop:"30px",}}></div></div>)
}export default Home

接下來做樣式的統一處理,引入lodash庫

import React, { useEffect, useRef } from 'react'
import 'axios'
import { Card, Col, Row, List } from 'antd'
import {EditOutlined,EllipsisOutlined,SettingOutlined,
} from '@ant-design/icons'
import { Avatar } from 'antd'
import axios from 'axios'
import * as Echarts from 'echarts'
// 把所有東西都導進打模塊中
import { useState } from 'react'
import _ from 'lodash'
const { Meta } = Cardfunction Home() {const [viewList, setviewList] = useState([])const [starList, setstarList] = useState([])const barRef = useRef(null)useEffect(() => {axios.get('http://localhost:3000/news?publishState=2&_expand=category&_sort=view&_order=desc&_limit=6').then((res) => {setviewList(res.data)}).catch((err) => {console.error('Request failed', err)})}, [])useEffect(() => {axios.get('http://localhost:3000/news?publishState=2&_expand=category&_sort=star&_order=desc&_limit=6').then((res) => {setstarList(res.data)}).catch((err) => {console.error('Request failed', err)})}, [])useEffect(() => {axios.get('/news?publishState=2&_expand=category').then((res) => {console.log(res.data)renderBarView(_.groupBy(res.data, (item) => item.category.title))}).catch((err) => {console.error('Request failed', err)})const renderBarView = (obj) => {var myChart = Echarts.init(barRef.current)// 指定圖表的配置項和數據var option = {title: {text: '新聞分類圖示',},tooltip: {},legend: {data: ['數量'],},xAxis: {data: Object.keys(obj),},yAxis: {},series: [{name: '數量',type: 'bar',// 把數組映射成長度data: Object.values(obj).map((item) => item.length),},],}// 使用剛指定的配置項和數據顯示圖表。myChart.setOption(option)return () => {myChart.dispose()}}}, [])const {username,region,role: { roleName },} = JSON.parse(localStorage.getItem('token'))return (<div><Row gutter={16}><Col span={8}><Card title="用戶最常瀏覽" variant="border"><Listsize="small"dataSource={viewList}renderItem={(item) => (<List.Item><a href={`#/news-manage/preview/${item.id}`}>{item.title}</a></List.Item>)}/></Card></Col><Col span={8}><Card title="用戶點贊最多" variant="border"><Listsize="small"dataSource={starList}renderItem={(item) => (<List.Item><a href={`#/news-manage/preview/${item.id}`}>{item.title}</a></List.Item>)}/></Card></Col><Col span={8}><Cardcover={<imgalt="example"src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png"/>}actions={[<SettingOutlined key="setting" />,<EditOutlined key="edit" />,<EllipsisOutlined key="ellipsis" />,]}><Metaavatar={<Avatar src="https://api.dicebear.com/7.x/miniavs/svg?seed=8" />}title={username}description={<div><b>{region ? region : '全球'}</b><spanstyle={{paddingLeft: '30px',}}>{roleName}</span></div>}/></Card></Col></Row><divref={barRef}style={{width: '100%',height: '400px',marginTop: '30px',}}></div></div>)
}export default Home

現在的分類做出來了,但是沒有做響應式,所以優化一下

響應式

?進行響應式的優化:

import React, { useEffect, useRef } from 'react'
import { Card, Col, Row, List } from 'antd'
import {EditOutlined,EllipsisOutlined,SettingOutlined,
} from '@ant-design/icons'
import { Avatar } from 'antd'
import axios from 'axios'
import * as Echarts from 'echarts'
// 把所有東西都導進打模塊中
import { useState } from 'react'
import _ from 'lodash'
const { Meta } = Cardfunction Home() {const [viewList, setviewList] = useState([])const [starList, setstarList] = useState([])const barRef = useRef(null)useEffect(() => {axios.get('http://localhost:3000/news?publishState=2&_expand=category&_sort=view&_order=desc&_limit=6').then((res) => {setviewList(res.data)}).catch((err) => {console.error('Request failed', err)})}, [])useEffect(() => {axios.get('http://localhost:3000/news?publishState=2&_expand=category&_sort=star&_order=desc&_limit=6').then((res) => {setstarList(res.data)}).catch((err) => {console.error('Request failed', err)})}, [])useEffect(() => {axios.get('/news?publishState=2&_expand=category').then((res) => {renderBarView(_.groupBy(res.data, (item) => item.category.title))})return ()=>{window.onresize = null}}, [])const renderBarView = (obj) => {var myChart = Echarts.init(barRef.current)// 指定圖表的配置項和數據var option = {title: {text: '新聞分類圖示',},tooltip: {},legend: {data: ['數量'],},xAxis: {data: Object.keys(obj),axisLabel: {rotate: "60",//強制顯示interval: 0,},},yAxis: {// 讓顯示全是整數minInterval: 1},series: [{name: '數量',type: 'bar',// 把數組映射成長度data: Object.values(obj).map((item) => item.length),},],}// 使用剛指定的配置項和數據顯示圖表。myChart.setOption(option)window.onresize =()=>{//每次自動觸發myChart.resize()} return () => {myChart.dispose()}}const {username,region,role: { roleName },} = JSON.parse(localStorage.getItem('token'))return (<div><Row gutter={16}><Col span={8}><Card title="用戶最常瀏覽" variant="border"><Listsize="small"dataSource={viewList}renderItem={(item) => (<List.Item><a href={`#/news-manage/preview/${item.id}`}>{item.title}</a></List.Item>)}/></Card></Col><Col span={8}><Card title="用戶點贊最多" variant="border"><Listsize="small"dataSource={starList}renderItem={(item) => (<List.Item><a href={`#/news-manage/preview/${item.id}`}>{item.title}</a></List.Item>)}/></Card></Col><Col span={8}><Cardcover={<imgalt="example"src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png"/>}actions={[<SettingOutlined key="setting" />,<EditOutlined key="edit" />,<EllipsisOutlined key="ellipsis" />,]}><Metaavatar={<Avatar src="https://api.dicebear.com/7.x/miniavs/svg?seed=8" />}title={username}description={<div><b>{region ? region : '全球'}</b><spanstyle={{paddingLeft: '30px',}}>{roleName}</span></div>}/></Card></Col></Row><divref={barRef}style={{width: '100%',height: '400px',marginTop: '30px',}}></div></div>)
}export default Home

用onresize即可

餅狀圖

最開始寫的代碼有問題,會出現顯示不及時或者顯示出來的格式是錯的的問題:

// import React, { useEffect, useRef, useState } from 'react';
// import { Card, Col, Row, List, Drawer } from 'antd';
// import {
//   EditOutlined,
//   EllipsisOutlined,
//   SettingOutlined,
// } from '@ant-design/icons';
// import { Avatar } from 'antd';
// import axios from 'axios';
// import * as Echarts from 'echarts';
// import _ from 'lodash';// const { Meta } = Card;// function Home() {
//   const [viewList, setviewList] = useState([]);
//   const [starList, setstarList] = useState([]);
//   const [visible, setvisible] = useState(false);//   const barRef = useRef(null);
//   const pieRef = useRef(null);//   useEffect(() => {
//     axios
//       .get(
//         'http://localhost:3000/news?publishState=2&_expand=category&_sort=view&_order=desc&_limit=6'
//       )
//       .then((res) => {
//         setviewList(res.data);
//       })
//       .catch((err) => {
//         console.error('Request failed', err);
//       });
//   }, []);//   useEffect(() => {
//     axios
//       .get(
//         'http://localhost:3000/news?publishState=2&_expand=category&_sort=star&_order=desc&_limit=6'
//       )
//       .then((res) => {
//         setstarList(res.data);
//       })
//       .catch((err) => {
//         console.error('Request failed', err);
//       });
//   }, []);//   useEffect(() => {
//     let barCleanup;
//     let barResizeHandler;
//     let pieCleanup;
//     let pieResizeHandler;//     const fetchDataAndRender = async () => {
//       try {
//         const res = await axios.get('/news?publishState=2&_expand=category');
//         if (barRef.current) {
//           barCleanup = renderBarView(
//             _.groupBy(res.data, (item) => item.category.title)
//           );
//           barResizeHandler = () => {
//             if (barCleanup) {
//               const myChart = Echarts.getInstanceByDom(barRef.current);
//               if (myChart) {
//                 myChart.resize();
//               }
//             }
//           };
//           window.addEventListener('resize', barResizeHandler);
//         }
//       } catch (err) {
//         console.error('Request failed', err);
//       }
//     };//     fetchDataAndRender();//     return () => {
//       if (typeof barCleanup === 'function') {
//         barCleanup();
//       }
//       if (barResizeHandler) {
//         window.removeEventListener('resize', barResizeHandler);
//       }
//       if (typeof pieCleanup === 'function') {
//         pieCleanup();
//       }
//       if (pieResizeHandler) {
//         window.removeEventListener('resize', pieResizeHandler);
//       }
//     };
//   }, []);//   const renderBarView = (obj) => {
//     if (!barRef.current) return;
//     var myChart = Echarts.init(barRef.current);//     // 指定圖表的配置項和數據
//     var option = {
//       title: {
//         text: '新聞分類圖示',
//       },
//       tooltip: {},
//       legend: {
//         data: ['數量'],
//       },
//       xAxis: {
//         data: Object.keys(obj),
//         axisLabel: {
//           rotate: 60,
//           // 強制顯示
//           interval: 0,
//         },
//       },
//       yAxis: {
//         // 讓顯示全是整數
//         minInterval: 1,
//       },
//       series: [
//         {
//           name: '數量',
//           type: 'bar',
//           // 把數組映射成長度
//           data: Object.values(obj).map((item) => item.length),
//         },
//       ],
//     };
//     // 使用剛指定的配置項和數據顯示圖表。
//     myChart.setOption(option);//     return () => {
//       myChart.dispose();
//     };
//   };//   const renderPieView = (obj) => {
//     if (!pieRef.current) return;
//     var myChart = Echarts.init(pieRef.current);//     var option = {
//       title: {
//         text: 'Referer of a Website',
//         subtext: 'Fake Data',
//         left: 'center',
//       },
//       tooltip: {
//         trigger: 'item',
//       },
//       legend: {
//         orient: 'vertical',
//         left: 'left',
//       },
//       series: [
//         {
//           name: 'Access From',
//           type: 'pie',
//           radius: '50%',
//           data: [
//             { value: 1048, name: 'Search Engine' },
//             { value: 735, name: 'Direct' },
//             { value: 580, name: 'Email' },
//             { value: 484, name: 'Union Ads' },
//             { value: 300, name: 'Video Ads' },
//           ],
//           emphasis: {
//             itemStyle: {
//               shadowBlur: 10,
//               shadowOffsetX: 0,
//               shadowColor: 'rgba(0, 0, 0, 0.5)',
//             },
//           },
//         },
//       ],
//     };
//     option && myChart.setOption(option);//     const resizeHandler = () => {
//       myChart.resize();
//     };
//     window.addEventListener('resize', resizeHandler);//     return () => {
//       window.removeEventListener('resize', resizeHandler);
//       myChart.dispose();
//     };
//   };//   const tokenData = localStorage.getItem('token');
//   const {
//     username = '',
//     region = '',
//     role: { roleName = '' } = {},
//   } = tokenData ? JSON.parse(tokenData) : {};//   return (
//     <div>
//       <Row gutter={16}>
//         <Col span={8}>
//           <Card title="用戶最常瀏覽" variant="border">
//             <List
//               size="small"
//               dataSource={viewList}
//               renderItem={(item) => (
//                 <List.Item>
//                   <a href={`#/news-manage/preview/${item.id}`}>{item.title}</a>
//                 </List.Item>
//               )}
//             />
//           </Card>
//         </Col>
//         <Col span={8}>
//           <Card title="用戶點贊最多" variant="border">
//             <List
//               size="small"
//               dataSource={starList}
//               renderItem={(item) => (
//                 <List.Item>
//                   <a href={`#/news-manage/preview/${item.id}`}>{item.title}</a>
//                 </List.Item>
//               )}
//             />
//           </Card>
//         </Col>
//         <Col span={8}>
//           <Card
//             cover={
//               <img
//                 alt="example"
//                 src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png"
//               />
//             }
//             actions={[
//               <SettingOutlined
//                 key="setting"
//                 onClick={() => {
//                   setTimeout(() => {
//                     setvisible(true);
//                     //init初始化
//                     renderPieView();
//                   }, 0);
//                 }}
//               />,
//               <EditOutlined key="edit" />,
//               <EllipsisOutlined key="ellipsis" />,
//             ]}
//           >
//             <Meta
//               avatar={
//                 <Avatar src="https://api.dicebear.com/7.x/miniavs/svg?seed=8" />
//               }
//               title={username}
//               description={
//                 <div>
//                   <b>{region ? region : '全球'}</b>
//                   <span
//                     style={{
//                       paddingLeft: '30px',
//                     }}
//                   >
//                     {roleName}
//                   </span>
//                 </div>
//               }
//             />
//           </Card>
//         </Col>
//       </Row>//       <Drawer
//         width="500px"
//         title="個人新聞分類"
//         placement="right"
//         closable={true}
//         onClose={() => {
//           setvisible(false);
//         }}
//         visible={visible}
//       >
//         <div
//           ref={pieRef}
//           style={{
//             width: '100%',
//             height: '400px',
//             marginTop: '30px',
//           }}
//         ></div>
//       </Drawer>//       <div
//         ref={barRef}
//         style={{
//           width: '100%',
//           height: '400px',
//           marginTop: '30px',
//         }}
//       ></div>
//     </div>
//   );
// }// export default Home;

拆特雞皮替告訴我是兩個問題導致的,一是我沒有傳數據給renderPieView(先獲取數據再分組),二是DOM沒有準備好(所以要延時):

<SettingOutlinedkey="setting"onClick={async () => {setvisible(true);// 延遲一點,等 Drawer 動畫打開再渲染圖表setTimeout(async () => {const token = JSON.parse(localStorage.getItem('token'));const username = token?.username;try {const res = await axios.get(`/news?author=${username}&publishState=2&_expand=category`);const groupedData = _.groupBy(res.data, (item) => item.category.title);const pieData = Object.keys(groupedData).map((key) => ({name: key,value: groupedData[key].length,}));renderPieView(pieData);} catch (err) {console.error('Failed to fetch pie data', err);}}, 300); // 等 Drawer 動畫展開后再繪制圖表}}
/>

?點擊圖標時觸發這個異步函數(async),它將打開抽屜并加載圖表數據。打開 Drawer,這是控制抽屜顯示的 visible 狀態。

Drawer 打開時有動畫,如果立即渲染圖表,容器尺寸可能為 0,Echarts 會渲染失敗或圖表不顯示

setTimeout(..., 300) 延遲 300ms 再渲染圖表,確保 Drawer 打開完成、DOM 有尺寸

從本地存儲獲取當前用戶 token 并解析出用戶名,用于之后的請求過濾(只看當前用戶發布的新聞)

使用 lodash 的 groupBy 對新聞按分類標題進行分組,便于做餅圖

修改 renderPieView 函數接收參數為 data(數組形式)?

const renderPieView = (data) => {if (!pieRef.current) return;const myChart = Echarts.init(pieRef.current);const option = {title: {text: '個人新聞分類',subtext: '按分類統計',left: 'center',},tooltip: {trigger: 'item',},legend: {orient: 'vertical',left: 'left',},series: [{name: '新聞數量',type: 'pie',radius: '50%',data: data,emphasis: {itemStyle: {shadowBlur: 10,shadowOffsetX: 0,shadowColor: 'rgba(0, 0, 0, 0.5)',},},},],};myChart.setOption(option);const resizeHandler = () => {myChart.resize();};window.addEventListener('resize', resizeHandler);return () => {window.removeEventListener('resize', resizeHandler);myChart.dispose();};
};

完整代碼:

import React, { useEffect, useRef, useState } from 'react';
import { Card, Col, Row, List, Drawer } from 'antd';
import {EditOutlined,EllipsisOutlined,SettingOutlined,
} from '@ant-design/icons';
import { Avatar } from 'antd';
import axios from 'axios';
import * as Echarts from 'echarts';
import _ from 'lodash';const { Meta } = Card;function Home() {const [viewList, setviewList] = useState([]);const [starList, setstarList] = useState([]);const [visible, setvisible] = useState(false);const barRef = useRef(null);const pieRef = useRef(null);useEffect(() => {axios.get('/news?publishState=2&_expand=category&_sort=view&_order=desc&_limit=6').then((res) => {setviewList(res.data);}).catch((err) => {console.error('Request failed', err);});}, []);useEffect(() => {axios.get('/news?publishState=2&_expand=category&_sort=star&_order=desc&_limit=6').then((res) => {setstarList(res.data);}).catch((err) => {console.error('Request failed', err);});}, []);useEffect(() => {let barCleanup;let barResizeHandler;const fetchDataAndRender = async () => {try {const res = await axios.get('/news?publishState=2&_expand=category');if (barRef.current) {barCleanup = renderBarView(_.groupBy(res.data, (item) => item.category.title));barResizeHandler = () => {if (barCleanup) {const myChart = Echarts.getInstanceByDom(barRef.current);if (myChart) {myChart.resize();}}};window.addEventListener('resize', barResizeHandler);}} catch (err) {console.error('Request failed', err);}};fetchDataAndRender();return () => {if (typeof barCleanup === 'function') {barCleanup();}if (barResizeHandler) {window.removeEventListener('resize', barResizeHandler);}};}, []);const renderBarView = (obj) => {if (!barRef.current) return;var myChart = Echarts.init(barRef.current);var option = {title: {text: '新聞分類圖示',},tooltip: {},legend: {data: ['數量'],},xAxis: {data: Object.keys(obj),axisLabel: {rotate: 60,interval: 0,},},yAxis: {minInterval: 1,},series: [{name: '數量',type: 'bar',data: Object.values(obj).map((item) => item.length),},],};myChart.setOption(option);return () => {myChart.dispose();};};const renderPieView = (data) => {if (!pieRef.current) return;const myChart = Echarts.init(pieRef.current);const option = {title: {text: '個人新聞分類',subtext: '按分類統計',left: 'center',},tooltip: {trigger: 'item',},legend: {orient: 'vertical',left: 'left',},series: [{name: '新聞數量',type: 'pie',radius: '50%',data: data,emphasis: {itemStyle: {shadowBlur: 10,shadowOffsetX: 0,shadowColor: 'rgba(0, 0, 0, 0.5)',},},},],};myChart.setOption(option);const resizeHandler = () => {myChart.resize();};window.addEventListener('resize', resizeHandler);return () => {window.removeEventListener('resize', resizeHandler);myChart.dispose();};};const tokenData = localStorage.getItem('token');const {username = '',region = '',role: { roleName = '' } = {},} = tokenData ? JSON.parse(tokenData) : {};return (<div><Row gutter={16}><Col span={8}><Card title="用戶最常瀏覽" variant="border"><Listsize="small"dataSource={viewList}renderItem={(item) => (<List.Item><a href={`#/news-manage/preview/${item.id}`}>{item.title}</a></List.Item>)}/></Card></Col><Col span={8}><Card title="用戶點贊最多" variant="border"><Listsize="small"dataSource={starList}renderItem={(item) => (<List.Item><a href={`#/news-manage/preview/${item.id}`}>{item.title}</a></List.Item>)}/></Card></Col><Col span={8}><Cardcover={<imgalt="example"src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png"/>}actions={[<SettingOutlinedkey="setting"onClick={async () => {setvisible(true);setTimeout(async () => {const token = JSON.parse(localStorage.getItem('token'));const username = token?.username;try {const res = await axios.get(`/news?author=${username}&publishState=2&_expand=category`);const groupedData = _.groupBy(res.data,(item) => item.category.title);const pieData = Object.keys(groupedData).map((key) => ({name: key,value: groupedData[key].length,}));renderPieView(pieData);} catch (err) {console.error('Failed to fetch pie data', err);}}, 300);}}/>,<EditOutlined key="edit" />,<EllipsisOutlined key="ellipsis" />,]}><Metaavatar={<Avatar src="https://api.dicebear.com/7.x/miniavs/svg?seed=8" />}title={username}description={<div><b>{region ? region : '全球'}</b><spanstyle={{paddingLeft: '30px',}}>{roleName}</span></div>}/></Card></Col></Row><Drawerwidth="500px"title="個人新聞分類"placement="right"closable={true}onClose={() => {setvisible(false);}}visible={visible}><divref={pieRef}style={{width: '100%',height: '400px',marginTop: '30px',}}></div></Drawer><divref={barRef}style={{width: '100%',height: '400px',marginTop: '30px',}}></div></div>);
}export default Home;

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/78983.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/78983.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/78983.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用Set和Map解題思路

前言 Set和Map這兩種數據結構,在解決一些題上&#xff0c;效率很高。跟大家簡單分享一些題以及如何使用Set和Map去解決這些題目。 題目鏈接 136. 只出現一次的數字 - 力扣&#xff08;LeetCode&#xff09; 138. 隨機鏈表的復制 - 力扣&#xff08;LeetCode&#xff09; 舊…

嘗試leaflet+webassemly

前言 筆者在github發現rust版本的leaflet&#xff0c;發現是用wasm-bindgen包裝的&#xff0c;嘗試使用一下 Issues slowtec/leaflet-rshttps://github.com/slowtec/leaflet-rs 正文 準備 新建一個react項目&#xff0c;安裝rsw依賴 pnpm i -D vite-plugin-rsw cargo ins…

機器學習實戰,天貓雙十一銷量與中國人壽保費預測,使用多項式回歸,梯度下降,EDA數據探索,彈性網絡等技術

前言 很多同學學機器學習時總感覺&#xff1a;“公式推導我會&#xff0c;代碼也能看懂&#xff0c;但自己從頭做項目就懵”。 這次我們選了兩個小數據集&#xff0c;降低復雜度&#xff0c;帶大家從頭開始進行分析&#xff0c;建模&#xff0c;預測&#xff0c;可視化等&…

SQL數據庫系統全解析:從入門到實踐

一、數據庫世界入門指南 在數字時代&#xff0c;數據就像新時代的石油&#xff0c;而數據庫系統就是儲存和管理這些寶貴資源的倉庫。對于初學者來說&#xff0c;理解數據庫的基本概念是邁入這個領域的第一步。 數據庫本質上是一個有組織的數據集合&#xff0c;它允許我們高效…

【大模型】圖像生成:StyleGAN3:生成對抗網絡的革命性進化

深度解析StyleGAN3&#xff1a;生成對抗網絡的革命性進化 技術演進與架構創新代際技術對比StyleGAN3架構解析 環境配置與快速入門硬件要求安裝步驟預訓練模型下載 實戰全流程解析1. 圖像生成示例2. 自定義數據集訓練3. 潛在空間操作 核心技術深度解析1. 連續信號建模2. 傅里葉特…

PHP-Cookie

Cookie 是什么&#xff1f; cookie 常用于識別用戶。cookie 是一種服務器留在用戶計算機上的小文件。每當同一臺計算機通過瀏覽器請求頁面時&#xff0c;這臺計算機將會發送 cookie。通過 PHP&#xff0c;您能夠創建并取回 cookie 的值。 設置Cookie 在PHP中&#xff0c;你可…

“Everything“工具 是 Windows 上文件名搜索引擎神奇

01 Everything 和其他搜索引擎有何不同 輕量安裝文件。 干凈簡潔的用戶界面。 快速文件索引。 快速搜索。 快速啟動。 最小資源使用。 輕量數據庫。 實時更新。 官網&#xff1a;https://www.voidtools.com/zh-cn/downloads/ 通過網盤分享的文件&#xff1a;Every…

CSS:選擇器-基本選擇器

文章目錄 1、通配選擇器2、元素選擇器3、類選擇器4、ID選擇器 1、通配選擇器 2、元素選擇器 3、類選擇器 4、ID選擇器

一種動態分配內存錯誤的解決辦法

1、項目背景 一款2年前開發的無線網絡通信軟件在最近的使用過程中出現網絡中傳感器離線的問題&#xff0c;此軟件之前已經使用的幾年了&#xff0c;基本功能還算穩定。這次為什么出了問題。 先派工程師去現場調試一下&#xff0c;初步的結果是網絡信號弱&#xff0c;并且有個別…

React 第三十四節 Router 開發中 useLocation Hook 的用法以及案例詳解

一、useLocation基礎用法 作用&#xff1a;獲取當前路由的 location 對象 返回對象結構&#xff1a; {pathname: "/about", // 當前路徑search: "?namejohn", // 查詢參數&#xff08;URL參數&#xff09;hash: "#contact", …

DeepSeek-Prover-V2-671B最新體驗地址:Prover版僅適合解決專業數學證明問題

DeepSeek-Prover-V2-671B最新體驗地址&#xff1a;Prover版僅適合解決專業數學證明問題 DeepSeek 團隊于 2025 年 4 月 30 日正式在Hugging Face開源了其重量級新作 —— DeepSeek-Prover-V2-671B&#xff0c;這是一款專為解決數學定理證明和形式化推理任務而設計的超大規模語…

tornado_登錄頁面(案例)

目錄 1.基礎知識?編輯 2.腳手架&#xff08;模版&#xff09; 3.登錄流程圖&#xff08;processon&#xff09; 4.登錄表單 4.1后&#xff08;返回值&#xff09;任何值&#xff1a;username/password &#xff08;4.1.1&#xff09;app.py &#xff08;4.1.2&#xff…

Android學習總結之自定義view設計模式理解

面試題 1&#xff1a;請舉例說明自定義 View 中模板方法模式的應用 考點分析 此問題主要考查對模板方法模式的理解&#xff0c;以及該模式在 Android 自定義 View 生命周期方法里的實際運用。 回答內容 模板方法模式定義了一個操作的算法骨架&#xff0c;把一些步驟的實現延…

【Scrapy】簡單項目實戰--爬取dangdang圖書信息

目錄 一、基本步驟 1、新建項目 &#xff1a;新建一個新的爬蟲項目 2、明確目標 &#xff08;items.py&#xff09;&#xff1a;明確你想要抓取的目標 3、制作爬蟲 &#xff08;spiders/xxspider.py&#xff09;&#xff1a;制作爬蟲開始爬取網頁 4、存儲內容 &#xff08;p…

開源CMS系統的SEO優化功能主要依賴哪些插件?

在當今互聯網時代&#xff0c;搜索引擎優化&#xff08;SEO&#xff09;是網站獲取流量的核心手段之一。開源內容管理系統&#xff08;CMS&#xff09;因其靈活性和豐富的插件生態&#xff0c;成為許多開發者和企業的首選。本文將以主流開源CMS為例&#xff0c;深入解析其SEO優…

在 JMeter 中使用 BeanShell 獲取 HTTP 請求體中的 JSON 數據

在 JMeter 中&#xff0c;您可以使用 BeanShell 處理器來獲取 HTTP 請求體中的 JSON 數據。以下是幾種方法&#xff1a; 方法一&#xff1a;使用前置處理器獲取請求體 如果您需要在發送請求前訪問請求體&#xff1a; 添加一個 BeanShell PreProcessor 到您的 HTTP 請求采樣器…

在 WSL (Windows Subsystem for Linux) 中配置和安裝 Linux 環境

在 WSL (Windows Subsystem for Linux) 中配置和安裝 Linux 環境 WSL 允許你在 Windows 上運行 Linux 環境&#xff0c;以下是詳細的配置和安裝指南。 1. 安裝前的準備工作 系統要求 Windows 10 版本 2004 及更高版本(內部版本 19041 及更高版本)或 Windows 11 64 位系統 虛…

AlphaFold蛋白質結構數據庫介紹

AlphaFold Protein Structure Database (AlphaFold DB) 是 DeepMind + EMBL-EBI 合作開發的公開蛋白質結構預測數據庫,是利用 AlphaFold2/AlphaFold3 AI模型 預測的全基因組級蛋白質三維結構庫。 網址: https://alphafold.ebi.ac.uk 項目內容主辦單位DeepMind + EMBL-EBI上線…

3.2goweb框架GORM

GORM 是 Go 語言中功能強大的 ORM&#xff08;對象關系映射&#xff09;框架&#xff0c;支持 MySQL、PostgreSQL、SQLite、SQL Server 等主流數據庫。以下是 GORM 的核心概念和用法詳解&#xff1a; ??一、基礎入門?? 1. 安裝 go get -u gorm.io/gorm go get -u gorm.io…

第三部分:特征提取與目標檢測

像邊緣、角點、特定的紋理模式等都是圖像的特征。提取這些特征是許多計算機視覺任務的關鍵第一步&#xff0c;例如圖像匹配、對象識別、圖像拼接等。目標檢測則是在圖像中找到特定對象&#xff08;如人臉、汽車等&#xff09;的位置。 本部分將涵蓋以下關鍵主題&#xff1a; …