الجمع بين التفاعل و D3 ونظامهم البيئي
نشرت: 2022-03-10منذ إنشائها في عام 2011 ، أصبحت D3.js المعيار الفعلي لبناء تصورات البيانات المعقدة على الويب. تنضج React أيضًا بسرعة كمكتبة مفضلة لإنشاء واجهات مستخدم قائمة على المكونات.
تعد كل من React و D3 أداتين ممتازتين مصممتين بأهداف تتعارض أحيانًا. كلاهما يتحكم في عناصر واجهة المستخدم ، ويقومان بذلك بطرق مختلفة. كيف يمكننا جعلهم يعملون معًا مع تحسين مزاياهم المميزة وفقًا لمشروعك الحالي؟
في هذا المنشور ، سنرى كيف يمكننا التعامل مع بناء مشاريع React التي تحتاج إلى جودة الرسوم البيانية القوية لـ D3. سوف نكتشف تقنيات مختلفة وكيفية اختيار أفضل مكتبة لاحتياجاتك في عملك الرئيسي والمشاريع الجانبية.
D3 و DOM
يرمز D3 في D3.js إلى المستندات المستندة إلى البيانات. D3.js هي مكتبة منخفضة المستوى توفر اللبنات الأساسية اللازمة لإنشاء تصورات تفاعلية. يستخدم معايير الويب مثل SVG و HTML و canvas و CSS لتجميع صندوق أدوات أمامي بواجهة برمجة تطبيقات واسعة وتحكم غير محدود تقريبًا في مظهر وسلوك التصورات. كما يوفر العديد من الوظائف الرياضية التي تساعد المستخدمين على حساب مسارات SVG المعقدة.
كيف يعمل؟
باختصار ، يقوم D3.js بتحميل البيانات وإرفاقها بـ DOM. بعد ذلك ، يقوم بربط تلك البيانات بعناصر DOM ويقوم بتحويل تلك العناصر ، والانتقال بين الدول إذا لزم الأمر.
تتشابه تحديدات D3.js مع كائنات jQuery ، لأنها تساعدنا في التعامل مع تعقيد SVG. الطريقة التي يتم بها ذلك يمكن مقارنتها بالطريقة التي يتعامل بها jQuery مع عناصر HTML DOM. تشترك كلتا المكتبتين أيضًا في واجهة برمجة تطبيقات مماثلة تعتمد على السلسلة واستخدام DOM كتخزين البيانات.
البيانات تنضم
تنضم البيانات ، كما هو موضح في مقالة مايك بوستوكس بعنوان "التفكير مع الصلات" ، وهي العملية التي تربط D3 البيانات بعناصر DOM من خلال استخدام التحديدات.
تساعدنا عمليات ضم البيانات في مطابقة البيانات التي نقدمها مع العناصر التي تم إنشاؤها بالفعل وإضافة العناصر المفقودة وإزالة العناصر التي لم تعد مطلوبة. يستخدمون تحديدات D3.js ، والتي ، عند دمجها مع البيانات ، تقسم العناصر المحددة إلى ثلاث مجموعات مختلفة: العناصر التي يجب إنشاؤها (مجموعة الإدخال) ، والعناصر التي يجب تحديثها (مجموعة التحديث) والعناصر التي تحتاج المراد إزالتها (مجموعة الخروج).

من الناحية العملية ، يمثل كائن JavaScript ذو المصفوفتين صلة بيانات. يمكننا تشغيل العمليات على مجموعات الدخول والخروج عن طريق استدعاء طرق الإدخال والخروج الخاصة بالاختيار ، بينما يمكننا العمل مباشرة على مجموعة التحديث في أحدث إصدار من D3.js.
كما أوضح بوستوك ، مع عمليات ضم البيانات ، "يمكنك تصور البيانات في الوقت الفعلي ، والسماح بالاستكشاف التفاعلي ، والانتقال بسلاسة بين مجموعات البيانات." إنها خوارزمية فرق فعالة ، على غرار الطريقة التي تدير بها React عرض العناصر الفرعية ، كما سنرى في الأقسام التالية.
مكتبات D3
لم يجد مجتمع D3 طريقة قياسية لإنشاء مكونات من كود D3 ، وهي حاجة متكررة لأن D3.js منخفض المستوى بشكل ملحوظ. يمكننا أن نقول أن هناك ما يقرب من العديد من أنماط التغليف مثل المكتبات المستندة إلى D3 ، على الرغم من أنني سأقوم بتصنيفها - من خلال واجهة برمجة التطبيقات الخاصة بهم - إلى أربع مجموعات: موجهة للكائنات ، وتوضيحية ، ووظيفية ، ومقيدة (أو تشبه D3).
لقد أجريت بعض الأبحاث حول النظام البيئي D3.js واخترت مجموعة فرعية صغيرة عالية الجودة. إنها مكتبات مُحدَّثة بإصدار D3.js 4 وتغطية اختبارية جيدة. وهي تختلف في نوع API ودرجة تجريدها.
مؤامرة
Plottable هي مكتبة رسوم بيانية شائعة موجهة للكائنات تتميز بدقة منخفضة ؛ لذلك ، نحتاج إلى إعداد المحاور والمقاييس والمخططات يدويًا لإنشاء المخططات. يمكنك الاطلاع على مثال هنا.

لوحة
Billboard عبارة عن شوكة مكتبة C3.js الشهيرة ، تم تحديثها بتوافق D3.js الإصدار 4 وتهدف إلى توفير استمرارية لهذه المكتبة الكلاسيكية. تمت كتابته باستخدام ECMAScript 6 والأدوات الحديثة الجديدة مثل Webpack. تعتمد واجهة برمجة التطبيقات الخاصة بها على كائنات التكوين التي تم تمريرها إلى المخططات ، لذلك يمكننا القول إنها واجهة برمجة تطبيقات تعريفية.

فيجا
يأخذ Vega المسار التعريفي إلى أبعد من ذلك قليلاً ، حيث يطور التكوينات من كائنات JavaScript إلى ملفات JSON نقية. يهدف إلى تنفيذ قواعد التصور المستوحاة من The Grammar of Graphics ، وهو كتاب من تأليف Leland Wilkinson يضفي الطابع الرسمي على اللبنات الأساسية لتصورات البيانات والتي كانت مصدر إلهام لـ D3.js أيضًا. يمكنك اللعب بمحررها ، واختيار أحد الأمثلة كنقطة بداية.

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

بريتشارتس
تستخدم Britecharts - وهي مكتبة أنشأتها Eventbrite ، وأنا أحد المساهمين الأساسيين فيها - واجهة برمجة تطبيقات الرسوم البيانية القابلة لإعادة الاستخدام ، وهي نمط تغليف شاعه مايك بوستوك في رسالته "نحو مخططات قابلة لإعادة الاستخدام" وتم توظيفها في مكتبات أخرى مثل NVD3. ينشئ Britecharts تجريدًا عالي المستوى ، مما يجعل من السهل إنشاء المخططات ، مع الحفاظ على مستوى منخفض من التعقيد من الداخل ، مما يسمح لمطوري D3 بتخصيص Britecharts لاستخدامهم. لقد أمضينا الكثير من الوقت في بناء واجهة مستخدم مصقولة والعديد من العروض التوضيحية التي يمكن الوصول إليها.

بتلخيص المكتبات من خلال واجهات برمجة التطبيقات الخاصة بهم ، يمكننا تمثيلها على النحو التالي:

رد فعل و DOM
React هي مكتبة JavaScript تساعدنا في بناء واجهات مستخدم عن طريق تكوين مكونات . تقوم هذه المكونات بتتبع حالتها وتمرير الخصائص لإعادة تقديم نفسها بشكل فعال ، وتحسين أداء التطبيق.
كيف يعمل؟
DOM الظاهري ، الذي يمثل تمثيلًا لحالة DOM الحالية ، هو التكنولوجيا التي تمكّن تحسينات React من إعادة العرض. تستخدم المكتبة خوارزمية فرق معقدة لفهم أجزاء التطبيق التي تحتاج إلى إعادة تصيير عندما تتغير الظروف. تسمى خوارزمية الفرق هذه "خوارزمية التسوية".
مكونات الطفل الديناميكية
عند عرض المكونات التي تحتوي على قائمة بالعناصر ، يحتاج المطورون إلى استخدام خاصية "مفتاح" فريدة مرتبطة بالمكونات الفرعية. تساعد هذه القيمة خوارزمية الفرق في معرفة ما إذا كان العنصر بحاجة إلى إعادة تصيير عند تمرير بيانات جديدة - أو حالة ، كما يطلق عليها في عالم React - إلى المكون. تتحقق خوارزمية التسوية من قيم المفاتيح لمعرفة ما إذا كان العنصر بحاجة إلى الإضافة أو الإزالة. هل يبدو هذا مألوفًا بعد التعرف على صلات بيانات D3.js؟
منذ الإصدار 0.14 ، يحافظ React أيضًا على العارض في وحدة منفصلة. بهذه الطريقة ، يمكننا استخدام نفس المكونات لتقديمها في وسائط مختلفة ، مثل التطبيقات الأصلية (React Native) ، والواقع الافتراضي (React VR) و DOM (تفاعل دوم). هذه المرونة مشابهة للطريقة التي يمكن بها عرض كود D3.js في سياقات مختلفة ، مثل SVG و canvas.
رد فعل و D3.js
يشترك كل من React و D3 في هدف مساعدتنا في التعامل مع DOM وتعقيده بطريقة محسّنة للغاية. كما أنها تشترك في تفضيل الوظائف البحتة - الكود الذي ، لمدخل معين ، يُرجع دائمًا نفس المخرجات دون تكبد آثار جانبية - والمكونات عديمة الحالة.
ومع ذلك ، فإن الاهتمام المشترك بشأن DOM يجعل هاتين المكتبتين اللتين تتبادلان الآراء تتعارض عند تحديد أيهما سيتم عرض عناصر واجهة المستخدم وتحريكها. سنرى طرقًا مختلفة لحل هذا النزاع ، ولا توجد إجابة سهلة. يمكننا إنشاء قاعدة صارمة ، على الرغم من ذلك: يجب ألا يشاركوا تحكم DOM أبدًا . سيكون ذلك وصفة لكارثة.
اقتراب
عند دمج React و D3.js ، يمكننا القيام بذلك على مستويات مختلفة ، مع الاعتماد بشكل أكبر على جانب D3.js أو جانب React. دعونا نرى خياراتنا الأربعة الرئيسية.
D3.js داخل React
النهج الأول الذي يمكننا اتباعه هو منح كود D3 أكبر قدر ممكن من التحكم في DOM. يستخدم مكون React لتصيير عنصر SVG فارغ يعمل كعنصر جذر لتصور البيانات لدينا. ثم تستخدم طريقة دورة حياة componentDidUpdate
من أجل ، باستخدام عنصر الجذر هذا ، لإنشاء المخطط باستخدام كود D3.js الذي سنستخدمه في سيناريو جافا سكريبت الفانيليا. يمكننا أيضًا حظر أي تحديثات إضافية للمكونات بجعل التابع shouldComponentUpdate
يعيد القيمة false
دائمًا.
class Line extends React.Component { static propTypes = {...} componentDidMount() { // D3 Code to create the chart // using this._rootNode as container } shouldComponentUpdate() { // Prevents component re-rendering return false; } _setRef(componentNode) { this._rootNode = componentNode; } render() { <div className="line-container" ref={this._setRef.bind(this)} /> } }
عند تقييم هذا النهج ، فإننا ندرك أنه يقدم بعض الفوائد والعيوب. من بين الفوائد ، هذا حل بسيط يعمل بشكل جيد في معظم الأوقات. إنه أيضًا الحل الأكثر طبيعية عند نقل كود موجود إلى React ، أو عند استخدام مخططات D3.js التي كانت تعمل بالفعل في مكان آخر.
على الجانب السلبي ، يمكن اعتبار خلط كل من كود React وشفرة D3.js داخل مكون React على أنه إجمالي بعض الشيء ، حيث يتضمن الكثير من التبعيات ويجعل هذا الملف طويلاً جدًا بحيث لا يمكن اعتباره رمزًا عالي الجودة. أيضًا ، لا يشعر هذا التطبيق بعبارات تفاعلية على الإطلاق. أخيرًا ، نظرًا لأن خادم تصيير React لا يستدعي طريقة componentDidUpdate
، لا يمكننا شحن إصدار مُصَوَّر من المخطط في HTML الأولي.
رد فعل Faux DOM
نفذها أوليفر كالدويل ، React Faux DOM "هي طريقة لاستخدام أدوات D3 الحالية ولكن يتم عرضها من خلال React في React ethos." يستخدم تطبيق DOM مزيفًا لخداع D3.js ليعتقد أنه يتعامل مع DOM حقيقي. بهذه الطريقة ، نحتفظ بشجرة React DOM أثناء استخدام D3.js في - تقريبًا - كل إمكاناتها.
import {withFauxDOM} from 'react-faux-dom' class Line extends React.Component { static propTypes = {...} componentDidMount() { const faux = this.props.connectFauxDOM('div', 'chart'); // D3 Code to create the chart // using faux as container d3.select(faux) .append('svg') {...} } render() { <div className="line-container"> {this.props.chart} </div> } } export default withFauxDOM(Line);
تتمثل إحدى ميزات هذا الأسلوب في أنه يسمح لك باستخدام معظم واجهات برمجة تطبيقات D3.js ، مما يسهل التكامل مع كود D3.js الذي تم إنشاؤه بالفعل. كما يسمح أيضًا بالتقديم من جانب الخادم. عيب هذه الإستراتيجية هو أنها أقل أداءً ، لأننا نضع تطبيق DOM مزيفًا آخر قبل DOM الظاهري لـ React ، مع محاكاة DOM الافتراضية مرتين. تقصر هذه المشكلة استخدامها على تصورات البيانات الصغيرة والمتوسطة الحجم.
التفاف طرق دورة الحياة
هذا النهج ، الذي ذكره نيكولاس هيري لأول مرة ، يستخدم طرق دورة الحياة الموجودة في مكونات React القائمة على الصنف. إنه يلف بشكل أنيق إنشاء وتحديث وإزالة مخططات D3.js ، مما يضع حدًا واضحًا بين كود React و D3.js.
import D3Line from './D3Line' class Line extends React.Component { static propTypes = {...} componentDidMount() { // D3 Code to create the chart this._chart = D3Line.create( this._rootNode, this.props.data, this.props.config ); } componentDidUpdate() { // D3 Code to update the chart D3Line.update( this._rootNode, this.props.data, this.props.config, this._chart ); } componentWillUnmount() { D3Line.destroy(this._rootNode); } _setRef(componentNode) { this._rootNode = componentNode; } render() { <div className="line-container" ref={this._setRef.bind(this)} /> } }
D3Line شيء من هذا القبيل:
const D3Line = {}; D3Line.create = (el, data, configuration) => { // D3 Code to create the chart }; D3Line.update = (el, data, configuration, chart) => { // D3 Code to update the chart }; D3Line.destroy = () => { // Cleaning code here }; export default D3Line;
ينتج عن الترميز بهذه الطريقة مكون React خفيف الوزن يتواصل مع مثيل مخطط قائم على D3.js من خلال واجهة برمجة تطبيقات بسيطة (إنشاء وتحديث وإزالة) ، مما يدفع إلى أسفل أي طرق رد نرغب في الاستماع إليها.

تعزز هذه الاستراتيجية فصلًا واضحًا للمخاوف ، باستخدام واجهة لإخفاء تفاصيل تنفيذ المخطط. يمكن أن يغلف أي رسم بياني ، والواجهة التي تم إنشاؤها بسيطة. فائدة أخرى هي أنه من السهل الدمج مع أي كود D3.js مكتوب بالفعل ، ويسمح لنا باستخدام انتقالات D3.js الممتازة. العيب الرئيسي لهذه الطريقة هو أن التقديم من جانب الخادم غير ممكن.
تفاعل مع DOM و D3 للرياضيات
في هذه الإستراتيجية ، نحد من استخدام D3.js إلى الحد الأدنى. يعني هذا إجراء حسابات لمسارات ومقاييس وتخطيطات SVG وأي تحويلات تأخذ بيانات المستخدم وتحولها إلى شيء يمكننا رسمه باستخدام React.
يمكن استخدام D3.js للرياضيات فقط بفضل عدد كبير من الوحدات الفرعية D3.js التي لا تتعلق بـ DOM. هذا المسار هو الأكثر ملاءمة للتفاعل ، مما يمنح مكتبة Facebook سيطرة كاملة على DOM ، وهو أمر تقوم به بشكل جيد بشكل ملحوظ.
دعنا نرى مثالا مبسطا:
class Line extends React.Component { static propTypes = {...} drawLine() { let xScale = d3.scaleTime() .domain(d3.extent(this.props.data, ({date}) => date)); .rangeRound([0, this.props.width]); let yScale = d3.scaleLinear() .domain(d3.extent(this.props.data, ({value}) => value)) .rangeRound([this.props.height, 0]); let line = d3.line() .x((d) => xScale(d.date)) .y((d) => yScale(d.value)); return ( <path className="line" d={line(this.props.data)} /> ); } render() { <svg className="line-container" width={this.props.width} height={this.props.height} > {this.drawLine()} </svg> } }
هذه التقنية هي المفضلة لدى مطوري React المخضرمين لأنها تتوافق مع طريقة React. أيضًا ، بمجرد وضعه في مكانه ، فإن إنشاء المخططات مع الكود الخاص به يكون أمرًا رائعًا. فائدة أخرى تتمثل في العرض على جانب الخادم ، وربما React Native أو React VR.
ومن المفارقات أن هذا هو النهج الذي يتطلب مزيدًا من المعرفة حول كيفية عمل D3.js ، لأننا بحاجة إلى التكامل مع وحداته الفرعية بمستوى منخفض. يجب علينا إعادة تنفيذ بعض وظائف D3.js - المحاور والأشكال هي الأكثر شيوعًا ؛ من المحتمل أن تكون الفرش والتكبيرات والسحب هي الأصعب - وهذا يعني قدرًا كبيرًا من العمل المسبق.
سنحتاج أيضًا إلى تنفيذ جميع الرسوم المتحركة. لدينا أدوات رائعة في نظام React البيئي تسمح لنا بإدارة الرسوم المتحركة - انظر مجموعة انتقال التفاعل ، وحركة التفاعل ، وحركة التفاعل - على الرغم من عدم تمكننا من إنشاء عمليات إقحام معقدة لمسارات SVG. أحد الأسئلة المعلقة هو كيف يمكن الاستفادة من هذا الأسلوب لتقديم المخططات باستخدام عنصر لوحة HTML5.
في الرسم التخطيطي التالي ، يمكننا رؤية جميع الأساليب الموصوفة وفقًا لمستوى التكامل مع كل من React و D3.js:

مكتبات React-D3.js
لقد أجريت بعض الأبحاث حول مكتبات D3.js-React والتي نأمل أن تساعدك عندما تواجه قرار اختيار مكتبة للعمل معها أو المساهمة بها أو التفرع. يحتوي على بعض المقاييس الذاتية ، لذا يرجى التعامل معها بحذر.
أظهر هذا البحث أنه على الرغم من وجود العديد من المكتبات ، إلا أنه لا يتم الاحتفاظ بالكثير منها. بصفتي مشرفًا ، يمكنني أن أفهم مدى صعوبة مواكبة التغييرات في مكتبة رئيسية واحدة وكيف أن الاضطرار إلى الاعتناء باثنين سيكون مهمة شاقة.
أيضًا ، لا يزال عدد المكتبات الجاهزة للإنتاج (بدءًا من الإصدار 1.0.0 وما بعده) منخفضًا جدًا. ربما يتعلق الأمر بحجم العمل الضروري لشحن مكتبة من هذا النوع.
دعنا نرى بعض من المفضلة.
فوز
مشروع من قبل شركة الاستشارات Formidable Labs ، Victory عبارة عن مكتبة مكونة منخفضة المستوى لعناصر المخطط. نظرًا لتلك الخاصية منخفضة المستوى ، يمكن تجميع مكونات Victory مع تكوينات مختلفة لإنشاء تصورات بيانات معقدة. تحت غطاء المحرك ، فإنه يعيد تحسين ميزات D3.js مثل الفرشاة والتكبير / التصغير ، على الرغم من أنه يستخدم d3-interpolate للرسوم المتحركة.

قد يبدو استخدامه للرسم البياني الخطي كما يلي:
class LineChart extends React.Component { render() { return ( <VictoryChart height={400} width={400} containerComponent={<VictoryVoronoiContainer/>} > <VictoryGroup labels={(d) => `y: ${dy}`} labelComponent={ <VictoryTooltip style={{ fontSize: 10 }} /> } data={data} > <VictoryLine/> <VictoryScatter size={(d, a) => {return a ? 8 : 3;}} /> </VictoryGroup> </VictoryChart> ); } }
ينتج عن ذلك مخطط خطي مثل هذا:

يعد بدء استخدام Victory أمرًا سهلاً ، وله بعض المزايا الرائعة ، مثل ميزة التكبير / التصغير وحاوية Voronoi للحصول على تلميحات الأدوات. إنها مكتبة عصرية ، على الرغم من أنها لا تزال في حالة ما قبل الإصدار ولديها عدد كبير من الأخطاء المعلقة. Victory هي المكتبة الوحيدة في الوقت الحالي التي يمكنك استخدامها مع React Native.
يعيد رسم الخرائط
مصقولة جمالياً ، مع تجربة مستخدم ممتعة ورسوم متحركة سلسة وتلميح أدوات رائع المظهر ، Recharts هي واحدة من مكتبات React-D3.js المفضلة لدي. تستخدم Recharts فقط المقياس d3 و d3-interpolate و d3-shape. إنه يوفر مستوى أعلى من التفصيل من Victory ، مما يحد من مقدار تصورات البيانات التي يمكننا تكوينها.

يبدو استخدام Recharts كما يلي:
class LineChart extends React.Component { render () { return ( <LineChart width={600} height={300} data={data} margin={{top: 5, right: 30, left: 20, bottom: 5}} > <XAxis dataKey="name"/> <YAxis/> <CartesianGrid strokeDasharray="3 3"/> <Tooltip/> <Legend /> <Line type="monotone" dataKey="pv" stroke="#8884d8" activeDot={{r: 8}}/> <Line type="monotone" dataKey="uv" stroke="#82ca9d" /> </LineChart> ); } }

تم أيضًا اختبار هذه المكتبة جيدًا ، وعلى الرغم من أنها لا تزال في مرحلة تجريبية ، إلا أنها تتميز ببعض المخططات المعتادة ومخطط رادار وخرائط شجرية وحتى فرش. يمكنك التحقق من الأمثلة لمعرفة المزيد. وضع المطورون المساهمون في هذا المشروع عملاً جادًا فيه ، وحققوا رسومًا متحركة سلسة من خلال تفاعل مشروع الرسوم المتحركة الخاص بهم بسلاسة.
نيفو
Nivo هي مكتبة رسوم بيانية عالية المستوى من React-D3.js. يوفر الكثير من الخيارات للعرض: SVG ، قماش ، حتى إصدار HTML قائم على API من المخططات التي تعتبر مثالية للعرض من جانب الخادم. يستخدم React Motion للرسوم المتحركة.

تختلف واجهة برمجة التطبيقات الخاصة بها قليلاً ، لأنها تكشف عن مكون واحد فقط قابل للتكوين لكل مخطط. دعنا نرى مثالا:
class LineChart extends React.Component { render () { return ( <ResponsiveLine data={data} margin={{ "top": 50, "right": 110, "bottom": 50, "left": 60 }} minY="auto" stacked={true} axisBottom={{ "orient": "bottom", "tickSize": 5, "tickPadding": 5, "tickRotation": 0, "legend": "country code", "legendOffset": 36, "legendPosition": "center" }} axisLeft={{ "orient": "left", "tickSize": 5, "tickPadding": 5, "tickRotation": 0, "legend": "count", "legendOffset": -40, "legendPosition": "center" }} dotSize={10} dotColor="inherit:darker(0.3)" dotBorderWidth={2} dotBorderColor="#ffffff" enableDotLabel={true} dotLabel="y" dotLabelYOffset={-12} animate={true} motionStiffness={90} motionDamping={15} legends={[ { "anchor": "bottom-right", "direction": "column", "translateX": 100, "itemWidth": 80, "itemHeight": 20, "symbolSize": 12, "symbolShape": "circle" } ]} /> ); } }

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

دعنا نرى بعض التعليمات البرمجية:
class VXLineChart extends React.Component { render () { let {width, height, margin} = this.props; // bounds const xMax = width - margin.left - margin.right; const yMax = height - margin.top - margin.bottom; // scales const xScale = scaleTime({ range: [0, xMax], domain: extent(data, x), }); const yScale = scaleLinear({ range: [yMax, 0], domain: [0, max(data, y)], nice: true, }); return ( <svg width={width} height={height} > <rect x={0} y={0} width={width} height={height} fill="white" rx={14} /> <Group top={margin.top}> <LinePath data={data} xScale={xScale} yScale={yScale} x={x} y={y} stroke='#32deaa' strokeWidth={2} /> </Group> </svg> ); } };

بالنظر إلى هذا المستوى المنخفض من التفصيل ، أعتقد أن VX هو D3.js لعالم React. إنه محايد بشأن مكتبة الرسوم المتحركة التي يريد المستخدم استخدامها. في الوقت الحالي ، لا يزال في مرحلة تجريبية مبكرة ، على الرغم من استخدامه في إنتاج شركة Airbnb. تتمثل عيوبه في هذه اللحظة في عدم وجود دعم للتفاعلات مثل التنظيف بالفرشاة والتكبير.
بريتشارتس تتفاعل
لا تزال Britecharts React في مرحلة تجريبية ، وهي الوحيدة من بين هذه المكتبات التي تستخدم نهج التفاف طريقة دورة الحياة. يهدف إلى السماح باستخدام تصورات Britecharts في React عن طريق إنشاء غلاف تعليمات برمجية سهل الاستخدام.

فيما يلي رمز بسيط للمخطط الخطي:
class LineChart extends React.Component { render () { const margin = { top: 60, right: 30, bottom: 60, left: 70, }; return ( <TooltipComponent data={lineData.oneSet()} topicLabel="topics" title="Tooltip Title" render={(props) => ( <LineComponent margin={margin} lineCurve="basis" {...props} /> )} /> ); } }

لا يمكنني أن أكون موضوعيًا بشأن هذا. يمكن استخدام Britecharts React كسقالة لتصيير مخططات D3.js كمكونات React. لا يدعم العرض من جانب الخادم ، على الرغم من أننا قمنا بتضمين حالات التحميل للتغلب على هذا بطريقة ما.
لا تتردد في التحقق من العروض التوضيحية عبر الإنترنت واللعب بالرمز.
اختيار نهج أو مكتبة
لقد جمعت الاعتبارات في بناء التطبيقات مع الرسوم البيانية في أربع فئات: الجودة والوقت والنطاق والتكلفة. إنها كثيرة جدًا ، لذا علينا التبسيط.
لنفترض أننا نصلح الجودة . يمكن أن نهدف إلى الحصول على قاعدة تعليمات برمجية يتم اختبارها جيدًا ، ومحدثة مع الإصدار 4 من D3.js ومع توثيق شامل.
إذا فكرنا في الوقت ، فإن السؤال المفيد الذي يجب أن نسأله لأنفسنا هو ، "هل هذا استثمار طويل الأجل؟" إذا كانت الإجابة "نعم" ، فإنني أنصحك بإنشاء مكتبة بناءً على D3.js ولفها بـ React باستخدام نهج أساليب دورة الحياة. يفصل هذا النهج الكود الخاص بنا عن طريق التقنيات وهو أكثر مقاومة للوقت.
على العكس من ذلك ، إذا كان للمشروع مواعيد نهائية ضيقة ولا يحتاج الفريق إلى الحفاظ عليه لفترة طويلة ، فإنني أنصح بالاستيلاء على مكتبة React-D3.js أو D3.js الأقرب إلى المواصفات ، وقم بتقسيمها واستخدامها ، في محاولة للمساهمة على طول الطريق.
عندما نتعامل مع النطاق ، يجب أن نفكر فيما إذا كان ما نحتاجه هو عدد صغير من المخططات الأساسية ، أو تصور معقد لمرة واحدة أو عدة رسومات مخصصة للغاية. في الحالة الأولى ، سأختار مرة أخرى أقرب مكتبة للمواصفات وأقطعها. بالنسبة لتصورات البيانات المفصلة التي تحتوي على الكثير من الحركات أو التفاعلات ، فإن البناء باستخدام D3.js العادي هو الخيار الأفضل. أخيرًا ، إذا كنت تخطط لاستخدام مخططات مختلفة بمواصفات معينة - ربما بدعم من UX'ers والمصممين - فإن إنشاء مكتبة D3 الخاصة بك من البداية أو التفرع وتخصيص مكتبة موجودة سيكون أفضل.
أخيرًا ، يرتبط جانب التكلفة في القرار بميزانية الفريق وتدريبه. ما أنواع المهارات التي يمتلكها فريقك؟ إذا كان لديك مطورو D3.js ، فإنهم يفضلون الفصل الواضح بين D3.js و React ، لذلك من المحتمل أن يكون النهج الذي يستخدم التفاف طريقة دورة الحياة مفيدًا. ومع ذلك ، إذا كان فريقك في الغالب من مطوري React ، فسيستمتعون بتوسيع أي من مكتبات React-D3.js الحالية. أيضًا ، يمكن استخدام طرق دورة الحياة جنبًا إلى جنب مع أمثلة D3.js. نادرًا ما أوصي به هو طرح مكتبة React-D3.js الخاصة بك. حجم العمل اللازم مقدمًا أمر شاق ، كما أن خطوات التحديث في كلتا المكتبتين تجعل تكاليف الصيانة غير مهمة.
ملخص
تعتبر React و D3.js أدوات رائعة لمساعدتنا في التعامل مع DOM وتحدياته. يمكنهم بالتأكيد العمل معًا ، ونحن مخولون لاختيار مكان رسم الخط الفاصل بينهم. يوجد نظام بيئي سليم للمكتبات لمساعدتنا على استخدام D3.js. هناك الكثير من الخيارات المثيرة أيضًا لـ React-D3.js ، وكلا المكتبتين في تطور مستمر ، لذا فإن المشاريع التي تجمع بين الاثنين ستواجه صعوبة في مواكبة ذلك.
يعتمد الاختيار على العديد من المتغيرات التي لا يمكن حسابها جميعًا في مقال واحد. ومع ذلك ، فقد غطينا معظم الاعتبارات الرئيسية ، ونأمل أن نمكنك من اتخاذ قرارك المستنير.
مع هذا الأساس ، أشجعك على الشعور بالفضول والتحقق من المكتبات المذكورة وإضافة بعض الخير للرسوم البيانية لمشاريعك.
هل استخدمت أيًا من هذه المشاريع؟ إذا كان لديك ، ما هي تجربتك؟ شاركنا ببعض الكلمات في التعليقات.