تخطيط الرسم البياني
Pivotick يدعم استراتيجيات تخطيط متعددة لتحديد موضع العقد. يمكنك تكوين التخطيط من خلال الخيار layout، أو من خلال simulation.layout؛ عندما يتم ضبط كلاهما، layout يفوز.
| الخيار | اكتب | الافتراضي | الوصف |
|---|---|---|---|
type | 'force' | 'tree' | 'structured' | 'force' | خوارزمية التخطيط المستخدمة. 'force' يطبق تخطيط القوة القائم على الفيزياء. 'tree' يرتب العقد في هيكل شجرة. 'structured' يرسم رسمًا بيانيًا صغيرًا بالطريقة التي قد يتبعها الشخص، راجع التخطيط المنظم. |
خيارات تخطيط الشجرة
عند تحديد type: 'tree'، تتوفر الخيارات الإضافية التالية:
| الخيار | اكتب | الافتراضي | الوصف |
|---|---|---|---|
rootId | string | undefined | حدد معرف العقدة المراد استخدامها كجذر. إذا لم يتم توفيره، فسيقوم Pivotick تلقائيًا بتحديد جذر بناءً على rootIdAlgorithmFinder. |
rootIdAlgorithmFinder | - | MaxReachability | الخوارزمية المستخدمة للعثور على العقدة الجذرية تلقائيًا. |
parentKey | string | undefined | اسم المفتاح node.data الذي يحمل معرف أصل العقدة. بدون تحديد، تأتي الأبوة من الحواف. انظر إعلان التسلسل الهرمي. |
depthKey | string | undefined | اسم المفتاح node.data الذي يحمل الصف الذي تقع عليه العقدة، والعد من 0. بدون تعيين، تقع العقدة أسفل العقدة الأصلية بصف واحد. |
strength | number | 0.1 | قوة القوة للحفاظ على هيكل الشجرة. |
horizontal | boolean | false | ترتيب العقد أفقيًا وليس رأسيًا. |
radial | boolean | false | ضع العقد في تخطيط شعاعي بدلاً من الرأسي. |
radialGap | number | 750 | الفجوة بين الطبقات في التخطيط الشعاعي. |
spacing | 'auto' | 'manual' | 'auto' | ما إذا كان المضاعفان أدناه يضبطان نفسيهما من حجم العقد وشكل الشجرة. تعيين أي منهما يعني صراحة 'manual'. |
levelSpacing | number | 1 | ضرب المسافة بين المستويات المتتالية (بين الحلقات، عندما radial). 1 تناسب الشجرة مع القماش كما في السابق. |
siblingSpacing | number | 1 | مضاعفة المسافة بين العقد ضمن المستوى. يتم التجاهل عند radial، حيث يمتد المستوى دائمًا إلى الدائرة الكاملة. |
دورات والرسوم البيانية المنفصلة
تم بناء التسلسل الهرمي من عرض أول شجرة ممتدة متجذرة في rootId، وليس من الخام الحواف، لذلك لا يوقف أي منهما تخطيط الشجرة:
- Cycles. الحافة الأولى التي تصل إلى العقدة تجعلها الأصل لتلك العقدة؛ حافة تصل إلى العقدة الموضوعة بالفعل ليست جزءًا من التسلسل الهرمي ويتم رسمها عبر المستويات مثل أي عقدة حافة أخرى. وبالمثل، يطالب أحدهما بالعقدة التي تضم والدين.
- عدة مكونات. كل مكون لا يستطيع الجذر الوصول إليه يحصل على جذر خاص به - مفضلاً العقدة مع عدم وجود حواف واردة، لذلك يتم رسم المكون الذي هو التسلسل الهرمي كواحد - والمكونات تم وضعها جنبًا إلى جنب.
- العقد بدون حواف على الإطلاق. هذه ليس لها مكان في التسلسل الهرمي، لذا فهي متوقفة بدلاً من ذلك من المعطاة: فهي تملأ المساحة الميتة بجانب المستويات الضحلة، عند الحافة الخلفية لل التخطيط الذي تتركه الشجرة فارغًا لأنه يتسع عند نزولها. في التخطيط الشعاعي يأخذون حلقة خاصة بهم خارج الماضي. فقط العقد التي لا تشير إلى شيء هي * و* والتي تشير إلى لا شيء متوقفة، لذلك لا تترك أي حافة تمتد من الشجرة إلى منطقة وقوف السيارات.
لاحظ أن rootIdAlgorithmFinder: 'MinMaxDistance' و'MinHeight' هما نفس البحث — العقدة أطول مسار له هو الأقصر - وكلاهما يعتمد على النوع الطوبولوجي، لذلك على الرسم البياني مع دورة يحذرون ويعودون إلى العقدة الأولى. الافتراضي 'MaxReachability' ليس له مثل هذا القيد.
مكتشف جذر الشجرة
في التخطيط القائم على الشجرة، يجب تعيين عقدة واحدة كجذر. يمكنك تحديد العقدة الجذرية باستخدام الخيار rootId.
إذا لم تكن متأكدًا من العقدة التي يجب أن تكون الجذر، فلا تقلق! Pivotick سيختار واحدًا تلقائيًا باستخدام الخوارزمية المحددة في rootIdAlgorithmFinder.
يتم السير على اسم rootId ** متجاهلاً اتجاه الحافة **، بحيث يمكن لأي عقدة تجذير شجرة بأكملها - اختر يتم إعادة تعليق الورقة والرسم البياني أسفلها، مع مستوى الأصل السابق لأسفل. (بعد الأسهم من ورقة لن يصل إلى شيء، وسيتم وضع بقية الرسم البياني بجانبها كثانية المكون.) لا تزال الحواف نفسها مرسومة كما هي، لذلك يتم استخدام الرابط في الاتجاه المعاكس يظهر كسهم يشير إلى المستوى الأعلى. الجذر الذي اختاره rootIdAlgorithmFinder يستمر في السير والسهام: قرأ عليها في المقام الأول.
ما لم تكن الأسهم تسلسلًا هرميًا. على البيانات التي تتقارب — كل ورقة مصدر، جميعها الإشارة إلى عدد قليل من المحاور، وهو شكل معظم بيانات المصدر و"المشاهدة مع" - لا تصل أي عقدة الرسم البياني على طول الأسهم، أيهما يتم سؤال الباحث. ثم يترك المشي الموجه كل عقدة تقريبًا كجذر خاص بها، وتخرج الشجرة كمشط من الجذوع تتطاير معظم حوافها عبر الشجرة تخطيط. لذلك عندما لا توجد عقدة على الإطلاق يمكنها تغطية نصف المكون الخاص بها باتباع الأسهم، يتوقف التخطيط عن قراءة الاتجاه: فهو يسير في كل حافة في كلا الاتجاهين ويعيد تجذيره في منتصف الرسم البياني. لا تزال الحواف مرسومة تمامًا كما هي، مما يعني أن أسهمها تشير إلى أعلى الشجرة باتجاه الجذر - العرض الصادق للبيانات التي تشير إلى هذا الاتجاه.
هذا إجراء احتياطي، وليس القاعدة، والاختبار يتعلق بالرسم البياني وليس بالجذر الذي كان موجودًا اختار:
- عندما تشكل الأسهم تسلسلًا هرميًا، فهي أفضل ما يمكن وضعه، ويحتفظ به كل مكتشف إجابتها الخاصة - بما في ذلك
'MinHeight'، التي تكون إجابتها على الشجرة دائمًا ورقة، حيث تصل إلى لا شيء عن قصد. يتم إلغاء الجذر الذي يغطي القليل من الرسم البياني فقط عندما لا يكون هناك شيء آخر كان من الممكن أن تغطي أكثر من ذلك. - لا يزال الرسم البياني لعدة تسلسلات هرمية منفصلة يظهر كغابة: يتم قياس التغطية مقابلها المكون الخاص بالجذر، لذلك لا يمكن الخلط بين التسلسل الهرمي متعدد المكونات الجيد تمامًا وبين a الفشل.
- يتخطى
rootIdالمثبت الاختبار تمامًا - لقد تم السير عليه بالفعل متجاهلاً الاتجاه.
rootId تسمية عقدة غير موجودة في الرسم البياني - تمت تصفيتها وحذفها داخل مجموعة مطوية - يتم تجاهله طالما كان ذلك صحيحًا، ويختار الباحث الجذر بدلاً من ذلك. ويبقى الخيار وبالتالي فإن العقدة التي تعود تعيد تجذير الشجرة.
يمكن أيضًا تغيير الجذر في وقت التشغيل — حيث تعرضه قائمة الفيزياء كقائمة في الصف Root عندما يكون تخطيط الشجرة نشطًا. تقوم القائمة بتسمية كل مكتشف وتقول ما يفعله؛ دخولها الأول هي "العقدة التي حددتها"، والتي تظهر باللون الرمادي حتى يتم تحديد عقدة واحدة بالضبط. بمجرد وجود العقدة المثبت، يعرض الصف تسمية تلك العقدة بدلاً من اسم الباحث:
graph.simulation.setTreeRoot({ rootId: 'node-42' }) // pin the tree to a node
graph.simulation.setTreeRoot({ algorithm: 'MinHeight' }) // drop the pin, let the finder choose
graph.simulation.getTreeRoot() // { rootId: undefined, algorithm: 'MinHeight' }إعلان التسلسل الهرمي
عادةً ما يعمل Pivotick على إنشاء التسلسل الهرمي لنفسه: الأبوة من شجرة ممتدة فوق الحواف، وكل عقدة صف واحد أسفل العقدة الأم. هناك خياران يسمحان للبيانات بقول ذلك بدلاً من ذلك.
parentKeyيسمي المفتاحnode.dataالذي يحمل المعرف الأصلي للعقدة.depthKeyيسمي المفتاحnode.dataالذي يحمل الصف الذي يجلس عليه، والعد من0عند الجذر الضحل.
يتم إلغاء ضبط كلاهما افتراضيًا، ولا تتم قراءة أي شيء على الإطلاق حتى تقوم بتسمية مفتاح - أي رسم بياني بياناته يحدث أن يحمل حقل depth أو parent لا يتأثر حتى تطلبه.
قد يكون أي من المفتاحين مفقودًا من أي عقدة فردية. العقدة التي ليس لها أصل مُعلن تحصل على واحدة من حواف كالمعتاد. العقدة التي لا تحتوي على صف مُعلن تقع أسفل العقدة الأصلية. رسم بياني لا يعلن عن أي منهما تم وضعه تمامًا كما كان دائمًا.
بدء شجرة إلى أسفل
هذا هو الغرض الأساسي من depthKey. رسم بياني لعدة أشجار منفصلة هو غابة، وجذورها جميعهم يشتركون في خلاف سطحي، ولم تكن هناك في السابق طريقة للقول بأن أحدهم ينتمي إلى أبعد من ذلك أسفل. أعط هذا الجذر صفًا:
const data = {
nodes: [
{ id: 'a' }, { id: 'a1' }, { id: 'a2' },
{ id: 'b', data: { level: 2 } }, { id: 'b1' }, { id: 'b2' },
],
edges: [
{ from: 'a', to: 'a1' }, { from: 'a', to: 'a2' },
{ from: 'b', to: 'b1' }, { from: 'b', to: 'b2' },
],
}
const graph = new Pivotick(container, data, {
layout: { type: 'tree', depthKey: 'level' },
})row 0 a
row 1 a1 a2
row 2 b <- b asked for row 2
row 3 b1 b2الشجرة بأكملها تتحرك مع جذرها: أطفال b يتبعونها إلى الأسفل. في التخطيط radial يوجد صف حلقة، لذا فإن نفس الإعلان يبدأ تلك الشجرة بحلقتين.
ماذا تعني الصفوف
لا يمكن للصف إلا أن يدفع العقدة للأسفل. الشجرة المرتبة تضع الطفل تحتها صف واحد بالضبط الأصل، لذلك لا يمكن رسم صف ليس أقل من الأصل - فهو مثبت على parent + 1 وتحذير من الأسماء كم كان عددهم. البديل هو تكريم الصف عن طريق فصل العقدة عنه أحد الوالدين، سيترك رقمًا خاطئًا يكسر الشجرة إلى قطع إضافية.
يتم ترك الصفوف التي يتم تخطي البيانات فيها فارغة، وتشغل مساحة حقيقية — وهذا ما يجعل الإعلان معلنًا صف يعني أي شيء. يتم تغيير حجم الشجرة لتناسب اللوحة القماشية، لذلك يتم إعلان الصف 50 على سطح ضحل الرسم البياني يجعله يبلغ طوله واحدًا وخمسين صفًا ويضغط كل صف حقيقي على لا شيء. levelSpacing و التباعد التلقائي هو طريق العودة.
ما يفعله الوالد المعلن
يتم تكريم الوالد المعلن سواء انضمت الحافة إلى الزوج أم لا. مما يجعلها قادرة على الدولة تسلسل هرمي لا تحتوي عليه الحواف - ولكنه يعني أيضًا أن هذا الفرع مرسوم بدون خط لأنه لا توجد حافة هناك لرسمها. الإعلان هو المكان الذي يأتي منه التسلسل الهرمي؛ ال يتم رسم الحواف فقط كما هي.
هناك نتيجتان مفيدتان: يمكن للعقدة ذات الحواف الواردة المتعددة أن تحدد أي منها هو الأصل الحقيقي لها (خلافًا لذلك، ستأخذ الشجرة الممتدة أيًا كان يصل إليها أولاً)، وعقدة بدون حواف على الإطلاق تعلن أن أحد الوالدين يحصل على مكان مناسب في الشجرة بدلاً من المنطقة المتوقفة.
يتم إسقاط الإعلانات التي لا يمكن استخدامها لتلك العقدة، والتي تعود بعد ذلك إلى الحواف، و تحذير واحد يحصيهم جميعًا:
- يقوم أحد الوالدين بتسمية العقدة التي لم يتم وضعها - والتي تمت تصفيتها أو حذفها أو داخلها مطوية الكتلة - بنفس الطريقة
rootIdتتراجع عندما تكون العقدة التي تسميها مفقودة؛ - أحد الوالدين الذي من شأنه أن يغلق الدورة (الرابط الذي يغلقها هو الذي تم إسقاطه)؛
- صف ليس رقم
0أو أكبر.
الأسبقية
rootId الرتب العليا parentKey. تثبيت جذر — في الخيارات، أو عن طريق اختيار واحد في الفيزياء Rail - هو طلب لإعادة تعليق الشجرة من تلك العقدة، بحيث يتم إعادة اشتقاق الأبوة من الحواف ويتم تخصيص الآباء المعلنين لهذا المرور. أعلن صفوف لم تتأثر: يقولون مدى عمق العقدة تجلس، وليس ما تتدلى منه.
egoTree يتجاهل كلا الخيارين؛ إنه يبني نجمًا من جيران الجذر.
تباعد
تم وضع الشجرة بحيث تناسب تناسب اللوحة القماشية، لذا فإن تباعدها الطبيعي يتبع بالفعل حجم اللوحة القماشية و مدى عمق وعرض الشجرة. levelSpacing و siblingSpacing المقياس المناسب للهندسة: 2 يعني "ضعف المسافة بين التصميم المجهز" على محور العمق والعرض على التوالي. كلاهما الافتراضي هو 1، وهو التخطيط المناسب نفسه، وكلاهما يقبل 0.5 إلى 10.
ويمكن أيضًا تغييرها في وقت التشغيل - حيث توفرها القائمة المنبثقة للفيزياء كمنزلقات عند وجود شجرة التخطيط نشط (بدلاً من مقابض المحاكاة، التي يتجاهلها تخطيط الشجرة):
graph.simulation.setTreeSpacing({ levelSpacing: 2 })
graph.simulation.getTreeSpacing() // { levelSpacing: 2, siblingSpacing: 1 }تباعد تلقائي
بشكل افتراضي، تعمل الشجرة على تباعدها الخاص. يتم تحديد حجم تخطيط الشجرة من القماش وليس أبدًا ينظر إلى حجم العقد، بحيث يتم وضع شجرة من النقاط الصغيرة وشجرة من العقد الكبيرة ذات العلامات خارج بشكل مماثل - والثاني يتداخل. spacing: 'auto' يقيس أضيق زوج من الجيران على كل محور، يحدد ما يحتاجون إليه لأنصاف أقطارهم (بالإضافة إلى مساحة لرأس السهم بين المستويات)، ويقيس المضاعفات لتناسبها. ويعيد اشتقاقها كلما تغير الرسم البياني.
شيئان لن يفعلهما عمدا:
- ** لا تقوم أبدًا بتعبئة شجرة أكثر إحكامًا من التصميم المجهز. ** تلقائي فقط يرفع المضاعف أعلاه
1، لذلك يتم وضع الرسم البياني الذي لم يكن مزدحمًا أبدًا كما كان دائمًا. - لا يتجاوز أبدًا الاختيار الذي قمت به. الشجرة التي تحدد
levelSpacingأوsiblingSpacingهي تم اعتباره قد اتخذ قراره، وتحريك أي من شريط التمرير يدويًا يترك تلقائيًا للأبد. تسليم المضاعفات مرة أخرى معsimulation.enableAutoTreeSpacing().
في التخطيط radial، حيث يمتد المستوى دائمًا إلى الدائرة الكاملة، لا يمكن التزاحم داخل الحلقة إلا يمكن الشعور بالارتياح عن طريق دفع الحلقات إلى الخارج - لذا فإن كلا القياسين يقودان levelSpacing إلى هناك.
تخطيط منظم
type: 'structured' يرسم رسمًا بيانيًا صغيرًا بالطريقة التي يرسمها الشخص، من أجل جزء مضمن المشاهد الذي يجب أن يكون قابلاً للقراءة في لمحة. يتم حسابها بدلاً من محاكاتها: كل عقدة كذلك يتم وضعها وتثبيتها، بحيث يعطي نفس الرسم البياني دائمًا نفس الصورة، ويتحرك سحب العقدة فقط تلك العقدة.
- **المكونات جنبًا إلى جنب. ** يتم وضع كل مكون متصل بمفرده، و يتم تعبئة المكونات في صفوف. عرض الصف هو الذي يناسب التخطيط بأكمله قماش في أكبر التكبير.
- اصطفاف المعجبين. ثلاث أوراق أو أكثر من نفس النوع تتدلى من نفس الورقة أو الاثنتين العقد (الورقة بها جارتان على الأكثر) تقف في صف أو عمود واحد متباعد بشكل متساوٍ، مع العقد التي يتدلى منها على جانب واحد منه. المجموعة هي المجموعة المبسطة نفس الجيران استخدامات القاعدة، مكتوبة بواسطة
UI.simplify.typeOf، وإلاrender.nodeTypeAccessor. لا شيء مطوية بعيدا. - ** المسافات تتبع الحواف. ** كل شيء آخر يتم وضعه عن طريق تكبير الضغط: العقد واحدة الحافة المتباعدة تفصل بينهما مسافة واحدة، والحافتان متباعدتان بمقدار ضعف ذلك، وهكذا. محور يخرج الجيران من حوله وتخرج السلسلة بشكل مستقيم، دون أي حالة خاصة لأي منهما.
- ** صينية للعقد السائبة. ** العقد التي ليس لها حافة على الإطلاق تكون شبكية أسفل الباقي، أو إليها صحيح.
- ملصقات على الجانب الحر. ملصق عائم (
textVerticalShiftأوtextHorizontalShift1 أو أكثر) يتم رسمها على جانب عقدتها بحيث تترك حوافها حرة، بعيدًا عن اسلوب وضعه. تتجه جميع ملصقات المروحة بعيدًا عن العقد التي تتدلى منها.
تتم إعادة التصميم كلما تغير الرسم البياني المرئي، ومرة أخرى بعد السحب الأول، عندما تكون الأحجام الحقيقية للعقد معروفة. يتم تباعد العقد بـ getLayoutRadius()، لذا فإن نمط العقدة الذي يعلن layoutSize تم وضعه بهذا الحجم مهما كان ما يرسمه. إنه مخصص للرسوم البيانية ما يصل إلى بضع مئات من العقد.
| الخيار | اكتب | الافتراضي | الوصف |
|---|---|---|---|
groupMin | number | 3 | أقل عدد من الأوراق يشاركون النوع وجيرانهم يصطفون كمشجعين. يتم وضع عدد أقل واحدًا تلو الآخر. |
direction | 'auto' | 'row' | 'column' | 'auto' | كيف يصطف أحد المعجبين. 'auto' يقف عبر الخط إلى العقد التي يتدلى منها. |
gap | number | 30 | مسح المساحة بين العقدتين. يتم رسم الحافة مرتين بهذا الطول؛ المكونات والصينية تتباعد ثلاث مرات. |
trayPosition | 'bottom' | 'right' | 'bottom' | حيث تذهب العقد بدون حافة. |
labelSides | boolean | true | انقل كل ملصق عائم إلى الجانب الذي تترك حوافه حرة. false يترك التسميات حيث يضعها النمط. |
new Pivotick(container, data, {
layout: { type: 'structured', trayPosition: 'right' },
render: {
nodeTypeAccessor: (node) => node.getData().type,
defaultNodeStyle: { text: (node) => node.getData().label, textVerticalShift: -1.4 },
},
})graph.simulation.getLabelSide(id) يشير إلى الجانب المختار للعقدة: 'top'، 'bottom'، 'left' أو 'right' أو undefined تحت أي تخطيط آخر.
يتم ملاءمة العرض مع العقد، وليس مع تسمياتها، لذلك يتم وضع علامة طويلة بجانب العقدة عند الحافة من التخطيط يمكن أن يمر عبر اللوحة القماشية.
خطر
أضف مثالاً بالتخطيطين!
شجرة عمودية
const options = {
layout: {
type: 'tree'
},
UI: {
mode: 'static'
}
}شجرة عمودية
const options = {
layout: {
type: 'tree',
radial: true,
radialGap: 300,
},
UI: {
mode: 'static'
}
}