{"id":916,"date":"2016-03-21T05:28:09","date_gmt":"2016-03-21T09:28:09","guid":{"rendered":"https:\/\/www.visophyte.org\/blog\/?p=916"},"modified":"2016-03-21T05:28:09","modified_gmt":"2016-03-21T09:28:09","slug":"web-worker-assisted-email-visualizations-using-vega","status":"publish","type":"post","link":"https:\/\/www.visophyte.org\/blog\/2016\/03\/21\/web-worker-assisted-email-visualizations-using-vega\/","title":{"rendered":"Web Worker-assisted Email Visualizations using Vega"},"content":{"rendered":"<p><a href=\"https:\/\/www.visophyte.org\/blog\/wp-content\/uploads\/2016\/03\/20160321-034849.png\" rel=\"attachment wp-att-917\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-thumbnail wp-image-917\" src=\"https:\/\/www.visophyte.org\/blog\/wp-content\/uploads\/2016\/03\/20160321-034849-482x600.png\" alt=\"Faceted and overview visualizations\" width=\"482\" height=\"600\" srcset=\"https:\/\/www.visophyte.org\/blog\/wp-content\/uploads\/2016\/03\/20160321-034849-482x600.png 482w, https:\/\/www.visophyte.org\/blog\/wp-content\/uploads\/2016\/03\/20160321-034849-241x300.png 241w, https:\/\/www.visophyte.org\/blog\/wp-content\/uploads\/2016\/03\/20160321-034849.png 669w\" sizes=\"auto, (max-width: 482px) 100vw, 482px\" \/><\/a><\/p>\n<p>tl;dr: <a href=\"https:\/\/github.com\/asutherland\/glodastrophe\">glodastrophe<\/a>, the experimental entirely-client-side JS desktop-ish email app now supports <a href=\"https:\/\/vega.github.io\/\">Vega<\/a>-based visualizations in addition to new support infrastructure for extension-y things and creating derived views based on the search\/filter infrastructure.<\/p>\n<p>Two of the dreams of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Mozilla_Messaging\">Mozilla Messaging<\/a> were:<\/p>\n<ol>\n<li>Shareable email workflows (credit to <a href=\"https:\/\/ascher.ca\/\">:davida<\/a>).\u00a0 If you could figure out how to set up your email client in a way that worked for you, you should be able to share that with others in a way that doesn&#8217;t require them to manually duplicate your efforts and ideally without you having to write code.\u00a0 (And ideally without anyone having to review code\/anything in order to ensure there are no privacy or security problems in the workflow.)<\/li>\n<li>Useful email visualizations.\u00a0 While in the end, the only visualization ever shipped with Thunderbird was the simple timeline view of the faceted global search, various experiments happened along the way, some abandoned.\u00a0 For example, the following screenshot shows one of the earlier stages of faceted search development where each facet attempted to visualize the relative proportion of messages sharing that facet.<\/li>\n<\/ol>\n<p><a href=\"https:\/\/www.visophyte.org\/blog\/wp-content\/uploads\/2016\/03\/faceted-top-and-clicky-with-gpbugzilla-faceting.png\" rel=\"attachment wp-att-918\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-thumbnail wp-image-918\" src=\"https:\/\/www.visophyte.org\/blog\/wp-content\/uploads\/2016\/03\/faceted-top-and-clicky-with-gpbugzilla-faceting-600x193.png\" alt=\"faceted search UI prototype\" width=\"600\" height=\"193\" srcset=\"https:\/\/www.visophyte.org\/blog\/wp-content\/uploads\/2016\/03\/faceted-top-and-clicky-with-gpbugzilla-faceting-600x193.png 600w, https:\/\/www.visophyte.org\/blog\/wp-content\/uploads\/2016\/03\/faceted-top-and-clicky-with-gpbugzilla-faceting-300x96.png 300w, https:\/\/www.visophyte.org\/blog\/wp-content\/uploads\/2016\/03\/faceted-top-and-clicky-with-gpbugzilla-faceting-768x246.png 768w, https:\/\/www.visophyte.org\/blog\/wp-content\/uploads\/2016\/03\/faceted-top-and-clicky-with-gpbugzilla-faceting-1024x329.png 1024w, https:\/\/www.visophyte.org\/blog\/wp-content\/uploads\/2016\/03\/faceted-top-and-clicky-with-gpbugzilla-faceting.png 1474w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/a><\/p>\n<p>At the time, the <a href=\"https:\/\/mbostock.github.io\/protovis\/\">protovis<\/a> JS visualization library was the state of the art.\u00a0 Its successor the amazing, continually evolving <a href=\"https:\/\/d3js.org\/\">d3<\/a> has eclipsed it.\u00a0 d3, being a JS library, requires someone to write JS code.\u00a0 A visualization written directly in JS runs into the whole code review issue.\u00a0 What would be ideal is a means of specifying visualizations that is substantially more inert and easy to sandbox.<\/p>\n<p>Enter, <a href=\"https:\/\/vega.github.io\/\">Vega<\/a>, a visualization grammar that can be expressed in JSON that can not only define <a href=\"https:\/\/vega.github.io\/vega-editor\/?mode=vega&amp;spec=scatter_matrix\">&#8220;simple&#8221; static visualizations<\/a>, but also <a href=\"https:\/\/vega.github.io\/vega-editor\/?mode=vega&amp;spec=dimpvis\">mind-blowing gapminder-style interactive visualizations<\/a>.\u00a0 Also, it has some <a href=\"https:\/\/idl.cs.washington.edu\/papers\/reactive-vega-architecture\">very clever dataflow stuff<\/a> under the hood and builds on d3 and its well-proven magic.\u00a0 I performed a fairly extensive survey of the current visualization, faceting, and data processing options to help bring visualizations and faceted filtered search to glodastrophe and other potential gaia mail consumers like the Firefox OS Gaia Mail App.<\/p>\n<p>Digression: Two relevant significant changes in how the gaia mail backend was designed compared to its predecessor Thunderbird (and its global database) are:<\/p>\n<ol>\n<li>As much as can possibly be done in a DOM\/Web Worker(s) is done so.\u00a0 This greatly assists in UI responsiveness.\u00a0 Thunderbird has to do most things on the main thread because of hard-to-unwind implementation choices that permeate the codebase.<\/li>\n<li>It&#8217;s assumed that the local mail client may only have a subset of the messages known to the server, that the server may be smart, and that it&#8217;s possible to convince servers to support new functionality.\u00a0 In many ways, this is still aspirational (the backend has not yet implemented search on server), but the architecture has always kept this in mind.<\/li>\n<\/ol>\n<p>In terms of visualizations, what this means is that we pre-chew as much of the data in the worker as we can, drastically reducing both the amount of computation that needs to happen on the main (page) thread and the amount of data we have to send to it.\u00a0 It also means that we could potentially farm all of this out to the server if its search capabilities are sufficiently advanced.\u00a0 And\/or the backend could cache previous results.<\/p>\n<p>For example, in the faceted visualizations on the sidebar (placed side-by-side here):<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-919\" src=\"https:\/\/www.visophyte.org\/blog\/wp-content\/uploads\/2016\/03\/faceted-histograms.png\" alt=\"faceted-histograms\" width=\"444\" height=\"350\" srcset=\"https:\/\/www.visophyte.org\/blog\/wp-content\/uploads\/2016\/03\/faceted-histograms.png 444w, https:\/\/www.visophyte.org\/blog\/wp-content\/uploads\/2016\/03\/faceted-histograms-300x236.png 300w\" sizes=\"auto, (max-width: 444px) 100vw, 444px\" \/><\/p>\n<p>In the <a href=\"https:\/\/github.com\/mozilla-b2g\/gaia-email-libs-and-more\/blob\/79ff3cb9e61751656b5df23e6ab7bf15a65fefe2\/js\/extras\/vis_facet\/schemas\/facet_activity_sparkline.js\">&#8220;Prolific Authors&#8221; visualization definition<\/a>, the backend in the worker constructs a Vega dataflow (only!).\u00a0 The search\/filter mechanism is spun up and the visualization&#8217;s data gathering needs specify that we will load the messages that belong to each conversation in consideration.\u00a0 Then for each message we extract the author and age of the message and feed that to the dataflow graph.\u00a0 The data transforms bin the messages by date, facet the messages by author, and aggregate the message bins within each author.\u00a0 We then sort the authors by the number of messages they authored, and limit it to the top 5 authors which we then alphabetically sort.\u00a0 If we were doing this on the front-end, we&#8217;d have to send all N messages from the back-end.\u00a0 Instead, we send over just 5 histograms with a maximum of 60 data-points in each histogram, one per bin.<\/p>\n<p>Same deal with &#8220;Prolific domains&#8221;, but we extract the author&#8217;s mail domain and aggregate based on that.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-921\" src=\"https:\/\/www.visophyte.org\/blog\/wp-content\/uploads\/2016\/03\/authored-content-size-overview-heatmap.png\" alt=\"Authored content size overview heatmap\" width=\"667\" height=\"62\" srcset=\"https:\/\/www.visophyte.org\/blog\/wp-content\/uploads\/2016\/03\/authored-content-size-overview-heatmap.png 667w, https:\/\/www.visophyte.org\/blog\/wp-content\/uploads\/2016\/03\/authored-content-size-overview-heatmap-600x56.png 600w, https:\/\/www.visophyte.org\/blog\/wp-content\/uploads\/2016\/03\/authored-content-size-overview-heatmap-300x28.png 300w\" sizes=\"auto, (max-width: 667px) 100vw, 667px\" \/><\/p>\n<p>Similarly, the overview <a href=\"https:\/\/github.com\/mozilla-b2g\/gaia-email-libs-and-more\/blob\/79ff3cb9e61751656b5df23e6ab7bf15a65fefe2\/js\/extras\/vis_facet\/schemas\/overview_authored_content_heatmap.js\">Authored content size over time heatmap visualization<\/a> sends only the aggregated heatmap bins over the wire, not all the messages.\u00a0 Elaborating, for each message body part, we (now) compute an estimate of the number of actual &#8220;fresh&#8221; content bytes in the message.\u00a0 Anything we can detect as a quote or a mailing list footer or multiple paragraphs of legal disclaimers doesn&#8217;t count.\u00a0 The x-axis bins by time; now is on the right, the oldest considered message is on the left.\u00a0 The y-axis bins by the log of the authored content size.\u00a0 Messages with zero new bytes are at the bottom, massive essays are at the top.\u00a0 The current visualization is useless, but I think the ingredients can and will be used to create something more informative.<\/p>\n<p>Other notable glodastrophe changes since the last blog post:<\/p>\n<ul>\n<li>Front-end state management is now done using <a href=\"https:\/\/github.com\/reactjs\/redux\">redux<\/a><\/li>\n<li>The <a href=\"http:\/\/www.material-ui.com\/\">Material UI React library<\/a> has been adopted for UI widget purposes, though the conversation and message summaries still need to be overhauled.<\/li>\n<li>React was upgraded<\/li>\n<li>A war was fought with flexbox and flexbox won.\u00a0 Hard-coding and calc() are the only reason the visualizations look reasonably sized.<\/li>\n<li>Webpack is now used for bundling in order to facilitate all of these upgrades and reduce potential contributor friction.<\/li>\n<\/ul>\n<p>More to come!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>tl;dr: glodastrophe, the experimental entirely-client-side JS desktop-ish email app now supports Vega-based visualizations in addition to new support infrastructure for extension-y things and creating derived views based on the search\/filter infrastructure. Two of the dreams of Mozilla Messaging were: Shareable &hellip; <a href=\"https:\/\/www.visophyte.org\/blog\/2016\/03\/21\/web-worker-assisted-email-visualizations-using-vega\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[5,116,3,13,4],"tags":[132],"class_list":["post-916","post","type-post","status-publish","format-standard","hentry","category-email","category-firefox-os","category-mozilla","category-shiny","category-visualizing","tag-glodastrophe"],"_links":{"self":[{"href":"https:\/\/www.visophyte.org\/blog\/wp-json\/wp\/v2\/posts\/916","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.visophyte.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.visophyte.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.visophyte.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.visophyte.org\/blog\/wp-json\/wp\/v2\/comments?post=916"}],"version-history":[{"count":5,"href":"https:\/\/www.visophyte.org\/blog\/wp-json\/wp\/v2\/posts\/916\/revisions"}],"predecessor-version":[{"id":926,"href":"https:\/\/www.visophyte.org\/blog\/wp-json\/wp\/v2\/posts\/916\/revisions\/926"}],"wp:attachment":[{"href":"https:\/\/www.visophyte.org\/blog\/wp-json\/wp\/v2\/media?parent=916"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.visophyte.org\/blog\/wp-json\/wp\/v2\/categories?post=916"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.visophyte.org\/blog\/wp-json\/wp\/v2\/tags?post=916"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}