@antv/infographic 0.2.16 → 0.2.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/dist/infographic.min.js +121 -120
- package/dist/infographic.min.js.map +1 -1
- package/esm/constants/service.d.ts +1 -1
- package/esm/constants/service.js +1 -1
- package/esm/designs/structures/chart-line.js +7 -4
- package/esm/editor/interactions/dblclick-edit-text.js +3 -3
- package/esm/editor/managers/interaction.js +6 -4
- package/esm/editor/plugins/components/button.d.ts +2 -1
- package/esm/editor/plugins/components/button.js +4 -4
- package/esm/editor/plugins/components/color-picker.d.ts +1 -0
- package/esm/editor/plugins/components/color-picker.js +3 -3
- package/esm/editor/plugins/components/popover.d.ts +3 -1
- package/esm/editor/plugins/components/popover.js +29 -9
- package/esm/editor/plugins/edit-bar/edit-bar.d.ts +3 -1
- package/esm/editor/plugins/edit-bar/edit-bar.js +17 -7
- package/esm/editor/plugins/edit-bar/edit-items/align-elements.js +6 -4
- package/esm/editor/plugins/edit-bar/edit-items/font-align.js +8 -5
- package/esm/editor/plugins/edit-bar/edit-items/font-color.js +7 -4
- package/esm/editor/plugins/edit-bar/edit-items/font-family.js +11 -9
- package/esm/editor/plugins/edit-bar/edit-items/font-size.js +8 -5
- package/esm/editor/plugins/edit-bar/edit-items/icon-color.js +7 -4
- package/esm/editor/plugins/edit-bar/edit-items/types.d.ts +5 -1
- package/esm/editor/plugins/reset-viewbox.d.ts +4 -1
- package/esm/editor/plugins/reset-viewbox.js +12 -6
- package/esm/editor/utils/index.d.ts +1 -0
- package/esm/editor/utils/index.js +1 -0
- package/esm/editor/utils/root.d.ts +3 -0
- package/esm/editor/utils/root.js +18 -0
- package/esm/exporter/svg.js +229 -3
- package/esm/options/parser.js +8 -6
- package/esm/options/types.d.ts +3 -3
- package/esm/renderer/renderer.js +1 -1
- package/esm/resource/loaders/search.js +2 -6
- package/esm/runtime/options.js +1 -1
- package/esm/syntax/index.js +56 -10
- package/esm/syntax/mapper.js +20 -6
- package/esm/syntax/parser.js +9 -0
- package/esm/syntax/types.d.ts +1 -1
- package/esm/templates/registry.d.ts +1 -0
- package/esm/templates/registry.js +6 -0
- package/esm/templates/utils.d.ts +1 -0
- package/esm/templates/utils.js +68 -0
- package/esm/themes/built-in.js +3 -0
- package/esm/utils/padding.js +1 -1
- package/esm/utils/style.d.ts +3 -1
- package/esm/utils/style.js +27 -4
- package/esm/version.d.ts +1 -1
- package/esm/version.js +1 -1
- package/lib/constants/service.d.ts +1 -1
- package/lib/constants/service.js +1 -1
- package/lib/designs/structures/chart-line.js +7 -4
- package/lib/editor/interactions/dblclick-edit-text.js +3 -3
- package/lib/editor/managers/interaction.js +7 -5
- package/lib/editor/plugins/components/button.d.ts +2 -1
- package/lib/editor/plugins/components/button.js +4 -4
- package/lib/editor/plugins/components/color-picker.d.ts +1 -0
- package/lib/editor/plugins/components/color-picker.js +3 -3
- package/lib/editor/plugins/components/popover.d.ts +3 -1
- package/lib/editor/plugins/components/popover.js +32 -12
- package/lib/editor/plugins/edit-bar/edit-bar.d.ts +3 -1
- package/lib/editor/plugins/edit-bar/edit-bar.js +17 -7
- package/lib/editor/plugins/edit-bar/edit-items/align-elements.js +6 -4
- package/lib/editor/plugins/edit-bar/edit-items/font-align.js +8 -5
- package/lib/editor/plugins/edit-bar/edit-items/font-color.js +7 -4
- package/lib/editor/plugins/edit-bar/edit-items/font-family.js +11 -9
- package/lib/editor/plugins/edit-bar/edit-items/font-size.js +8 -5
- package/lib/editor/plugins/edit-bar/edit-items/icon-color.js +7 -4
- package/lib/editor/plugins/edit-bar/edit-items/types.d.ts +5 -1
- package/lib/editor/plugins/reset-viewbox.d.ts +4 -1
- package/lib/editor/plugins/reset-viewbox.js +12 -6
- package/lib/editor/utils/index.d.ts +1 -0
- package/lib/editor/utils/index.js +1 -0
- package/lib/editor/utils/root.d.ts +3 -0
- package/lib/editor/utils/root.js +22 -0
- package/lib/exporter/svg.js +229 -3
- package/lib/options/parser.js +7 -5
- package/lib/options/types.d.ts +3 -3
- package/lib/renderer/renderer.js +1 -1
- package/lib/resource/loaders/search.js +2 -6
- package/lib/runtime/options.js +1 -1
- package/lib/syntax/index.js +56 -10
- package/lib/syntax/mapper.js +20 -6
- package/lib/syntax/parser.js +9 -0
- package/lib/syntax/types.d.ts +1 -1
- package/lib/templates/registry.d.ts +1 -0
- package/lib/templates/registry.js +7 -0
- package/lib/templates/utils.d.ts +1 -0
- package/lib/templates/utils.js +71 -0
- package/lib/themes/built-in.js +3 -0
- package/lib/utils/padding.js +1 -1
- package/lib/utils/style.d.ts +3 -1
- package/lib/utils/style.js +27 -4
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +1 -1
- package/src/constants/service.ts +1 -1
- package/src/designs/structures/chart-line.tsx +8 -4
- package/src/editor/interactions/dblclick-edit-text.ts +3 -2
- package/src/editor/managers/interaction.ts +9 -7
- package/src/editor/plugins/components/button.ts +5 -2
- package/src/editor/plugins/components/color-picker.ts +4 -2
- package/src/editor/plugins/components/popover.ts +31 -12
- package/src/editor/plugins/edit-bar/edit-bar.ts +26 -11
- package/src/editor/plugins/edit-bar/edit-items/align-elements.ts +7 -2
- package/src/editor/plugins/edit-bar/edit-items/font-align.ts +8 -3
- package/src/editor/plugins/edit-bar/edit-items/font-color.ts +7 -2
- package/src/editor/plugins/edit-bar/edit-items/font-family.ts +11 -7
- package/src/editor/plugins/edit-bar/edit-items/font-size.ts +8 -3
- package/src/editor/plugins/edit-bar/edit-items/icon-color.ts +7 -2
- package/src/editor/plugins/edit-bar/edit-items/types.ts +6 -1
- package/src/editor/plugins/reset-viewbox.ts +17 -8
- package/src/editor/utils/index.ts +1 -0
- package/src/editor/utils/root.ts +26 -0
- package/src/exporter/svg.ts +274 -3
- package/src/options/parser.ts +7 -6
- package/src/options/types.ts +3 -3
- package/src/renderer/renderer.ts +1 -1
- package/src/resource/loaders/search.ts +2 -5
- package/src/runtime/options.ts +1 -1
- package/src/syntax/index.ts +71 -10
- package/src/syntax/mapper.ts +20 -6
- package/src/syntax/parser.ts +10 -0
- package/src/syntax/types.ts +1 -0
- package/src/templates/registry.ts +6 -0
- package/src/templates/utils.ts +111 -0
- package/src/themes/built-in.ts +4 -0
- package/src/utils/padding.ts +1 -1
- package/src/utils/style.ts +31 -4
- package/src/version.ts +1 -1
package/lib/options/types.d.ts
CHANGED
|
@@ -4,8 +4,8 @@ import type { ThemeConfig } from '../themes';
|
|
|
4
4
|
import type { Data, Padding, ParsedData } from '../types';
|
|
5
5
|
import type { Path } from '../utils';
|
|
6
6
|
export interface InfographicOptions {
|
|
7
|
-
/**
|
|
8
|
-
container?: string |
|
|
7
|
+
/** 容器,可以是选择器、Element 或 ShadowRoot */
|
|
8
|
+
container?: string | Element | ShadowRoot;
|
|
9
9
|
/** 宽度 */
|
|
10
10
|
width?: number | string;
|
|
11
11
|
/** 高度 */
|
|
@@ -34,7 +34,7 @@ export interface InfographicOptions {
|
|
|
34
34
|
elements?: ElementProps[];
|
|
35
35
|
}
|
|
36
36
|
export interface ParsedInfographicOptions {
|
|
37
|
-
container:
|
|
37
|
+
container: Element | ShadowRoot;
|
|
38
38
|
width?: number | string;
|
|
39
39
|
height?: number | string;
|
|
40
40
|
padding?: Padding;
|
package/lib/renderer/renderer.js
CHANGED
|
@@ -16,7 +16,6 @@ const image_1 = require("./image");
|
|
|
16
16
|
const remote_1 = require("./remote");
|
|
17
17
|
const svg_1 = require("./svg");
|
|
18
18
|
const queryIcon = (query) => __awaiter(void 0, void 0, void 0, function* () {
|
|
19
|
-
var _a;
|
|
20
19
|
try {
|
|
21
20
|
const params = new URLSearchParams({ text: query, topK: '1' });
|
|
22
21
|
const url = `${constants_1.ICON_SERVICE_URL}?${params.toString()}`;
|
|
@@ -24,9 +23,9 @@ const queryIcon = (query) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
24
23
|
if (!response.ok)
|
|
25
24
|
return null;
|
|
26
25
|
const result = yield response.json();
|
|
27
|
-
if (!(result === null || result === void 0 ? void 0 : result.
|
|
26
|
+
if (!(result === null || result === void 0 ? void 0 : result.success) || !Array.isArray(result.data))
|
|
28
27
|
return null;
|
|
29
|
-
return result.data
|
|
28
|
+
return result.data[0] || null;
|
|
30
29
|
}
|
|
31
30
|
catch (error) {
|
|
32
31
|
console.error(`Failed to query icon for "${query}":`, error);
|
|
@@ -58,9 +57,6 @@ function loadSearchResource(query, format) {
|
|
|
58
57
|
const svgText = commaIndex >= 0 ? result.slice(commaIndex + 1) : result;
|
|
59
58
|
return (0, svg_1.loadSVGResource)(svgText);
|
|
60
59
|
}
|
|
61
|
-
if (mimeType === 'image/svg+xml' && format === 'svg' && isBase64) {
|
|
62
|
-
return (0, image_1.loadImageBase64Resource)(result);
|
|
63
|
-
}
|
|
64
60
|
return (0, image_1.loadImageBase64Resource)(result);
|
|
65
61
|
}
|
|
66
62
|
return (0, remote_1.loadRemoteResource)(result, format);
|
package/lib/runtime/options.js
CHANGED
package/lib/syntax/index.js
CHANGED
|
@@ -16,6 +16,15 @@ const mapper_1 = require("./mapper");
|
|
|
16
16
|
const parser_1 = require("./parser");
|
|
17
17
|
const relations_1 = require("./relations");
|
|
18
18
|
const schema_1 = require("./schema");
|
|
19
|
+
const ALLOWED_ROOT_KEYS = new Set([
|
|
20
|
+
'infographic',
|
|
21
|
+
'template',
|
|
22
|
+
'design',
|
|
23
|
+
'data',
|
|
24
|
+
'theme',
|
|
25
|
+
'width',
|
|
26
|
+
'height',
|
|
27
|
+
]);
|
|
19
28
|
function normalizeItems(items) {
|
|
20
29
|
var _a;
|
|
21
30
|
const seen = new Set();
|
|
@@ -36,6 +45,13 @@ function normalizeItems(items) {
|
|
|
36
45
|
}
|
|
37
46
|
return normalized.reverse();
|
|
38
47
|
}
|
|
48
|
+
function assignMissingNodeIds(items) {
|
|
49
|
+
items.forEach((item) => {
|
|
50
|
+
if (!item.id && item.label) {
|
|
51
|
+
item.id = item.label;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
39
55
|
function resolveTemplate(node, errors) {
|
|
40
56
|
if (!node)
|
|
41
57
|
return undefined;
|
|
@@ -49,12 +65,42 @@ function resolveTemplate(node, errors) {
|
|
|
49
65
|
}
|
|
50
66
|
return undefined;
|
|
51
67
|
}
|
|
68
|
+
function inferTemplateFromBareFirstLine(entries, warnings) {
|
|
69
|
+
if ('infographic' in entries || 'template' in entries) {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
const [firstEntry] = Object.entries(entries);
|
|
73
|
+
if (!firstEntry)
|
|
74
|
+
return undefined;
|
|
75
|
+
const [key, node] = firstEntry;
|
|
76
|
+
if (ALLOWED_ROOT_KEYS.has(key) || node.kind !== 'object') {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
if (node.value !== undefined || Object.keys(node.entries).length > 0) {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
warnings.push({
|
|
83
|
+
path: 'template',
|
|
84
|
+
line: node.line,
|
|
85
|
+
code: 'implicit_template',
|
|
86
|
+
message: 'Inferred template from a bare first line. Prefix it with "infographic" or "template" to make the syntax explicit.',
|
|
87
|
+
raw: key,
|
|
88
|
+
});
|
|
89
|
+
return {
|
|
90
|
+
template: key,
|
|
91
|
+
inferredKey: key,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
52
94
|
function parseSyntax(input) {
|
|
53
95
|
var _a;
|
|
54
96
|
const { ast, errors } = (0, parser_1.parseSyntaxToAst)(input);
|
|
55
97
|
const warnings = [];
|
|
56
98
|
const options = {};
|
|
57
99
|
const mergedEntries = Object.assign({}, ast.entries);
|
|
100
|
+
const inferredTemplate = inferTemplateFromBareFirstLine(ast.entries, warnings);
|
|
101
|
+
if (inferredTemplate) {
|
|
102
|
+
delete mergedEntries[inferredTemplate.inferredKey];
|
|
103
|
+
}
|
|
58
104
|
const infographicNode = ast.entries.infographic;
|
|
59
105
|
let templateFromInfographic;
|
|
60
106
|
if (infographicNode && infographicNode.kind === 'object') {
|
|
@@ -65,17 +111,8 @@ function parseSyntax(input) {
|
|
|
65
111
|
mergedEntries[key] = value;
|
|
66
112
|
});
|
|
67
113
|
}
|
|
68
|
-
const allowedRootKeys = new Set([
|
|
69
|
-
'infographic',
|
|
70
|
-
'template',
|
|
71
|
-
'design',
|
|
72
|
-
'data',
|
|
73
|
-
'theme',
|
|
74
|
-
'width',
|
|
75
|
-
'height',
|
|
76
|
-
]);
|
|
77
114
|
Object.keys(mergedEntries).forEach((key) => {
|
|
78
|
-
if (!
|
|
115
|
+
if (!ALLOWED_ROOT_KEYS.has(key)) {
|
|
79
116
|
errors.push({
|
|
80
117
|
path: key,
|
|
81
118
|
line: mergedEntries[key].line,
|
|
@@ -92,6 +129,9 @@ function parseSyntax(input) {
|
|
|
92
129
|
if (!options.template && templateFromInfographic) {
|
|
93
130
|
options.template = templateFromInfographic;
|
|
94
131
|
}
|
|
132
|
+
if (!options.template && inferredTemplate) {
|
|
133
|
+
options.template = inferredTemplate.template;
|
|
134
|
+
}
|
|
95
135
|
const designNode = mergedEntries.design;
|
|
96
136
|
if (designNode) {
|
|
97
137
|
const design = (0, mapper_1.mapWithSchema)(designNode, schema_1.DesignSchema, 'design', errors);
|
|
@@ -114,6 +154,12 @@ function parseSyntax(input) {
|
|
|
114
154
|
const parsed = (0, relations_1.parseRelationsNode)(relationsNode, errors, 'data.relations');
|
|
115
155
|
if (parsed.relations.length > 0 || parsed.items.length > 0) {
|
|
116
156
|
const current = ((_a = options.data) !== null && _a !== void 0 ? _a : {});
|
|
157
|
+
if (Array.isArray(current.items)) {
|
|
158
|
+
assignMissingNodeIds(current.items);
|
|
159
|
+
}
|
|
160
|
+
if (Array.isArray(current.nodes)) {
|
|
161
|
+
assignMissingNodeIds(current.nodes);
|
|
162
|
+
}
|
|
117
163
|
// 优先使用已存在的数据列表 (sequences, lists, etc.)
|
|
118
164
|
const dataKeys = Object.keys(schema_1.DataSchema.fields).filter((key) => key !== 'items' && key !== 'relations');
|
|
119
165
|
let hasStructuredData = false;
|
package/lib/syntax/mapper.js
CHANGED
|
@@ -12,11 +12,20 @@ function createValueNode(value, line) {
|
|
|
12
12
|
}
|
|
13
13
|
const HEX_COLOR_PATTERN = /^(#[0-9a-f]{8}|#[0-9a-f]{6}|#[0-9a-f]{4}|#[0-9a-f]{3})/i;
|
|
14
14
|
const FUNCTION_COLOR_PATTERN = /^((?:rgb|rgba|hsl|hsla)\([^)]*\))/i;
|
|
15
|
+
function normalizeBooleanLiteral(value) {
|
|
16
|
+
const trimmed = value.trim();
|
|
17
|
+
if (/^true$/i.test(trimmed))
|
|
18
|
+
return 'true';
|
|
19
|
+
if (/^false$/i.test(trimmed))
|
|
20
|
+
return 'false';
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
15
23
|
function parseScalar(value) {
|
|
16
24
|
const trimmed = value.trim();
|
|
17
|
-
|
|
25
|
+
const normalizedBoolean = normalizeBooleanLiteral(trimmed);
|
|
26
|
+
if (normalizedBoolean === 'true')
|
|
18
27
|
return true;
|
|
19
|
-
if (
|
|
28
|
+
if (normalizedBoolean === 'false')
|
|
20
29
|
return false;
|
|
21
30
|
if (/^-?\d+(\.\d+)?$/.test(trimmed))
|
|
22
31
|
return parseFloat(trimmed);
|
|
@@ -182,11 +191,12 @@ function mapWithSchema(node, schema, path, errors) {
|
|
|
182
191
|
addError(errors, node, path, 'schema_mismatch', 'Expected boolean value.');
|
|
183
192
|
return undefined;
|
|
184
193
|
}
|
|
185
|
-
|
|
194
|
+
const normalizedBoolean = normalizeBooleanLiteral(value);
|
|
195
|
+
if (!normalizedBoolean) {
|
|
186
196
|
addError(errors, node, path, 'invalid_value', 'Invalid boolean value.', value);
|
|
187
197
|
return undefined;
|
|
188
198
|
}
|
|
189
|
-
return
|
|
199
|
+
return normalizedBoolean === 'true';
|
|
190
200
|
}
|
|
191
201
|
case 'enum': {
|
|
192
202
|
const value = readScalar(node);
|
|
@@ -194,11 +204,15 @@ function mapWithSchema(node, schema, path, errors) {
|
|
|
194
204
|
addError(errors, node, path, 'schema_mismatch', 'Expected enum value.');
|
|
195
205
|
return undefined;
|
|
196
206
|
}
|
|
197
|
-
|
|
207
|
+
const normalizedBoolean = normalizeBooleanLiteral(value);
|
|
208
|
+
const enumValue = normalizedBoolean && schema.values.includes(normalizedBoolean)
|
|
209
|
+
? normalizedBoolean
|
|
210
|
+
: value;
|
|
211
|
+
if (!schema.values.includes(enumValue)) {
|
|
198
212
|
addError(errors, node, path, 'invalid_value', 'Invalid enum value.', value);
|
|
199
213
|
return undefined;
|
|
200
214
|
}
|
|
201
|
-
return
|
|
215
|
+
return enumValue;
|
|
202
216
|
}
|
|
203
217
|
case 'array': {
|
|
204
218
|
if (node.kind === 'array') {
|
package/lib/syntax/parser.js
CHANGED
|
@@ -27,6 +27,13 @@ function getIndentInfo(line) {
|
|
|
27
27
|
function stripComments(content) {
|
|
28
28
|
return content.trimEnd();
|
|
29
29
|
}
|
|
30
|
+
function isCommentLine(content) {
|
|
31
|
+
const trimmed = content.trimStart();
|
|
32
|
+
return trimmed.startsWith('#') || trimmed.startsWith('//');
|
|
33
|
+
}
|
|
34
|
+
function isCodeFenceLine(content) {
|
|
35
|
+
return /^```[\w-]*\s*$/.test(content.trim());
|
|
36
|
+
}
|
|
30
37
|
function looksLikeRelationExpression(text) {
|
|
31
38
|
return /[<>=o.x-]{2,}/.test(text);
|
|
32
39
|
}
|
|
@@ -137,6 +144,8 @@ function parseSyntaxToAst(input) {
|
|
|
137
144
|
if (!line.trim())
|
|
138
145
|
return;
|
|
139
146
|
const { indent, content } = getIndentInfo(line);
|
|
147
|
+
if (isCommentLine(content) || isCodeFenceLine(content))
|
|
148
|
+
return;
|
|
140
149
|
const stripped = stripComments(content);
|
|
141
150
|
if (!stripped.trim())
|
|
142
151
|
return;
|
package/lib/syntax/types.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export interface ArrayNode {
|
|
|
16
16
|
line: number;
|
|
17
17
|
items: SyntaxNode[];
|
|
18
18
|
}
|
|
19
|
-
export type SyntaxErrorCode = 'unknown_key' | 'schema_mismatch' | 'invalid_value' | 'bad_indent' | 'bad_list' | 'bad_syntax';
|
|
19
|
+
export type SyntaxErrorCode = 'implicit_template' | 'unknown_key' | 'schema_mismatch' | 'invalid_value' | 'bad_indent' | 'bad_list' | 'bad_syntax';
|
|
20
20
|
export interface SyntaxError {
|
|
21
21
|
path: string;
|
|
22
22
|
line: number;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { TemplateOptions } from './types';
|
|
2
2
|
export declare function registerTemplate(type: string, template: TemplateOptions): void;
|
|
3
|
+
export declare function resolveTemplateKey(type: string): string | undefined;
|
|
3
4
|
export declare function getTemplate(type: string): TemplateOptions | undefined;
|
|
4
5
|
export declare function getTemplates(): string[];
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.registerTemplate = registerTemplate;
|
|
4
|
+
exports.resolveTemplateKey = resolveTemplateKey;
|
|
4
5
|
exports.getTemplate = getTemplate;
|
|
5
6
|
exports.getTemplates = getTemplates;
|
|
7
|
+
const utils_1 = require("./utils");
|
|
6
8
|
const TEMPLATE_REGISTRY = new Map();
|
|
7
9
|
function registerTemplate(type, template) {
|
|
8
10
|
TEMPLATE_REGISTRY.set(type, template);
|
|
9
11
|
}
|
|
12
|
+
function resolveTemplateKey(type) {
|
|
13
|
+
if (TEMPLATE_REGISTRY.has(type))
|
|
14
|
+
return type;
|
|
15
|
+
return (0, utils_1.findClosestTemplateKey)(type, TEMPLATE_REGISTRY.keys());
|
|
16
|
+
}
|
|
10
17
|
function getTemplate(type) {
|
|
11
18
|
return TEMPLATE_REGISTRY.get(type);
|
|
12
19
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function findClosestTemplateKey(type: string, keys: Iterable<string>): string | undefined;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.findClosestTemplateKey = findClosestTemplateKey;
|
|
4
|
+
function normalizeTemplateKey(type) {
|
|
5
|
+
return type
|
|
6
|
+
.trim()
|
|
7
|
+
.toLowerCase()
|
|
8
|
+
.replace(/[_\s]+/g, '-')
|
|
9
|
+
.replace(/-+/g, '-');
|
|
10
|
+
}
|
|
11
|
+
function getLevenshteinDistance(source, target) {
|
|
12
|
+
if (source === target)
|
|
13
|
+
return 0;
|
|
14
|
+
if (!source.length)
|
|
15
|
+
return target.length;
|
|
16
|
+
if (!target.length)
|
|
17
|
+
return source.length;
|
|
18
|
+
const previous = Array.from({ length: target.length + 1 }, (_, index) => index);
|
|
19
|
+
const current = new Array(target.length + 1);
|
|
20
|
+
for (let sourceIndex = 1; sourceIndex <= source.length; sourceIndex += 1) {
|
|
21
|
+
current[0] = sourceIndex;
|
|
22
|
+
const sourceCode = source.charCodeAt(sourceIndex - 1);
|
|
23
|
+
for (let targetIndex = 1; targetIndex <= target.length; targetIndex += 1) {
|
|
24
|
+
const replaceCost = sourceCode === target.charCodeAt(targetIndex - 1) ? 0 : 1;
|
|
25
|
+
current[targetIndex] = Math.min(previous[targetIndex] + 1, current[targetIndex - 1] + 1, previous[targetIndex - 1] + replaceCost);
|
|
26
|
+
}
|
|
27
|
+
for (let index = 0; index < current.length; index += 1) {
|
|
28
|
+
previous[index] = current[index];
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return previous[target.length];
|
|
32
|
+
}
|
|
33
|
+
function getCommonPrefixLength(source, target) {
|
|
34
|
+
const limit = Math.min(source.length, target.length);
|
|
35
|
+
let index = 0;
|
|
36
|
+
while (index < limit &&
|
|
37
|
+
source.charCodeAt(index) === target.charCodeAt(index)) {
|
|
38
|
+
index += 1;
|
|
39
|
+
}
|
|
40
|
+
return index;
|
|
41
|
+
}
|
|
42
|
+
function isBetterMatch(bestMatch, bestDistance, bestPrefixLength, candidateKey, candidateDistance, candidatePrefixLength) {
|
|
43
|
+
return (candidateDistance < bestDistance ||
|
|
44
|
+
(candidateDistance === bestDistance &&
|
|
45
|
+
candidatePrefixLength > bestPrefixLength) ||
|
|
46
|
+
(candidateDistance === bestDistance &&
|
|
47
|
+
candidatePrefixLength === bestPrefixLength &&
|
|
48
|
+
(!bestMatch || candidateKey < bestMatch)));
|
|
49
|
+
}
|
|
50
|
+
function findClosestTemplateKey(type, keys) {
|
|
51
|
+
const normalizedType = normalizeTemplateKey(type);
|
|
52
|
+
if (!normalizedType)
|
|
53
|
+
return undefined;
|
|
54
|
+
let bestMatch;
|
|
55
|
+
let bestDistance = Number.POSITIVE_INFINITY;
|
|
56
|
+
let bestPrefixLength = -1;
|
|
57
|
+
for (const key of keys) {
|
|
58
|
+
const normalizedKey = normalizeTemplateKey(key);
|
|
59
|
+
if (normalizedKey === normalizedType) {
|
|
60
|
+
return key;
|
|
61
|
+
}
|
|
62
|
+
const distance = getLevenshteinDistance(normalizedType, normalizedKey);
|
|
63
|
+
const prefixLength = getCommonPrefixLength(normalizedType, normalizedKey);
|
|
64
|
+
if (isBetterMatch(bestMatch, bestDistance, bestPrefixLength, key, distance, prefixLength)) {
|
|
65
|
+
bestMatch = key;
|
|
66
|
+
bestDistance = distance;
|
|
67
|
+
bestPrefixLength = prefixLength;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return bestMatch;
|
|
71
|
+
}
|
package/lib/themes/built-in.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const registry_1 = require("./registry");
|
|
4
|
+
(0, registry_1.registerTheme)('light', {
|
|
5
|
+
colorBg: '#ffffff',
|
|
6
|
+
});
|
|
4
7
|
(0, registry_1.registerTheme)('dark', {
|
|
5
8
|
colorBg: '#1F1F1F',
|
|
6
9
|
base: {
|
package/lib/utils/padding.js
CHANGED
package/lib/utils/style.d.ts
CHANGED
package/lib/utils/style.js
CHANGED
|
@@ -1,11 +1,34 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.injectStyleOnce = injectStyleOnce;
|
|
4
|
-
function
|
|
5
|
-
if (
|
|
4
|
+
function resolveStyleRoot(target) {
|
|
5
|
+
if (!target)
|
|
6
|
+
return document;
|
|
7
|
+
if (target instanceof Document || target instanceof ShadowRoot)
|
|
8
|
+
return target;
|
|
9
|
+
if (!target.isConnected)
|
|
10
|
+
return document;
|
|
11
|
+
const root = target.getRootNode();
|
|
12
|
+
return root instanceof ShadowRoot ? root : document;
|
|
13
|
+
}
|
|
14
|
+
function hasStyle(root, id) {
|
|
15
|
+
if (root instanceof Document)
|
|
16
|
+
return Boolean(root.getElementById(id));
|
|
17
|
+
return Boolean(root.querySelector(`#${id}`));
|
|
18
|
+
}
|
|
19
|
+
function injectStyleOnce(id, styles, target) {
|
|
20
|
+
var _a;
|
|
21
|
+
const root = resolveStyleRoot(target);
|
|
22
|
+
if (hasStyle(root, id))
|
|
6
23
|
return;
|
|
7
|
-
const
|
|
24
|
+
const doc = root instanceof Document ? root : ((_a = root.ownerDocument) !== null && _a !== void 0 ? _a : document);
|
|
25
|
+
const style = doc.createElement('style');
|
|
8
26
|
style.id = id;
|
|
9
27
|
style.textContent = styles;
|
|
10
|
-
|
|
28
|
+
if (root instanceof Document) {
|
|
29
|
+
root.head.appendChild(style);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
root.appendChild(style);
|
|
33
|
+
}
|
|
11
34
|
}
|
package/lib/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "0.2.
|
|
1
|
+
export declare const VERSION = "0.2.18";
|
package/lib/version.js
CHANGED
package/package.json
CHANGED
package/src/constants/service.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const ICON_SERVICE_URL = 'https://www.weavefox.cn/api/
|
|
1
|
+
export const ICON_SERVICE_URL = 'https://www.weavefox.cn/api/v1/infographic/icon';
|
|
@@ -18,6 +18,9 @@ export interface ChartLineProps extends BaseStructureProps {
|
|
|
18
18
|
valueFormatter?: (value: number, datum: ItemDatum) => string;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
const ITEM_POSITION_H = 'center' as const;
|
|
22
|
+
const ITEM_POSITION_V = 'normal' as const;
|
|
23
|
+
|
|
21
24
|
export const ChartLine: ComponentType<ChartLineProps> = (props) => {
|
|
22
25
|
const {
|
|
23
26
|
Title,
|
|
@@ -55,8 +58,8 @@ export const ChartLine: ComponentType<ChartLineProps> = (props) => {
|
|
|
55
58
|
indexes: [0],
|
|
56
59
|
datum: items[0],
|
|
57
60
|
data,
|
|
58
|
-
positionH:
|
|
59
|
-
positionV:
|
|
61
|
+
positionH: ITEM_POSITION_H,
|
|
62
|
+
positionV: ITEM_POSITION_V,
|
|
60
63
|
};
|
|
61
64
|
const sampleBounds = getElementBounds(<Item {...itemProps} />);
|
|
62
65
|
const labelWidth = sampleBounds.width;
|
|
@@ -121,6 +124,8 @@ export const ChartLine: ComponentType<ChartLineProps> = (props) => {
|
|
|
121
124
|
const tickElements: JSXElement[] = [];
|
|
122
125
|
|
|
123
126
|
const ticksY = scaleY.ticks(6);
|
|
127
|
+
const formatTickY = scaleY.tickFormat(6);
|
|
128
|
+
|
|
124
129
|
ticksY.forEach((tick) => {
|
|
125
130
|
const yPos = chartOriginY + scaleY(tick);
|
|
126
131
|
gridElements.push(
|
|
@@ -145,7 +150,7 @@ export const ChartLine: ComponentType<ChartLineProps> = (props) => {
|
|
|
145
150
|
fontSize={12}
|
|
146
151
|
fill={axisColor}
|
|
147
152
|
>
|
|
148
|
-
{
|
|
153
|
+
{formatTickY(tick)}
|
|
149
154
|
</Text>,
|
|
150
155
|
);
|
|
151
156
|
});
|
|
@@ -394,7 +399,6 @@ export const ChartLine: ComponentType<ChartLineProps> = (props) => {
|
|
|
394
399
|
</linearGradient>
|
|
395
400
|
<linearGradient id={gradientAreaId} x1="0%" y1="0%" x2="100%" y2="0%">
|
|
396
401
|
{areaStops}
|
|
397
|
-
<stop offset="100%" stopColor={colorPrimary} stopOpacity="0.04" />
|
|
398
402
|
</linearGradient>
|
|
399
403
|
</Defs>
|
|
400
404
|
<Group>{gridElements}</Group>
|
|
@@ -92,7 +92,7 @@ function editText(text: TextElement, options?: EditTextOptions) {
|
|
|
92
92
|
const entity = getTextEntity(text);
|
|
93
93
|
if (!entity) return;
|
|
94
94
|
|
|
95
|
-
ensureEditorStyles();
|
|
95
|
+
ensureEditorStyles(entity);
|
|
96
96
|
new InlineTextEditor(entity, options).start();
|
|
97
97
|
}
|
|
98
98
|
|
|
@@ -240,7 +240,7 @@ class InlineTextEditor {
|
|
|
240
240
|
}
|
|
241
241
|
}
|
|
242
242
|
|
|
243
|
-
function ensureEditorStyles() {
|
|
243
|
+
function ensureEditorStyles(target?: Node) {
|
|
244
244
|
injectStyleOnce(
|
|
245
245
|
EDITOR_STYLE_ID,
|
|
246
246
|
`
|
|
@@ -256,5 +256,6 @@ function ensureEditorStyles() {
|
|
|
256
256
|
background-color: #b3d4fc;
|
|
257
257
|
}
|
|
258
258
|
`,
|
|
259
|
+
target,
|
|
259
260
|
);
|
|
260
261
|
}
|
|
@@ -16,6 +16,7 @@ import type {
|
|
|
16
16
|
SelectionChangePayload,
|
|
17
17
|
SelectMode,
|
|
18
18
|
} from '../types';
|
|
19
|
+
import { eventPathContains } from '../utils';
|
|
19
20
|
import { Extension } from '../utils';
|
|
20
21
|
|
|
21
22
|
export class InteractionManager implements IInteractionManager {
|
|
@@ -129,18 +130,19 @@ export class InteractionManager implements IInteractionManager {
|
|
|
129
130
|
|
|
130
131
|
private handleClick = (event: MouseEvent) => {
|
|
131
132
|
const doc = this.editor.getDocument();
|
|
132
|
-
const
|
|
133
|
+
const path = typeof event.composedPath === 'function' ? event.composedPath() : [];
|
|
134
|
+
const insideInfographic =
|
|
135
|
+
eventPathContains(event, doc) ||
|
|
136
|
+
path.some(
|
|
137
|
+
(node) => node instanceof HTMLElement && isInfographicComponent(node),
|
|
138
|
+
);
|
|
133
139
|
|
|
134
|
-
if (!target) {
|
|
140
|
+
if (!event.target) {
|
|
135
141
|
this.deactivate();
|
|
136
142
|
return;
|
|
137
143
|
}
|
|
138
144
|
// 点击画布 SVG 或者标记为组件的元素
|
|
139
|
-
if (
|
|
140
|
-
doc.contains(target as Node) ||
|
|
141
|
-
isInfographicComponent(target as HTMLElement)
|
|
142
|
-
)
|
|
143
|
-
this.activate();
|
|
145
|
+
if (insideInfographic) this.activate();
|
|
144
146
|
else this.deactivate();
|
|
145
147
|
};
|
|
146
148
|
|
|
@@ -7,6 +7,7 @@ export interface IconButtonProps {
|
|
|
7
7
|
icon: Icon;
|
|
8
8
|
onClick?: () => void;
|
|
9
9
|
activate?: boolean;
|
|
10
|
+
root?: Node;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
export interface IconButtonHandle {
|
|
@@ -18,8 +19,9 @@ export const IconButton = ({
|
|
|
18
19
|
icon,
|
|
19
20
|
onClick,
|
|
20
21
|
activate = false,
|
|
22
|
+
root,
|
|
21
23
|
}: IconButtonProps): Button => {
|
|
22
|
-
ensureIconButtonStyle();
|
|
24
|
+
ensureIconButtonStyle(root);
|
|
23
25
|
|
|
24
26
|
const button = document.createElement('button');
|
|
25
27
|
button.type = 'button';
|
|
@@ -44,7 +46,7 @@ export const IconButton = ({
|
|
|
44
46
|
const ICON_BUTTON_CLASS = 'infographic-edit-bar-icon-btn';
|
|
45
47
|
const ICON_BUTTON_STYLE_ID = 'infographic-edit-bar-icon-btn-style';
|
|
46
48
|
|
|
47
|
-
function ensureIconButtonStyle() {
|
|
49
|
+
function ensureIconButtonStyle(target?: Node) {
|
|
48
50
|
injectStyleOnce(
|
|
49
51
|
ICON_BUTTON_STYLE_ID,
|
|
50
52
|
`
|
|
@@ -73,5 +75,6 @@ function ensureIconButtonStyle() {
|
|
|
73
75
|
background-color: #d9d9d9;
|
|
74
76
|
}
|
|
75
77
|
`,
|
|
78
|
+
target,
|
|
76
79
|
);
|
|
77
80
|
}
|
|
@@ -6,6 +6,7 @@ export type ColorPickerProps = {
|
|
|
6
6
|
value?: string;
|
|
7
7
|
swatches?: string[];
|
|
8
8
|
onChange?: (value: string) => void;
|
|
9
|
+
root?: Node;
|
|
9
10
|
};
|
|
10
11
|
|
|
11
12
|
export type ColorPickerHandle = {
|
|
@@ -66,7 +67,7 @@ export function ColorPicker(
|
|
|
66
67
|
throw new Error('ColorPicker can only be used in the browser.');
|
|
67
68
|
}
|
|
68
69
|
|
|
69
|
-
ensureColorPickerStyles();
|
|
70
|
+
ensureColorPickerStyles(props.root);
|
|
70
71
|
|
|
71
72
|
const container = document.createElement('div');
|
|
72
73
|
container.classList.add(COLOR_PICKER_CLASS);
|
|
@@ -279,7 +280,7 @@ function createSwitchLabel(text: string): HTMLSpanElement {
|
|
|
279
280
|
return span;
|
|
280
281
|
}
|
|
281
282
|
|
|
282
|
-
function ensureColorPickerStyles() {
|
|
283
|
+
function ensureColorPickerStyles(target?: Node) {
|
|
283
284
|
injectStyleOnce(
|
|
284
285
|
COLOR_PICKER_STYLE_ID,
|
|
285
286
|
`
|
|
@@ -393,5 +394,6 @@ function ensureColorPickerStyles() {
|
|
|
393
394
|
color: #ffffff;
|
|
394
395
|
}
|
|
395
396
|
`,
|
|
397
|
+
target,
|
|
396
398
|
);
|
|
397
399
|
}
|