-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #699 from GraphScope/update-docs
feat: Update the homepage of the interactive site, Add responsive design and theme switching.
- Loading branch information
Showing
13 changed files
with
517 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'; | ||
}; |
Oops, something went wrong.