הכירו את Observable Plot - הגירסה הקלה של D3

31/08/2024

אני אוהב את D3 כי אפשר לעשות איתו הכל ויש אינסוף דוגמאות ברשת, אבל אי אפשר להכחיש ש D3 קצת מסובך וכולל שפה ומושגים שלא לכולם יש כח להכיר. אם אתם רק צריכים להוסיף איזה גרף למסכי הניהול שלכם בלי יותר מדי אינטרקציה ספריית Observable Plot יכולה לתת פיתרון מהיר. השימוש העיקרי שלה אגב הוא בתוך מחברות ג'ופיטר כשצד השרת הוא deno.

1. דוגמה 1 - ציור הפונקציה x בריבוע

בדוגמה הראשונה נראה גרף פשוט של הפונקציה x בריבוע. את observable plot אפשר לטעון דרך jsdeliver ישירות לדפדפן עם הפקודה:

import * as Plot from "https://cdn.jsdelivr.net/npm/@observablehq/plot@0.6/+esm";

המטרה של Observable Plot היא לקחת מידע והוראות איך להציג אותו ולחבר אותם יחד לגרף, לכן אנחנו מתחילים עם יצירת המידע:

const data = Array.from({length: 100}, (_, i) => {
  let x = i - 50;
  return {x, y: x * x};
});

מה שיוצר מערך של מאה תאיך, כל תא מכיל אוביקט עם שדה בשם x שמכיל מספר (בין מינוס 50 ל 50) ושדה y שמכיל את x בריבוע.

החלק השני לוקח את המערך והוראות איך להציג אותו ויוצר אוביקט plot:

const plot = Plot.plot({
  marks: [
    Plot.line(data, {x: "x", y: "y", stroke: "blue"})
  ],
  x: {label: "x"},
  y: {label: "f = x²"},
})

התוצאה plot היא ממש SVG שאפשר להוסיף ל DOM. אפשר לראות את הקוד המלא והתוצאה בקודפן:

https://codepen.io/ynonp/pen/abgamwv?editors=1010

או מוטמע:

2. דוגמה 2 - היסטוגרמת תדירות מילים

דוגמה שניה וקצת יותר מורכבת היא ציור היסטוגרמת תדירות הופעה של מילים בטקסט. אני מתחיל עם המידע:

const wordFrequency = [
  {word: "quick", count: 4},
  {word: "brown", count: 2},
  {word: "fox", count: 2},
  {word: "jumps", count: 1},
  {word: "over", count: 1},
  {word: "the", count: 5},
  {word: "lazy", count: 3},
  {word: "dog", count: 2},
  {word: "is", count: 3},
  {word: "very", count: 2},
  {word: "and", count: 1},
  {word: "agile", count: 1},
  {word: "not", count: 1},
  {word: "as", count: 1},
  {word: "but", count: 1},
  {word: "certainly", count: 1}
];

וכן אין בעיה לקחת מחרוזת ולייצר את המידע הזה דינמית, פשוט רציתי להראות כאן את המידע כמו שהוא עובר ל Observable Plot.

בחלק השני אני יוצר את ה SVG:

const plot = Plot.plot({
  marks: [
    Plot.barY(wordFrequency, {x: "word", y: "count", sort: {x: "y", reverse: true}})
  ],
  x: {
    label: "Word",
    tickRotate: -45
  },
  y: {
    label: "Frequency",
    tickFormat: d => d, // Ensure only integer ticks are shown
    ticks: Math.max(...wordFrequency.map(d => d.count)) + 1 // Set the number of ticks to match the highest count
  },
  height: 400,
  width: 600
});

הפעם יש קצת יותר קוד כי רציתי לשלוט באופן ציור השנתות על ציר ה y ולוודא שלא יופיעו חצאי מספרים. עדיין מה שחשוב זה המיפוי בין אוביקט המידע ל plot, מיפוי שבא לידי ביטוי בשורה:

Plot.barY(wordFrequency, {x: "word", y: "count", sort: {x: "y", reverse: true}})

התוצאה שוב בקודפן: https://codepen.io/ynonp/pen/gONdwZK?editors=1010

או מוטמעת:

למידע נוסף על הספריה ועוד אינסוף דוגמאות שווה לבקר באתר שלהם בקישור:

https://observablehq.com/plot/