הפניית API 2.0 להמחשה חזותית בהתאמה אישית

קריאה לפונקציה looker.plugins.visualizations.add היא נקודת הכניסה ל-Visualization API. הפונקציה הזו מקבלת אובייקט של תצוגה חזותית שמגדיר באופן מלא את התצוגה החזותית בהתאמה אישית.

הנה דוגמה להמחשה חזותית:

looker.plugins.visualizations.add({
    create: function(element, config){
        element.innerHTML = "<h1>Ready to render!</h1>";
    },
    updateAsync: function(data, element, config, queryResponse, details, doneRendering){
        var html = "";
        for(var row of data) {
            var cell = row[queryResponse.fields.dimensions[0].name];
            html += LookerCharts.Utils.htmlForCell(cell);
        }
        element.innerHTML = html;
        doneRendering()
    }
});

סביבה

מכיוון ש-Visualization API הוא JavaScript רגיל, אפשר להשתמש בכל ספריות JavaScript כדי להציג את הנתונים שלכם.

קוד ה-JavaScript יפעל ב-iframe בארגז חול, בנפרד מהמכונה של Looker. בכל מקרה, מחברי ההדמיות המותאמות אישית אחראים לוודא שהקוד שהם כותבים מאובטח.

בדומה לכל פיתוח אתרים, תמיכה בדפדפני אינטרנט שונים (Chrome, ‏ Edge, ‏ Firefox) יכולה לפעמים להיות בעייתית. ‫Visualization API פועל בכל הדפדפנים שנתמכים ב-Looker, אבל אתם צריכים לוודא שהדפדפן תומך בקוד בהתאמה אישית. לדוגמה, שימוש ב-ES6 כמו let או ()=> יפעל ברוב הדפדפנים, אבל עלול לגרום לכשלים ב-IE11 או כשמבצעים עיבוד של קובצי PDF באמצעות PhantomJS.

התקנה

כדי להתקין תצוגות חזותיות מותאמות אישית, צריך להגדיר מניפסט באמצעות הטופס 'ניהול > פלטפורמה > תצוגות חזותיות'. מניפסט מורכב ממזהה מחרוזת ייחודי, תווית קריאה לאנשים, ה-URI של התצוגה החזותית וקישורים לכל יחסי התלות שאתם צריכים (למשל: d3,‏ jQuery,‏ underscore).

הדמיה מותאמת אישית צריכה להיות מוצגת כתוכן HTTPS חיצוני ל-Looker. אם אתם עוברים מהגרסה הראשונה של ה-API של התצוגה החזותית בהתאמה אישית, יכול להיות שיש לכם קבצים בספרייה looker/plugins/visualizations. עדיין אפשר לגשת למיקום הזה, ואפשר לספק נתיב יחסי להדמיה, אבל מומלץ להעביר את התוכן למיקום אחר. מכיוון שהספרייה ‎ /plugins לא נמצאת במערכת הקבצים המשותפת, לסביבות מקובצות לא תהיה גישה לקובצי התצוגה החזותית בכל הצמתים.

אובייקט התרשים להמחשה

אובייקט התצוגה החזותית משתמש במאפיינים הבאים: מאפייני חובה, מאפיינים אופציונליים ומאפיינים שנוספו.

מאפייני חובה

  • create function

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

    פרטים נוספים על הפונקציה create ←

  • ‫updateAsync / update פונקציה

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

    אפשר לקרוא לפונקציה הזו מסיבות רבות, אבל בדרך כלל זה קורה כשהשאילתה להצגה חזותית השתנתה, אפשרות הגדרה השתנתה או שהגודל של ההצגה החזותית השתנה.

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

    פרטים נוספים על הפונקציות האלה של update ←

מאפיינים אופציונליים

  • options object

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

    מידע נוסף על חשיפת ממשק משתמש להגדרות →

  • destroy function Not yet implemented in API V2

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

מאפייני המודעה שנוספו

‫Looker מוסיף את המאפיינים הבאים לאובייקט באופן אוטומטי אחרי שהוויזואליזציה מועברת אל looker.plugins.visualizations.add. אפשר להפנות אליהם באמצעות this בהקשר של הפונקציות create,‏ update,‏ updateAsync ו-destroy.

  • addError פונקציה

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

    אחרי שמוסיפים שגיאה, היא תישאר גלויה עד שמפעילים את clearErrors.

    לדוגמה:

    this.addError({
        title: "Two Dimensions Required",
        message: "This really great visualization requires two dimensions."
    });
    
  • clearErrors פונקציה

    פונקציה שהקוד של הוויזואליזציה עשוי לקרוא לה כדי לנקות שגיאות שנוספו באמצעות addError.

    לדוגמה:

    this.clearErrors();
    
  • trigger פונקציה

    פונקציה שאפשר לקרוא לה כדי להפעיל אירוע מחוץ להמחשה החזותית.

    פרטים על אירועים ←

    לדוגמה:

    this.trigger("limit", [20]);
    

הפונקציה create

לפונקציה create יועברו שני פרמטרים, element ו-config.

create: function(element, config){
  // Your update code here.
},

פרמטרים

  • element DOMElement

    רכיב DOM שמייצג מאגר שבו יוצג התרשים.

  • config אובייקט

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

    דוגמה: {my_configuration_option: "User Value"}

הפונקציות updateAsync ו-update

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

לגרסה הזו של הפונקציה יש פרמטר נוסף, שהוא קריאה חוזרת (callback) שמתבצעת כשהעיבוד מסתיים:

updateAsync: function(data, element, config, queryResponse, details, done){
    // An example of an asynchronous update, fetching a file.
    d3.request("https://example.com/fun-file.docx").response(function(xhr) {
        // Your update code here that uses this file.
        done();
    });
}

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

בחלק מהתצוגות החזותיות הישנות יותר נעשה שימוש בפונקציה update. הפונקציה הזו עדיין פועלת, אבל היא לא השיטה המועדפת, כי השימוש בה אומר ש-Looker לא יקבל התראה כשהעיבוד של התצוגה החזותית יושלם. הפונקציה update תעביר חמישה פרמטרים:

update: function(data, element, config, queryResponse, details){
  // Your update code here.
}

פרמטרים

  • data מערך

    מערך של שורות שמייצג את הנתונים הנוכחיים בשאילתה. יכול להיות null.

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

  • element DOMElement

    רכיב DOM שמייצג מאגר שבו יוצג התרשים.

  • config אובייקט

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

    לדוגמה: {my_configuration_option: "User Value"}

  • queryResponse object

    אובייקט שמייצג מטא-נתונים לגבי השאילתה הנוכחית, כמו מטא-נתונים לגבי שדות. יכול להיות null.

  • details אובייקט

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

    במסננים מצטלבים במרכזי הבקרה של Looker שמשתמשים בממשק החדש של מרכז הבקרה, המאפיינים המותרים כוללים את crossfilterEnabled ו-crossfilters.

    אפשר להשתמש במאפיין print בשילוב עם הפונקציה done כדי לשפר את העיבוד של קובצי PDF בתצוגות חזותיות בהתאמה אישית, במיוחד כאלה שכוללות אנימציה. לדוגמה:

    if (details.print) {
            done();
    }
    
  • done פונקציה

    קריאה חוזרת (callback) שמציינת שהעיבוד של התצוגה החזותית הושלם. חשוב במיוחד להפעיל את הפונקציה הזו אם הוויזואליזציה צריכה לבצע קריאות אסינכרוניות או אם צריך להציג אותה כקובץ PDF.

Rendering Data

ל-Looker יש קבוצה עשירה של כלים לעיצוב נתונים ב-LookML, שאפשר להשתמש בהם כדי להתאים אישית את המראה וההתנהגות של נקודות נתונים. הכלים האלה כוללים הגדרות LookML ברמת השדה, כמו פורמטים של ערכים בהתאמה אישית, HTML, קישורים להצגת פירוט ופעולות בנתונים.

לתאים יש מאפיין value, שהוא המאפיין היחיד שקיים בכל המקרים. המאפיין הזה הוא סוג JavaScript שתואם לסוג השדה שאליו התא שייך. עם זאת, לא בטוח להוסיף מאפיין value ישירות ל-HTML או ל-SVG, כי לא בוצעו תווי בריחה (escape) ב-HTML, וחלק מערכי השדות הם מערכים או אובייקטים ב-JavaScript מורכבים שיוצגו בדרכים לא רצויות או מבלבלות.

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

כל פונקציות העזר האלה זמינות באובייקט הגלובלי LookerCharts.Utils.

  • LookerCharts.Utils.textForCell(cell)

    הפונקציה הזו מקבלת תא ומחזירה ייצוג מחרוזת שלו שמתאים לתצוגה. הוא תמיד יהיה מחרוזת – הפונקציה הזו אף פעם לא מחזירה null או כל סוג אחר.

  • LookerCharts.Utils.htmlForCell(cell)

    הפונקציה הזו מקבלת תא ומחזירה מחרוזת שמכילה HTML. הוא תמיד יהיה מחרוזת – הפונקציה הזו אף פעם לא מחזירה null או כל סוג אחר.

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

  • LookerCharts.Utils.filterableValueForCell(cell)

    הפונקציה הזו מקבלת תא ומחזירה מחרוזת תחביר של סינון מתקדם ב-Looker שתואמת לערך של התא הזה.

  • LookerCharts.Utils.toggleCrossfilter({row, pivot, event})

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

    d3.select("#myElement")
    .on("click", function (d) {
        if (details.crossfilterEnabled) {
                LookerCharts.Utils.toggleCrossfilter({
                    row: d.row,
                    event: d3.event,
                });
        } else {
          // ... handle click when cross-filtering is not enabled
        }
    });
    
  • LookerCharts.Utils.getCrossfilterSelection(row, pivot?)

    הפונקציה מקבלת שורה או ציר, ומשמשת לבדיקה אם השורה או הציר נבחרו בתרשים בהתאמה אישית. הפונקציה מחזירה ערך enum עבור CrossfilterSelection {NONE, SELECTED, UNSELECTED}: 0 אם NONE, 1 אם SELECTED ו-2 אם UNSELECTED.

    בדוגמה הבאה, צבע מילוי מוחל באופן מותנה על שורה אם מופעל בה סינון מצליב, וצבעי ברירת המחדל מוחלים אם לא מופעל בה סינון מצליב:

    d3.select("#myElement")
    .attr("fill", function (d) {
        const crossfilter = LookerCharts.Utils.getCrossfilterSelection(d.row)
        if (details.crossfilterEnabled && crossfilter === 1) {
                return d.color
        } else {
                return "#DEE1E5" //Hex used for unselected elements in native visualizations
    ...
    
  • LookerCharts.Utils.openDrillMenu(options)

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

    לאובייקט options יש את הפרמטרים הבאים:

    • ‫links חובה מערך

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

      { label: string, type: 'drill', type_label: string, url: url }

    • event אירוע HTML DOM

      אירוע הקליק (או אירוע אחר) שגרם לאירוע הפירוט. ‫Looker ישתמש בזה כדי לקבוע איפה למקם את תפריט הפירוט. אם אין לכם, נסו להעביר אובייקט עם הקואורדינטות pageX ו-pageY.

    לדוגמה:

    for (var row of data) {
        var cell = row[queryResponse.fields.dimensions[0].name];
        var cellElement = myBuildElementFunction(cell);
        cellElement.onclick = function(event) {
            LookerCharts.Utils.openDrillMenu({
                links: cell.links,
                event: event
            });
        };
        // ... more visualization stuff...
    }
    

הצגת ממשק המשתמש של ההגדרות

הפרמטר options הוא אובייקט שבו המפתחות הם מזהה שרירותי של שם האפשרות, והערך הוא אובייקט שמתאר מידע על האפשרות.

הנה דוגמה:

options: {
    color_range: {
      type: "array",
      label: "Color Range",
      display: "colors"
    },
   top_label: {
      type: "string",
      label: "Label (for top)",
      placeholder: "My Great Chart"
    },
    transport_mode: {
      type: "string",
      label: "Mode of Transport",
      display: "select",
      values: [
         {"Airplane": "airplane"},
         {"Car": "car"},
         {"Unicycle": "unicycle"}
      ],
      default: "unicycle"
    }
}

פרמטרים של אובייקט האפשרויות

לאובייקט option יש את הפרמטרים הבסיסיים הבאים, מאפיינים ספציפיים לתצוגה ואפשרויות לארגון.

פרמטרים בסיסיים

  • type מחרוזת

    סוג הנתונים של האפשרות.

    ערכים מותרים: string (ברירת מחדל), number, ‏ boolean, ‏ array

  • label מחרוזת

    התווית הקריאה לאנשים של האפשרות שתוצג למשתמש.

  • default

    ערך ברירת המחדל של האפשרות. אם לא מציינים ערך, הערך של האפשרות הוא null. הערך צריך להיות מאותו סוג כמו type.

  • display מחרוזת

    ערכים מסוימים של type יכולים להופיע בממשק המשתמש בדרכים שונות.

    • כשהערך בשדה type הוא string:

      ערכים מותרים: text (ברירת מחדל), select, radio

    • כשהערך בשדה type הוא number:

      ערכים מותרים: number (ברירת מחדל), range

    • כשהערך בשדה type הוא array:

      ערכים מותרים: text (ברירת מחדל), color, colors

  • placeholder מחרוזת

    עבור ערכי display שמאפשרים זאת, ערך לדוגמה או הסבר כדי לתת למשתמש רמז לגבי מה להקליד.

מאפיינים ספציפיים לתצוגה

  • values מערך של אובייקטים

    אם הערך של display הוא radio או select, מערך שמכיל תוויות וערכים שיוצגו בממשק.

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

    לדוגמה:

    values: [
        {"Center": "c"},
        {"Left": "l"},
        {"Right": "r"}
    ]
    

    אם display הוא radio, אפשר לתת לכל אפשרות גם description:

    values: [
        {"Cool": "c"},
        {"Uncool": {
                value: "unc",
                description: "Only choose this if the data is very uncool."
            }
        }
    ]
    
  • max מספר

    כאשר display הוא range, המספר המקסימלי שמותר לבחור באמצעות פס ההזזה של הטווח.

  • min מספר

    כשdisplay הוא range, זה המספר המינימלי שאפשר לבחור באמצעות פס ההזזה.

  • step מספר

    כשהערך של display הוא range, הסכום שכל שנתה של פס ההזזה של הטווח מייצגת.

אפשרויות ארגון

  • section מחרוזת

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

    אם משתמשים ב-section, צריך להגדיר אותו בכל אפשרות.

  • order number

    מספר שמייצג את סדר האפשרויות להצגה בממשק המשתמש. אם מציינים את הסדר, האפשרויות ימוינו לפיו.

  • display_size מחרוזת

    סוג גודל שמייצג את רוחב האפשרות בממשק המשתמש. לדוגמה, אם רוצים להציג את האפשרויות 'מינימום' ו'מקסימום' זו לצד זו, אפשר להגדיר את גודל התצוגה של כל אחת מהן ל-half.

    ערכים מותרים: normal (ברירת מחדל), half, third

אירועים

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

אפשר להפעיל אותם על ידי קריאה לפונקציה trigger באובייקט הוויזואליזציה. הפרמטר הראשון הוא תמיד שם האירוע והפרמטר השני הוא מערך של ארגומנטים.

this.trigger("limit", [20]);

אירועים זמינים

  • updateConfig

    מעדכנים את הגדרות התצורה הנוכחיות של התרשים.

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

    לדוגמה:

    var vis = this;
    $(element).find(".axis").click(function(){
        vis.trigger("updateConfig", [{axis_hidden: true}]);
    });
    
  • limit

    עדכון ההגבלה של השאילתה הבסיסית:

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

    var vis = this;
    $(element).find(".show-all").click(function(){
        vis.trigger("limit", [500]);
    });
    
  • filter

    כדי לעדכן את הערך של מסנן בשאילתה הבסיסית:

    var vis = this;
    $(element).find(".show-all-tommys").click(function(){
        vis.trigger("filter", [{
            field: "users.name", // the name of the field to filter
            value: "%tommy%", // the "advanced syntax" for the filter
            run: true, // whether to re-run the query with the new filter
        }]);
    });
    
  • loadingStart

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

    הוא יופיע במצב טעינה עד שהפעולה loadingEnd תופעל.

  • loadingEnd

    מסמנים שהוויזואליזציה לא נטענת יותר.

  • printSize (Looker 26.0 ואילך)

    מאפשר להשתמש באפשרות 'הרחבת הטבלאות כדי להציג את כל השורות' בתצוגות חזותיות כשמעבדים מרכזי בקרה לקובץ PDF. האירוע הזה מאפשר לאפליקציה לדעת מה הגובה של התוכן שעבר עיבוד, ולהרחיב את המשבצת במרכז הבקרה בהתאם כדי שכל המידע יהיה גלוי להדפסה.

      this.trigger('printSize', {
        heightExpanded: FULL_HEIGHT_IN_PIXELS
      });
    
  • ‫registerOptions (Looker 5.24 ואילך)

    מאפשרת לתרשימים לרשום אפשרויות נוספות אחרי שהתרשים נרשם:

      update: function(data, element, config, queryResponse, details){
        options = {}
        // Create an option for each measure in your query
        queryResponse.fields.measure_like.forEach(function(field) {
          id = "color_" + field.name
          options[id] =
          {
        label: field.label_short + " Color",
        default: "#8B7DA8",
        section: "Style",
        type: "string",
        display: "color"
          }
        })
        this.trigger('registerOptions', options) // register options with parent page to update visConfig
        ...
      }
    });