{"id":21260,"date":"2019-09-03T18:01:49","date_gmt":"2019-09-03T17:01:49","guid":{"rendered":"https:\/\/www.intercom.com\/blog\/?p=21260"},"modified":"2020-07-30T12:54:34","modified_gmt":"2020-07-30T11:54:34","slug":"building-interactive-data-visualizations-with-ember","status":"publish","type":"post","link":"https:\/\/www.intercom.com\/blog\/building-interactive-data-visualizations-with-ember\/","title":{"rendered":"How we built a component API for interactive data visualizations with Ember"},"content":{"rendered":"<p>At Intercom, one of our core principles is to <a href=\"https:\/\/www.intercom.com\/blog\/run-less-software\/\" target=\"_blank\" rel=\"noopener noreferrer\">run less software<\/a>, which involves using standard technology. By doing so, we all become experts in the same tools, allowing us to increase our speed of building new product and reduce the cost of engineering decisions.<\/p>\n<p>An example of this is our admin app, which is built with <a href=\"https:\/\/www.intercom.com\/blog\/ember-delivers-rapid-improvements-at-intercom\/\" target=\"_blank\" rel=\"noopener noreferrer\">Ember.js<\/a>. We have invested in building and documenting an internal design system made of reusable Ember components, so that any Intercom product engineer can skim the markup in an unfamiliar part of Intercom\u2019s product and quickly make changes or additions without needing to learn new patterns.<\/p>\n<blockquote class=\"pullquote-style-one\"><p>&#8220;Any engineer wanting to add data visualization to part of the product doesn\u2019t need to become an expert on a new technology&#8221;<\/p><\/blockquote>\n<p>When it comes to building rich data visualizations, we previously used <a href=\"https:\/\/d3js.org\/\" target=\"_blank\" rel=\"noopener noreferrer\">D3<\/a>, which is the industry standard tool for data visualization on the web. However, D3 requires thinking about UI in a different way to building components with Ember in HTML, CSS, and JavaScript. Because D3 isn\u2019t one of our standard technologies, and because it requires engineers to think about UI differently, D3 visualizations created a sort of barrier for engineers in our codebase between product features and data visualization.<\/p>\n<p>Product engineers shouldn\u2019t all have to be D3 experts. Instead, when we build rich data visualizations, for instance in <a href=\"https:\/\/app.intercom.com\/a\/apps\/_\/reports\" target=\"_blank\" rel=\"noopener noreferrer\">displaying reports<\/a>, we built a composable component library of simple Ember components, and only use D3 to draw SVGs when we want to make shapes that HTML and CSS aren\u2019t equipped for. As a result, we\u2019re now in a position where any engineer wanting to add data visualization to part of the product doesn\u2019t need to become an expert in a new technology, like D3, and doesn\u2019t have to learn new best practices before getting started.<\/p>\n<h2 id=\"constructing-a-component-architecture\">Constructing a component architecture<\/h2>\n<p>When setting out to simplify how engineers build data visualizations at Intercom, we had a few considerations:<\/p>\n<ul>\n<li>Building data visualizations should feel like building product anywhere else in our codebase.<\/li>\n<li>Product performance should not be impacted, and hopefully should improve.<\/li>\n<\/ul>\n<p>Ideally, we wanted to end up with a simple, shared component architecture \u2013 just like any good design system \u2013 so our visualizations could maintain consistency in behavior and appearance. Making it easier and faster for any product engineer to implement data visualizations should improve productivity and increase adoption of data visualizations.<\/p>\n<h2 id=\"so-how-did-we-do-this\">So how did we do this?<\/h2>\n<p>Previously, the visualizations we used were single files that controlled the entire visualization. We broke those singles files down into multiple components that can be grouped into two distinct categories:<\/p>\n<ul>\n<li><strong>Presentational components<\/strong>: To be used generically in any visualization.<\/li>\n<li><strong>Data components<\/strong>: To be used to interpolate different data types and connect to all of our generic presentational components.<\/li>\n<\/ul>\n<p>Critically, the two different types of components operate independently of one another, which allows us to use the entire system of components together in any context.<\/p>\n<h3>Presentational Components<\/h3>\n<p>We built our presentational component parts \u2013 like bars, labels, plots, and grid lines \u2013 in plain HTML and CSS, rather than SVG elements. These simple HTML components allow us to easily share and compose visualizations from a shared set of core visual tools. We can use the same simple component anytime it\u2019s needed and maintain a single source of truth for how it should look and behave. These also allow us to compose more complex visualizations from the same, reusable core elements.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-21266 size-full\" src=\"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2019\/09\/bar.gif\" alt=\"\" width=\"500\" height=\"93\" \/><\/p>\n<p style=\"text-align: center;\"><small><em>Here\u2019s a simple &lt;Bar&gt; component.<\/em><\/small><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-21267 size-full\" src=\"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2019\/09\/bargroup.gif\" alt=\"\" width=\"500\" height=\"113\" \/><\/p>\n<p style=\"text-align: center;\"><small><em>Here\u2019s a &lt;BarGroup&gt;, that&#8217;s composed of multiple &lt;Bar&gt; components.<\/em><\/small><\/p>\n<h3>Composing with shared data components<\/h3>\n<p>Once we had defined a set of presentational components, we could compose them together with our data components. We componentized D3\u2019s excellent library of data interpolation helpers and isolated this part of building visualizations from our presentation components. This allowed us to keep our presentational components generic and make any number of visualizations by composing data components and presentational components together.<\/p>\n<p>This means that for a horizontal bar chart, like we used to display conversation ratings in our <a href=\"https:\/\/app.intercom.com\/a\/apps\/_\/reports\" target=\"_blank\" rel=\"noopener noreferrer\">overview report<\/a>, we can just use:<\/p>\n<ul>\n<li><span style=\"font-weight: 400;\">&lt;XScale&gt; <\/span>\u2013 to map the data to an x coordinate.<\/li>\n<li><span style=\"font-weight: 400;\">&lt;BarGroup&gt; <\/span>\u2013 to visualize the data we mapped to an x coordinate.<\/li>\n<li><span style=\"font-weight: 400;\">&lt;XAxis&gt; <\/span>\u2013 to represent the scale for the data.<\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-21265\" src=\"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2019\/09\/horizontal_bar_chart.jpg\" alt=\"\" width=\"850\" height=\"84\" srcset=\"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2019\/09\/horizontal_bar_chart.jpg 850w, https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2019\/09\/horizontal_bar_chart-300x30.jpg 300w, https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2019\/09\/horizontal_bar_chart-768x76.jpg 768w, https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2019\/09\/horizontal_bar_chart-700x69.jpg 700w, https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2019\/09\/horizontal_bar_chart-600x59.jpg 600w\" sizes=\"auto, (max-width: 850px) 100vw, 850px\" \/><\/p>\n<p>We still need to use SVGs and D3 for complex visualization shapes, such as in a line chart. However, we preserved our composable component system here too. Rather than build the entire line chart with D3, we created a component that only drew lines \u2013 everything else we continued to build with our component library. This meant that when we wanted to create a new sparkline chart, for instance, we were able to simply strip down our existing line chart by recomposing only the components needed, rather than by passing a complex configuration or creating forking logic in a pure D3 line chart.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-21268 size-full\" src=\"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2019\/09\/sparkline-chart.gif\" alt=\"\" width=\"500\" height=\"84\" \/><\/p>\n<h2 id=\"why-this-works-for-us\">Why this works for us<\/h2>\n<p>We could have done all of the above using Ember components, while still rendering SVG elements. However, we opted to use plain HTML components for two reasons:<\/p>\n<ol>\n<li>It allowed us to leverage the same design system components other product teams use.<\/li>\n<li>It eliminated the need to deeply understand SVG layout, and instead, use the same layout tools we use in the rest of the product.<\/li>\n<\/ol>\n<p>This approach won\u2019t work for everyone. Because we\u2019re positioning HTML elements with transforms, rather than SVG elements inside an SVG as D3 does, we\u2019re creating \u201clayers\u201d in the browser. Even though these layers are offloaded to the GPU, a lot of layers can use more memory and have performance issues on lower-end devices. Since our product prioritizes readability and interactivity, this means that we avoid having many data points in a single visualization, and we avoid the issue of having too many layers.<\/p>\n<p>Since we\u2019re no longer locked in to animating SVG elements, we can offset potential performance impact by doing our animations with CSS transitions and keyframe animations, specifically leveraging the power of CSS 3D transforms, rather than using D3\u2019s normal approach of using JavaScript to animate SVG elements frame by frame. This has a huge positive impact on the ability to smoothly animate visualization between data points.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-21269 size-full\" src=\"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2019\/09\/line-chart.gif\" alt=\"\" width=\"500\" height=\"139\" \/><\/p>\n<p>Moving our process away from individually created visualizations using D3 towards visualizations composed of standard building block components \u2013 with the same web technology all Intercom engineers use to build product \u2013 has made building visualizations more accessible to all engineers at Intercom, improved the quality of our product, and increased our speed and iteration of development. We\u2019ve done all this without tanking performance \u2013 in fact, we\u2019ve improved it. And because we\u2019re using components, we get improvements and bug fixes automatically. The benefits of using components are manifold, and the system operates as a small but telling example of how &#8220;run less software&#8221; is a philosophy that keeps on giving.<\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>At Intercom, one of our core principles is to run less software, which involves using standard technology. By doing so, we all become experts in the same tools, allowing us to increase our speed of building&hellip;<\/p>\n","protected":false},"author":420,"featured_media":21264,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"category":[12898],"tags":[],"coauthors":[18578],"class_list":["post-21260","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-engineering"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.3 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>How We Used Ember to Build a Data Visualization API | Intercom<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.intercom.com\/blog\/building-interactive-data-visualizations-with-ember\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How we built a component API for interactive data visualizations with Ember\" \/>\n<meta property=\"og:description\" content=\"At Intercom, one of our core principles is to run less software, which involves using standard technology. By doing so, we all become experts in the same tools, allowing us to increase our speed of building&hellip;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.intercom.com\/blog\/building-interactive-data-visualizations-with-ember\/\" \/>\n<meta property=\"og:site_name\" content=\"The Intercom Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/intercominc\" \/>\n<meta property=\"article:published_time\" content=\"2019-09-03T17:01:49+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-07-30T11:54:34+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2019\/09\/data_visualizations.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2500\" \/>\n\t<meta property=\"og:image:height\" content=\"1207\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Adam Seckel\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@hemlok_\" \/>\n<meta name=\"twitter:site\" content=\"@intercom\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Adam Seckel\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/building-interactive-data-visualizations-with-ember\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/building-interactive-data-visualizations-with-ember\\\/\"},\"author\":{\"name\":\"Adam Seckel\",\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/#\\\/schema\\\/person\\\/de26b6bd78aebf96f273f5a48fec147c\"},\"headline\":\"How we built a component API for interactive data visualizations with Ember\",\"datePublished\":\"2019-09-03T17:01:49+00:00\",\"dateModified\":\"2020-07-30T11:54:34+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/building-interactive-data-visualizations-with-ember\\\/\"},\"wordCount\":1175,\"publisher\":{\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/building-interactive-data-visualizations-with-ember\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/data_visualizations.jpg\",\"articleSection\":[\"Engineering\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/building-interactive-data-visualizations-with-ember\\\/\",\"url\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/building-interactive-data-visualizations-with-ember\\\/\",\"name\":\"How We Used Ember to Build a Data Visualization API | Intercom\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/building-interactive-data-visualizations-with-ember\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/building-interactive-data-visualizations-with-ember\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/data_visualizations.jpg\",\"datePublished\":\"2019-09-03T17:01:49+00:00\",\"dateModified\":\"2020-07-30T11:54:34+00:00\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.intercom.com\\\/blog\\\/building-interactive-data-visualizations-with-ember\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/building-interactive-data-visualizations-with-ember\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/data_visualizations.jpg\",\"contentUrl\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/data_visualizations.jpg\",\"width\":2500,\"height\":1207},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/\",\"name\":\"The Intercom Blog\",\"description\":\"Articles and Podcasts on Customer Service, AI and Automation, Product, and more\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/#organization\",\"name\":\"The Intercom Blog\",\"url\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/08\\\/Intercom-logo-sq-black-trans.png\",\"contentUrl\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/08\\\/Intercom-logo-sq-black-trans.png\",\"width\":1000,\"height\":1000,\"caption\":\"The Intercom Blog\"},\"image\":{\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/intercominc\",\"https:\\\/\\\/x.com\\\/intercom\",\"https:\\\/\\\/www.instagram.com\\\/intercom\\\/\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/2491343\",\"https:\\\/\\\/www.pinterest.ie\\\/intercom\\\/\",\"https:\\\/\\\/www.youtube.com\\\/channel\\\/UCJG0MvLP03kyzzAkD-w98aQ\",\"https:\\\/\\\/en.wikipedia.org\\\/wiki\\\/Intercom_(company)\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/#\\\/schema\\\/person\\\/de26b6bd78aebf96f273f5a48fec147c\",\"name\":\"Adam Seckel\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/de1309f7e39bffaf13152107c99a9d41b634ef3321a83e82240f6b98dc564233?s=96&d=mm&r=pg58f01736a9b3397c8d29cc2d82067c9e\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/de1309f7e39bffaf13152107c99a9d41b634ef3321a83e82240f6b98dc564233?s=96&d=mm&r=pg\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/de1309f7e39bffaf13152107c99a9d41b634ef3321a83e82240f6b98dc564233?s=96&d=mm&r=pg\",\"caption\":\"Adam Seckel\"},\"description\":\"Adam was a product engineer at Intercom. He is passionate about delivering pixel perfect and exciting web experiences, building user-focused products, and component based front-end architecture.\",\"sameAs\":[\"https:\\\/\\\/www.linkedin.com\\\/in\\\/adamseckel\\\/\",\"https:\\\/\\\/x.com\\\/hemlok_\"],\"url\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/author\\\/hemlok_\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"How We Used Ember to Build a Data Visualization API | Intercom","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.intercom.com\/blog\/building-interactive-data-visualizations-with-ember\/","og_locale":"en_US","og_type":"article","og_title":"How we built a component API for interactive data visualizations with Ember","og_description":"At Intercom, one of our core principles is to run less software, which involves using standard technology. By doing so, we all become experts in the same tools, allowing us to increase our speed of building&hellip;","og_url":"https:\/\/www.intercom.com\/blog\/building-interactive-data-visualizations-with-ember\/","og_site_name":"The Intercom Blog","article_publisher":"https:\/\/www.facebook.com\/intercominc","article_published_time":"2019-09-03T17:01:49+00:00","article_modified_time":"2020-07-30T11:54:34+00:00","og_image":[{"width":2500,"height":1207,"url":"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2019\/09\/data_visualizations.jpg","type":"image\/jpeg"}],"author":"Adam Seckel","twitter_card":"summary_large_image","twitter_creator":"@hemlok_","twitter_site":"@intercom","twitter_misc":{"Written by":"Adam Seckel","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.intercom.com\/blog\/building-interactive-data-visualizations-with-ember\/#article","isPartOf":{"@id":"https:\/\/www.intercom.com\/blog\/building-interactive-data-visualizations-with-ember\/"},"author":{"name":"Adam Seckel","@id":"https:\/\/www.intercom.com\/blog\/#\/schema\/person\/de26b6bd78aebf96f273f5a48fec147c"},"headline":"How we built a component API for interactive data visualizations with Ember","datePublished":"2019-09-03T17:01:49+00:00","dateModified":"2020-07-30T11:54:34+00:00","mainEntityOfPage":{"@id":"https:\/\/www.intercom.com\/blog\/building-interactive-data-visualizations-with-ember\/"},"wordCount":1175,"publisher":{"@id":"https:\/\/www.intercom.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.intercom.com\/blog\/building-interactive-data-visualizations-with-ember\/#primaryimage"},"thumbnailUrl":"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2019\/09\/data_visualizations.jpg","articleSection":["Engineering"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.intercom.com\/blog\/building-interactive-data-visualizations-with-ember\/","url":"https:\/\/www.intercom.com\/blog\/building-interactive-data-visualizations-with-ember\/","name":"How We Used Ember to Build a Data Visualization API | Intercom","isPartOf":{"@id":"https:\/\/www.intercom.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.intercom.com\/blog\/building-interactive-data-visualizations-with-ember\/#primaryimage"},"image":{"@id":"https:\/\/www.intercom.com\/blog\/building-interactive-data-visualizations-with-ember\/#primaryimage"},"thumbnailUrl":"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2019\/09\/data_visualizations.jpg","datePublished":"2019-09-03T17:01:49+00:00","dateModified":"2020-07-30T11:54:34+00:00","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.intercom.com\/blog\/building-interactive-data-visualizations-with-ember\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.intercom.com\/blog\/building-interactive-data-visualizations-with-ember\/#primaryimage","url":"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2019\/09\/data_visualizations.jpg","contentUrl":"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2019\/09\/data_visualizations.jpg","width":2500,"height":1207},{"@type":"WebSite","@id":"https:\/\/www.intercom.com\/blog\/#website","url":"https:\/\/www.intercom.com\/blog\/","name":"The Intercom Blog","description":"Articles and Podcasts on Customer Service, AI and Automation, Product, and more","publisher":{"@id":"https:\/\/www.intercom.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.intercom.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.intercom.com\/blog\/#organization","name":"The Intercom Blog","url":"https:\/\/www.intercom.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.intercom.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2019\/08\/Intercom-logo-sq-black-trans.png","contentUrl":"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2019\/08\/Intercom-logo-sq-black-trans.png","width":1000,"height":1000,"caption":"The Intercom Blog"},"image":{"@id":"https:\/\/www.intercom.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/intercominc","https:\/\/x.com\/intercom","https:\/\/www.instagram.com\/intercom\/","https:\/\/www.linkedin.com\/company\/2491343","https:\/\/www.pinterest.ie\/intercom\/","https:\/\/www.youtube.com\/channel\/UCJG0MvLP03kyzzAkD-w98aQ","https:\/\/en.wikipedia.org\/wiki\/Intercom_(company)"]},{"@type":"Person","@id":"https:\/\/www.intercom.com\/blog\/#\/schema\/person\/de26b6bd78aebf96f273f5a48fec147c","name":"Adam Seckel","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/de1309f7e39bffaf13152107c99a9d41b634ef3321a83e82240f6b98dc564233?s=96&d=mm&r=pg58f01736a9b3397c8d29cc2d82067c9e","url":"https:\/\/secure.gravatar.com\/avatar\/de1309f7e39bffaf13152107c99a9d41b634ef3321a83e82240f6b98dc564233?s=96&d=mm&r=pg","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/de1309f7e39bffaf13152107c99a9d41b634ef3321a83e82240f6b98dc564233?s=96&d=mm&r=pg","caption":"Adam Seckel"},"description":"Adam was a product engineer at Intercom. He is passionate about delivering pixel perfect and exciting web experiences, building user-focused products, and component based front-end architecture.","sameAs":["https:\/\/www.linkedin.com\/in\/adamseckel\/","https:\/\/x.com\/hemlok_"],"url":"https:\/\/www.intercom.com\/blog\/author\/hemlok_\/"}]}},"jetpack_featured_media_url":"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2019\/09\/data_visualizations.jpg","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.intercom.com\/blog\/wp-json\/wp\/v2\/posts\/21260","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.intercom.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.intercom.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.intercom.com\/blog\/wp-json\/wp\/v2\/users\/420"}],"replies":[{"embeddable":true,"href":"https:\/\/www.intercom.com\/blog\/wp-json\/wp\/v2\/comments?post=21260"}],"version-history":[{"count":0,"href":"https:\/\/www.intercom.com\/blog\/wp-json\/wp\/v2\/posts\/21260\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.intercom.com\/blog\/wp-json\/wp\/v2\/media\/21264"}],"wp:attachment":[{"href":"https:\/\/www.intercom.com\/blog\/wp-json\/wp\/v2\/media?parent=21260"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.intercom.com\/blog\/wp-json\/wp\/v2\/category?post=21260"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.intercom.com\/blog\/wp-json\/wp\/v2\/tags?post=21260"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.intercom.com\/blog\/wp-json\/wp\/v2\/coauthors?post=21260"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}