بناء رسم معلوماتي تفاعلي باستخدام Vue.js
نشرت: 2022-03-10تقدم هذه المقالة مقاربة حديثة لبناء مخطط معلوماتي تفاعلي. يمكنك بالتأكيد الحصول على رسم بياني عادي مع جميع المعلومات المتاحة مقدمًا - دون أي تدخل من المستخدم. لكن التفكير في بناء تجربة تفاعلية - يغير المشهد التكنولوجي الذي نختاره. لذلك ، دعنا نفهم أولاً ، لماذا Vue.js؟ وسترى لماذا أصبح GSAP (GreenSock Animation Platform) و SVG (Scalable Vector Graphics) خيارات واضحة.
يوفر Vue.js طرقًا عملية لبناء واجهات مستخدم ديناميكية قائمة على المكونات حيث يمكنك التعامل مع عناصر DOM وإدارتها بطرق قوية. في هذه الحالة ، ستكون SVG. يمكنك بسهولة تحديث وإدارة عناصر SVG المختلفة - ديناميكيًا - باستخدام مجموعة فرعية صغيرة فقط من الميزات المتوفرة في Vue.js - بعض الميزات الأساسية التي تناسب الفاتورة هنا ، هي ، ربط البيانات ، عرض القائمة ، ربط الفئة الديناميكي لتسمية قليل. يتيح لك هذا أيضًا تجميع عناصر SVG ذات الصلة معًا ، وتكوينها.
يلعب Vue.js بشكل جيد مع المكتبات الخارجية دون أن يفقد مجدها ، وهذا هو GSAP هنا. هناك العديد من الفوائد الأخرى لاستخدام Vue.js ، أحدها أن Vue.js يسمح لك بعزل القوالب والبرامج النصية والأنماط ذات الصلة لكل مكون. بهذه الطريقة ، يعزز Vue.js بنية التطبيق المعيارية.
القراءة الموصى بها : استبدال jQuery بـ Vue.js: لا ضرورة لخطوة البناء
يأتي Vue.js أيضًا معبأ بمشابك قوية لدورة الحياة تتيح لك الاستفادة من مراحل التطبيق المختلفة لتعديل سلوك التطبيق. لا يتطلب إعداد تطبيقات Vue.js وصيانتها التزامًا كبيرًا ، مما يعني أنه يمكنك اتباع نهج تدريجي لتوسيع نطاق مشروعك كما تذهب.
إن الرسم البياني خفيف الوزن للغاية بالمعنى المرئي ، حيث أن الهدف الرئيسي من هذه المقالة هو تعلم كيفية التفكير من حيث البيانات والعناصر المرئية وبالطبع Vue.js - الإطار الذي يجعل التفاعل ممكنًا. بالإضافة إلى ذلك ، سنستخدم GreenSock ، مكتبة لتحريك عناصر SVG. قبل أن نتعمق ، ألق نظرة على العرض التوضيحي.
سنبدأ بـ:
- نظرة عامة على بيانات مخطط المعلومات الرسومي ؛
- إعداد صورة SVG ؛
- نظرة عامة على مكونات Vue في سياق عمل SVG الفني ؛
- عينات التعليمات البرمجية والرسوم التخطيطية للتفاعل الرئيسي.
الرسم المعلوماتي الذي سنقوم ببنائه يدور حول Tour De France ، الحدث السنوي لسباق الدراجات الذي يقام في فرنسا.
نظرة عامة على بيانات تور دو فرانس
في تصميم مخطط المعلومات الرسومي ، تقود البيانات تصميم مخطط المعلومات الرسومي الخاص بك. لذلك ، أثناء التخطيط لتصميم مخطط المعلومات الرسومي الخاص بك ، من الجيد دائمًا أن تتوفر جميع البيانات والمعلومات والإحصاءات للموضوع المحدد.
خلال سباق Tour De France لعام 2017 ، تعلمت كل شيء عن أكبر حدث لركوب الدراجات استطعت أن أتمكن من لعبه خلال 21 يومًا من المباراة في يوليو ، وأطلعت على الموضوع.
الكيانات الأساسية للعرق التي قررت أن أختارها في تصميمي هي ،
- مراحل،
- فرق،
- طرق ،
- الفائزون ،
- طول وتصنيفات كل مسار.
يعتمد الجزء التالي من العملية على أسلوب تفكيرك ، لذا يمكنك أن تكون مبدعًا هنا.
لقد أنشأت مجموعتين من البيانات ، واحدة للمراحل والأخرى للفرق. تحتوي مجموعتي البيانات هاتين على صفوف متعددة من البيانات (ولكن within limit
) - والتي تتطابق مع عجلتين للدراجة ذات مكبرات صوت متعددة في كل منهما. وقد حدد ذلك العنصر الأساسي للتصميم ، The Bicycle Art
الذي رأيته في البداية - حيث سيكون كل حديث تفاعليًا ومسؤولًا عن تحديد المعلومات التي يتم الكشف عنها على الشاشة.
لقد ذكرت within limits
أعلاه ، لأن ما نهدف إليه في هذه الحالة ليس تصورًا كاملاً للبيانات في سياق البيانات الضخمة ، بل بالأحرى رسم بياني ببيانات عالية المستوى.
لذلك ، اقضِ وقتًا ممتعًا مع البيانات وابحث عن أوجه التشابه أو الاختلافات أو التسلسل الهرمي أو الاتجاهات التي يمكن أن تساعدك في نقل قصة مرئية. ولا تنسَ المزيج المذهل بين SVG و Vue.js أثناء تواجدك فيه ، حيث سيساعدك على تحقيق التوازن الصحيح بين المعلومات (البيانات) والتفاعل (Vue.js) وعناصر التصميم (SVG Artwork ) من مخطط المعلومات الرسومي.
فيما يلي مقتطف من كائن بيانات المرحلة:
{ "ID": 1, "NAME": "STAGE 01", "DISTANCE": "14", "ROUTE": "KMDUSSELDORF / DUSSELDORF", "WINNER": "THOMAS G.",
"UCI_CODE": "SKY",
"TYPE": "Individual Time Trial",
"DATE": "Saturday July 1st",
"KEY_MOMENT": " Geraint Thomas takes his first win at 32"
}
ومقتطف كائن بيانات الفريق على النحو التالي:
{ "ID": 1,
"UCI_CODE": "SKY",
"NAME": " TEAM SKY",
"COUNTRY": "Great Britain",
"STAGE_VICTORIES": 1,
"RIDERS": 8
}
يتم تشغيل مخطط المعلومات هذا من خلال منطق بسيط للغاية.
UCI_CODE (Union Cycliste Internationale) هو مفتاح الاتصال بين المرحلة وكائن الفريق. عندما يتم النقر على مرحلة ما ، سنقوم أولاً بتنشيط تلك المرحلة ، ولكن أيضًا نستخدم مفتاح UCI_CODE
لتنشيط الفريق الفائز المقابل.
تحضير SVG
بوجود مجموعتين من مجموعات البيانات ومفهوم تقريبي لفن الدراجات جاهز ، إليك SVG CodePen الثابت للرسومات البيانية التي توصلت إليها.
لقد أنشأنا صوتًا واحدًا فقط لكل عجلة ، وذلك لأننا سننشئ ديناميكيًا بقية المتحدث باستخدام عدد من السجلات الموجودة في مجموعة البيانات ، ونقوم بتحريكها باستخدام مكتبة GreenSock.
كما أن سير العمل لإنشاء كود SVG بسيط للغاية. قم بإنشاء عملك الفني Infographic في Adobe Illustrator وحفظه بتنسيق SVG. تأكد من تسمية كل group
layer
أثناء العمل في Illustrator ، لأنك ستحتاج إلى هذه المعرفات لفصل أجزاء من كود SVG والتي ستملأ في النهاية منطقة <template>
لمكونات Vue. تذكر أن أسماء الطبقات الواردة في Illustrator تصبح element ids
في ترميز SVG.
يمكنك أيضًا استخدام SVGOMG وتحسين كود SVG الذي تم تصديره من Adobe Illustrator.
ملاحظة مهمة: إذا كنت تستخدم SVGOMG لتحسين ترميز SVG ، فمن المؤكد أن الكود الخاص بك سيبدو أنيقًا ، لكن لاحظ أنه سيحول جميع عناصر <تصحيح> إلى <مسار> بسمة d
. ينتج عن هذا فقدان قيم x
و y
للمستطيل ، في حالة رغبتك في ضبط عدد قليل من وحدات البكسل يدويًا لاحقًا.
ثانيًا ، تأكد من إلغاء تحديد خيار Clean Id
(خيارات الجانب الأيمن في واجهة SVGOMG) ، سيساعد ذلك في الحفاظ على سلامة جميع المجموعات والمعرفات التي تم إنشاؤها في Illustrator.
نظرة عامة على مكون Vue
حتى إذا كان التفاعل وتدفق البيانات في مشروع الإنفوجرافيك الخاص بك بسيطًا جدًا بطبيعته ، يجب عليك دائمًا قضاء بعض الوقت في رسم مخطط شجرة للمكونات.
سيساعد هذا بشكل خاص في حالة عدم استخدامك لأي آلية بيانات مشتركة ، حيث تعتمد المكونات الفرعية على القيم المرسلة من المكون الرئيسي (أي عبر الدعائم) أو العكس (على سبيل المثال. أحداث $ emit). هذه فرصتك لتبادل الأفكار حول قيم العناصر هذه ، وبث الأحداث والبيانات المحلية - وتوثيقها قبل البدء في كتابة الكود.
الرسم التخطيطي أعلاه هو لقطة لمكونات Vue مشتقة جزئيًا من متطلبات التفاعل وتعتمد جزئيًا على ترميز SVG. يجب أن تكون قادرًا على رؤية كيفية تقسيم ترميز SVG بناءً على هيكل الشجرة هذا. إنها تشرح نفسها بنفسها من وجهة نظر التسلسل الهرمي.
- ستقلد عجلة السلسلة دوران المتحدث.
- مكون المرحلة هو العجلة الخلفية التي ستدرج جميع المراحل الـ 21.
- سيعرض مكون تفاصيل المرحلة المعلومات ذات الصلة على مسار منحن (الجانب الأيسر).
- مكون الفريق هو العجلة الأمامية التي ستدرج جميع الفرق المشاركة على المتحدث.
- سيعرض مكون تفاصيل الفريق المعلومات ذات الصلة على مسار منحن (الجانب الأيمن).
- سيتضمن التنقل زر الرجوع والزر التالي للوصول إلى المراحل.
يمثل الرسم البياني أدناه نفس مكونات Vue الموضحة أعلاه ، ولكن في سياق تصميم مخطط المعلومات الرسومي.
الأقل هو الأكثر - يجب أن يكون هذا هو النهج الذي يجب أن تحاول اتباعه أثناء العمل في مشاريع مماثلة. فكر في متطلبات الرسوم المتحركة والانتقال لديك ، إذا كان بإمكانك استخدام TweenLite بدلاً من TweenMax - افعل ذلك. إذا كان لديك خيار اختيار الأشكال الأولية والمسارات الأبسط على الأشكال المعقدة - فحاول بكل الوسائل الاشتراك في العناصر خفيفة الوزن التي يسهل تحريكها - دون أي عقوبة على الأداء.
سيأخذك القسم التالي إلى جزء مثير مع الرسوم المتحركة GreenSock و Vue.js.
الرسوم المتحركة GreenSock
دعنا نلقي نظرة فاحصة على:
- الرسوم المتحركة للنص على مسار منحن ؛
- تكلم الرسوم المتحركة على عجلة.
تذكر مسار المنحنى المرئي حول عجلة الدراجة ، هذا المسار المنحني أكبر قليلاً من نصف قطر عجلة الدراجة. لذلك ، عندما نقوم بتحريك النص على هذا المسار ، سيبدو كما لو أنه يتبع شكل العجلة.
يعد path
و textPath
من عناصر SVG التي تسمح لك بتعيين النص على أي مسار باستخدام xlink:href
.
<pathlanguage-javascript">curvedPath
" stroke="none" fill="none" d="..."/>
<text>
<textPath xlink:href="
#curvedPath
"
class="stageDetail"
startOffset="0%">
{{ stage.KEY_MOMENT }}
</textPath>
</text>
لتحريك النص على طول المسار ، سنقوم ببساطة بتحريك سمة startOffset
الخاصة به باستخدام GreenSock.
tl.fromTo( ".stageDetail", 1, { opacity: 0,
attr: { startOffset: "0%" }
},
{
opacity: 1,
attr: { startOffset: "10%" }
}, 0.5 );
كلما زادت نسبة startOffset
، سينتقل النص أكثر عبر محيط الدائرة.
في مشروعنا النهائي ، يتم تشغيل هذه الرسوم المتحركة في كل مرة يتم فيها النقر فوق أي كلمة. الآن ، دعنا ننتقل إلى جزء أكثر إثارة من الرسوم المتحركة.
مراحل متحركة / المتحدث داخل العجلة
يتضح من العرض التوضيحي أن stage
ومكونات team
متشابهة في طبيعتها مع وجود بعض الاختلافات الصغيرة. لذا ، دعونا نركز على عجلة واحدة فقط للدراجة.
يقوم مثال CodePen أدناه بتكبير الأفكار الرئيسية الثلاثة فقط:
- إحضار بيانات المرحلة ؛
- ترتيب المتحدث ديناميكيًا بناءً على البيانات ؛
- أعد ترتيب المتحدث عند النقر فوق المرحلة (تحدث).
ربما لاحظت في SVG CodePen الثابت أعلاه أن المتحدث ليس سوى مستطيلات SVG ونص مجمع معًا. لقد جمعتهم معًا لأنني أردت اختيار كل من النص والمستطيل لغرض الرسوم المتحركة.
<g v-for="stage in stages"
class="stage">
<rect x="249" y="250" width="215" height="1" stroke="#3F51B5" stroke-width="1"/>
<text transform="translate(410 245)" fill="#3F51B5" >
{{ stage.NAME }}
</text>
</g>
سنعرضها في منطقة <template>
لمكون Vue باستخدام القيم التي تم جلبها من مصدر البيانات.
عندما تكون جميع المراحل الـ 21 متاحة على الشاشة ، سنقوم بتعيين مواضعها الأولية عن طريق استدعاء ، دعنا نقول ، setSpokes()
.
// setSpokes() let stageSpokes = document.querySelectorAll(".stage") let stageAngle = 360/this.stages.length _.map(stageSpokes, (item, index) => { TweenMax.to(item, 2, { rotation: stageAngle*index, transformOrigin: "0% 100%" }, 1) }
ثلاثة عناصر رئيسية لتهيئة المسرح هي:
- دوران
لتدوير المتحدث ، سنقوم ببساطة بتعيين جميع العناصر باستخدام classNamestage
، وتعيين قيمةrotation
الديناميكي التي يتم حسابها لكل حديث. - أصل التحويل
لاحظtransformOrigin
القيمة الأصلية في الكود أعلاه ، والتي لا تقل أهمية عن قيمةindex
، لأن "0٪ 100٪" تمكن كل حديث من التدوير من مركز العجلة. - المرحلة
يتم حساب ذلك باستخدام إجمالي عدد المراحل مقسومًا على 360 درجة. سيساعدنا ذلك في وضع كل شعاع بالتساوي في دائرة 360 درجة.
زيادة التفاعل
ستكون الخطوة التالية هي إضافة حدث نقرة في كل مرحلة لجعلها تفاعلية ومتفاعلة مع تغييرات البيانات - وبالتالي ، ستضفي مزيدًا من الحياة على صورة SVG!
لنفترض أنه إذا تم النقر على المرحلة / الكلام ، فسيتم تنفيذ goAnimate()
، وهو المسؤول عن تنشيط وتدوير المرحلة التي يتم النقر عليها باستخدام المعلمة stageId
.
goAnimate (stageId) { // activate stage id this.activeId = stageId // rotate spokes }
سنستخدم DirectionalRotationPlugin… وهو مكون رئيسي لهذا التفاعل. ونعم ، يتم تضمينه في TweenMax.
هناك ثلاث طرق مختلفة لاستخدام هذا البرنامج المساعد. إنه يحرك خاصية الدوران في 1) اتجاه عقارب الساعة ، 2) عكس اتجاه عقارب الساعة و 3) في أقصر مسافة محسوبة إلى الوجهة.
كما خمنت الآن ، نحن نستخدم الخيار الثالث لتدوير أقصر مسافة بين المرحلة الحالية والمرحلة الجديدة.
راجع CodePen أعلاه وسترى كيف تتحرك Stage 01 باستمرار حول الدائرة ، تاركة مكانها الأصلي لمرحلة نشطة جديدة بزاوية 0 درجة.
أولاً ، نحتاج إلى إيجاد زاوية المرحلة التي يتم النقر عليها ، وتبادل دورانها مع المرحلة 01 . إذن ، كيف نجد قيمة دوران المرحلة التي يتم النقر عليها؟ تحقق من الرسم البياني أدناه.
على سبيل المثال ، إذا تم النقر فوق المرحلة 05 (كما ترى أعلاه) ، فإن الرحلة من المرحلة 01 إلى المرحلة 05 - تتطلب 4 × قيمة زاوية.
وبالتالي ، يمكننا الحصول على الزاوية الصحيحة باستخدام (Active stage Id - 1) * 17 degree,
متبوعًا بـ postfix سلسلة قصيرة لتشغيل البرنامج المساعد للدوران الاتجاهي.
angle = 360/21 stages = 17 activeId = 5
new angle = (
(activeId-1)
*angle)+'_short'
= ((5-1)\*17)+'_short'
= 68
ستبدو وظيفة goAnimate()
النهائية كما يلي:
_.map(spokes, (item, index) => { if(activeId == index+1) { // active stage TweenMax.to(item, 2, { rotation: 0+'_short', transformOrigin: "0 100%" }) } else if (index == 0) { // first stage TweenMax.to(item, 2,
{ rotation: (activeId*angle)-angle+'_short',
transformOrigin: "0 100%"
})
} else {
TweenMax.to(item, 2,
{ rotation: index*angle+'_short',
transformOrigin: "0 100%"
})
}
}) // end of map
بمجرد أن تكون العجلة الخلفية جاهزة ، يجب أن تتبع العجلة الأمامية (للفريق) نفس المنطق مع بعض التعديلات.
بدلاً من المرحلة ، سنقوم بإحضار بيانات الفريق وتحديث نقطة التسجيل الخاصة transformOrigin
لتمكين إنشاء المتحدث من نقطة تسجيل معاكسة عن عجلة المرحلة.
// set team spokes map(teamSpokes, (index, key) => { TweenMax.to(index, 2, { rotation: angle*key, transformOrigin: "100% 100%"
}, 1)
})
المشروع النهائي
مثلي ، إذا كنت قد كتبت جميع الوظائف المتعلقة بالرسوم المتحركة والبيانات في مكونات Vue نفسها. حان الوقت لتنظيفها باستخدام Vuex و Mixins.
VUEX
تعمل Vuex على تسهيل إدارة البيانات المشتركة بين المكونات ، والأهم من ذلك ، أنها تبسط التعليمات البرمجية الخاصة بك ، وتحافظ على methods
data()
نظيفة ومرتبة ، وترك المكونات لتقديم البيانات فقط ، وليس التعامل معها.
تعتبر Lifecycle hooks مكانًا مناسبًا جدًا لتنفيذ أي طلبات HTTP. نقوم بإحضار البيانات الأولية في الخطاف created
، عندما يتم تهيئة تطبيق Vue ، لكن لم يتم تحميله بعد في DOM.
يتم تحديث متغيرات الحالة الفارغة stages
teams
باستخدام الطفرات في هذه المرحلة. بعد ذلك ، نستخدم مراقب (مرة واحدة فقط) لتتبع هذين المتغيرين ، وبمجرد تحديثهما ، نستدعي نص الرسوم المتحركة (من mixin.js
).
في كل مرة يتفاعل فيها المستخدم مع المرحلة أو مكون الفريق ، سيتواصل مع متجر Vuex ، وينفذ setActiveData
، ويقوم بتحديث المرحلة الحالية وقيم الفريق الحالية. هذه هي الطريقة التي نضع بها البيانات النشطة.
وعندما يتم تعيين البيانات النشطة بعد تحديث الحالة ، goAnimate
(تدوير اتجاهي) باستخدام القيم المحدثة.
يوصى بالقراءة : إنشاء مدخلات مخصصة باستخدام Vue.js
الخلطات
الآن بعد أن تم التعامل مع البيانات بواسطة Vuex ، سنقوم بفصل الرسوم المتحركة GreenSock. سيؤدي هذا إلى منع ازدحام مكونات Vue الخاصة بنا بنصوص الرسوم المتحركة الطويلة. يتم تجميع جميع وظائف GreenSock معًا في ملف mixin.js
.
نظرًا لأن لديك حق الوصول إلى Vuex Store داخل Mixins ، فإن جميع وظائف GSAP تستخدم متغيرات state
لتحريك عناصر SVG. يمكنك رؤية store.js
و mixin.js
بكامل طاقتهما في مثال CodeSandbox هنا.
خاتمة
يتطلب إنشاء رسوم بيانية تفاعلية وجذابة أن تكون تحليليًا مع البيانات ، وأن تكون مبدعًا مع المرئيات وفعالة مع التكنولوجيا التي تستخدمها ، والتي في هذه الحالة هي Vue.js. يمكنك استخدام هذه المفاهيم بشكل أكبر في مشروعك. كملاحظة ختامية ، سأتركك مع عجلة الألوان التفاعلية الدائرية أدناه والتي تستخدم فكرة مشابهة لتلك التي ناقشناها في هذه المقالة.
بلا شك ، يتمتع Vue.js بالعديد من الميزات الرائعة ؛ نحن قادرون على إنشاء رسوم بيانية تفاعلية باستخدام عدد قليل من الأشياء ، مثل المراقبين والخصائص المحسوبة والمزيجات والتوجيهات (انظر مثال عجلة الألوان) وبعض الطرق الأخرى. Vue.js هو الغراء الذي يجمع كلاً من SVG و GreenSock للرسوم المتحركة معًا بكفاءة ، مما يمنحك فرصة كبيرة للإبداع في أي عدد من الموضوعات والتفاعل المخصص في نفس الوقت.