fix: the max embedding value exceeds the limit.
This commit is contained in:
@@ -2,12 +2,26 @@ import Chart from '@/components/echarts/chart';
|
|||||||
import useChartConfig from '@/components/echarts/config';
|
import useChartConfig from '@/components/echarts/config';
|
||||||
import EmptyData from '@/components/empty-data';
|
import EmptyData from '@/components/empty-data';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import React, { memo, useCallback, useMemo, useRef } from 'react';
|
import React, { useCallback, useMemo, useRef } from 'react';
|
||||||
import { ChartProps } from './types';
|
import { ChartProps } from './types';
|
||||||
|
|
||||||
const Scatter: React.FC<ChartProps> = (props) => {
|
const Scatter: React.FC<
|
||||||
|
ChartProps & {
|
||||||
|
xMax?: number;
|
||||||
|
yMax?: number;
|
||||||
|
}
|
||||||
|
> = (props) => {
|
||||||
const { grid, title: titleConfig, isDark, chartColorMap } = useChartConfig();
|
const { grid, title: titleConfig, isDark, chartColorMap } = useChartConfig();
|
||||||
const { seriesData, xAxisData, height, width, showEmpty, title } = props;
|
const {
|
||||||
|
seriesData,
|
||||||
|
xAxisData,
|
||||||
|
height,
|
||||||
|
width,
|
||||||
|
showEmpty,
|
||||||
|
title,
|
||||||
|
xMax = 1,
|
||||||
|
yMax = 1
|
||||||
|
} = props;
|
||||||
|
|
||||||
const chart = useRef<any>(null);
|
const chart = useRef<any>(null);
|
||||||
|
|
||||||
@@ -36,8 +50,8 @@ const Scatter: React.FC<ChartProps> = (props) => {
|
|||||||
borderRadius: 4
|
borderRadius: 4
|
||||||
},
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
min: -1,
|
min: -xMax,
|
||||||
max: 1,
|
max: xMax,
|
||||||
scale: false,
|
scale: false,
|
||||||
slient: true,
|
slient: true,
|
||||||
splitNumber: 15,
|
splitNumber: 15,
|
||||||
@@ -62,8 +76,8 @@ const Scatter: React.FC<ChartProps> = (props) => {
|
|||||||
boundaryGap: [0.05, 0.05]
|
boundaryGap: [0.05, 0.05]
|
||||||
},
|
},
|
||||||
yAxis: {
|
yAxis: {
|
||||||
min: -1,
|
min: -yMax,
|
||||||
max: 1,
|
max: yMax,
|
||||||
scale: false,
|
scale: false,
|
||||||
slient: true,
|
slient: true,
|
||||||
splitNumber: 10,
|
splitNumber: 10,
|
||||||
@@ -99,7 +113,7 @@ const Scatter: React.FC<ChartProps> = (props) => {
|
|||||||
},
|
},
|
||||||
series: []
|
series: []
|
||||||
};
|
};
|
||||||
}, [isDark]);
|
}, [isDark, xMax, yMax]);
|
||||||
|
|
||||||
const findOverlappingPoints = useCallback(
|
const findOverlappingPoints = useCallback(
|
||||||
(data: any[], currentPoint: any) => {
|
(data: any[], currentPoint: any) => {
|
||||||
@@ -201,7 +215,10 @@ const Scatter: React.FC<ChartProps> = (props) => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{!seriesData.length && showEmpty ? (
|
{!seriesData.length && showEmpty ? (
|
||||||
<EmptyData height={height} title={title}></EmptyData>
|
<EmptyData
|
||||||
|
height={height}
|
||||||
|
title={_.get(title, 'text', title || '')}
|
||||||
|
></EmptyData>
|
||||||
) : (
|
) : (
|
||||||
<Chart
|
<Chart
|
||||||
ref={chart}
|
ref={chart}
|
||||||
@@ -214,4 +231,4 @@ const Scatter: React.FC<ChartProps> = (props) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(Scatter);
|
export default Scatter;
|
||||||
|
|||||||
+1
-6
@@ -212,16 +212,11 @@ body {
|
|||||||
// set for the non-form item
|
// set for the non-form item
|
||||||
.ant-input-outlined,
|
.ant-input-outlined,
|
||||||
.ant-input-affix-wrapper,
|
.ant-input-affix-wrapper,
|
||||||
.ant-select,
|
.ant-select-lg,
|
||||||
.ant-picker {
|
.ant-picker {
|
||||||
height: 40px;
|
height: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
// form item help
|
|
||||||
.ant-form-item-with-help .ant-form-item-explain {
|
|
||||||
// padding-left: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// icon
|
// icon
|
||||||
.anticon {
|
.anticon {
|
||||||
&.size-16 {
|
&.size-16 {
|
||||||
|
|||||||
@@ -162,5 +162,6 @@ export default {
|
|||||||
'Please enter a direct image URL (e.g. https://.../image.png). Press ESC to cancel.',
|
'Please enter a direct image URL (e.g. https://.../image.png). Press ESC to cancel.',
|
||||||
'playground.uploadImage.url.holder': 'Enter an image URL',
|
'playground.uploadImage.url.holder': 'Enter an image URL',
|
||||||
'playground.uploadImage.url.button': 'Add Image from URL',
|
'playground.uploadImage.url.button': 'Add Image from URL',
|
||||||
'playground.params.duration': 'Duration (seconds)'
|
'playground.params.duration': 'Duration (seconds)',
|
||||||
|
'playground.params.resolution': 'Resolution'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -165,7 +165,8 @@ export default {
|
|||||||
'Please enter a direct image URL (e.g. https://.../image.png). Press ESC to cancel.',
|
'Please enter a direct image URL (e.g. https://.../image.png). Press ESC to cancel.',
|
||||||
'playground.uploadImage.url.holder': 'Enter an image URL',
|
'playground.uploadImage.url.holder': 'Enter an image URL',
|
||||||
'playground.uploadImage.url.button': 'Add Image from URL',
|
'playground.uploadImage.url.button': 'Add Image from URL',
|
||||||
'playground.params.duration': 'Duration (seconds)'
|
'playground.params.duration': 'Duration (seconds)',
|
||||||
|
'playground.params.resolution': 'Resolution'
|
||||||
};
|
};
|
||||||
|
|
||||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||||
@@ -175,5 +176,6 @@ export default {
|
|||||||
// 4. 'playground.uploadImage.url.invalid': 'Please enter a direct image URL(e.g. https://.../image.png). Press ESC to cancel.',
|
// 4. 'playground.uploadImage.url.invalid': 'Please enter a direct image URL(e.g. https://.../image.png). Press ESC to cancel.',
|
||||||
// 5. 'playground.uploadImage.url.holder': 'Enter an image URL'
|
// 5. 'playground.uploadImage.url.holder': 'Enter an image URL'
|
||||||
// 6. 'playground.uploadImage.url.button': 'Add Image from URL',
|
// 6. 'playground.uploadImage.url.button': 'Add Image from URL',
|
||||||
// 7. 'playground.params.duration': 'Duration (seconds)'
|
// 7. 'playground.params.duration': 'Duration (seconds)',
|
||||||
|
// 8. 'playground.params.resolution': 'Resolution'
|
||||||
// ========== End of To-Do List ==========
|
// ========== End of To-Do List ==========
|
||||||
|
|||||||
@@ -159,12 +159,14 @@ export default {
|
|||||||
'Please enter a direct image URL (e.g. https://.../image.png). Press ESC to cancel.',
|
'Please enter a direct image URL (e.g. https://.../image.png). Press ESC to cancel.',
|
||||||
'playground.uploadImage.url.holder': 'Enter an image URL',
|
'playground.uploadImage.url.holder': 'Enter an image URL',
|
||||||
'playground.uploadImage.url.button': 'Add Image from URL',
|
'playground.uploadImage.url.button': 'Add Image from URL',
|
||||||
'playground.params.duration': 'Duration (seconds)'
|
'playground.params.duration': 'Duration (seconds)',
|
||||||
|
'playground.params.resolution': 'Resolution'
|
||||||
};
|
};
|
||||||
|
|
||||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||||
// 1. 'playground.uploadImage.url.invalid': 'Please enter a direct image URL(e.g. https://.../image.png). Press ESC to cancel.',
|
// 1. 'playground.uploadImage.url.invalid': 'Please enter a direct image URL(e.g. https://.../image.png). Press ESC to cancel.',
|
||||||
// 2. 'playground.uploadImage.url.holder': 'Enter an image URL',
|
// 2. 'playground.uploadImage.url.holder': 'Enter an image URL',
|
||||||
// 3. 'playground.uploadImage.url.button': 'Add Image from URL',
|
// 3. 'playground.uploadImage.url.button': 'Add Image from URL',
|
||||||
// 4. 'playground.params.duration': 'Duration (seconds)'
|
// 4. 'playground.params.duration': 'Duration (seconds)',
|
||||||
|
// 5. 'playground.params.resolution': 'Resolution'
|
||||||
// ========== End of To-Do List ==========
|
// ========== End of To-Do List ==========
|
||||||
|
|||||||
@@ -155,5 +155,6 @@ export default {
|
|||||||
'请输入直接的图片链接(例如:https://…/image.png)。按 ESC 可取消。',
|
'请输入直接的图片链接(例如:https://…/image.png)。按 ESC 可取消。',
|
||||||
'playground.uploadImage.url.holder': '请输入图片链接',
|
'playground.uploadImage.url.holder': '请输入图片链接',
|
||||||
'playground.uploadImage.url.button': '从链接添加图片',
|
'playground.uploadImage.url.button': '从链接添加图片',
|
||||||
'playground.params.duration': '时长 (秒)'
|
'playground.params.duration': '时长 (秒)',
|
||||||
|
'playground.params.resolution': '分辨率'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -215,6 +215,7 @@ const GroundEmbedding: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
|
|
||||||
workerRef.current!.onmessage = (event: MessageEvent) => {
|
workerRef.current!.onmessage = (event: MessageEvent) => {
|
||||||
const { scatterData, embeddingData } = event.data;
|
const { scatterData, embeddingData } = event.data;
|
||||||
|
|
||||||
setScatterData(scatterData);
|
setScatterData(scatterData);
|
||||||
setEmbeddingData(embeddingData);
|
setEmbeddingData(embeddingData);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
|||||||
@@ -1,6 +1,52 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { PCA } from 'ml-pca';
|
import { PCA } from 'ml-pca';
|
||||||
|
|
||||||
|
type Point = {
|
||||||
|
value: [number, number];
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
const normalizeEmbeddingToCanvas = (
|
||||||
|
data: Point[],
|
||||||
|
padding = 0.9 // 90% fill the canvas
|
||||||
|
) => {
|
||||||
|
let minX = Infinity,
|
||||||
|
maxX = -Infinity;
|
||||||
|
let minY = Infinity,
|
||||||
|
maxY = -Infinity;
|
||||||
|
|
||||||
|
data.forEach((p) => {
|
||||||
|
const [x, y] = p.value;
|
||||||
|
minX = Math.min(minX, x);
|
||||||
|
maxX = Math.max(maxX, x);
|
||||||
|
minY = Math.min(minY, y);
|
||||||
|
maxY = Math.max(maxY, y);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2. center point
|
||||||
|
const cx = (minX + maxX) / 2;
|
||||||
|
const cy = (minY + maxY) / 2;
|
||||||
|
|
||||||
|
// 3. max radius
|
||||||
|
let maxRadius = 0;
|
||||||
|
data.forEach((p) => {
|
||||||
|
const dx = Math.abs(p.value[0] - cx);
|
||||||
|
const dy = Math.abs(p.value[1] - cy);
|
||||||
|
maxRadius = Math.max(maxRadius, dx, dy);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (maxRadius === 0) maxRadius = 1;
|
||||||
|
|
||||||
|
// 4. scale factor
|
||||||
|
const scale = padding / maxRadius;
|
||||||
|
|
||||||
|
// 5. normalization
|
||||||
|
return data.map((p) => ({
|
||||||
|
...p,
|
||||||
|
value: [(p.value[0] - cx) * scale, (p.value[1] - cy) * scale]
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
self.onmessage = (
|
self.onmessage = (
|
||||||
event: MessageEvent<{
|
event: MessageEvent<{
|
||||||
embeddings: any[];
|
embeddings: any[];
|
||||||
@@ -49,7 +95,7 @@ self.onmessage = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
self.postMessage({
|
self.postMessage({
|
||||||
scatterData: list,
|
scatterData: normalizeEmbeddingToCanvas(list),
|
||||||
embeddingData: embeddingData
|
embeddingData: embeddingData
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -36,13 +36,8 @@ export const videoParamsConfig: ParamsSchema[] = [
|
|||||||
type: 'Select',
|
type: 'Select',
|
||||||
name: 'size',
|
name: 'size',
|
||||||
options: videoSizeOptions,
|
options: videoSizeOptions,
|
||||||
description: {
|
|
||||||
text: 'playground.params.size.description',
|
|
||||||
html: true,
|
|
||||||
isLocalized: true
|
|
||||||
},
|
|
||||||
label: {
|
label: {
|
||||||
text: 'playground.params.size',
|
text: 'playground.params.resolution',
|
||||||
isLocalized: true
|
isLocalized: true
|
||||||
},
|
},
|
||||||
rules: [
|
rules: [
|
||||||
|
|||||||
Reference in New Issue
Block a user