style: area chart

main
jialin 2 years ago
parent 5746eb191f
commit 018c8cd208

@ -0,0 +1,79 @@
import { Area } from '@ant-design/plots';
import EmptyData from './empty-data';
interface LineChartProps {
title?: string;
height?: number;
data: any[];
color?: string[];
xField?: string;
yField?: string;
locale?: string;
labelFormatter?: (v: any) => string;
slider?: any;
}
const LineChart: React.FC<LineChartProps> = (props) => {
const {
data,
title,
color,
xField,
locale,
yField,
slider,
height,
labelFormatter
} = props;
const config = {
title,
height,
xField: xField || 'time',
yField: yField || 'value',
autoFit: true,
slider,
shapeField: 'smooth',
axis: {
x: {
textStyle: {
autoRoate: true
}
},
y: {
tick: false,
// size: 14,
// title: '%',
titlePosition: 'top',
titleFontSize: 12,
labelFormatter
}
},
style: {
fill: 'rgba(84, 204, 152,0.8)'
},
legend: {
color: {
layout: { justifyContent: 'center' }
},
size: {
itemLabelFontSize: 14,
itemLabelFontWeight: 500
}
},
tooltip: {
title: 'time',
items: [{ channel: 'y' }]
}
};
return (
<>
{data.length === 0 ? (
<EmptyData height={height} title={title} />
) : (
<Area data={data} {...config} />
)}
</>
);
};
export default LineChart;

@ -2,8 +2,8 @@ import { Empty } from 'antd';
import React from 'react';
const EmptyData: React.FC<{
height: string | number;
title: React.ReactNode;
height?: string | number;
title?: React.ReactNode;
}> = ({ height, title }) => {
return (
<div
@ -13,12 +13,14 @@ const EmptyData: React.FC<{
}}
className="flex-center flex-column "
>
<h3
className="justify-center"
style={{ padding: '16px 0', marginBottom: 0 }}
>
{title}
</h3>
{title && (
<h3
className="justify-center"
style={{ padding: '16px 0', marginBottom: 0 }}
>
{title}
</h3>
)}
<div
className="flex-center justify-center flex-column"
style={{ height: '100%' }}

@ -1,4 +1,5 @@
import { Line } from '@ant-design/plots';
import EmptyData from './empty-data';
interface LineChartProps {
title?: string;
@ -7,7 +8,7 @@ interface LineChartProps {
color?: string[];
xField?: string;
yField?: string;
locale: string;
locale?: string;
labelFormatter?: (v: any) => string;
slider?: any;
}
@ -79,7 +80,11 @@ const LineChart: React.FC<LineChartProps> = (props) => {
};
return (
<>
<Line data={data} {...config} />
{data.length === 0 ? (
<EmptyData height={height} title={title} />
) : (
<Line data={data} {...config} />
)}
</>
);
};

@ -39,6 +39,7 @@ const SealInputNumber: React.FC<InputNumberProps & SealFormItemProps> = (
};
const handleChange = (e: any) => {
e.target.value = e.target.value?.trim?.();
props.onChange?.(e);
};
@ -48,6 +49,7 @@ const SealInputNumber: React.FC<InputNumberProps & SealFormItemProps> = (
};
const handleOnBlur = (e: any) => {
e.target.value = e.target.value?.trim?.();
if (!inputRef.current?.value) {
setIsFocus(false);
props.onBlur?.(e);

@ -37,6 +37,7 @@ const SealPassword: React.FC<InputProps & SealFormItemProps> = (props) => {
};
const handleChange = (e: any) => {
e.target.value = e.target.value?.trim?.();
props.onChange?.(e);
};
@ -46,6 +47,7 @@ const SealPassword: React.FC<InputProps & SealFormItemProps> = (props) => {
};
const handleOnBlur = (e: any) => {
e.target.value = e.target.value?.trim?.();
if (!inputRef.current?.input?.value) {
setIsFocus(false);
props.onBlur?.(e);

@ -42,6 +42,7 @@ const SealInput: React.FC<InputProps & SealFormItemProps> = (props) => {
};
const handleChange = (e: any) => {
e.target.value = e.target.value?.trim?.();
props.onChange?.(e);
};
@ -51,6 +52,7 @@ const SealInput: React.FC<InputProps & SealFormItemProps> = (props) => {
};
const handleOnBlur = (e: any) => {
e.target.value = e.target.value?.trim?.();
if (!inputRef.current?.input?.value) {
setIsFocus(false);
props.onBlur?.(e);

@ -3,6 +3,7 @@ import '../styles/row-children.less';
const RowChildren = (props: any) => {
const { children } = props;
return <div className="row-children">{children}</div>;
};

@ -33,6 +33,7 @@ const TableRow: React.FC<
const [loading, setLoading] = useState(false);
const pollTimer = useRef<any>(null);
const chunkRequestRef = useRef<any>(null);
const childrenRendered = useRef<any>(null);
const { updateChunkedList } = useUpdateChunkedList(childrenData, {
setDataList: setChildrenData
@ -58,6 +59,10 @@ const TableRow: React.FC<
};
}, []);
const renderChildrenData = () => {
return renderChildren?.(childrenData);
};
const handlePolling = async () => {
if (pollingChildren) {
try {
@ -110,12 +115,12 @@ const TableRow: React.FC<
setExpanded(!expanded);
onExpand?.(!expanded, record);
chunkRequestRef.current?.current?.cancel?.();
if (pollTimer.current) {
clearInterval(pollTimer.current);
}
if (expanded) {
chunkRequestRef.current?.current?.cancel?.();
return;
}
@ -124,9 +129,6 @@ const TableRow: React.FC<
pollTimer.current = setInterval(() => {
handlePolling();
}, 1000);
} else if (watchChildren) {
await handleLoadChildren();
createChunkRequest();
} else {
handleLoadChildren();
}
@ -146,6 +148,12 @@ const TableRow: React.FC<
}
};
useEffect(() => {
if (childrenData.length) {
createChunkRequest();
}
}, [childrenData]);
const renderRowPrefix = () => {
if (expandable && rowSelection) {
return (
@ -220,11 +228,7 @@ const TableRow: React.FC<
{expanded && (
<div className="expanded-row">
<Spin spinning={loading}>
{childrenData.length ? (
renderChildren?.(childrenData)
) : (
<Empty></Empty>
)}
{childrenData.length ? renderChildrenData() : <Empty></Empty>}
</Spin>
</div>
)}

@ -118,7 +118,11 @@ const SealTable: React.FC<SealTableProps> = (props) => {
const renderContent = () => {
if (!props.dataSource.length) {
return <Empty></Empty>;
return (
<div className="empty-wrapper">
<Empty></Empty>
</div>
);
}
return (
<div className="seal-table-content">

@ -74,4 +74,11 @@
margin-top: 20px;
min-height: 100px;
}
.empty-wrapper {
display: flex;
min-height: 160px;
justify-content: center;
align-items: center;
}
}

@ -61,6 +61,7 @@ export function useUpdateChunkedList(
dataList,
(sItem: any) => sItem.id === item.id
);
console.log('updateIndex===========', dataList, updateIndex, data);
if (updateIndex > -1) {
const updateItem = _.cloneDeep(item);
dataList[updateIndex] = updateItem;

@ -19,5 +19,10 @@ export default {
'users.password.number': 'At least one number',
'users.password.special': 'At least one special character',
'users.password.length': 'Length between 6 and 12 characters',
'users.password.modify.title': 'Modify Password'
'users.password.modify.title': 'Modify Password',
'users.password.modify.description':
"For your account's security, please change your initial password.",
'users.password.confirm': 'Confirm New Password',
'users.password.confirm.empty': 'Please confirm the new password.',
'users.password.confirm.error': 'The two passwords entered do not match.'
};

@ -19,5 +19,9 @@ export default {
'users.password.number': '至少包含一个数字',
'users.password.special': '至少包含一个特殊字符',
'users.password.length': '长度在6至12个字符之间',
'users.password.modify.title': '修改密码'
'users.password.modify.title': '修改密码',
'users.password.modify.description': '为了确保您的账户安全,请修改初始密码',
'users.password.confirm': '确认新密码',
'users.password.confirm.empty': '请确认新密码',
'users.password.confirm.error': '两次输入的密码不一致'
};

@ -1,4 +1,5 @@
import CardWrapper from '@/components/card-wrapper';
import AreaChart from '@/components/charts/area';
import ColumnBar from '@/components/charts/column-bar';
import HBar from '@/components/charts/h-bar';
import PageTools from '@/components/page-tools';
@ -34,16 +35,16 @@ const projects = [
const APIRequestData = generateRandomArray({
length: times.length,
max: 100,
min: 0,
offset: 10
max: 1000,
min: 10,
offset: 0
});
const TokensData = generateRandomArray({
length: times.length,
max: 2000,
min: 200,
offset: 200
min: 0,
offset: 500
});
const usersData = generateRandomArray({
@ -189,7 +190,11 @@ const Usage = () => {
</span>
}
right={
<RangePicker onChange={handleSelectDate} style={{ width: 300 }} />
<RangePicker
onChange={handleSelectDate}
style={{ width: 300 }}
picker="month"
/>
}
/>
<Row style={{ width: '100%' }} gutter={[0, 20]}>
@ -204,13 +209,13 @@ const Usage = () => {
<CardWrapper style={{ width: '100%' }}>
<Row style={{ width: '100%' }}>
<Col span={12}>
<ColumnBar
<AreaChart
title={intl.formatMessage({ id: 'dashboard.apirequest' })}
data={requestData}
xField="time"
yField="value"
height={360}
></ColumnBar>
></AreaChart>
</Col>
<Col span={12}>
<ColumnBar

@ -371,7 +371,7 @@ const Models: React.FC = () => {
};
useEffect(() => {
fetchData();
// fetchData();
createModelsChunkRequest();
return () => {
chunkRequedtRef.current?.current?.cancel?.();

@ -47,8 +47,21 @@ const PasswordForm: React.FC = () => {
style={{ width: '400px', margin: '0 auto', paddingTop: '5%' }}
onFinish={handleSubmit}
>
<h2 className="justify-center m-b-20">
{intl.formatMessage({ id: 'users.password.modify.title' })}
<h2 className="justify-center m-b-20 flex-column flex-center">
<span>
{' '}
{intl.formatMessage({ id: 'users.password.modify.title' })}
</span>
<span
style={{
padding: '6px 0',
fontSize: 'var(--font-size-base)',
fontWeight: 'var(--font-weight-normal)',
color: 'var(--ant-color-text-tertiary)'
}}
>
{intl.formatMessage({ id: 'users.password.modify.description' })}
</span>
</h2>
<Form.Item
@ -87,8 +100,42 @@ const PasswordForm: React.FC = () => {
label={intl.formatMessage({ id: 'users.form.newpassword' })}
/>
</Form.Item>
<Form.Item
name="confirm_password"
dependencies={['new_password']}
rules={[
{
required: true,
message: intl.formatMessage({
id: 'users.password.confirm.empty'
})
},
({ getFieldValue }) => ({
validator(_, value) {
if (!value || getFieldValue('new_password') === value) {
return Promise.resolve();
}
return Promise.reject(
new Error(
intl.formatMessage({ id: 'users.password.confirm.error' })
)
);
}
})
]}
>
<SealInput.Password
prefix={<LockOutlined />}
label={intl.formatMessage({ id: 'users.password.confirm' })}
/>
</Form.Item>
<Button htmlType="submit" type="primary" block>
<Button
htmlType="submit"
type="primary"
block
style={{ marginTop: 20 }}
>
{intl.formatMessage({ id: 'common.button.submit' })}
</Button>
</Form>

Loading…
Cancel
Save