Skip to content

Commit

Permalink
Merge pull request #699 from GraphScope/update-docs
Browse files Browse the repository at this point in the history
feat: Update the homepage of the interactive site, Add responsive design and theme switching.
  • Loading branch information
pomelo-nwu authored Feb 19, 2025
2 parents 0ca433e + 35d7bff commit 93d2f3b
Show file tree
Hide file tree
Showing 13 changed files with 517 additions and 26 deletions.
39 changes: 30 additions & 9 deletions docs/interactive/components/Header/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import React from 'react';
import { Divider, Typography, Flex } from 'antd';

const Logo = ({ style }) => {
const { color = '#333' } = style || {};
import { Divider, Typography, Flex, theme, ConfigProvider } from 'antd';
import { useTheme } from '../Hooks';
const Logo = () => {
const { token } = theme.useToken();
const color = token.colorText;

return (
<div
style={{
display: 'flex',
width: '120px',
...style,
}}
>
<svg width="365px" height="113px" viewBox="0 0 365 113" version="1.1" xmlns="http://www.w3.org/2000/svg">
Expand Down Expand Up @@ -102,16 +102,37 @@ const Logo = ({ style }) => {
</div>
);
};
function Header({ title, style = {} }) {
function Header({ title }: { title: string }) {
return (
<Flex align="center" justify="center" gap={6} style={{ width: '250px' }}>
<Logo style={{ width: '120px', ...style }} />
<Logo />
<Divider type="vertical" style={{ height: '20px', borderInlineStart: '1px solid #ddd', marginTop: '4px' }} />
<Typography.Title level={5} style={{ margin: '0px' }}>
<Typography.Title level={5} style={{ margin: '0px' }} italic>
{title}
</Typography.Title>
</Flex>
);
}

export default Header;
const algorithmMap = {
dark: theme.darkAlgorithm,
light: theme.defaultAlgorithm,
system: theme.defaultAlgorithm,
};
export default ({ title }: { title: string }) => {
const theme = useTheme();
//@ts-ignore
const algorithm = algorithmMap[theme];
return (
<ConfigProvider
theme={{
algorithm,
token: {
colorPrimary: '#2581f0', //'#00b96b',
},
}}
>
<Header title={title} />
</ConfigProvider>
);
};
6 changes: 6 additions & 0 deletions docs/interactive/components/Home/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.container {
width: 100%;
max-width: 90rem;
margin: 0 auto;
padding: 0 1.5rem;
}
223 changes: 206 additions & 17 deletions docs/interactive/components/Home/index.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,212 @@
import React from 'react';

import React, { useRef } from 'react';
import LightArea, { useLightArea } from '../LightArea';
import { Flex, Col, Row, Button, Space, theme, Typography, ConfigProvider, Descriptions, Card } from 'antd';
import { useDynamicStyle, useIsMobile, useTheme } from '../Hooks';
import Icons from '../Icons';
import { GithubOutlined } from '@ant-design/icons';
const features = [
{
icon: Icons.Model,
title: 'Graph Modeling',
description: [
'Property Graph Data Model',
'Cypher Query Language, Extensible for Other Query Language, e.g. GQL, Gremlin',
],
},
{
icon: Icons.Database,
title: 'Graph-native Storage and Query Optimization',
description: [
'Graph-native Adjacency List | No KV/Relational Wrapper',
'Vectorized Storage and Compressed Result',
// 'Self-developed graph query optimization with optimality guarantee',
],
},
{
icon: Icons.Qps,
title: 'Tens of thousands of Queries per Second',
description: [
'Record-breaking LDBC Benchmarking Resutls',
'Multi-core Concurrent Query Execution',
// 'Horisontally Scalable',
],
},
{
icon: Icons.Explorer,
title: 'Visualization Toolkit',
description: ['Graph visualization in miniseconds', 'Self-developed Exploration Tool', 'LLM integration'],
},
];
const Home = () => {
const { token } = theme.useToken();
const isMobile = useIsMobile();

const bannerRef = useRef(null);
const { updatePosition, lightAreaRef } = useLightArea();
useDynamicStyle(
`
body{
overflow-x: hidden;
background-color:${token.colorBgContainer},
}
.container {
width: 100%;
max-width: 90rem;
margin: 0 auto;
padding: 0 1.5rem;
}
`,
'root',
);
return (
<Flex vertical align="center" justify="center" gap={12}>
{/** banner */}
<Flex
vertical
align="center"
style={{ width: '100%', overflow: 'hidden' }}
ref={bannerRef}
//@ts-ignore
onMouseMove={updatePosition}
>
{/** light area */}
<LightArea rootRef={bannerRef} ref={lightAreaRef} />
{/** banner area */}
<Flex
vertical
justify="center"
style={{
height: '50vh',
padding: '1.5rem',
textAlign: 'center',
zIndex: 1,
maxWidth: '70rem',
}}
>
<Typography.Title level={1} style={{ lineHeight: 1.1, fontWeight: 700 }}>
A High-Performance, Graph-native Engine for Massive Concurrent Queries
</Typography.Title>

<Flex justify="center" gap={12} style={{ paddingTop: 24 }}>
<Button
size="large"
style={{
width: '140px',
borderRadius: '20px',
background: token.colorPrimary,
color: token.colorBgBase,
borderColor: token.colorPrimary,
}}
>
Try it online
</Button>
<Button
size="large"
style={{
width: '140px',
borderRadius: '20px',
background: 'transparent',
color: token.colorText,
borderColor: token.colorPrimary,
}}
icon={<GithubOutlined />}
>
Github
</Button>
</Flex>
</Flex>
</Flex>

<Flex vertical align="center" style={{ width: '100%', maxWidth: '90rem', padding: '0 1.5rem' }} justify="center">
<Flex vertical style={{ width: '100%' }} gap={24} align="center">
<Typography.Title level={2}>Core Features</Typography.Title>
<Row
gutter={[
{
xs: 12,
sm: 12,
md: 12,
lg: 24,
xl: 24,
},
{
xs: 12,
sm: 12,
md: 12,
lg: 24,
xl: 24,
},
]}
>
{features.map((item, index) => {
const { icon: Icon, title, description } = item;

return (
<Col key={index} xs={24} sm={12} md={12} lg={6} xl={6}>
<Card hoverable>
<Flex vertical gap={12}>
<Icon
style={{
fontSize: 48,
color: token.colorPrimary,
// position: 'absolute',
// top: '0px',
// right: '0px',
zIndex: 0,
}}
/>
<Typography.Title level={4} style={{ margin: '0px' }}>
{title}
</Typography.Title>
<Typography.Text style={{ fontWeight: 500, margin: '0px' }} type="secondary">
{description.join(',')}
</Typography.Text>
</Flex>
</Card>
</Col>
);
})}
</Row>
</Flex>

<section
style={{
height: '400px',
// background: 'grey',
width: '100%',
}}
></section>
{/* <section style={{ height: '50vh', background: 'yellow', width: '100%' }}>Core Features</section> */}
</Flex>
</Flex>
);
};

const algorithmMap = {
dark: theme.darkAlgorithm,
light: theme.defaultAlgorithm,
system: theme.defaultAlgorithm,
};
export default () => {
const isMobile = useIsMobile();
const theme = useTheme();
//@ts-ignore
const algorithm = algorithmMap[theme];

console.log('isMobile', isMobile, theme);
return (
<div
style={{
height: '100vh',
padding: '200px',
background: 'grey',
textAlign: 'center',
color: '#fff',
<ConfigProvider
theme={{
algorithm,
token: {
colorPrimary: '#2581f0', //'#00b96b',
fontSizeHeading1: isMobile ? 32 : 60,
},
}}
>
<h1 style={{ fontSize: '60px', marginBottom: '12px' }}>Unleash the Power of Graph Data</h1>
<h2 style={{ fontSize: '40px', marginBottom: '12px' }}>GraphScope Interactive Engine</h2>
<h5 style={{ fontSize: '20px' }}>
High-performance graph processing and analytics for enterprise-scale applications Flex
</h5>
</div>
<Home />
</ConfigProvider>
);
};

export default Home;
3 changes: 3 additions & 0 deletions docs/interactive/components/Hooks/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { useDynamicStyle } from './useDynamicStyle';
export { useIsMobile } from './useIsMobile';
export { useTheme } from './useTheme';
45 changes: 45 additions & 0 deletions docs/interactive/components/Hooks/useDynamicStyle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { useEffect, useRef } from 'react';

/**
* 自定义 Hook,用于在组件中动态插入和移除 <style> 标签
* @param {string} css - 要插入的 CSS 样式字符串
* @param {string} [id] - <style> 标签的唯一 ID,默认为 'dynamic-style'
*/
export function useDynamicStyle(css: string, id: string = 'dynamic-style') {
const styleRef = useRef<HTMLStyleElement | null>(null);

useEffect(() => {
// 如果已经插入了样式,则跳过
if (styleRef.current) {
return;
}

// 创建一个 <style> 标签
const style = document.createElement('style');
style.type = 'text/css';
style.id = id;

// 将 CSS 样式插入到 <style> 标签中
if ('sheet' in style) {
// 现代浏览器
style.appendChild(document.createTextNode(css));
} else if ('styleSheet' in style) {
// IE8 及以下版本
(style as any).styleSheet.cssText = css;
}

// 将 <style> 标签插入到文档的 <head> 中
document.head.appendChild(style);

// 保存 <style> 标签的引用
styleRef.current = style;

// 清理函数,确保在组件卸载时移除 <style> 标签
return () => {
if (styleRef.current) {
document.head.removeChild(styleRef.current);
styleRef.current = null;
}
};
}, [css, id]);
}
20 changes: 20 additions & 0 deletions docs/interactive/components/Hooks/useIsMobile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { useState, useEffect } from 'react';

export const useIsMobile = () => {
const [isMobile, setIsMobile] = useState(false);

useEffect(() => {
const mediaQuery = window.matchMedia('(max-width: 768px)');
const handleMediaChange = (e: any) => {
setIsMobile(e.matches);
};

setIsMobile(mediaQuery.matches);
mediaQuery.addEventListener('change', handleMediaChange);
return () => {
mediaQuery.removeEventListener('change', handleMediaChange);
};
}, []);

return isMobile;
};
28 changes: 28 additions & 0 deletions docs/interactive/components/Hooks/useTheme.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { useState, useEffect } from 'react';

const KEY = 'theme';
export const useTheme = () => {
const [value, setValue] = useState('');

useEffect(() => {
const targetElement = document.querySelector('html'); // 目标元素
const observer = new MutationObserver((mutationsList, observer) => {
for (let mutation of mutationsList) {
if (mutation.type === 'attributes' && mutation.attributeName === 'style') {
// const { cssText } = mutation.target.style;
const theme_value = localStorage.getItem('theme') || 'light';
setValue(theme_value);
}
}
});
//@ts-ignore
observer.observe(targetElement, {
attributes: true,
attributeFilter: ['style'], // 仅观察 'style' 属性
});
const theme_value = localStorage.getItem('theme') || 'light';
setValue(theme_value);
}, []);

return value || 'light';
};
Loading

0 comments on commit 93d2f3b

Please sign in to comment.