pi-feishu-cli 0.1.0
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/LICENSE +21 -0
- package/README.md +111 -0
- package/dist/src/bot.d.ts +29 -0
- package/dist/src/bot.js +75 -0
- package/dist/src/cards.d.ts +6 -0
- package/dist/src/cards.js +87 -0
- package/dist/src/config.d.ts +3 -0
- package/dist/src/config.js +28 -0
- package/dist/src/daemon.d.ts +2 -0
- package/dist/src/daemon.js +151 -0
- package/dist/src/extension.d.ts +2 -0
- package/dist/src/extension.js +124 -0
- package/dist/src/poller.d.ts +33 -0
- package/dist/src/poller.js +94 -0
- package/dist/src/renderer.d.ts +8 -0
- package/dist/src/renderer.js +31 -0
- package/dist/src/session-registry.d.ts +15 -0
- package/dist/src/session-registry.js +82 -0
- package/dist/src/types.d.ts +25 -0
- package/dist/src/types.js +1 -0
- package/dist/tests/bot.test.d.ts +1 -0
- package/dist/tests/bot.test.js +89 -0
- package/dist/tests/cards.test.d.ts +1 -0
- package/dist/tests/cards.test.js +39 -0
- package/dist/tests/config.test.d.ts +1 -0
- package/dist/tests/config.test.js +59 -0
- package/dist/tests/renderer.test.d.ts +1 -0
- package/dist/tests/renderer.test.js +61 -0
- package/dist/tests/session-registry.test.d.ts +1 -0
- package/dist/tests/session-registry.test.js +92 -0
- package/dist/tests/types.test.d.ts +1 -0
- package/dist/tests/types.test.js +30 -0
- package/package.json +35 -0
- package/skills/lark-approval/SKILL.md +56 -0
- package/skills/lark-apps/SKILL.md +92 -0
- package/skills/lark-apps/references/lark-apps-access-scope-get.md +104 -0
- package/skills/lark-apps/references/lark-apps-access-scope-set.md +126 -0
- package/skills/lark-apps/references/lark-apps-create.md +112 -0
- package/skills/lark-apps/references/lark-apps-html-publish.md +151 -0
- package/skills/lark-apps/references/lark-apps-list.md +95 -0
- package/skills/lark-apps/references/lark-apps-update.md +86 -0
- package/skills/lark-attendance/SKILL.md +57 -0
- package/skills/lark-base/SKILL.md +359 -0
- package/skills/lark-base/references/dashboard-block-data-config.md +350 -0
- package/skills/lark-base/references/examples.md +140 -0
- package/skills/lark-base/references/formula-field-guide.md +737 -0
- package/skills/lark-base/references/lark-base-advperm-disable.md +83 -0
- package/skills/lark-base/references/lark-base-advperm-enable.md +80 -0
- package/skills/lark-base/references/lark-base-base-copy.md +74 -0
- package/skills/lark-base/references/lark-base-base-create.md +68 -0
- package/skills/lark-base/references/lark-base-base-get.md +39 -0
- package/skills/lark-base/references/lark-base-cell-value.md +151 -0
- package/skills/lark-base/references/lark-base-dashboard-arrange.md +83 -0
- package/skills/lark-base/references/lark-base-dashboard-block-create.md +108 -0
- package/skills/lark-base/references/lark-base-dashboard-block-delete.md +46 -0
- package/skills/lark-base/references/lark-base-dashboard-block-get.md +57 -0
- package/skills/lark-base/references/lark-base-dashboard-block-list.md +53 -0
- package/skills/lark-base/references/lark-base-dashboard-block-update.md +84 -0
- package/skills/lark-base/references/lark-base-dashboard-create.md +73 -0
- package/skills/lark-base/references/lark-base-dashboard-delete.md +44 -0
- package/skills/lark-base/references/lark-base-dashboard-get.md +59 -0
- package/skills/lark-base/references/lark-base-dashboard-list.md +52 -0
- package/skills/lark-base/references/lark-base-dashboard-update.md +69 -0
- package/skills/lark-base/references/lark-base-dashboard.md +240 -0
- package/skills/lark-base/references/lark-base-data-analysis-sop.md +88 -0
- package/skills/lark-base/references/lark-base-data-query.md +375 -0
- package/skills/lark-base/references/lark-base-field-create.md +104 -0
- package/skills/lark-base/references/lark-base-field-delete.md +51 -0
- package/skills/lark-base/references/lark-base-field-get.md +42 -0
- package/skills/lark-base/references/lark-base-field-list.md +44 -0
- package/skills/lark-base/references/lark-base-field-search-options.md +48 -0
- package/skills/lark-base/references/lark-base-field-update.md +97 -0
- package/skills/lark-base/references/lark-base-field.md +22 -0
- package/skills/lark-base/references/lark-base-form-create.md +87 -0
- package/skills/lark-base/references/lark-base-form-delete.md +64 -0
- package/skills/lark-base/references/lark-base-form-detail.md +198 -0
- package/skills/lark-base/references/lark-base-form-get.md +68 -0
- package/skills/lark-base/references/lark-base-form-list.md +73 -0
- package/skills/lark-base/references/lark-base-form-questions-create.md +118 -0
- package/skills/lark-base/references/lark-base-form-questions-delete.md +68 -0
- package/skills/lark-base/references/lark-base-form-questions-list.md +84 -0
- package/skills/lark-base/references/lark-base-form-questions-update.md +92 -0
- package/skills/lark-base/references/lark-base-form-questions.md +23 -0
- package/skills/lark-base/references/lark-base-form-submit.md +171 -0
- package/skills/lark-base/references/lark-base-form-update.md +82 -0
- package/skills/lark-base/references/lark-base-form.md +25 -0
- package/skills/lark-base/references/lark-base-history.md +16 -0
- package/skills/lark-base/references/lark-base-record-batch-create.md +58 -0
- package/skills/lark-base/references/lark-base-record-batch-update.md +53 -0
- package/skills/lark-base/references/lark-base-record-delete.md +62 -0
- package/skills/lark-base/references/lark-base-record-history-list.md +86 -0
- package/skills/lark-base/references/lark-base-record-share-link-create.md +72 -0
- package/skills/lark-base/references/lark-base-record-upsert.md +64 -0
- package/skills/lark-base/references/lark-base-record.md +31 -0
- package/skills/lark-base/references/lark-base-role-create.md +89 -0
- package/skills/lark-base/references/lark-base-role-delete.md +83 -0
- package/skills/lark-base/references/lark-base-role-get.md +87 -0
- package/skills/lark-base/references/lark-base-role-list.md +81 -0
- package/skills/lark-base/references/lark-base-role-update.md +94 -0
- package/skills/lark-base/references/lark-base-shortcut-field-properties.md +481 -0
- package/skills/lark-base/references/lark-base-table-create.md +62 -0
- package/skills/lark-base/references/lark-base-table-delete.md +51 -0
- package/skills/lark-base/references/lark-base-table-get.md +46 -0
- package/skills/lark-base/references/lark-base-table-list.md +43 -0
- package/skills/lark-base/references/lark-base-table-update.md +49 -0
- package/skills/lark-base/references/lark-base-table.md +20 -0
- package/skills/lark-base/references/lark-base-view-create.md +50 -0
- package/skills/lark-base/references/lark-base-view-delete.md +48 -0
- package/skills/lark-base/references/lark-base-view-get-card.md +38 -0
- package/skills/lark-base/references/lark-base-view-get-filter.md +38 -0
- package/skills/lark-base/references/lark-base-view-get-group.md +38 -0
- package/skills/lark-base/references/lark-base-view-get-sort.md +38 -0
- package/skills/lark-base/references/lark-base-view-get-timebar.md +38 -0
- package/skills/lark-base/references/lark-base-view-get-visible-fields.md +28 -0
- package/skills/lark-base/references/lark-base-view-get.md +38 -0
- package/skills/lark-base/references/lark-base-view-list.md +44 -0
- package/skills/lark-base/references/lark-base-view-rename.md +44 -0
- package/skills/lark-base/references/lark-base-view-set-card.md +55 -0
- package/skills/lark-base/references/lark-base-view-set-filter.md +181 -0
- package/skills/lark-base/references/lark-base-view-set-group.md +65 -0
- package/skills/lark-base/references/lark-base-view-set-sort.md +63 -0
- package/skills/lark-base/references/lark-base-view-set-timebar.md +51 -0
- package/skills/lark-base/references/lark-base-view-set-visible-fields.md +46 -0
- package/skills/lark-base/references/lark-base-view.md +44 -0
- package/skills/lark-base/references/lark-base-workflow-create.md +180 -0
- package/skills/lark-base/references/lark-base-workflow-disable.md +94 -0
- package/skills/lark-base/references/lark-base-workflow-enable.md +94 -0
- package/skills/lark-base/references/lark-base-workflow-get.md +147 -0
- package/skills/lark-base/references/lark-base-workflow-guide.md +718 -0
- package/skills/lark-base/references/lark-base-workflow-list.md +124 -0
- package/skills/lark-base/references/lark-base-workflow-schema.md +935 -0
- package/skills/lark-base/references/lark-base-workflow-update.md +167 -0
- package/skills/lark-base/references/lark-base-workflow.md +23 -0
- package/skills/lark-base/references/lark-base-workspace.md +18 -0
- package/skills/lark-base/references/lookup-field-guide.md +512 -0
- package/skills/lark-base/references/role-config.md +539 -0
- package/skills/lark-calendar/SKILL.md +154 -0
- package/skills/lark-calendar/references/lark-calendar-agenda.md +78 -0
- package/skills/lark-calendar/references/lark-calendar-create.md +109 -0
- package/skills/lark-calendar/references/lark-calendar-freebusy.md +124 -0
- package/skills/lark-calendar/references/lark-calendar-room-find.md +113 -0
- package/skills/lark-calendar/references/lark-calendar-rsvp.md +42 -0
- package/skills/lark-calendar/references/lark-calendar-schedule-meeting.md +265 -0
- package/skills/lark-calendar/references/lark-calendar-suggestion.md +125 -0
- package/skills/lark-calendar/references/lark-calendar-update.md +105 -0
- package/skills/lark-contact/SKILL.md +45 -0
- package/skills/lark-contact/references/lark-contact-get-user.md +19 -0
- package/skills/lark-contact/references/lark-contact-search-user.md +124 -0
- package/skills/lark-doc/SKILL.md +65 -0
- package/skills/lark-doc/references/lark-doc-create.md +89 -0
- package/skills/lark-doc/references/lark-doc-fetch.md +141 -0
- package/skills/lark-doc/references/lark-doc-md.md +71 -0
- package/skills/lark-doc/references/lark-doc-media-download.md +50 -0
- package/skills/lark-doc/references/lark-doc-media-insert.md +114 -0
- package/skills/lark-doc/references/lark-doc-media-preview.md +41 -0
- package/skills/lark-doc/references/lark-doc-update.md +252 -0
- package/skills/lark-doc/references/lark-doc-whiteboard.md +100 -0
- package/skills/lark-doc/references/lark-doc-xml.md +169 -0
- package/skills/lark-doc/references/style/lark-doc-create-workflow.md +56 -0
- package/skills/lark-doc/references/style/lark-doc-style.md +106 -0
- package/skills/lark-doc/references/style/lark-doc-update-workflow.md +54 -0
- package/skills/lark-drive/SKILL.md +369 -0
- package/skills/lark-drive/references/lark-drive-add-comment.md +182 -0
- package/skills/lark-drive/references/lark-drive-apply-permission.md +77 -0
- package/skills/lark-drive/references/lark-drive-create-folder.md +73 -0
- package/skills/lark-drive/references/lark-drive-create-shortcut.md +103 -0
- package/skills/lark-drive/references/lark-drive-delete.md +79 -0
- package/skills/lark-drive/references/lark-drive-download.md +31 -0
- package/skills/lark-drive/references/lark-drive-export-download.md +50 -0
- package/skills/lark-drive/references/lark-drive-export.md +119 -0
- package/skills/lark-drive/references/lark-drive-import.md +159 -0
- package/skills/lark-drive/references/lark-drive-inspect.md +50 -0
- package/skills/lark-drive/references/lark-drive-move.md +120 -0
- package/skills/lark-drive/references/lark-drive-pull.md +137 -0
- package/skills/lark-drive/references/lark-drive-push.md +162 -0
- package/skills/lark-drive/references/lark-drive-reactions.md +113 -0
- package/skills/lark-drive/references/lark-drive-search.md +266 -0
- package/skills/lark-drive/references/lark-drive-status.md +198 -0
- package/skills/lark-drive/references/lark-drive-task-result.md +302 -0
- package/skills/lark-drive/references/lark-drive-upload.md +67 -0
- package/skills/lark-drive/references/lark-drive-version-delete.md +38 -0
- package/skills/lark-drive/references/lark-drive-version-get.md +71 -0
- package/skills/lark-drive/references/lark-drive-version-history.md +73 -0
- package/skills/lark-drive/references/lark-drive-version-revert.md +198 -0
- package/skills/lark-event/SKILL.md +145 -0
- package/skills/lark-event/references/lark-event-im.md +86 -0
- package/skills/lark-im/SKILL.md +162 -0
- package/skills/lark-im/references/lark-im-chat-create.md +162 -0
- package/skills/lark-im/references/lark-im-chat-identity.md +55 -0
- package/skills/lark-im/references/lark-im-chat-list.md +198 -0
- package/skills/lark-im/references/lark-im-chat-messages-list.md +148 -0
- package/skills/lark-im/references/lark-im-chat-search.md +136 -0
- package/skills/lark-im/references/lark-im-chat-update.md +84 -0
- package/skills/lark-im/references/lark-im-flag-cancel.md +198 -0
- package/skills/lark-im/references/lark-im-flag-create.md +67 -0
- package/skills/lark-im/references/lark-im-flag-list.md +100 -0
- package/skills/lark-im/references/lark-im-messages-mget.md +95 -0
- package/skills/lark-im/references/lark-im-messages-reply.md +228 -0
- package/skills/lark-im/references/lark-im-messages-resources-download.md +94 -0
- package/skills/lark-im/references/lark-im-messages-search.md +232 -0
- package/skills/lark-im/references/lark-im-messages-send.md +229 -0
- package/skills/lark-im/references/lark-im-reactions.md +297 -0
- package/skills/lark-im/references/lark-im-threads-messages-list.md +111 -0
- package/skills/lark-mail/SKILL.md +648 -0
- package/skills/lark-mail/references/lark-mail-decline-receipt.md +115 -0
- package/skills/lark-mail/references/lark-mail-draft-create.md +123 -0
- package/skills/lark-mail/references/lark-mail-draft-edit.md +400 -0
- package/skills/lark-mail/references/lark-mail-forward.md +173 -0
- package/skills/lark-mail/references/lark-mail-message.md +230 -0
- package/skills/lark-mail/references/lark-mail-messages.md +108 -0
- package/skills/lark-mail/references/lark-mail-reply-all.md +206 -0
- package/skills/lark-mail/references/lark-mail-reply.md +242 -0
- package/skills/lark-mail/references/lark-mail-send-receipt.md +198 -0
- package/skills/lark-mail/references/lark-mail-send.md +216 -0
- package/skills/lark-mail/references/lark-mail-share-to-chat.md +198 -0
- package/skills/lark-mail/references/lark-mail-signature.md +98 -0
- package/skills/lark-mail/references/lark-mail-template-create.md +129 -0
- package/skills/lark-mail/references/lark-mail-template-update.md +198 -0
- package/skills/lark-mail/references/lark-mail-thread.md +111 -0
- package/skills/lark-mail/references/lark-mail-triage.md +122 -0
- package/skills/lark-mail/references/lark-mail-watch.md +94 -0
- package/skills/lark-minutes/SKILL.md +139 -0
- package/skills/lark-minutes/references/lark-minutes-download.md +137 -0
- package/skills/lark-minutes/references/lark-minutes-search.md +206 -0
- package/skills/lark-minutes/references/lark-minutes-upload.md +104 -0
- package/skills/lark-okr/SKILL.md +133 -0
- package/skills/lark-okr/references/lark-okr-contentblock.md +359 -0
- package/skills/lark-okr/references/lark-okr-cycle-detail.md +84 -0
- package/skills/lark-okr/references/lark-okr-cycle-list.md +90 -0
- package/skills/lark-okr/references/lark-okr-entities.md +329 -0
- package/skills/lark-okr/references/lark-okr-image-upload.md +116 -0
- package/skills/lark-okr/references/lark-okr-progress-create.md +81 -0
- package/skills/lark-okr/references/lark-okr-progress-delete.md +47 -0
- package/skills/lark-okr/references/lark-okr-progress-get.md +62 -0
- package/skills/lark-okr/references/lark-okr-progress-list.md +80 -0
- package/skills/lark-okr/references/lark-okr-progress-update.md +81 -0
- package/skills/lark-openapi-explorer/SKILL.md +153 -0
- package/skills/lark-shared/SKILL.md +144 -0
- package/skills/lark-sheets/SKILL.md +343 -0
- package/skills/lark-sheets/references/lark-sheets-cell-data.md +197 -0
- package/skills/lark-sheets/references/lark-sheets-cell-images.md +59 -0
- package/skills/lark-sheets/references/lark-sheets-cell-style-and-merge.md +141 -0
- package/skills/lark-sheets/references/lark-sheets-dropdown.md +133 -0
- package/skills/lark-sheets/references/lark-sheets-filter-views.md +193 -0
- package/skills/lark-sheets/references/lark-sheets-float-images.md +125 -0
- package/skills/lark-sheets/references/lark-sheets-formula.md +88 -0
- package/skills/lark-sheets/references/lark-sheets-row-column-management.md +151 -0
- package/skills/lark-sheets/references/lark-sheets-sheet-management.md +164 -0
- package/skills/lark-sheets/references/lark-sheets-spreadsheet-management.md +140 -0
- package/skills/lark-skill-maker/SKILL.md +85 -0
- package/skills/lark-slides/SKILL.md +296 -0
- package/skills/lark-slides/assets/templates/administration--all_hands_meeting.xml +1999 -0
- package/skills/lark-slides/assets/templates/administration--annual_gala.xml +1160 -0
- package/skills/lark-slides/assets/templates/administration--company_intro.xml +1376 -0
- package/skills/lark-slides/assets/templates/administration--corporate_culture.xml +1765 -0
- package/skills/lark-slides/assets/templates/hr--employee_training.xml +912 -0
- package/skills/lark-slides/assets/templates/hr--employee_training_workshop.xml +1504 -0
- package/skills/lark-slides/assets/templates/hr--onboarding.xml +933 -0
- package/skills/lark-slides/assets/templates/marketing--brand_communication.xml +1367 -0
- package/skills/lark-slides/assets/templates/marketing--brand_logo_design.xml +1347 -0
- package/skills/lark-slides/assets/templates/marketing--brand_operations_plan.xml +1309 -0
- package/skills/lark-slides/assets/templates/marketing--business_plan.xml +1646 -0
- package/skills/lark-slides/assets/templates/marketing--marketing_plan.xml +198 -0
- package/skills/lark-slides/assets/templates/marketing--marketing_strategy.xml +1484 -0
- package/skills/lark-slides/assets/templates/marketing--product_whitepaper.xml +198 -0
- package/skills/lark-slides/assets/templates/marketing--roadshow_business_plan.xml +1506 -0
- package/skills/lark-slides/assets/templates/misc--book_sharing.xml +198 -0
- package/skills/lark-slides/assets/templates/misc--club_event_plan.xml +4885 -0
- package/skills/lark-slides/assets/templates/misc--student_career_plan.xml +1854 -0
- package/skills/lark-slides/assets/templates/office--dark_general.xml +3763 -0
- package/skills/lark-slides/assets/templates/office--dept_annual_report.xml +1192 -0
- package/skills/lark-slides/assets/templates/office--light_general.xml +3378 -0
- package/skills/lark-slides/assets/templates/office--project_kickoff.xml +3152 -0
- package/skills/lark-slides/assets/templates/office--quarterly_review.xml +1253 -0
- package/skills/lark-slides/assets/templates/office--work_report.xml +1099 -0
- package/skills/lark-slides/assets/templates/office--work_summary.xml +4420 -0
- package/skills/lark-slides/assets/templates/office--work_summary_report.xml +1523 -0
- package/skills/lark-slides/assets/templates/operations--brand_logo_design.xml +1347 -0
- package/skills/lark-slides/assets/templates/operations--brand_operations_plan.xml +1309 -0
- package/skills/lark-slides/assets/templates/operations--marketing_plan.xml +1469 -0
- package/skills/lark-slides/assets/templates/operations--product_promotion.xml +687 -0
- package/skills/lark-slides/assets/templates/personal--experience_sharing.xml +2242 -0
- package/skills/lark-slides/assets/templates/personal--personal_resume.xml +2047 -0
- package/skills/lark-slides/assets/templates/personal--promotion_defense.xml +1099 -0
- package/skills/lark-slides/assets/templates/personal--promotion_report.xml +1039 -0
- package/skills/lark-slides/assets/templates/personal--self_intro.xml +696 -0
- package/skills/lark-slides/assets/templates/personal--teaching_sharing.xml +3013 -0
- package/skills/lark-slides/assets/templates/product--business_case_analysis.xml +1341 -0
- package/skills/lark-slides/assets/templates/product--market_analysis.xml +898 -0
- package/skills/lark-slides/assets/templates/product--product_analysis.xml +1537 -0
- package/skills/lark-slides/assets/templates/product--product_intro.xml +2838 -0
- package/skills/lark-slides/assets/templates/product--product_promotion.xml +687 -0
- package/skills/lark-slides/assets/templates/product--product_promotion_2.xml +198 -0
- package/skills/lark-slides/references/asset-planning.md +124 -0
- package/skills/lark-slides/references/examples.md +261 -0
- package/skills/lark-slides/references/lark-slides-create.md +137 -0
- package/skills/lark-slides/references/lark-slides-edit-workflows.md +142 -0
- package/skills/lark-slides/references/lark-slides-media-upload.md +128 -0
- package/skills/lark-slides/references/lark-slides-replace-slide.md +239 -0
- package/skills/lark-slides/references/lark-slides-xml-presentation-slide-create.md +220 -0
- package/skills/lark-slides/references/lark-slides-xml-presentation-slide-delete.md +123 -0
- package/skills/lark-slides/references/lark-slides-xml-presentation-slide-get.md +110 -0
- package/skills/lark-slides/references/lark-slides-xml-presentation-slide-replace.md +186 -0
- package/skills/lark-slides/references/lark-slides-xml-presentations-get.md +98 -0
- package/skills/lark-slides/references/planning-layer.md +219 -0
- package/skills/lark-slides/references/slide-templates.md +201 -0
- package/skills/lark-slides/references/slides_demo.xml +226 -0
- package/skills/lark-slides/references/slides_xml_schema_definition.xml +3004 -0
- package/skills/lark-slides/references/template-catalog.md +463 -0
- package/skills/lark-slides/references/template-index.json +198 -0
- package/skills/lark-slides/references/troubleshooting.md +198 -0
- package/skills/lark-slides/references/validation-checklist.md +102 -0
- package/skills/lark-slides/references/visual-planning.md +250 -0
- package/skills/lark-slides/references/xml-format-guide.md +369 -0
- package/skills/lark-slides/references/xml-schema-quick-ref.md +215 -0
- package/skills/lark-slides/scripts/template_tool.py +970 -0
- package/skills/lark-slides/scripts/template_tool_test.py +177 -0
- package/skills/lark-slides/scripts/xml_text_overlap_lint.py +367 -0
- package/skills/lark-slides/scripts/xml_text_overlap_lint_test.py +263 -0
- package/skills/lark-task/SKILL.md +165 -0
- package/skills/lark-task/references/lark-task-assign.md +38 -0
- package/skills/lark-task/references/lark-task-comment.md +28 -0
- package/skills/lark-task/references/lark-task-complete.md +27 -0
- package/skills/lark-task/references/lark-task-create.md +57 -0
- package/skills/lark-task/references/lark-task-followers.md +35 -0
- package/skills/lark-task/references/lark-task-get-my-tasks.md +55 -0
- package/skills/lark-task/references/lark-task-get-related-tasks.md +53 -0
- package/skills/lark-task/references/lark-task-reminder.md +36 -0
- package/skills/lark-task/references/lark-task-reopen.md +27 -0
- package/skills/lark-task/references/lark-task-search.md +41 -0
- package/skills/lark-task/references/lark-task-set-ancestor.md +32 -0
- package/skills/lark-task/references/lark-task-subscribe-event.md +86 -0
- package/skills/lark-task/references/lark-task-tasklist-create.md +35 -0
- package/skills/lark-task/references/lark-task-tasklist-members.md +36 -0
- package/skills/lark-task/references/lark-task-tasklist-search.md +38 -0
- package/skills/lark-task/references/lark-task-tasklist-task-add.md +38 -0
- package/skills/lark-task/references/lark-task-update.md +37 -0
- package/skills/lark-task/references/lark-task-upload-attachment.md +59 -0
- package/skills/lark-vc/SKILL.md +168 -0
- package/skills/lark-vc/references/lark-vc-notes.md +126 -0
- package/skills/lark-vc/references/lark-vc-recording.md +153 -0
- package/skills/lark-vc/references/lark-vc-search.md +193 -0
- package/skills/lark-vc-agent/SKILL.md +121 -0
- package/skills/lark-vc-agent/references/lark-vc-agent-meeting-events.md +247 -0
- package/skills/lark-vc-agent/references/lark-vc-agent-meeting-join.md +133 -0
- package/skills/lark-vc-agent/references/lark-vc-agent-meeting-leave.md +111 -0
- package/skills/lark-whiteboard/SKILL.md +144 -0
- package/skills/lark-whiteboard/references/connectors.md +102 -0
- package/skills/lark-whiteboard/references/content.md +40 -0
- package/skills/lark-whiteboard/references/image.md +80 -0
- package/skills/lark-whiteboard/references/lark-whiteboard-query.md +49 -0
- package/skills/lark-whiteboard/references/lark-whiteboard-update.md +100 -0
- package/skills/lark-whiteboard/references/layout.md +374 -0
- package/skills/lark-whiteboard/references/schema.md +357 -0
- package/skills/lark-whiteboard/references/style.md +318 -0
- package/skills/lark-whiteboard/references/typography.md +73 -0
- package/skills/lark-whiteboard/routes/dsl.md +107 -0
- package/skills/lark-whiteboard/routes/mermaid.md +27 -0
- package/skills/lark-whiteboard/routes/svg.md +54 -0
- package/skills/lark-whiteboard/scenes/architecture.md +433 -0
- package/skills/lark-whiteboard/scenes/bar-chart.md +187 -0
- package/skills/lark-whiteboard/scenes/comparison.md +135 -0
- package/skills/lark-whiteboard/scenes/fishbone.md +238 -0
- package/skills/lark-whiteboard/scenes/flowchart.md +198 -0
- package/skills/lark-whiteboard/scenes/flywheel.md +195 -0
- package/skills/lark-whiteboard/scenes/funnel.md +198 -0
- package/skills/lark-whiteboard/scenes/line-chart.md +214 -0
- package/skills/lark-whiteboard/scenes/mermaid.md +130 -0
- package/skills/lark-whiteboard/scenes/milestone.md +139 -0
- package/skills/lark-whiteboard/scenes/organization.md +173 -0
- package/skills/lark-whiteboard/scenes/photo-showcase.md +198 -0
- package/skills/lark-whiteboard/scenes/pyramid.md +99 -0
- package/skills/lark-whiteboard/scenes/swimlane.md +371 -0
- package/skills/lark-whiteboard/scenes/treemap.md +198 -0
- package/skills/lark-wiki/SKILL.md +119 -0
- package/skills/lark-wiki/references/lark-wiki-delete-space.md +205 -0
- package/skills/lark-wiki/references/lark-wiki-member-add.md +66 -0
- package/skills/lark-wiki/references/lark-wiki-member-list.md +76 -0
- package/skills/lark-wiki/references/lark-wiki-member-remove.md +61 -0
- package/skills/lark-wiki/references/lark-wiki-move.md +183 -0
- package/skills/lark-wiki/references/lark-wiki-node-copy.md +72 -0
- package/skills/lark-wiki/references/lark-wiki-node-create.md +127 -0
- package/skills/lark-wiki/references/lark-wiki-node-delete.md +62 -0
- package/skills/lark-wiki/references/lark-wiki-node-get.md +56 -0
- package/skills/lark-wiki/references/lark-wiki-node-list.md +198 -0
- package/skills/lark-wiki/references/lark-wiki-space-create.md +46 -0
- package/skills/lark-wiki/references/lark-wiki-space-list.md +198 -0
- package/skills/lark-workflow-meeting-summary/SKILL.md +104 -0
- package/skills/lark-workflow-standup-report/SKILL.md +120 -0
- package/skills/mmx-cli/SKILL.md +440 -0
- package/src/bot.ts +109 -0
- package/src/cards.ts +105 -0
- package/src/config.ts +33 -0
- package/src/daemon.ts +217 -0
- package/src/extension.ts +132 -0
- package/src/poller.ts +135 -0
- package/src/renderer.ts +47 -0
- package/src/session-registry.ts +90 -0
- package/src/types.ts +29 -0
- package/tests/bot.test.ts +104 -0
- package/tests/cards.test.ts +48 -0
- package/tests/config.test.ts +59 -0
- package/tests/renderer.test.ts +74 -0
- package/tests/session-registry.test.ts +94 -0
- package/tests/types.test.ts +35 -0
- package/tsconfig.json +16 -0
- package/vitest.config.ts +7 -0
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# 增长飞轮图 (Flywheel)
|
|
2
|
+
|
|
3
|
+
> **必须写脚本生成 JSON。** 飞轮图需要极坐标计算阶段标签位置和 SVG 圆环切割,直接手写 JSON 无法正确实现同心圆环结构。请用下方脚本模板。
|
|
4
|
+
|
|
5
|
+
## Content 约束
|
|
6
|
+
|
|
7
|
+
- 阶段 4-6 个,每阶段短标签(title + 可选 subtitle/desc)
|
|
8
|
+
- 中心放置飞轮主题标题
|
|
9
|
+
|
|
10
|
+
## Layout 选型
|
|
11
|
+
|
|
12
|
+
- **脚本生成坐标**(必须):用 .cjs 脚本极坐标计算阶段标签位置、SVG 圆环切割,脚本输出 JSON 文件后调用 `npx -y @larksuite/whiteboard-cli@^0.2.11` 渲染
|
|
13
|
+
|
|
14
|
+
## Layout 规则
|
|
15
|
+
|
|
16
|
+
- 同心圆遮挡法构建圆环:大圆(底色)+ 小圆(白色遮罩)+ 中心文字
|
|
17
|
+
- nodes 数组顺序决定 z-index:先大圆 -> 小圆 -> 中心文字 -> SVG 切割 -> 外围卡片
|
|
18
|
+
- 阶段标签均匀分布在圆环外围,每个标签到圆心距离相等
|
|
19
|
+
- SVG polyline 切割圆环形成分段 + 箭头方向感
|
|
20
|
+
- 阶段数多时需动态放大半径、缩小箭头折角、收紧文字容器
|
|
21
|
+
|
|
22
|
+
### 同心圆遮挡法详解
|
|
23
|
+
|
|
24
|
+
画一个大圆(作为飞轮的底层颜色),然后在它正中心画一个小圆(填充为白色 `#FFFFFF`)。大圆和小圆都设置 `borderWidth: 0`,通过叠加遮挡形成圆环。
|
|
25
|
+
|
|
26
|
+
nodes 数组中的图层顺序(必须严格遵守):
|
|
27
|
+
|
|
28
|
+
1. **底层大圆** (`type: 'ellipse'`, 填色, `borderWidth: 0`)
|
|
29
|
+
2. **遮罩小圆** (`type: 'ellipse'`, 白色填色, `borderWidth: 0`)
|
|
30
|
+
3. **中心文字** — 必须在两个圆之后添加,否则被白色小圆盖住
|
|
31
|
+
4. **SVG 切割箭头** — 覆盖在圆环上,用白色粗线 polyline 切出分段
|
|
32
|
+
5. **外围阶段卡片** — 极坐标计算位置
|
|
33
|
+
|
|
34
|
+
### SVG 箭头线切割分段
|
|
35
|
+
|
|
36
|
+
通过插入一个铺满大圆区域的 `svg` 节点,利用极坐标计算每个分段交界处的坐标,使用 `<polyline>` 画与背景色相同的粗线条(白色、20px+ 宽度)。线条从内圆边缘穿过大圆边缘,并在穿过时产生一定角度的偏转(`da` 参数),在视觉上"切断"圆环并形成箭头方向感。
|
|
37
|
+
|
|
38
|
+
### 外围文字环绕布局
|
|
39
|
+
|
|
40
|
+
- 利用极坐标 `x = cx + R * cos(θ)` 计算每个分段的中心角度
|
|
41
|
+
- 在计算出的坐标点放置 `frame` 容器(`layout: 'vertical'`)
|
|
42
|
+
- 外围文字容器内部的 `text` 节点不能用 `width: 'fill-container'`,必须指定固定 width 配合 `height: 'fit-content'`
|
|
43
|
+
|
|
44
|
+
### 动态缩放优化(阶段数 >= 8 时必须)
|
|
45
|
+
|
|
46
|
+
当阶段数量较多(8 个、12 个或 16 个以上)时,必须动态调整:
|
|
47
|
+
|
|
48
|
+
- **放大画布与圆环半径**:节点越多,需要越长的圆周容纳外围文字。适当调大 `rOut` 和 `rIn`(如 16 阶段时 `rOut` 可设为 400+),同步放大 `cx`/`cy` 避免超出边界
|
|
49
|
+
- **缩小箭头切割角度**:段数增多时每段夹角变小,保持默认折角会导致缝隙过大。应减小 `da`(如 `da = 4`)
|
|
50
|
+
- **收紧外围文字容器**:缩窄 `boxWidth`,减小文字字号,确保相邻文本框不互相覆盖
|
|
51
|
+
|
|
52
|
+
## 骨架示例
|
|
53
|
+
|
|
54
|
+
此场景必须用 .cjs 脚本生成。Agent 使用时只需修改 `stages` 数组和 `centerTitle`/`centerSubtitle`,其余坐标全自动计算。
|
|
55
|
+
|
|
56
|
+
```javascript
|
|
57
|
+
const { writeFileSync } = require('fs');
|
|
58
|
+
|
|
59
|
+
// ══════════════════════════════════════════════════════════════
|
|
60
|
+
// 只需修改这里 -- 填入用户要求的阶段数据和中心标题
|
|
61
|
+
// ══════════════════════════════════════════════════════════════
|
|
62
|
+
|
|
63
|
+
const centerTitle = '{{CENTER_TITLE}}';
|
|
64
|
+
const centerSubtitle = '{{CENTER_SUBTITLE}}'; // 可选,不需要就留空字符串
|
|
65
|
+
|
|
66
|
+
const stages = [
|
|
67
|
+
{ title: '{{STAGE_1}}', subtitle: '{{SUB_1}}', desc: '{{DESC_1}}' },
|
|
68
|
+
{ title: '{{STAGE_2}}', subtitle: '{{SUB_2}}', desc: '{{DESC_2}}' },
|
|
69
|
+
{ title: '{{STAGE_3}}', subtitle: '{{SUB_3}}', desc: '{{DESC_3}}' },
|
|
70
|
+
{ title: '{{STAGE_4}}', subtitle: '{{SUB_4}}', desc: '{{DESC_4}}' },
|
|
71
|
+
];
|
|
72
|
+
|
|
73
|
+
// ══════════════════════════════════════════════════════════════
|
|
74
|
+
// 以下是自动计算逻辑,不需要修改
|
|
75
|
+
// ══════════════════════════════════════════════════════════════
|
|
76
|
+
|
|
77
|
+
// --- 布局参数 ---
|
|
78
|
+
const numSegments = stages.length;
|
|
79
|
+
const cx = 600, cy = 450; // 画布中心
|
|
80
|
+
const rOut = 240, rIn = 160; // 内外圆半径
|
|
81
|
+
const textDist = rOut + 40; // 文字离圆心距离
|
|
82
|
+
const boxWidth = 220; // 外围文字卡片宽度
|
|
83
|
+
const boxHeight = 80; // 估算高度(用于偏移计算)
|
|
84
|
+
const da = 8; // 箭头折角
|
|
85
|
+
|
|
86
|
+
const nodes = [];
|
|
87
|
+
|
|
88
|
+
// --- 图层 1:底层大圆(圆环底色) ---
|
|
89
|
+
nodes.push({
|
|
90
|
+
type: 'ellipse',
|
|
91
|
+
x: cx - rOut, y: cy - rOut,
|
|
92
|
+
width: rOut * 2, height: rOut * 2,
|
|
93
|
+
borderWidth: 0,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// --- 图层 2:遮罩小圆(白色) ---
|
|
97
|
+
nodes.push({
|
|
98
|
+
type: 'ellipse',
|
|
99
|
+
x: cx - rIn, y: cy - rIn,
|
|
100
|
+
width: rIn * 2, height: rIn * 2,
|
|
101
|
+
borderWidth: 0,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// --- 图层 3:中心文字(必须在两个圆之后) ---
|
|
105
|
+
nodes.push({
|
|
106
|
+
type: 'text',
|
|
107
|
+
x: cx - rIn, y: cy - (centerSubtitle ? 30 : 20),
|
|
108
|
+
width: rIn * 2, height: 'fit-content',
|
|
109
|
+
text: [{ content: centerTitle, bold: true, fontSize: 32 }],
|
|
110
|
+
textAlign: 'center',
|
|
111
|
+
});
|
|
112
|
+
if (centerSubtitle) {
|
|
113
|
+
nodes.push({
|
|
114
|
+
type: 'text',
|
|
115
|
+
x: cx - rIn, y: cy + 20,
|
|
116
|
+
width: rIn * 2, height: 'fit-content',
|
|
117
|
+
text: [{ content: centerSubtitle, fontSize: 18 }],
|
|
118
|
+
textAlign: 'center',
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// --- 图层 4:SVG 切割箭头 ---
|
|
123
|
+
let svg = `<svg viewBox="0 0 ${rOut * 2} ${rOut * 2}" xmlns="http://www.w3.org/2000/svg">`;
|
|
124
|
+
for (let i = 0; i < numSegments; i++) {
|
|
125
|
+
const a = -90 + i * (360 / numSegments);
|
|
126
|
+
const rad = (a * Math.PI) / 180;
|
|
127
|
+
const radMid = ((a + da) * Math.PI) / 180;
|
|
128
|
+
const R1 = rIn - 5, R2 = rOut + 5, Rm = (rIn + rOut) / 2;
|
|
129
|
+
const x1 = rOut + R1 * Math.cos(rad), y1 = rOut + R1 * Math.sin(rad);
|
|
130
|
+
const x2 = rOut + Rm * Math.cos(radMid), y2 = rOut + Rm * Math.sin(radMid);
|
|
131
|
+
const x3 = rOut + R2 * Math.cos(rad), y3 = rOut + R2 * Math.sin(rad);
|
|
132
|
+
svg += `<polyline points="${x1},${y1} ${x2},${y2} ${x3},${y3}" stroke="#FFFFFF" stroke-width="20" fill="none" stroke-linejoin="round" stroke-linecap="round" />`;
|
|
133
|
+
}
|
|
134
|
+
svg += `</svg>`;
|
|
135
|
+
nodes.push({
|
|
136
|
+
type: 'svg',
|
|
137
|
+
x: cx - rOut, y: cy - rOut,
|
|
138
|
+
width: rOut * 2, height: rOut * 2,
|
|
139
|
+
svg: { code: svg },
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// --- 图层 5:外围阶段卡片(极坐标计算位置) ---
|
|
143
|
+
for (let i = 0; i < numSegments; i++) {
|
|
144
|
+
const stage = stages[i];
|
|
145
|
+
const a = -90 + (360 / numSegments) / 2 + i * (360 / numSegments);
|
|
146
|
+
const rad = (a * Math.PI) / 180;
|
|
147
|
+
const tx = cx + textDist * Math.cos(rad);
|
|
148
|
+
const ty = cy + textDist * Math.sin(rad);
|
|
149
|
+
|
|
150
|
+
// 动态偏移:根据角度将文本框向外推
|
|
151
|
+
let offsetX = 0, offsetY = 0;
|
|
152
|
+
if (Math.cos(rad) > 0.1) offsetX = 0;
|
|
153
|
+
else if (Math.cos(rad) < -0.1) offsetX = -boxWidth;
|
|
154
|
+
else offsetX = -boxWidth / 2;
|
|
155
|
+
if (Math.sin(rad) > 0.1) offsetY = 0;
|
|
156
|
+
else if (Math.sin(rad) < -0.1) offsetY = -boxHeight;
|
|
157
|
+
else offsetY = -boxHeight / 2;
|
|
158
|
+
|
|
159
|
+
const textW = boxWidth - 24; // 卡片 padding 12 * 2
|
|
160
|
+
nodes.push({
|
|
161
|
+
type: 'frame',
|
|
162
|
+
x: tx + offsetX, y: ty + offsetY,
|
|
163
|
+
width: boxWidth, height: 'fit-content',
|
|
164
|
+
layout: 'vertical', gap: 8, padding: 12,
|
|
165
|
+
alignItems: 'start',
|
|
166
|
+
borderWidth: 2, borderRadius: 8,
|
|
167
|
+
children: [
|
|
168
|
+
{ type: 'text', width: textW, height: 'fit-content',
|
|
169
|
+
text: [{ content: stage.title, bold: true, fontSize: 18 }], textAlign: 'left' },
|
|
170
|
+
{ type: 'text', width: textW, height: 'fit-content',
|
|
171
|
+
text: [{ content: stage.subtitle, fontSize: 14 }], textAlign: 'left' },
|
|
172
|
+
{ type: 'text', width: textW, height: 'fit-content',
|
|
173
|
+
text: [{ content: stage.desc, fontSize: 12 }], textAlign: 'left' },
|
|
174
|
+
],
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// --- 图表标题 ---
|
|
179
|
+
nodes.push({
|
|
180
|
+
type: 'text',
|
|
181
|
+
x: cx - rOut - 100, y: 30,
|
|
182
|
+
width: (rOut + 100) * 2, height: 'fit-content',
|
|
183
|
+
text: [{ content: centerTitle, bold: true, fontSize: 24 }],
|
|
184
|
+
textAlign: 'center',
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
writeFileSync('diagram.json', JSON.stringify({ version: 2, nodes }, null, 2));
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## 陷阱
|
|
191
|
+
|
|
192
|
+
- **中心文字被 SVG 遮挡**:中心文字节点必须在大圆和小圆之后、SVG 之前添加,确保 z-index 正确
|
|
193
|
+
- **缺方向指示箭头**:SVG polyline 切割线必须带角度偏转(da 参数),形成顺时针/逆时针箭头感
|
|
194
|
+
- **标签位置不对称**:外围卡片必须用极坐标公式 `x = cx + R * cos(θ)` 均匀分布,不可手动摆放
|
|
195
|
+
- **外围文字容器死锁**:`layout: 'vertical'` 的 frame 内部 text 节点不能用 `width: 'fill-container'`,必须指定固定 width
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<link rel="icon" href="favicon.ico" />
|
|
7
|
+
<title></title>
|
|
8
|
+
<style>
|
|
9
|
+
* {
|
|
10
|
+
box-sizing: border-box;
|
|
11
|
+
padding: 0;
|
|
12
|
+
margin: 0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.open-platform-wrapper {
|
|
16
|
+
display: flex;
|
|
17
|
+
flex-direction: column;
|
|
18
|
+
align-items: center;
|
|
19
|
+
justify-content: center;
|
|
20
|
+
height: 100vh;
|
|
21
|
+
background-color: #ffffff;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.open-platform-icon {
|
|
25
|
+
width: 120px;
|
|
26
|
+
height: 120px;
|
|
27
|
+
display: block;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.open-platform-desc {
|
|
31
|
+
margin-top: 16px;
|
|
32
|
+
line-height: 22px;
|
|
33
|
+
font-size: 14px;
|
|
34
|
+
color: #646a73;
|
|
35
|
+
text-align: center
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.open-platform-back {
|
|
39
|
+
border-radius: 6px;
|
|
40
|
+
font-size: 14px;
|
|
41
|
+
height: 32px;
|
|
42
|
+
line-height: 22px;
|
|
43
|
+
min-width: 80px;
|
|
44
|
+
padding: 4px 11px;
|
|
45
|
+
text-align: center;
|
|
46
|
+
text-decoration: none;
|
|
47
|
+
touch-action: manipulation;
|
|
48
|
+
transition: color .1s ease-in, background-color .1s ease-in, border-color .1s ease-in, width .2s ease-in;
|
|
49
|
+
user-select: none;
|
|
50
|
+
white-space: nowrap;
|
|
51
|
+
background: #1456f0;
|
|
52
|
+
border: 1px solid #1456f0;
|
|
53
|
+
color: #ffffff;
|
|
54
|
+
margin-top: 16px;
|
|
55
|
+
}
|
|
56
|
+
</style>
|
|
57
|
+
</head>
|
|
58
|
+
<body>
|
|
59
|
+
<div class="open-platform-wrapper">
|
|
60
|
+
<img class="open-platform-icon"
|
|
61
|
+
src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwIiBoZWlnaHQ9IjEyMCIgdmlld0JveD0iMCAwIDEyMCAxMjAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTEyLjkxMyA1NS4yNDRjLTUuNjMyIDIuOTUtOC4yNDYgNi4yODQtOC4yNDYgOS40NHY5LjcyYzAtMy4xNTYgMi42MTQtNi40OSA4LjI0Ni05LjQ0di05LjcyWm05NC4xNjMtMTIuMDg0di05LjcyNmM1LjkzNC0zLjE5IDguOTgxLTYuODkxIDguOTgxLTEwLjcyNXY5LjcyYzAgMy44NC0zLjA0NyA3LjU0My04Ljk4MSAxMC43MzJaIiBmaWxsPSIjMEMyOTZFIi8+PHBhdGggZD0iTTYwLjIyOSAxOS4wNTkgNDguNzMgNDkuOTIyIDYwLjM2NSA3Mi45MmwtOC40NzQgMjMuODczSDE2LjkyM2E0IDQgMCAwIDEtNC00VjIzLjA2YTQgNCAwIDAgMSA0LTRINjAuMjNaIiBmaWxsPSIjQkJCRkM0IiBmaWxsLW9wYWNpdHk9Ii40NSIvPjxwYXRoIGQ9Ik03MS40MDggMTkuMDU5IDYwLjAxMyA0OS45MjIgNzEuNDYgNzIuOTJsLTguMzI1IDIzLjg3M2gzOS45NDNhNCA0IDAgMCAwIDQtNFYyMy4wNmE0IDQgMCAwIDAtNC00aC0zMS42N1oiIGZpbGw9IiNCQkJGQzQiIGZpbGwtb3BhY2l0eT0iLjQ1Ii8+PHBhdGggZD0iTTIxLjkyMyAyNi4xYTIgMiAwIDEgMSAwIDQgMiAyIDAgMCAxIDAtNFptMyAyYTMgMyAwIDEgMC02IDAgMyAzIDAgMCAwIDYgMFptNi45MTUtMmEyIDIgMCAxIDEgMCA0IDIgMiAwIDAgMSAwLTRabTMgMmEzIDMgMCAxIDAtNiAwIDMgMyAwIDAgMCA2IDBabS0xNS43NjMgNy4zOTRhLjUuNSAwIDAgMSAuNS0uNWgzMS41ODFhLjUuNSAwIDAgMSAwIDFIMTkuNTc1YS41LjUgMCAwIDEtLjUtLjVabTQ4LjQ3NyAwYS41LjUgMCAwIDEgLjUtLjVoMzIuNDY1YS41LjUgMCAwIDEgMCAxSDY4LjA1MmEuNS41IDAgMCAxLS41LS41WiIgZmlsbD0iIzhGOTU5RSIvPjxwYXRoIGQ9Ik05OCAxMTFjOS45NDEgMCAxOC04LjA1OSAxOC0xOHMtOC4wNTktMTgtMTgtMThjLTkuOTQyIDAtMTggOC4wNTktMTggMThzOC4wNTggMTggMTggMThaIiBmaWxsPSIjRjgwIi8+PHBhdGggZD0iTTk3LjE4MSA4NC44MThhLjgxOC44MTggMCAwIDAtLjgxOC44MTl2OS44MThjMCAuNDUyLjM2Ni44MTguODE4LjgxOGgxLjYzN2EuODE4LjgxOCAwIDAgMCAuODE4LS44MTh2LTkuODE5YS44MTguODE4IDAgMCAwLS44MTgtLjgxOEg5Ny4xOFptMCAxMy4wOTJhLjgxOC44MTggMCAwIDAtLjgxOC44MTh2MS42MzZjMCAuNDUyLjM2Ni44MTguODE4LjgxOGgxLjYzN2EuODE4LjgxOCAwIDAgMCAuODE4LS44MTh2LTEuNjM2YS44MTguODE4IDAgMCAwLS44MTgtLjgxOUg5Ny4xOFoiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNNC4wMjcgODUuMzFjMi40OSA1LjUxIDE0Ljc3IDkuOTQgNDEuNDUgOS45M3Y5LjcyMWMtMjYuNjguMDEtMzguOTYtNC40Mi00MS40NS05Ljkzdi05LjcyWm04NC44MS0yNy4yN2MxNy41Mi0yLjY5IDI1LjgwNy03LjAyNiAyNy4yLTExLjcxdjkuNzJjLS4zMyA0LjY3LTkuNjggOS4wMi0yNy4yIDExLjcxdi05LjcyWiIgZmlsbD0iIzMzNzBGRiIvPjxwYXRoIGQ9Ik04OS4yMzcgMTMuMDFjMTguMDU4IDAgMjYuOCAzLjI1IDI2LjggOS43MnY5LjcyYzAtNi40Ny04Ljc0Mi05LjcyLTI2LjgtOS43MnYtOS43MlptLTg0LjU3IDUxLjdjMCA2LjYgMTEuMzcgMTIuNDUgMzAuNDcgMTIuNDR2OS43MmMtMTkuMSAwLTMwLjQ3LTUuODQtMzAuNDctMTIuNDR2LTkuNzJaIiBmaWxsPSIjMDBENkI5Ii8+PC9zdmc+"
|
|
62
|
+
alt="">
|
|
63
|
+
<div class="open-platform-desc">The page does not exist.</div>
|
|
64
|
+
<a class="open-platform-back" href="/">Go to homepage</a>
|
|
65
|
+
</div>
|
|
66
|
+
<script>window.gfdatav1={"env":"prod","ver":"1.0.0.13","canary":0,"garrModules":null,"envName":"prod","region":"CN","idc":"hl","webServerCodeType":"DeployServerlessWebServer","runtime":"node","extra":{"canaryType":null}}</script><script>
|
|
67
|
+
|
|
68
|
+
function parseQueryString(queryString) {
|
|
69
|
+
// 移除开头的 "?"
|
|
70
|
+
if (queryString.charAt(0) === '?') {
|
|
71
|
+
queryString = queryString.substring(1);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
var params = {};
|
|
75
|
+
if (!queryString) return params;
|
|
76
|
+
|
|
77
|
+
// 分割参数对
|
|
78
|
+
var paramPairs = queryString.split('&');
|
|
79
|
+
|
|
80
|
+
for (var i = 0; i < paramPairs.length; i++) {
|
|
81
|
+
var paramPair = paramPairs[i].split('=');
|
|
82
|
+
var key = decodeURIComponent(paramPair[0]);
|
|
83
|
+
var value = paramPair.length > 1 ? decodeURIComponent(paramPair[1]) : '';
|
|
84
|
+
|
|
85
|
+
// 处理重复参数(转为数组)
|
|
86
|
+
if (params[key] === undefined) {
|
|
87
|
+
params[key] = value;
|
|
88
|
+
} else if (!Array.isArray(params[key])) {
|
|
89
|
+
params[key] = [params[key], value];
|
|
90
|
+
} else {
|
|
91
|
+
params[key].push(value);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return params;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function getLocale() {
|
|
99
|
+
var zhLang = 'zh-CN';
|
|
100
|
+
var enLang = 'en-US';
|
|
101
|
+
|
|
102
|
+
var queryLang = parseQueryString(window.location.search).lang;
|
|
103
|
+
var cookieLang = getCookieLocale();
|
|
104
|
+
var lang = enLang;
|
|
105
|
+
|
|
106
|
+
<!--从cookie中取值-->
|
|
107
|
+
function getCookieLocale() {
|
|
108
|
+
var locale = '';
|
|
109
|
+
var cookies = document.cookie.split('; ');
|
|
110
|
+
var loclaeKey = 'open_locale';
|
|
111
|
+
|
|
112
|
+
for (var i = 0; i < cookies.length; i++) {
|
|
113
|
+
var cookie = cookies[i].trim();
|
|
114
|
+
var cookieArr = cookie.split('=');
|
|
115
|
+
if (cookieArr[0] === loclaeKey) {
|
|
116
|
+
locale = cookieArr[1];
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return locale;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function setLocaleCookie(lang) {
|
|
124
|
+
var date = new Date();
|
|
125
|
+
// 300天到期
|
|
126
|
+
date.setTime(date.getTime() + (300 * 24 * 60 * 60 * 1000));
|
|
127
|
+
var expires = 'expires=' + date.toUTCString();
|
|
128
|
+
document.cookie = 'open_locale=' + lang + '; ' + expires + '; path=/;';
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// 获取浏览器默认语言
|
|
132
|
+
if (navigator.language.indexOf('en') !== -1) {
|
|
133
|
+
lang = enLang;
|
|
134
|
+
} else if (navigator.language.indexOf('zh') !== -1) {
|
|
135
|
+
lang = zhLang;
|
|
136
|
+
}
|
|
137
|
+
if (cookieLang === enLang) {
|
|
138
|
+
lang = enLang;
|
|
139
|
+
} else if (cookieLang === zhLang) {
|
|
140
|
+
lang = zhLang;
|
|
141
|
+
}
|
|
142
|
+
if (queryLang === enLang) {
|
|
143
|
+
lang = enLang;
|
|
144
|
+
} else if (queryLang === zhLang) {
|
|
145
|
+
lang = zhLang;
|
|
146
|
+
}
|
|
147
|
+
// 设置cookie
|
|
148
|
+
setLocaleCookie(lang);
|
|
149
|
+
return lang;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// 根据域名获取当前brand
|
|
153
|
+
function isLarkDomain() {
|
|
154
|
+
var defaultBrandMap = {
|
|
155
|
+
lark: ['larksuite'],
|
|
156
|
+
feishu: ['feishu', 'larkoffice', 'larkenterprise'],
|
|
157
|
+
};
|
|
158
|
+
const { hostname } = window.location;
|
|
159
|
+
|
|
160
|
+
if (defaultBrandMap.feishu.some((item) => hostname.includes(item))) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (defaultBrandMap.lark.some((item) => hostname.includes(item))) {
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (window.domainBrand) {
|
|
169
|
+
return window.domainBrand === 'lark';
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
var isLarkBrand = isLarkDomain();
|
|
176
|
+
|
|
177
|
+
var config = {
|
|
178
|
+
'zh-CN': {
|
|
179
|
+
'desc': '抱歉,您访问的页面不存在',
|
|
180
|
+
'back': '返回首页',
|
|
181
|
+
'title': (isLarkBrand ? 'Lark' : '飞书') + '开放平台',
|
|
182
|
+
},
|
|
183
|
+
'en-US': {
|
|
184
|
+
'desc': 'The page does not exist.',
|
|
185
|
+
'back': 'Go to homepage',
|
|
186
|
+
'title': (isLarkBrand ? 'Lark': 'Feishu') + ' Open Platform',
|
|
187
|
+
},
|
|
188
|
+
};
|
|
189
|
+
var locale = getLocale();
|
|
190
|
+
var descObj = document.querySelector('.open-platform-desc');
|
|
191
|
+
var backObj = document.querySelector('.open-platform-back');
|
|
192
|
+
descObj.innerHTML = config[locale].desc;
|
|
193
|
+
backObj.innerHTML = config[locale].back;
|
|
194
|
+
document.title = config[locale].title;
|
|
195
|
+
|
|
196
|
+
</script>
|
|
197
|
+
</body>
|
|
198
|
+
</html>
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# 折线图
|
|
2
|
+
|
|
3
|
+
## Content 约束
|
|
4
|
+
|
|
5
|
+
- 数据点 ≤ 15
|
|
6
|
+
- Y 轴必须有单位标注(如 "万元"、"%")
|
|
7
|
+
- 折线系列 ≤ 3(超过太密看不清)
|
|
8
|
+
|
|
9
|
+
## Layout 选型
|
|
10
|
+
|
|
11
|
+
- **脚本生成坐标**(推荐):用 .cjs 脚本计算数据点坐标和折线路径,脚本输出 JSON 文件后调用 `npx -y @larksuite/whiteboard-cli@^0.2.11` 渲染
|
|
12
|
+
|
|
13
|
+
## Layout 规则
|
|
14
|
+
|
|
15
|
+
- 白板坐标系 Y 轴向下为正,图表"底部原点"拥有最大 Y 值,数据点向上分布时 Y 减小
|
|
16
|
+
- 数据点用小 ellipse 标记(width: 12, height: 12)
|
|
17
|
+
- 折线用 connector straight 连接相邻数据点,endArrow: "none"
|
|
18
|
+
- 坐标轴用 connector 直线,末端带箭头(endArrow: "arrow")
|
|
19
|
+
- 格线用虚线 connector(lineStyle: "dashed",endArrow: "none")
|
|
20
|
+
- 刻度线短横线 connector(endArrow: "none")
|
|
21
|
+
- 数值标注放在数据点上方
|
|
22
|
+
- 类别标签放在 X 轴下方,居中对齐数据点
|
|
23
|
+
|
|
24
|
+
## 坐标与尺寸计算指南
|
|
25
|
+
|
|
26
|
+
白板坐标系中,**X 轴向右为正,Y 轴向下为正**。图表的"底部原点"拥有最大的 Y 坐标,数据点向上分布时 Y 坐标减小。
|
|
27
|
+
|
|
28
|
+
1. **确定图表区域**:
|
|
29
|
+
- 设定图表区高度 `chartHeight` 和宽度 `chartWidth`
|
|
30
|
+
- 设定左下角坐标原点 `(originX, originY)`
|
|
31
|
+
- 示例:originX=80, originY=480, chartWidth=900, chartHeight=400
|
|
32
|
+
2. **Y 轴范围自适应**:
|
|
33
|
+
- 找出数据最小值 `dataMin` 和最大值 `dataMax`
|
|
34
|
+
- yMin 不一定为 0:若数据集中在 80-120,Y 轴从 0 开始会让折线挤在顶部一小段区域
|
|
35
|
+
- 推荐:yMin = 向下取整到合适刻度(如 dataMin=82 → yMin=80),yMax = 向上取整(如 dataMax=118 → yMax=120)
|
|
36
|
+
- 当数据波动极小时(如 98-102),适当扩大范围避免折线过于平坦
|
|
37
|
+
3. **数据点坐标计算**:
|
|
38
|
+
- X 坐标:在可用宽度内均匀分布。`pointX = originX + (i / (pointCount - 1)) * chartWidth`
|
|
39
|
+
- Y 坐标:按比例映射到高度。`pointY = originY - ((value - yMin) / (yMax - yMin)) * chartHeight`
|
|
40
|
+
- ellipse 定位:`ellipseX = pointX - 6, ellipseY = pointY - 6`(圆心对齐数据点)
|
|
41
|
+
4. **连线逻辑**:
|
|
42
|
+
- 用 connector straight 将相邻数据点连接
|
|
43
|
+
- `from` = 点[i] 的 (pointX, pointY),`to` = 点[i+1] 的 (pointX, pointY)
|
|
44
|
+
- startArrow: "none", endArrow: "none"
|
|
45
|
+
5. **Y 轴刻度计算**:
|
|
46
|
+
- 将 yMin 到 yMax 等分为 4-5 个刻度
|
|
47
|
+
- 每个刻度的 Y 坐标:`gridY = originY - ((tickValue - yMin) / (yMax - yMin)) * chartHeight`
|
|
48
|
+
|
|
49
|
+
## 完整 JSON 示例
|
|
50
|
+
|
|
51
|
+
以下示例:4 个数据点,数据 [120, 200, 150, 180],yMin=100, yMax=220,originX=80, originY=480, chartWidth=900, chartHeight=400。
|
|
52
|
+
|
|
53
|
+
- 刻度:100, 130, 160, 190, 220(每 30 一格)
|
|
54
|
+
- 点0 (120): pointX=80, pointY=480-((120-100)/120)*400=480-66.7=413
|
|
55
|
+
- 点1 (200): pointX=80+300=380, pointY=480-((200-100)/120)*400=480-333.3=147
|
|
56
|
+
- 点2 (150): pointX=80+600=680, pointY=480-((150-100)/120)*400=480-166.7=313
|
|
57
|
+
- 点3 (180): pointX=80+900=980, pointY=480-((180-100)/120)*400=480-266.7=213
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"version": 2,
|
|
62
|
+
"nodes": [
|
|
63
|
+
{ "type": "rect", "x": 0, "y": 0, "width": 1100, "height": 580 },
|
|
64
|
+
|
|
65
|
+
{ "type": "text", "x": 80, "y": 10, "width": 900, "height": "fit-content",
|
|
66
|
+
"text": "季度销售额趋势", "fontSize": 24, "textAlign": "center" },
|
|
67
|
+
|
|
68
|
+
{ "type": "text", "x": 10, "y": 40, "width": 60, "height": "fit-content",
|
|
69
|
+
"text": "万元", "fontSize": 12, "textAlign": "center" },
|
|
70
|
+
|
|
71
|
+
{ "type": "connector", "connector": {
|
|
72
|
+
"from": { "x": 80, "y": 480 }, "to": { "x": 80, "y": 55 },
|
|
73
|
+
"lineShape": "straight", "lineWidth": 2, "endArrow": "arrow"
|
|
74
|
+
}},
|
|
75
|
+
{ "type": "connector", "connector": {
|
|
76
|
+
"from": { "x": 80, "y": 480 }, "to": { "x": 1000, "y": 480 },
|
|
77
|
+
"lineShape": "straight", "lineWidth": 2, "endArrow": "arrow"
|
|
78
|
+
}},
|
|
79
|
+
|
|
80
|
+
{ "type": "connector", "connector": {
|
|
81
|
+
"from": { "x": 70, "y": 480 }, "to": { "x": 80, "y": 480 },
|
|
82
|
+
"lineShape": "straight", "lineWidth": 1,
|
|
83
|
+
"startArrow": "none", "endArrow": "none"
|
|
84
|
+
}},
|
|
85
|
+
{ "type": "text", "x": 20, "y": 470, "width": 50, "height": 20,
|
|
86
|
+
"text": "100", "fontSize": 12, "textAlign": "right" },
|
|
87
|
+
|
|
88
|
+
{ "type": "connector", "connector": {
|
|
89
|
+
"from": { "x": 70, "y": 380 }, "to": { "x": 80, "y": 380 },
|
|
90
|
+
"lineShape": "straight", "lineWidth": 1,
|
|
91
|
+
"startArrow": "none", "endArrow": "none"
|
|
92
|
+
}},
|
|
93
|
+
{ "type": "text", "x": 20, "y": 370, "width": 50, "height": 20,
|
|
94
|
+
"text": "130", "fontSize": 12, "textAlign": "right" },
|
|
95
|
+
{ "type": "connector", "connector": {
|
|
96
|
+
"from": { "x": 80, "y": 380 }, "to": { "x": 980, "y": 380 },
|
|
97
|
+
"lineShape": "straight", "lineWidth": 1, "lineStyle": "dashed",
|
|
98
|
+
"startArrow": "none", "endArrow": "none"
|
|
99
|
+
}},
|
|
100
|
+
|
|
101
|
+
{ "type": "connector", "connector": {
|
|
102
|
+
"from": { "x": 70, "y": 280 }, "to": { "x": 80, "y": 280 },
|
|
103
|
+
"lineShape": "straight", "lineWidth": 1,
|
|
104
|
+
"startArrow": "none", "endArrow": "none"
|
|
105
|
+
}},
|
|
106
|
+
{ "type": "text", "x": 20, "y": 270, "width": 50, "height": 20,
|
|
107
|
+
"text": "160", "fontSize": 12, "textAlign": "right" },
|
|
108
|
+
{ "type": "connector", "connector": {
|
|
109
|
+
"from": { "x": 80, "y": 280 }, "to": { "x": 980, "y": 280 },
|
|
110
|
+
"lineShape": "straight", "lineWidth": 1, "lineStyle": "dashed",
|
|
111
|
+
"startArrow": "none", "endArrow": "none"
|
|
112
|
+
}},
|
|
113
|
+
|
|
114
|
+
{ "type": "connector", "connector": {
|
|
115
|
+
"from": { "x": 70, "y": 180 }, "to": { "x": 80, "y": 180 },
|
|
116
|
+
"lineShape": "straight", "lineWidth": 1,
|
|
117
|
+
"startArrow": "none", "endArrow": "none"
|
|
118
|
+
}},
|
|
119
|
+
{ "type": "text", "x": 20, "y": 170, "width": 50, "height": 20,
|
|
120
|
+
"text": "190", "fontSize": 12, "textAlign": "right" },
|
|
121
|
+
{ "type": "connector", "connector": {
|
|
122
|
+
"from": { "x": 80, "y": 180 }, "to": { "x": 980, "y": 180 },
|
|
123
|
+
"lineShape": "straight", "lineWidth": 1, "lineStyle": "dashed",
|
|
124
|
+
"startArrow": "none", "endArrow": "none"
|
|
125
|
+
}},
|
|
126
|
+
|
|
127
|
+
{ "type": "connector", "connector": {
|
|
128
|
+
"from": { "x": 70, "y": 80 }, "to": { "x": 80, "y": 80 },
|
|
129
|
+
"lineShape": "straight", "lineWidth": 1,
|
|
130
|
+
"startArrow": "none", "endArrow": "none"
|
|
131
|
+
}},
|
|
132
|
+
{ "type": "text", "x": 20, "y": 70, "width": 50, "height": 20,
|
|
133
|
+
"text": "220", "fontSize": 12, "textAlign": "right" },
|
|
134
|
+
{ "type": "connector", "connector": {
|
|
135
|
+
"from": { "x": 80, "y": 80 }, "to": { "x": 980, "y": 80 },
|
|
136
|
+
"lineShape": "straight", "lineWidth": 1, "lineStyle": "dashed",
|
|
137
|
+
"startArrow": "none", "endArrow": "none"
|
|
138
|
+
}},
|
|
139
|
+
|
|
140
|
+
{ "type": "connector", "connector": {
|
|
141
|
+
"from": { "x": 80, "y": 413 }, "to": { "x": 380, "y": 147 },
|
|
142
|
+
"lineShape": "straight", "lineWidth": 3,
|
|
143
|
+
"startArrow": "none", "endArrow": "none"
|
|
144
|
+
}},
|
|
145
|
+
{ "type": "connector", "connector": {
|
|
146
|
+
"from": { "x": 380, "y": 147 }, "to": { "x": 680, "y": 313 },
|
|
147
|
+
"lineShape": "straight", "lineWidth": 3,
|
|
148
|
+
"startArrow": "none", "endArrow": "none"
|
|
149
|
+
}},
|
|
150
|
+
{ "type": "connector", "connector": {
|
|
151
|
+
"from": { "x": 680, "y": 313 }, "to": { "x": 980, "y": 213 },
|
|
152
|
+
"lineShape": "straight", "lineWidth": 3,
|
|
153
|
+
"startArrow": "none", "endArrow": "none"
|
|
154
|
+
}},
|
|
155
|
+
|
|
156
|
+
{ "type": "ellipse", "id": "pt-0", "x": 74, "y": 407,
|
|
157
|
+
"width": 12, "height": 12 },
|
|
158
|
+
{ "type": "text", "x": 55, "y": 383,
|
|
159
|
+
"width": 50, "height": 20,
|
|
160
|
+
"text": "120", "fontSize": 14, "textAlign": "center" },
|
|
161
|
+
{ "type": "text", "x": 50, "y": 490,
|
|
162
|
+
"width": 60, "height": 30,
|
|
163
|
+
"text": "Q1", "fontSize": 14, "textAlign": "center" },
|
|
164
|
+
|
|
165
|
+
{ "type": "ellipse", "id": "pt-1", "x": 374, "y": 141,
|
|
166
|
+
"width": 12, "height": 12 },
|
|
167
|
+
{ "type": "text", "x": 355, "y": 117,
|
|
168
|
+
"width": 50, "height": 20,
|
|
169
|
+
"text": "200", "fontSize": 14, "textAlign": "center" },
|
|
170
|
+
{ "type": "text", "x": 350, "y": 490,
|
|
171
|
+
"width": 60, "height": 30,
|
|
172
|
+
"text": "Q2", "fontSize": 14, "textAlign": "center" },
|
|
173
|
+
|
|
174
|
+
{ "type": "ellipse", "id": "pt-2", "x": 674, "y": 307,
|
|
175
|
+
"width": 12, "height": 12 },
|
|
176
|
+
{ "type": "text", "x": 655, "y": 283,
|
|
177
|
+
"width": 50, "height": 20,
|
|
178
|
+
"text": "150", "fontSize": 14, "textAlign": "center" },
|
|
179
|
+
{ "type": "text", "x": 650, "y": 490,
|
|
180
|
+
"width": 60, "height": 30,
|
|
181
|
+
"text": "Q3", "fontSize": 14, "textAlign": "center" },
|
|
182
|
+
|
|
183
|
+
{ "type": "ellipse", "id": "pt-3", "x": 974, "y": 207,
|
|
184
|
+
"width": 12, "height": 12 },
|
|
185
|
+
{ "type": "text", "x": 955, "y": 183,
|
|
186
|
+
"width": 50, "height": 20,
|
|
187
|
+
"text": "180", "fontSize": 14, "textAlign": "center" },
|
|
188
|
+
{ "type": "text", "x": 950, "y": 490,
|
|
189
|
+
"width": 60, "height": 30,
|
|
190
|
+
"text": "Q4", "fontSize": 14, "textAlign": "center" }
|
|
191
|
+
]
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
坐标推导验证:
|
|
196
|
+
- 点0 (Q1, 120): pointX = 80 + (0/3)*900 = 80, pointY = 480 - ((120-100)/120)*400 = 413
|
|
197
|
+
- 点1 (Q2, 200): pointX = 80 + (1/3)*900 = 380, pointY = 480 - ((200-100)/120)*400 = 147
|
|
198
|
+
- 点2 (Q3, 150): pointX = 80 + (2/3)*900 = 680, pointY = 480 - ((150-100)/120)*400 = 313
|
|
199
|
+
- 点3 (Q4, 180): pointX = 80 + (3/3)*900 = 980, pointY = 480 - ((180-100)/120)*400 = 213
|
|
200
|
+
- ellipse 定位:ellipseX = pointX - 6, ellipseY = pointY - 6
|
|
201
|
+
|
|
202
|
+
## 陷阱
|
|
203
|
+
|
|
204
|
+
- Y 轴范围不合理:若数据集中在 80-120,Y 轴从 0 到 120 会让折线挤在顶部一小段区域,应设 yMin 接近数据最小值
|
|
205
|
+
- 缺 Y 轴单位标注,读者无法理解数值含义
|
|
206
|
+
- 数据点太密时标注互相遮挡(超过 10 个点考虑隔一个标注一次)
|
|
207
|
+
- 折线段忘记设 endArrow: "none",默认带箭头
|
|
208
|
+
- 多系列时折线颜色相近难以区分,应使用对比度高的不同色系
|
|
209
|
+
|
|
210
|
+
此场景必须用 .cjs 脚本生成。Agent 使用时只需修改 `data` 数组,其余坐标与折线生成全自动计算。
|
|
211
|
+
|
|
212
|
+
```javascript
|
|
213
|
+
const { writeFileSync } = require('fs');
|
|
214
|
+
```
|