infographic-creator

安装量: 404
排名: #2410

安装

npx skills add https://github.com/antvis/chart-visualization-skills --skill infographic-creator

Infographics convert data, information, and knowledge into perceptible visual language. They combine visual design with data visualization, compressing complex information with intuitive symbols to help audiences quickly understand and remember key points.

Infographic = Information Structure + Visual Expression

This task uses AntV Infographic to create visual infographics.

Before starting the task, you need to understand the AntV Infographic syntax specifications, including template list, data structure, themes, etc.

Specifications AntV Infographic Syntax

AntV Infographic syntax is a custom DSL used to describe infographic rendering configurations. It uses indentation to describe information, has strong robustness, and is convenient for AI streaming output and infographic rendering. It mainly contains the following information:

template: Use templates to express the text information structure. data: Infographic data, including title, desc, data items, etc. Data items typically contain fields such as label, desc, icon, etc. theme: Theme contains style configurations such as palette, font, etc.

For example:

infographic list-row-horizontal-icon-arrow data title Title desc Description lists - label Label value 12.5 desc Explanation icon document text theme palette #3b82f6 #8b5cf6 #f97316

Syntax Specifications

The first line must be infographic , template selected from the list below (see "Available Templates" section).

Use data / theme blocks, with two-space indentation within blocks.

Key-value pairs use "key space value"; arrays use - as entry prefix.

icon uses icon keywords (e.g., star fill).

data should contain title/desc + template-specific main data field (not necessarily items).

Main data field selection (use only one, avoid mixing):

list- → lists sequence- → sequences (optional order asc|desc) compare- → compares (supports children for grouped comparisons), can contain multiple comparison items hierarchy-structure → items (each item corresponds to an independent hierarchy, each level can contain sub-items, can be nested up to 3 levels) hierarchy- → single root (tree structure, nested through children); relation- → nodes + relations; simple relation diagrams can omit nodes, using arrow syntax in relations chart- → values (numeric statistics, optional category) Use items as fallback when uncertain

compare-binary- / compare-hierarchy-left-right- binary templates: must have two root nodes, all comparison items hang under these two root nodes' children

hierarchy-*: use single root, nested through children (do not repeat root)

theme is used to customize themes (palette, font, etc.) For example: dark theme + custom color scheme

infographic list-row-horizontal-icon-arrow theme dark palette - #61DDAA - #F6BD16 - #F08BB4

Use theme.base.text.font-family to specify font, such as handwriting style 851tegakizatsu

Use theme.stylize to select built-in styles and pass parameters Common styles:

rough: hand-drawn effect pattern: pattern fill linear-gradient / radial-gradient: linear/radial gradient

For example: hand-drawn style (rough)

infographic list-row-horizontal-icon-arrow theme stylize rough base text font-family 851tegakizatsu

Do not output JSON, Markdown, or explanatory text

Data Syntax Examples

Data syntax examples by template category (use corresponding fields, avoid adding items simultaneously):

list-* templates infographic list-grid-badge-card data title Feature List lists - label Fast icon flash fast - label Secure icon secure shield check

sequence-* templates infographic sequence-steps-simple data sequences - label Step 1 - label Step 2 - label Step 3 order asc

hierarchy-* templates infographic hierarchy-structure data root label Company children - label Dept A - label Dept B

compare-* templates infographic compare-swot data compares - label Strengths children - label Strong brand - label Loyal users - label Weaknesses children - label High cost - label Slow release

Quadrant diagram

infographic compare-quadrant-quarter-simple-card data compares - label High Impact & Low Effort - label High Impact & High Effort - label Low Impact & Low Effort - label Low Impact & High Effort

chart-* templates infographic chart-column-simple data values - label Visits value 1280 - label Conversion value 12.4

relation-* templates

Edge label syntax: A -label-> B or A -->|label| B

infographic relation-dagre-flow-tb-simple-circle-node data nodes - id A label Node A - id B label Node B relations A - approves -> B A -->|blocks| B

Fallback items example infographic list-row-horizontal-icon-arrow data items - label Item A desc Description icon sun - label Item B desc Description icon moon

Available Templates chart-bar-plain-text chart-column-simple chart-line-plain-text chart-pie-compact-card chart-pie-donut-pill-badge chart-pie-donut-plain-text chart-pie-plain-text chart-wordcloud compare-binary-horizontal-badge-card-arrow compare-binary-horizontal-simple-fold compare-binary-horizontal-underline-text-vs compare-hierarchy-left-right-circle-node-pill-badge compare-quadrant-quarter-circular compare-quadrant-quarter-simple-card compare-swot hierarchy-mindmap-branch-gradient-capsule-item hierarchy-mindmap-level-gradient-compact-card hierarchy-structure hierarchy-tree-curved-line-rounded-rect-node hierarchy-tree-tech-style-badge-card hierarchy-tree-tech-style-capsule-item list-column-done-list list-column-simple-vertical-arrow list-column-vertical-icon-arrow list-grid-badge-card list-grid-candy-card-lite list-grid-ribbon-card list-row-horizontal-icon-arrow list-sector-plain-text list-zigzag-down-compact-card list-zigzag-down-simple list-zigzag-up-compact-card list-zigzag-up-simple relation-dagre-flow-tb-animated-badge-card relation-dagre-flow-tb-animated-simple-circle-node relation-dagre-flow-tb-badge-card relation-dagre-flow-tb-simple-circle-node sequence-ascending-stairs-3d-underline-text sequence-ascending-steps sequence-circular-simple sequence-color-snake-steps-horizontal-icon-line sequence-cylinders-3d-simple sequence-filter-mesh-simple sequence-funnel-simple sequence-horizontal-zigzag-underline-text sequence-mountain-underline-text sequence-pyramid-simple sequence-roadmap-vertical-plain-text sequence-roadmap-vertical-simple sequence-snake-steps-compact-card sequence-snake-steps-simple sequence-snake-steps-underline-text sequence-stairs-front-compact-card sequence-stairs-front-pill-badge sequence-timeline-rounded-rect-node sequence-timeline-simple sequence-zigzag-pucks-3d-simple sequence-zigzag-steps-underline-text

Template Selection Recommendations:

Strict sequence (process/steps/development trend) → sequence- Timeline → sequence-timeline- Staircase diagram → sequence-stairs- Roadmap → sequence-roadmap-vertical- Zigzag path → sequence-zigzag- Circular progress → sequence-circular-simple Colorful snake steps → sequence-color-snake-steps- Pyramid → sequence-pyramid-simple Opinion listing → list-row- or list-column- Binary comparison (pros/cons) → compare-binary- SWOT → compare-swot Hierarchical structure (tree diagram) → hierarchy-tree- Data charts → chart- Quadrant analysis → compare-quadrant- Grid list (key points) → list-grid- Relationship display → relation- Word cloud → chart-wordcloud Mind map → hierarchy-mindmap-* Example

Creating an Internet technology evolution infographic

infographic list-row-horizontal-icon-arrow data title Internet Technology Evolution desc From Web 1.0 to AI era, key milestones lists - time 1991 label Web 1.0 desc Tim Berners-Lee published the first website, opening the Internet era icon web - time 2004 label Web 2.0 desc Social media and user-generated content become mainstream icon account multiple - time 2007 label Mobile desc iPhone released, smartphone changes the world icon cellphone - time 2015 label Cloud Native desc Containerization and microservices architecture are widely used icon cloud - time 2020 label Low Code desc Visual development lowers the technology threshold icon application brackets - time 2023 label AI Large Model desc ChatGPT ignites the generative AI revolution icon brain

Generation Process Step 1: Understand User Requirements

Before creating an infographic, first understand the user's needs and the information they want to express, in order to determine the template and data structure.

If the user provides a clear content description, it should be broken down into a clear and concise structure.

Otherwise, clarification from the user is needed (e.g., "Please provide a clear and concise content description.", "Which template do you want to use?")

Extract key information structure (title, desc, items, etc.). Clarify required data fields (title, desc, items, label, value, icon, etc.). Select appropriate template. Describe infographic content using AntV Infographic syntax {syntax}.

Key Note: Must respect the language of user input. For example, if the user inputs in Chinese, the text in the syntax must also be in Chinese.

Step 2: Render the Infographic

When you have the final AntV Infographic syntax, you can generate a complete HTML file following these steps:

Create a complete HTML file with the following structure: DOCTYPE and HTML meta (charset: utf-8) Title: {title} - Infographic Include AntV Infographic script: https://unpkg.com/@antv/infographic@latest/dist/infographic.min.js Create container div with id container Initialize Infographic (width: '100%', height: '100%') Replace {title} with actual title Replace {syntax} with actual AntV Infographic syntax Add SVG export functionality: const svgDataUrl = await infographic.toDataURL({ type: 'svg' });

Reference HTML template:

Use the Write tool to generate HTML file, named as -infographic.html</p> <p>Show to user:</p> <p>Generate file path and prompt: "Open directly with a browser to view and save as SVG" Output syntax and prompt: "Tell me if you need to adjust template/colors/content"</p> <p>Note: The HTML file must include:</p> <p>SVG export via export button Container is responsive, both width and height are 100%</p> </article> <a href="/" class="back-link">← <span data-i18n="detail.backToLeaderboard">返回排行榜</span></a> </div> <aside class="sidebar"> <section class="related-skills" id="relatedSkillsSection"> <h2 class="related-title" data-i18n="detail.relatedSkills">相关 Skills</h2> <div class="related-list" id="relatedSkillsList"> <div class="skeleton-card"></div> <div class="skeleton-card"></div> <div class="skeleton-card"></div> </div> </section> </aside> </div> </div> <script src="https://unpkg.com/i18next@23.11.5/i18next.min.js" defer></script> <script src="https://unpkg.com/i18next-browser-languagedetector@7.2.1/i18nextBrowserLanguageDetector.min.js" defer></script> <script defer> // Language resources - same pattern as index page const resources = { 'zh-CN': null, 'en': null, 'ja': null, 'ko': null, 'zh-TW': null, 'es': null, 'fr': null }; // Load language files (only current + fallback for performance) async function loadLanguageResources() { const savedLang = localStorage.getItem('i18nextLng') || 'en'; const langsToLoad = new Set([savedLang, 'en']); // current + fallback await Promise.all([...langsToLoad].map(async (lang) => { try { const response = await fetch(`/locales/${lang}.json`); if (response.ok) { resources[lang] = { translation: await response.json() }; } } catch (error) { console.warn(`Failed to load ${lang} language file:`, error); } })); } // Load a single language on demand (for language switching) async function loadLanguage(lang) { if (resources[lang]) return; try { const response = await fetch(`/locales/${lang}.json`); if (response.ok) { resources[lang] = { translation: await response.json() }; i18next.addResourceBundle(lang, 'translation', resources[lang].translation); } } catch (error) { console.warn(`Failed to load ${lang} language file:`, error); } } // Initialize i18next async function initI18n() { try { await loadLanguageResources(); // Filter out null values from resources const validResources = {}; for (const [lang, data] of Object.entries(resources)) { if (data !== null) { validResources[lang] = data; } } console.log('Loaded languages:', Object.keys(validResources)); console.log('zh-CN resource:', validResources['zh-CN']); console.log('detail.home in resource:', validResources['zh-CN']?.translation?.detail?.home); // 检查是否有保存的语言偏好 const savedLang = localStorage.getItem('i18nextLng'); // 如果没有保存的语言偏好,默认使用英文 const defaultLang = savedLang && ['zh-CN', 'en', 'ja', 'ko', 'zh-TW', 'es', 'fr'].includes(savedLang) ? savedLang : 'en'; await i18next .use(i18nextBrowserLanguageDetector) .init({ lng: defaultLang, // 强制设置初始语言 fallbackLng: 'en', supportedLngs: ['zh-CN', 'en', 'ja', 'ko', 'zh-TW', 'es', 'fr'], resources: validResources, detection: { order: ['localStorage'], // 只使用 localStorage,不检测浏览器语言 caches: ['localStorage'], lookupLocalStorage: 'i18nextLng' }, interpolation: { escapeValue: false } }); console.log('i18next initialized, language:', i18next.language); console.log('Test translation:', i18next.t('detail.home')); // Set initial language in selector const langSwitcher = document.getElementById('langSwitcher'); langSwitcher.value = i18next.language; // Update page language updatePageLanguage(); // Language switch event langSwitcher.addEventListener('change', async (e) => { await loadLanguage(e.target.value); // load on demand i18next.changeLanguage(e.target.value).then(() => { updatePageLanguage(); localStorage.setItem('i18nextLng', e.target.value); }); }); } catch (error) { console.error('i18next init failed:', error); } } // Translation helper function t(key, options = {}) { return i18next.t(key, options); } // Update all translatable elements function updatePageLanguage() { // Update HTML lang attribute document.documentElement.lang = i18next.language; // Update elements with data-i18n attribute document.querySelectorAll('[data-i18n]').forEach(el => { const key = el.getAttribute('data-i18n'); el.textContent = t(key); }); } // Copy command function function copyCommand() { const command = document.getElementById('installCommand').textContent; const btn = document.getElementById('copyBtn'); navigator.clipboard.writeText(command).then(() => { btn.textContent = t('copied'); btn.classList.add('copied'); setTimeout(() => { btn.textContent = t('copy'); btn.classList.remove('copied'); }, 2000); }).catch(() => { // Fallback for non-HTTPS const textArea = document.createElement('textarea'); textArea.value = command; textArea.style.position = 'fixed'; textArea.style.left = '-9999px'; document.body.appendChild(textArea); textArea.select(); document.execCommand('copy'); document.body.removeChild(textArea); btn.textContent = t('copied'); btn.classList.add('copied'); setTimeout(() => { btn.textContent = t('copy'); btn.classList.remove('copied'); }, 2000); }); } // Initialize document.getElementById('copyBtn').addEventListener('click', copyCommand); initI18n(); // 异步加载相关 Skills async function loadRelatedSkills() { const owner = 'antvis'; const skillName = 'infographic-creator'; const currentLang = 'zh-TW'; const listContainer = document.getElementById('relatedSkillsList'); const section = document.getElementById('relatedSkillsSection'); try { const response = await fetch(`/api/related-skills/${encodeURIComponent(owner)}/${encodeURIComponent(skillName)}?limit=6`); if (!response.ok) { throw new Error('Failed to load'); } const data = await response.json(); const relatedSkills = data.related_skills || []; if (relatedSkills.length === 0) { // 没有相关推荐时隐藏整个区域 section.style.display = 'none'; return; } // 渲染相关 Skills listContainer.innerHTML = relatedSkills.map(skill => { const desc = skill.description || ''; const truncatedDesc = desc.length > 60 ? desc.substring(0, 60) + '...' : desc; return ` <a href="${currentLang === 'en' ? '' : '/' + currentLang}/skill/${skill.owner}/${skill.repo}/${skill.skill_name}" class="related-card"> <div class="related-name">${escapeHtml(skill.skill_name)}</div> <div class="related-meta"> <span class="related-owner">${escapeHtml(skill.owner)}</span> <span class="related-installs">${skill.installs}</span> </div> <div class="related-desc">${escapeHtml(truncatedDesc)}</div> </a> `; }).join(''); } catch (error) { console.error('Failed to load related skills:', error); // 加载失败时显示提示或隐藏 listContainer.innerHTML = '<div class="related-empty">暂无相关推荐</div>'; } } // HTML 转义 function escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } // 页面加载完成后异步加载相关 Skills if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', loadRelatedSkills); } else { loadRelatedSkills(); } </script> </body> </html>