Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Design and implement several variable charts #716

Merged
merged 10 commits into from
Oct 22, 2023
35 changes: 35 additions & 0 deletions src/pages/Options/variable-charts/GridLayout.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* GridLayout.css */

.grid-container {
padding: 20px; /* Add padding to create space on the sides */
max-width: 100%; /* Ensure the container's width does not exceed the viewport */
}

.grid {
display: grid;
grid-template-columns: repeat(5, 1fr); /* 5 columns */
grid-gap: 10px; /* Gap between grid items */
}

.grid-item {
border: 1px solid #ddd;
background: #f5f5f5;
display: flex;
justify-content: center;
align-items: center;
min-height: 200px; /* Minimum height of a grid item */
cursor: pointer;
/*aspect-ratio: 1; !* 设置宽高比为1,保持正方形 *!*/
}

.size-1x2 {
grid-column: span 2; /* Occupies 2 columns */
}
.size-2x2 {
grid-column: span 2;
grid-row: span 2;
}
.size-2x3 {
grid-column: span 3;
grid-row: span 2;
}
56 changes: 56 additions & 0 deletions src/pages/Options/variable-charts/GridLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React, { useState } from 'react';
import './GridLayout.css';
import LineChart from './LineChart';

const chartSize = ['', '1x2', '2x2', '2x3'];

const GridLayout = () => {
// 定义网格布局的行列数
const numRows = 3;
const numCols = 5;

// 定义每个网格的占用情况,初始时全部为空
const [gridLayout, setGridLayout] = useState<number[]>(
Array.from({ length: numRows * numCols }, () => 0)
);

//设置某个网格的占用情况
const setGridItemSize = (index: number, size: number) => {
const newGridLayout = [...gridLayout];
newGridLayout[index] = size;
setGridLayout(newGridLayout);
};

const newsize = 1;
// 渲染网格布局
const renderGrid = () => {
const grid: JSX.Element[] = [];
for (let i = 0; i < numRows; i++) {
for (let j = 0; j < numCols; j++) {
const index = i * numCols + j;
const size = gridLayout[index];

grid.push(
<div
key={index}
className={`grid-item size-${chartSize[size]}`}
onClick={() => setGridItemSize(index, newsize)}
>
{/* 图表组件,根据占用情况来决定显示的内容 */}
{size > 0 ? <LineChart /> : ''}
</div>
);
wxharry marked this conversation as resolved.
Show resolved Hide resolved
}
}
return grid;
};

return (
<div className="grid-container">
<h2>3x5 Grid Layout</h2>
<div className="grid">{renderGrid()}</div>
</div>
);
};

export default GridLayout;
97 changes: 97 additions & 0 deletions src/pages/Options/variable-charts/LineChart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import React, { useEffect, useRef, useState } from 'react';
import * as echarts from 'echarts';
import generateDataByMonth from '../../../helpers/generate-data-by-month';
import { getStars } from '../../../api/repo';

//const RepoName = ['X-lab2017/open-digger','hypertrons/hypertrons-crx'];
const RepoName = [
'X-lab2017/open-digger',
'hypertrons/hypertrons-crx',
'X-lab2017/oss101',
];
// 声明 rawRepoData 的结构
interface RawRepoData {
[date: string]: number;
}

const computeSeriesData = (data: { [repo: string]: RawRepoData }) =>
Object.entries(data).map(([repoName, repoData]) => ({
name: repoName, // 系列的名称为仓库名
type: 'line',
data: generateDataByMonth(repoData), // 使用对应仓库的数据
}));

const LineChart = () => {
const divEL = useRef(null);
const [data, setData] = useState<{ [repo: string]: RawRepoData }>({});

useEffect(() => {
const fetchData = async () => {
for (const repo of RepoName) {
try {
// 调用 getStars() 获取仓库数据
const starsData = await getStars(repo);
// 更新 Data
setData((prevData) => ({ ...prevData, [repo]: starsData }));
} catch (error) {
console.error(`Error fetching stars data for ${repo}:`, error);
// 如果获取失败,则将数据置为空对象
setData((prevData) => ({ ...prevData, [repo]: {} }));
}
}
};
fetchData();
}, []);

useEffect(() => {
let chartDOM = divEL.current;
const option = {
title: {
text: 'Line Chart',
},
tooltip: {
trigger: 'axis',
},
legend: {
type: 'scroll',
orient: 'vertical',
right: 10,
top: 20,
bottom: 20,
},
grid: {
left: '5%',
right: '4%',
bottom: '3%',
containLabel: true,
},
xAxis: {
type: 'time',
axisLabel: {
formatter: {
year: '{yearStyle|{yy}}',
month: '{MMM}',
},
rich: {
yearStyle: {
fontWeight: 'bold',
},
},
},
},
yAxis: {
type: 'value',
},
series: computeSeriesData(data), // 使用转换后的系列数据
};
const instance = echarts.init(chartDOM as any);
instance.setOption(option);
return () => {
instance.dispose();
};
}, [data]);

return <div ref={divEL} style={{ width: '100%', height: '100%' }}></div>;
};

export default LineChart;
Loading