דוגמת Echarts - ניתוח נתוני לידות

05/01/2025

ספריית Echarts נותנת דרך קלה מאוד ליצור תרשימים וגרפים ב Web. בשילוב עם מאגר הנתונים הישראלי הממשלתי אפשר להתנסות בקלות בניתוח נתונים ושימוש בגרפים. הנה דוגמה קצרה עם קובץ של נתוני לידות שלקחתי מהקישור הזה:

https://data.gov.il/dataset/birth-data

1. איך נראה המידע

מאגר הנתונים כולל קובץ CSV שמכיל את העמודות: חודש לידה, גיל האם, מספר עוברים, שבוע לידה, מין התינוק ומשקל. יש פה הרבה עם מה לעבוד ואני בחרתי בשביל הדוגמה לבנות גרף עמודות שיראה את התפלגות הגילאים של היולדות בכל חודש בשנת 2014 (לה מתאים הקובץ). בשביל לעבוד עם הנתונים התחלתי עם הספריה csvkit של פייתון והפכתי את קובץ הנתונים ל JSON באמצעות הפקודה:

in2csv --encoding "utf-8" births.csv | csvjson > births.json

אלה שלושת האוביקטים הראשונים מהקובץ בשביל הדוגמה:

[
  {
    "birth_month": 1.0,
    "mother_age": "<18",
    "parity": "1",
    "gestation_week": "37-41",
    "birth_sex": "F",
    "birth_weight": "2500-2599"
  },
  {
    "birth_month": 1.0,
    "mother_age": "<18",
    "parity": "1",
    "gestation_week": "37-41",
    "birth_sex": "F",
    "birth_weight": "2500-2599"
  },
  {
    "birth_month": 1.0,
    "mother_age": "<18",
    "parity": "1",
    "gestation_week": "37-41",
    "birth_sex": "F",
    "birth_weight": "2500-2599"
  }
]

2. הכנת הנתונים לגרף

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

const dataByAge = _.chain(data).groupBy('mother_age').mapValues(
  row => _.chain(row).groupBy('birth_month').mapValues(v => v.length).value()
).value()

const series = _.toPairs(dataByAge).map(([mother_age, entries]) => ({
    name: mother_age,
    type: "bar",
    stack: "total",
    label: {
      show: true,
    },
    emphasis: {
      focus: "series",
    },
    data: Object.values(entries),
  })
)

התוצאה היא רשימה של אוביקטים, כלומר של סדרות, כאשר שם כל סידרה הוא קבוצת הגילאים של האם והערכים (במפתח data) הם רשימה בה כל איבר הוא מספר הלידות בקבוצת הגיל הנתונה בחודש אחר, כלומר האיבר הראשון הוא כמה לידות היו בינואר בקבוצת גיל זו, אחרי זה כמה לידות היו בפברואר וכך הלאה.

3. סיכום והקוד המלא

קוד ה JavaScript המלא לציור הגרף הוא:

import data from './births.json' with { type: "json" };
import _ from 'https://cdn.jsdelivr.net/npm/lodash@4.17.21/+esm'

window.data = data;
const months = {
  1: 'January',
  2: 'February',
  3: 'March',
  4: 'April',
  5: 'May',
  6: 'June',
  7: 'July',
  8: 'August',
  9: 'September',
  10: 'October',
  11: 'November',
  12: 'December'
};

var dom = document.getElementById("chart-container");
var myChart = echarts.init(dom, null, {
  renderer: "canvas",
  useDirtyRect: false,
});
var app = {};
var option;

const dataByAge = _.chain(data).groupBy('mother_age').mapValues(
  row => _.chain(row).groupBy('birth_month').mapValues(v => v.length).value()
).value()

const series = _.toPairs(dataByAge).map(([mother_age, entries]) => ({
    name: mother_age,
    type: "bar",
    stack: "total",
    label: {
      show: true,
    },
    emphasis: {
      focus: "series",
    },
    data: Object.values(entries),
  })
)

option = {
  tooltip: {
    trigger: "axis",    
    axisPointer: {
      // Use axis to trigger tooltip
      type: "shadow", // 'shadow' as default; can also be 'line' or 'shadow'
    },
  },
  legend: {},
  grid: {
    left: "3%",
    right: "4%",
    bottom: "3%",
    containLabel: true,
  },
  xAxis: {
    type: "value",
  },
  yAxis: {
    type: "category",
    data: Object.values(months),
  },
  series: series,
};

if (option && typeof option === "object") {
  myChart.setOption(option);
}

window.addEventListener("resize", myChart.resize);

ואפשר לראות את התוצאה בקישור:

https://ynonp.github.io/echarts-birth-demo/

וגם את קוד הפרויקט המלא בגיטהאב:

https://github.com/ynonp/echarts-birth-demo

מעבר לנוחות העבודה עם echarts, דוגמה זו הזכירה לי כמה קל לכתוב היום אתר סטטי בלי שלב בנייה ולאחסן אותו על Github Pages. בזכות התמיכה המובנית ב ES Modules ובטעינת קבצי JSON מתוך ES Modules אנחנו מקבלים בחינם הרבה מהדברים בשבילם היינו צריכים בעבר שלב בנייה.