קריאה לפונקציה 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 לא נמצאת במערכת הקבצים המשותפת, לסביבות מקובצות לא תהיה גישה לקובצי התצוגה החזותית בכל הצמתים.
אובייקט התרשים להמחשה
אובייקט התצוגה החזותית משתמש במאפיינים הבאים: מאפייני חובה, מאפיינים אופציונליים ומאפיינים שנוספו.
מאפייני חובה
createfunctionהפונקציה הזו נקראת פעם אחת, כשהתצוגה החזותית משורטטת לראשונה בדף. אפשר להגדיר כל דבר שרוצים שיהיה זמין תמיד בתרשים. אפשר לטעון ספרייה או ליצור קבוצה של רכיבים ופקדים לשימוש מאוחר יותר.
updateAsync/updateפונקציההפונקציה הזו נקראת בכל פעם שנדרש שינוי במצב של רכיב הוויזואליזציה. היא תמיד מופעלת אחרי
create, ויכול להיות שהיא תופעל הרבה פעמים, לכן היא צריכה להיות מהירה ככל האפשר.אפשר לקרוא לפונקציה הזו מסיבות רבות, אבל בדרך כלל זה קורה כשהשאילתה להצגה חזותית השתנתה, אפשרות הגדרה השתנתה או שהגודל של ההצגה החזותית השתנה.
לפונקציה הזו יש גרסה סינכרונית וגרסה אסינכרונית – צריך לציין רק אחת מהן. (אם מגדירים את שניהם, תופיע שגיאה). השיטה האסינכרונית אמינה יותר לעיבוד קובצי PDF בגלל האופי של תגי iframe.
מאפיינים אופציונליים
optionsobjectאובייקט שמפרט את האפשרויות שהמשתמשים יכולים להגדיר בתצוגה החזותית.
destroyfunction 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.
},
פרמטרים
elementDOMElementרכיב 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.כל שורה היא אובייקט עם מפתחות שמייצגים שמות של שדות, וערך שמייצג אובייקט של תא. כאן מפורט מידע על טיפול באובייקט התא.
elementDOMElementרכיב DOM שמייצג מאגר שבו יוצג התרשים.
configאובייקטאובייקט שמייצג את הערכים של אפשרויות ההגדרה שמשתמש הגדיר לתרשים הזה.
לדוגמה:
{my_configuration_option: "User Value"}queryResponseobjectאובייקט שמייצג מטא-נתונים לגבי השאילתה הנוכחית, כמו מטא-נתונים לגבי שדות. יכול להיות
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, arraylabelמחרוזתהתווית הקריאה לאנשים של האפשרות שתוצג למשתמש.
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, צריך להגדיר אותו בכל אפשרות.ordernumberמספר שמייצג את סדר האפשרויות להצגה בממשק המשתמש. אם מציינים את הסדר, האפשרויות ימוינו לפיו.
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 ... } });