انتقل إلى المحتوى

الإضافات ​

plugin عبارة عن حزمة قائمة بذاتها من عناصر واجهة المستخدم وارتباطات المفاتيح وخطافات دورة الحياة الذي يثبت نفسه في رسم بياني دون الحاجة إلى معرفة وجوده. سجل أحدهما تصريحاً أو حتماً:

ts
import { Pivotick, minimap } from 'pivotick'

// declaratively
const graph = new Pivotick(container, data, { plugins: [minimap()] })

// …or at any point later
graph.use(minimap({ position: 'bottom-left' }))

يتم ربط المكون الإضافي الذي تم تثبيته بعد تشغيل الرسم البياني بمرحلة دورة الحياة الحالية، لذلك لا يوجد "فات الأوان" - ويتم هدم كل شيء يتم تسجيله باستخدام واجهة المستخدم.

شكل البرنامج المساعد ​

ts
import type { PivotickPlugin } from 'pivotick'

const myPlugin: PivotickPlugin = {
    name: 'my-plugin',          // used for de-duplication and logging
    install(ctx) { /* … */ },   // called once
}

يؤدي تثبيت نفس name مرتين إلى التحذير وتخطي التكرار، لذلك يمكن إنشاء مكون إضافي مدرج في plugins ويُعاد تطبيقه من خلال graph.use دون مضاعفة.

ما install سلم ​

ctx هو {@الرابط PluginContext}:

عضوما الغرض منه
graphالبث المباشر Graph — العقد، الحواف، ناقل حدث البيانات، queryEngine
uiUIManager — الخيارات والإشعارات ومتجر الأوضاع
layoutسقالة DOM، اقرأ live (ليست لقطة أبدًا). layout.canvas هو المكان الذي يذهب إليه الكروم المثبت على القماش
addElement(element, slot?)ضع UIComponent في دورة الحياة، مثبتًا في slot
addPanel(panel) / removePanel(id) / refreshPanel(id?)لوحات الشريط الجانبي — نفس الباب مثل UI.extraPanels
addDockTab(tab) / removeDockTab(id)جزء في الرصيف السفلي - نفس الباب الذي تأتي من خلاله الطاولة المدمجة
addRailMode(mode) / removeRailMode(id)وضع على السكة اليسرى، بجانب تحديد / إنشاء / عرض / الفيزياء
addTopBarAction(action) / removeTopBarAction(id)حبة في الشريط العلوي — نفس الباب مثل UI.topBar.actions
addPivot(definition)إثراء قابل للتشغيل — راجع محاور وإثراء
onPhase(phase, cb)خطاف afterMount / graphReady / destroy; إرجاع إلغاء الاشتراك
addKeybinding(binding)اختصار تتم إزالته عندما يتم هدم واجهة المستخدم
keyManagerسجل ربط المفاتيح، لأي شيء أكثر أهمية

الرابط key هو المعدلات ثم المفتاح، انضم إليه +: 'Shift+K'، 'Ctrl+F'، 'ArrowUp'. اكتب المعدلات كـ Ctrl، Meta (Cmd on macOS)، Shift، Alt، في ذلك اطلب واستخدم Mod للمطابقة إما Ctrl أو Meta — وهو ما يعنيه الاختصار للعمل على كلا المنصتين يريد. المفتاح نفسه هو KeyboardEvent.key حرفيًا، فهو كذلك حساس لحالة الأحرف ويغيره Shift: نصفي زوج التراجع هما 'Mod+z' و 'Mod+Shift+Z'. لا يتم إطلاق الارتباطات مطلقًا أثناء التركيز على حقل النص.

أي فتحات layout موجودة تعتمد على الوضع: canvas وnotification دائمًا، graphnavigation في كل وضع ما عدا static، mainheader / modal / slidePanel / moderail / toolpanel / flyout / legend في full و light و sidebar في full فقط. اقرأ الفتحة في اللحظة التي تحتاجها فيها بدلاً من تخزينها مؤقتًا.

المساهمة بعنصر واجهة المستخدم ​

قم بتمديد UIComponent وسيتم توجيه دورة الحياة من أجلك - بما في ذلك هدم أي شيء تم تسجيله من خلال track / listen / trackInteraction :

ts
import { UIComponent } from 'pivotick'

class Watermark extends UIComponent {
    onMount(slot) {
        this.element = document.createElement('div')
        this.element.textContent = 'draft'
        slot?.appendChild(this.element)
    }

    onGraphReady() {
        // `listen` and `trackInteraction` unsubscribe themselves on destroy
        this.trackInteraction('canvasZoom', () => this.reposition())
    }

    onDestroy() {
        this.element?.remove()
    }
}

const watermark: PivotickPlugin = {
    name: 'watermark',
    install: (ctx) => ctx.addElement(new Watermark(ctx.ui), ctx.layout?.canvas),
}

المراحل الأربع هي mount(slot) → afterMount() → graphReady() → destroy(). graphReady تنطلق بمجرد استقرار المحاكاة، لذلك يمكن أن تكون ثواني بعد قم بالتركيب على رسم بياني كبير - أي شيء يجب أن يظهر على الشاشة ينتمي إليه على الفور onMount / onAfterMount (إطار مؤجل إذا احتاج إلى graph.renderer وهو تم إنشاؤها بعد واجهة المستخدم).

شاهد معرض التوسيع باستخدام البرنامج المساعد بطاقة للحصول على مثال حي وكامل.

المساهمة في جزء قفص الاتهام ​

ctx.addDockTab يضع جزءًا في الرصيف السفلي بجانب البيانات الجدول. يمتلك الرصيف المنطقة - ارتفاعه، وفاصله، وطيه، والشريط الذي يقوم بتسمية الأجزاء - ويمتلك الجزء الخاص بك ما بداخله:

ts
const auditLog: PivotickPlugin = {
    name: 'auditLog',
    install: (ctx) => ctx.addDockTab({
        label: 'Audit',
        render: () => buildPane(ctx.graph),   // once, on first activation
        toolbar: () => [clearButton],         // on every activation
        onActivate: () => resumePainting(),
        onDeactivate: () => stopPainting(),
    }),
}

أربعة أشياء تستحق المعرفة:

  • علامة التبويب عبارة عن جزء، وليست طريقة عرض واحدة. إذا كان الجزء الخاص بك يحتوي على عدة طرق عرض خاصة به، فسيتم ذلك يبقى علامة تبويب واحدة في قفص الاتهام ويرسم المفتاح الخاص به في toolbar، ويتصل handle.refresh() لتغيير الجسم - الذي يعيد استدعاء render. وهذا هو بالضبط ما جدول البيانات يعمل بـ Nodes / Edges، ولماذا لا يقوم شريط الرصيف بتسوية أحد أبدًا طرق عرض الجزء بجانب جزء آخر. يؤدي تبديل DOM الخاص بك خلف ظهر الرصيف إلى القيام بذلك لا يعمل: فهو يحتفظ بالعنصر render الذي قدمه له، وسيعيد ربط عقدة قديمة على التنشيط القادم. ارسم مفتاحًا داخليًا كعنصر تحكم مجزأ، وليس كعلامات تبويب - الخارجي يبدو المستوى بالفعل مثل علامات التبويب. pvt-dock-views على الشريط و pvt-dock-view على كل منهما الزر (زائد active) عام، لذا يبدو مثل مفتاح الجدول ويتبع الموضوع دون أن تعيد ذكره أيضًا.
  • الجزء الأول يبني المنطقة. تثبيت المكونات الإضافية بعد تم إنشاء واجهة المستخدم، لذا علامة تبويب يصل دائمًا متأخرًا جدًا بحيث لا تتمكن بوابة الوضع الخاصة بالمرسى من قول نعم نيابةً عنها. يؤدي تسجيل واحد إلى ظهور قاعدة الإرساء، مما يعني أن المكون الإضافي الخاص بك يعمل معها UI.table: false ولا يحتاج إلى تشغيل أي شيء سوى وضع full.
  • يتم استدعاء render مرة واحدة، بتكاسل، في المرة الأولى التي يتم فيها فتح الجزء؛ العنصر هو يتم الاحتفاظ بها وإعادة توصيلها بعد ذلك، بحيث تحتفظ بموضع التمرير الخاص بها. toolbar هو يتم إعادة بنائها عند كل عملية تنشيط، حتى تتمكن عناصر التحكم الخاصة بها من قراءة الحالة الحالية للجزء الخاص بك.
  • onActivate / onDeactivate هي الإشارة الوحيدة التي تشير إلى أنك خارج الشاشة، وماذا للقيام بها يعتمد على الجزء الخاص بك. المحتوى الذي يمثل دالة لتيار الرسم البياني يمكن أن تتوقف الحالة عن العمل أثناء إخفائها وإعادة اشتقاقها عند العودة - وهذا هو ما في الجدول يفعل. المحتوى الذي من شأنه أن يفتقد شيئًا ما (جزء يشاهد حافلة مباشرة - لقد اختفى حدث ما) بمجرد إطلاقه) يجب أن يستمر في العمل ويتوقف فقط عن الرسم، ومسح الأعمال المتراكمة عندما يعود. لا شيء عن الخطافات يفضل أيضًا.

علامة التبويب ليست UIComponent، لذلك لا شيء يدفع مراحل دورة الحياة إليها. عندما الجزء الخاص بك يحتاج graphReady، اضغط على UIComponent، addElement واتصل على addDockTab من مكانه onMount — راجع المساهمة بعنصر واجهة المستخدم أعلاه.

شاهد إضافة جزء إرساء بطاقة المعرض للبث المباشر، مثال كامل - جزء يحتوي على طريقتي عرض خاصتين به، بجانب جدول البيانات.

المساهمة في وضع السكك الحديدية ​

الأوضاع الأربعة للسكك الحديدية اليسرى — التحديد، والإنشاء، والعرض، والفيزياء — مدمجة فيها. وأي شيء آخر لك: addRailMode يضع وضعًا خاصًا بك تحت المقسم، بعدهم، أمر بين أقرانه بـ order.

يمتلك وضع المؤشر لوحة الأدوات السياقية. أعلن عن tools وترسم اللوحة لهم بالطريقة التي يتم بها رسم التحديد والإنشاء، مع حالات التسليح/التعطيل وتم التعامل مع الانهيار من أجلك:

js
const explore = {
    name: 'explore-mode',
    install(ctx) {
        const selected = () => ctx.graph.renderer.getGraphInteraction().getSelectedNode()?.node

        ctx.addRailMode({
            id: 'explore',
            label: 'Explore',
            icon: compassSvg,
            shortcut: 'E',
            tools: [
                { id: 'expand', label: 'Expand neighbours', icon: plusSvg, kind: 'action',
                  enabled: () => !!selected(),
                  run: () => expandFrom(ctx.graph, selected()) },
                { id: 'walk', label: 'Path walk', icon: pathSvg, kind: 'toggle',
                  run: (armed) => armPathWalk(ctx.graph, armed) },
            ],
            onExit: () => armPathWalk(ctx.graph, false),
        })
    },
}

new Pivotick(el, data, { plugins: [explore] })

الأداة kind تقرر كيفية تصرفها. يعمل 'action' مرة واحدة ويترك الوضع كما هو كان. أ 'toggle' ذراع أداة مشروطة: تنهار اللوحة، ويتحول ** زر السكة إلى رمز وتسمية هذه الأداة الخاصة**، تمامًا كما تصبح فتحة التحديد Lasso. ا 'default' هي الأداة التي يرتكز عليها الوضع؛ قم بتسميته defaultTool وهو ما يعود إليه التبديل.

tools قد تكون أيضًا دالة، أعد القراءة في كل مرة يتم فيها رسم اللوحة - استخدم ذلك عندما تعتمد الصفوف على ما تم تحديده، بدلاً من اللون الرمادي فقط. لأي شيء على التوالي لا يمكن التعبير، render() تُرجع عنصرًا ملحقًا أسفل الصفوف:

js
ctx.addRailMode({
    id: 'explore', label: 'Explore', icon: compassSvg,
    tools: () => toolsFor(ctx.graph.renderer.getGraphInteraction().getSelectedNode()),
    render: () => depthSlider(),
})

يفتح الوضع المتحرك تراكب الإعدادات بدلاً من ذلك، مثل العرض والفيزياء. فئة فرعية Flyout واليد addRailMode مصنع - يقوم القلب بتثبيت اللوحة، ويفتحها تمامًا أثناء الوضع الخاص بك نشط، ويزيله مع الوضع:

js
import { Pivotick, Flyout } from 'pivotick'

class EnrichFlyout extends Flyout {
    mode = 'enrich'                     // must match the definition's id
    template() { return this.headerRow(sparklesSvg, 'Enrich') + this.toggleRow('auto', gearSvg, 'Auto-enrich', 'Enrich on load') }
    wire() { this.wireToggle('auto', () => toggleAuto(), () => isAuto()) }
}

ctx.addRailMode({
    id: 'enrich', label: 'Enrich', icon: sparklesSvg,
    kind: 'flyout',
    flyout: (ui) => new EnrichFlyout(ui),
})

الأوضاع متنافية، لذا فإن وضعك يستبعد View وPhysics مجانًا - متجر واحد، واحد الوضع النشط.

ثلاثة أشياء تستحق المعرفة:

  • icon عبارة عن خيط SVG خام، يتم حقنه كـ HTML ولا يتم تعقيمه أبدًا. يجب أن يأتي من مصدر تثق به. CSS أحجامها تصل إلى 20 بكسل على السكة و18 بكسل على اللوحة.
  • shortcut يتبع قواعد ربط المفاتيح العادية: المطالبة بمفتاح شيء آخر بالفعل يمتلك الظلال، مع تحذير، حتى تتم إزالة الوضع الخاص بك.
  • onExit هو المكان الذي تقوم فيه بنزع سلاحك. يتم تشغيله عند ترك الوضع، وعند إزالته أثناء النشاط - وفي هذه الحالة يعود السكة إلى التحديد. إنه يعمل not على واجهة المستخدم تمزيق. المتخلصون من البرنامج المساعد الخاص بك يتتبعون بالفعل تغطية ذلك.

addRailMode يقوم بإرجاع المتخلص، ويعمل في كل وضع — يتم رسم الزر في المكان فقط هناك سكة تعني full و light.

قيادة إطار العرض ​

يتم استخدام أي شيء يتنقل في الرسم البياني — خريطة مصغرة أو نظرة عامة أو عنصر تحكم "الانتقال إلى". طريقتان للعرض:

ts
// The extent of everything drawn, in graph coordinates (null when there's nothing).
const bounds = graph.renderer.getContentBounds()

// Put a graph-space point in the middle of the canvas.
graph.renderer.setViewport({ x: 120, y: -40 })
graph.renderer.setViewport({ x: 0, y: 0, scale: 1.5, animate: true })

setViewport يترك الميزان وحده إلا إذا تجاوزت واحدًا، فهو البدائي لـ بالغسل. لقراءة مكان العرض حاليًا **، قم بعكس زوايا اللوحة القماشية بدلاً من الوصول إلى تحويل تكبير/تصغير - وهذا أمر حيادي للعارض:

ts
const rect = graph.UIManager.layout.canvas.getBoundingClientRect()
const topLeft = graph.renderer.screenToGraphCoordinates(rect.left, rect.top)
const bottomRight = graph.renderer.screenToGraphCoordinates(rect.right, rect.bottom)

fitAndCenter() (يناسب كل شيء)، zoomIn() / zoomOut() و focusElement(nodeOrEdge) تبقى اختصارات للحالات الشائعة.

الخريطة المصغرة ​

مكون إضافي للطرف الأول: نظرة عامة مخبأة على الرسم البياني بالكامل مثبتة في زاوية اللوحة القماشية، مع مستطيل يوضح ما هو موجود على الشاشة. انقر على لإعادة عرض العرض مرة أخرى؛ اسحب المستطيل للتحريك. تبديل صغير جدًا في الزاوية التي يواجهها يطويها بعيدًا إلى هذا الزر فقط، ويعيده.

وضع full يُثبت واحدًا لك — وهو جزء من الكروم الخاص بهذا الوضع، مثل الرأس، الشريط الجانبي وسكة الوضع. كل وضع آخر يترك الأمر لك:

ts
// full mode: already there, nothing to install
new Pivotick(container, data, { UI: { mode: 'full' } })

// any other mode: ask for it, with `UI.minimap` …
new Pivotick(container, data, { UI: { mode: 'light', minimap: true } })

// … or as the plugin it is
import { Pivotick, minimap } from 'pivotick'
new Pivotick(container, data, { UI: { mode: 'light' }, plugins: [minimap()] })

UI.minimap يأخذ نفس {@link MinimapOptions} الذي يفعله المكوّن الإضافي، لذلك { minimap: { position: 'top-left' } } يقوم بتكوين الوضع الكامل الذي يجلبه. UI.minimap: false يقمعها. تمرير minimap() الخاص بك في plugins يفوز أيضًا — يقف الوضع الكامل جانبًا بدلاً من تركيب وضع ثانٍ - لذا فهو موجود plugins: [minimap({ … })] يستمر في العمل كما كان تمامًا.

html
<!-- browser build: it hangs off the global, like Node and Edge -->
<script>new Pivotick(el, data, { plugins: [Pivotick.minimap()] })</script>

خيارات ​

الخياراكتبالافتراضيماذا يفعل
position'bottom-right' | 'bottom-left' | 'top-right' | 'top-left''bottom-right'الزاوية التي يرسو فيها. 'bottom-right' هي الزاوية الوحيدة التي يتركها الكروم المدمج مجانًا في الوضع full.
widthnumber200العرض بـ CSS بكسل، مع تضمين الحدود.
heightnumberمشتقةالارتفاع بـ CSS بكسل. تم حذفه، فهو يتبع نسبة العرض إلى الارتفاع للوحة القماشية (المثبتة على 70-400 بكسل) بحيث يحافظ المستطيل على شكل إطار العرض الحقيقي.
collapsedboolean | 'auto'false، أو 'auto' للواحد full يتصاعد الوضعالحالة التي يتم فتحها فيها. مفتاح التبديل موجود دائمًا؛ هذا هو المكان الوحيد الذي يبدأ فيه. راجع الابتعاد عن الطريق من أجل 'auto'.

لا يوجد شيء آخر قابل للتكوين، لأنه لا يوجد شيء آخر يجب أن يكون: مستوى التفاصيل و يتكيف إيقاع إعادة الرسم مع الرسم البياني.

ما يرسم ​

العقد هي نقاط باللون الذي أعطاها لها العارض، والحواف عبارة عن خطوط شعرية تحتها، و الملاحظات - المحتوى الوحيد الذي له حجم خاص به - يتم رسمها على نطاق واسع باعتبارها شفافة كتل في لونها الخاص، على العقد كما هي على القماش. مخفي و يتم استبعاد المحتوى الذي تمت تصفيته. بعد بضعة آلاف من العقد، تصبح الصورة كثيفة Map بدلاً من ذلك (ختم واحد لكل عقدة، بدون حواف)، والذي يقرأ بشكل أفضل من عشرات الآلاف من النقاط المتداخلة يتم رسم الملاحظات في كلتا الحالتين. يتم تخزينها مؤقتًا بالكامل ولا يتم إعادة تنقيطها إلا عندما لقد تغيرت الصورة بالفعل - تم إسقاط عقدة، وتم نقل ملاحظة، واستقر التخطيط، ومرشح تم تطبيقه - بحيث يظل التحريك والتكبير/التصغير مجانيًا مهما كان حجم الرسم البياني.

بطاقة HTML (html على shape: 'none') ليس لها لون يمكن للخريطة المصغرة قراءته، لذا فإن نقطتها يأخذ لون أصغر رسم يكون شكلاً: النمط الأساسي، وإلا الطبقة الأولى في tiers. بدون أي شيء، أو بلون transparent، يتم رسم النقطة للداخل الحبر الخاص بالخريطة المصغرة (--pvt-minimap-ink). يتم تحديد حجم النقاط وفقًا لما تغطيه العقدة، لذلك أ تحصل البطاقة أو العقدة renderNode على نقطة بحجم البطاقة بدلاً من حجم واحد بمقدار size.

الابتعاد عن الطريق ​

الخريطة المصغرة التي طلبتها تبقى حيث وضعتها. يتم تركيب الوضع full الواحد نيابة عنك لم يطلب، فيفتح collapsed: 'auto' ويأخذ في الاعتبار القماش: هو تظل مفتوحة بينما يبلغ عرض اللوحة القماشية أربع خرائط مصغرة على الأقل وطولها، وتطوي نفسها بعيدا عن التبديل أدناه. ويستمر في متابعة اللوحة القماشية منذ ذلك الحين، حيث يتم طيها بعيدًا عندما ينفتح الشريط الجانبي فوقه أو تضيق النافذة، ويعود عندما تضيق الغرفة.

في اللحظة التي يقوم فيها أي شخص بطيه أو إعادته - عن طريق التبديل أو من خلاله setCollapsed() — يتوقف: يبقى الاختيار الصريح ثابتًا، ولا يتم تجاوز تغيير الحجم لاحقًا ذلك. مرر collapsed: true / false صريحًا لإلغاء الاشتراك في 'auto' منذ البداية.

يشير سهم التبديل إلى الزاوية التي ترسو فيها الخريطة المصغرة - وهو الاتجاه الذي تطويه بعيدًا - وينقلب بمجرد انهياره. عند طيها بعيدًا، فإنها لا ترسم شيئًا على الإطلاق، ولا حتى مستطيل، فلا يكلف شيئا وهو بعيد عن الطريق؛ فتحه يعيد التنقيط لـ مهما كان شكل القماش بحلول ذلك الوقت. setCollapsed(boolean) و isCollapsed() على Minimap مثيل يقود نفس الشيء من الكود.

ما يرسم، وما يكلف ​

تقوم الخريطة المصغرة بتعيين حدود المحتوى مع منفذ العرض الحالي، وبالتالي فإن يكون المستطيل مرئيًا دائمًا وحجمه صادقًا - قم بالتصغير بعيدًا ويتقلص الرسم البياني داخل الإطار بدلاً من انزلاق المستطيل منه.

إنه يحتفظ بالرسم البياني في صورة نقطية خارج الشاشة ويعيد تنقيطه فقط عند ظهور الصورة تم التغيير فعليًا: عند تغيير البيانات، عندما يقوم المرشح بإخفاء العقد أو استعادتها، عندما تكون العقدة موجودة يتم إسقاطها بعد السحب، عند كل علامة محاكاة عاشرة أثناء استقرار التخطيط، وعند تغيير الحجم. التحريك والتكبير/التصغير يعيدان رسم صورة واحدة ومستطيل واحد، لذا فإن تكلفة التنقل هي نفسها ما إذا كان الرسم البياني يحتوي على 20 عقدة أو 50000.

التفاصيل تتحلل مع الحجم، عن قصد:

رسم بيانيمرسومة كما
≥ 1500 عقدةنقطة لكل عقدة باللون الذي حله العارض، بالإضافة إلى الحواف الدقيقة (تم إسقاطها بعد 4000 حافة)
أكثر من 1500 عقدةختم واحد لكل عقدة بحبر واحد، وتراكم ألفا - تتم قراءة المناطق الكثيفة كخريطة كثافة، ولا يتم حل أي نمط لكل عقدة على الإطلاق

يعمل في الأوضاع full و light و viewer و full هو الذي يقوم بتثبيته دون أن يطلب منك ذلك. في static — الذي لا يعد بأي تفاعلات — لم يتم تركيبه، و تثبيته هناك يحذر.

شاهد بطاقة معرض Minimap للحصول على بطاقة حية.