CINXE.COM
Unlock smarter decisions and enhance insights with live data visualizations
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Search engines --> <meta name="description" content="CSV to data visualization – in seconds! Flourish makes it easy to create real-time charts and maps without needing to manually republish them. Learn more in our blog post."> <!-- Twitter --> <meta name="twitter:card" content="summary_large_image"> <meta name="twitter:site" content="@f_l_o_u_r_i_s_h"> <meta name="twitter:image" content="https://flourish.studio/images/blog/live-csv-meta.png"> <meta name="twitter:title" content="Unlock smarter decisions and enhance insights with live data visualizations"> <meta name="twitter:description" content="CSV to data visualization – in seconds! Flourish makes it easy to create real-time charts and maps without needing to manually republish them. Learn more in our blog post."> <meta name="twitter:creator" content="@f_l_o_u_r_i_s_h"> <meta property="og:title" content="Unlock smarter decisions and enhance insights with live data visualizations"> <meta property="og:image" content="https://flourish.studio/images/blog/live-csv-meta.png"> <meta property="og:type" content="website"> <meta property="og:description" content="CSV to data visualization – in seconds! Flourish makes it easy to create real-time charts and maps without needing to manually republish them. Learn more in our blog post."> <meta property="og:site_name" content="Flourish"> <meta property="fb:app_id" content="102649676918117"> <title>Unlock smarter decisions and enhance insights with live data visualizations</title> <script src="https://cdn-au.onetrust.com/consent/c7f22011-a5da-4a30-8750-4cb18703c00d/OtAutoBlock.js" type="text/javascript"></script> <script src="https://cdn-au.onetrust.com/consent/c7f22011-a5da-4a30-8750-4cb18703c00d/otSDKStub.js" type="text/javascript" charset="UTF-8" data-domain-script="c7f22011-a5da-4a30-8750-4cb18703c00d" ></script> <script> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-44635456-19', 'auto'); ga('send', 'pageview'); function createFunctionWithTimeout(callback, timeout) { var called = false; function fn() { if (!called) { called = true; callback(); } } setTimeout(fn, timeout || 1000); // default is 1000ms return fn; } var trackOutboundLink = function(url) { ga('send', 'event', 'outbound', 'click', url, { 'transport': 'beacon', 'hitCallback': createFunctionWithTimeout(function() { document.location = url; }) }); }; var trackEmailClick = function(address_type) { ga('send', 'event', { eventCategory: 'click', eventAction: 'email', eventLabel: address_type }); }; var trackFormSubmit = function(label, method, path, params) { ga('send', 'event', { eventCategory: 'outbound', eventAction: 'click', eventLabel: label, hitCallback: createFunctionWithTimeout(function() { params = params || {}; var form = document.createElement('form'); form.setAttribute('method', method); form.setAttribute('action', path); for (var key in params) { if (params.hasOwnProperty(key)) { var hiddenField = document.createElement('input'); hiddenField.setAttribute('type', 'hidden'); hiddenField.setAttribute('name', key); hiddenField.setAttribute('value', params[key]); form.appendChild(hiddenField); } } document.body.appendChild(form); form.submit(); }) }); }; </script> <script src="https://www.googleoptimize.com/optimize.js?id=OPT-MLMV2BQ"></script> <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-PBJJP4J');</script> <script type="text/javascript"> (function () { const LOG_STYLES = { title: "color: #2563eb; font-weight: bold; font-size: 12px;", success: "color: #059669; font-weight: bold;", error: "color: #dc2626; font-weight: bold;", info: "color: #737373; font-size: 11px;" }; function logEvent(event_type, properties, context = []) { if (!false) return; console.group( `%c[SnowplowAnalytics]: ${event_type} (${new Date().toUTCString()})`, LOG_STYLES.title ); const tableData = [ ...Object.entries(properties).map(([key, value]) => ({ key, value, source: "event" })), ...context.flatMap(ctx => Object.entries(ctx.data).map(([key, value]) => ({ key, value, source: `context: ${ctx.schema}` })) ) ].reduce((acc, {key, value, source}) => { acc[key] = {value, source}; return acc; }, {}); console.table(tableData, ["value", "source"]); console.groupEnd(); } function initializeSnowplow() { try { // https://docs.snowplow.io/docs/sources/trackers/javascript-trackers/web-tracker/quick-start-guide/ // sp.js is called 9e10734c6f18ce57.js ;(function (p, l, o, w, i, n, g) { if (!p[i]) { p.GlobalSnowplowNamespace = p.GlobalSnowplowNamespace || []; p.GlobalSnowplowNamespace.push(i); p[i] = function () { (p[i].q = p[i].q || []).push(arguments) }; p[i].q = p[i].q || []; n = l.createElement(o); g = l.getElementsByTagName(o)[0]; n.async = 1; n.src = w; g.parentNode.insertBefore(n, g) } }(window, document, "script", "/js/9e10734c6f18ce57.js", "snowplow")); window.snowplow('newTracker', 'sp1', 'https://api.canva.com/_spi/ae/snowplow/5f60f4dc-c844-41b5-9da7-ab8d39e5f475', { appId: 'flourish', platform: 'web', cookieDomain: 'flourish.studio', contexts: { webPage: true, session: true, browser: true, }, stateStorageStrategy: 'cookieAndLocalStorage', referrerPolicy: 'no-referrer-when-downgrade', credentials: 'omit', eventMethod: 'post' }); window.snowplow('addPlugin', "https://cdn.jsdelivr.net/npm/@snowplow/browser-plugin-client-hints@latest/dist/index.umd.min.js", ["snowplowClientHints", "ClientHintsPlugin"] ); window.snowplow('addPlugin', "https://cdn.jsdelivr.net/npm/@snowplow/browser-plugin-ga-cookies@latest/dist/index.umd.min.js", ["snowplowGaCookies", "GaCookiesPlugin"], [{ ga4: true, ua: false, ga4MeasurementId: "G-KW52XHYN9H" }] ); window.sp = { trackInteraction: function (properties) { window.snowplow('trackSelfDescribingEvent', { event: { schema: 'iglu:studio.flourish/flourish_interacted/jsonschema/1-0-0', data: properties } }); logEvent('flourish_interacted', properties); }, trackFormInteraction: function (properties) { window.snowplow('trackSelfDescribingEvent', { event: { schema: 'iglu:studio.flourish/flourish_form_interacted/jsonschema/1-0-0', data: properties } }); logEvent('flourish_form_interacted', properties); }, }; // GA Duplicate Events (function () { const trackGAEvent = function (properties) { const eventData = { category: "ga4_event", action: properties.action || properties.event || 'unknown' }; window.snowplow('trackSelfDescribingEvent', { event: { schema: 'iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0', data: { schema: 'iglu:com.google.analytics.measurement-protocol/event/jsonschema/1-0-0', data: eventData } }, context: [{ schema: 'iglu:com.google.analytics.measurement-protocol/hit/jsonschema/1-0-0', data: {type: "event"} }] }); logEvent('ga_duplicator', eventData); }; if (window.dataLayer && Array.isArray(window.dataLayer)) { const originalDataLayerPush = Array.prototype.push; window.dataLayer.push = function (...args) { args.forEach(arg => { if (Array.isArray(arg) && arg[0] === "event") { const [_, eventName, eventParams] = arg; trackGAEvent({ ...eventParams, category: "ga4_event", action: eventName, }); } else if (typeof arg === "object" && arg !== null && "event" in arg) { const {event, ...params} = arg; trackGAEvent({ ...params, category: "ga4_event", action: event, }); } }); return originalDataLayerPush.apply(window.dataLayer, args); }; } const original_gtag = window.gtag; window.gtag = (...args) => { if (original_gtag) { original_gtag.apply(window, args); } const [command, action, parameters] = args; if (command === "set" || command === "consent") { return; } if (command === "event") { trackGAEvent({ ...parameters, category: "ga4_event", action, }); } }; })(); let pageLoadTime = Date.now(); let pageScrollDepth = 0; let scrollTimeout; let isUnloading = false; function trackClosed(action) { const properties = { seconds_on_page: Math.round((Date.now() - pageLoadTime) / 1000).toString(), page_scroll_depth: pageScrollDepth.toString(), action: action }; window.snowplow('trackSelfDescribingEvent', { event: { schema: 'iglu:studio.flourish/flourish_closed/jsonschema/1-0-0', data: properties } }); logEvent('flourish_closed', properties); } function updateScrollDepth() { const html = document.documentElement; const currentScrollDepth = Math.round( (html.scrollTop / (html.scrollHeight - html.clientHeight)) * 100 ); pageScrollDepth = Math.max(pageScrollDepth, currentScrollDepth); } window.addEventListener("scroll", () => { clearTimeout(scrollTimeout); scrollTimeout = setTimeout(updateScrollDepth, 100); }); window.addEventListener("beforeunload", () => { isUnloading = true; trackClosed("window_close"); }); document.addEventListener("visibilitychange", () => { if (document.visibilityState === "hidden" && !isUnloading) { trackClosed("tab_hidden"); } else if (document.visibilityState === "visible") { isUnloading = false; pageLoadTime = Date.now(); window.snowplow('trackPageView'); logEvent('page_view', {url: window.location.pathname}); } }); window.snowplow('trackPageView'); logEvent('page_view', {url: window.location.pathname}); } catch (error) { console.error('%c[SnowplowAnalytics] Error:', LOG_STYLES.error, error); } } window.OptanonWrapper = function () { if (!window.Optanon?.IsAlertBoxClosedAndValid()) return; if (window.OnetrustActiveGroups?.includes('C0002')) { initializeSnowplow(); } }; if (window.OnetrustActiveGroups?.includes('C0002')) { initializeSnowplow(); } })(); </script> <!-- TODO: This is temporary. We should import properly with rollup or remove d3-dependency --> <script src="/js/d3-dispatch.js"></script> <script src="/js/d3-interpolate.js"></script> <script src="/js/d3-selection.js"></script> <script src="/js/d3-timer.js"></script> <script src="/js/d3-transition.js"></script> <link rel="alternate" href="/atom.xml" title="Flourish" type="application/atom+xml"> <link href="/highlight.css?3e9f1d3cf8a99ebe7f3f230bae0e7d41" rel="stylesheet"> <link href="/style.css?20112024" rel="stylesheet"> <meta name="generator" content="Hexo 6.2.0"></head> <body onclick class="is-static"> <noscript> <iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PBJJP4J" height="0" width="0" style="display:none;visibility:hidden"></iframe> </noscript> <script> /** * Safely get the nearest element matching a selector */ const findClosestElement = (element, selector) => { if (!element || !element.closest) { return null; } try { return element.closest(selector); } catch (error) { console.warn('Error finding closest element:', error); return null; } } /** * Get data from the closest parent with specified attribute */ const getInheritedData = (element, attribute) => { try { const dataAttr = `data-${attribute}`; let current = element; while (current && current.nodeType === Node.ELEMENT_NODE) { if (current.hasAttribute(dataAttr)) { return current.getAttribute(dataAttr); } current = current.parentElement; } return null; } catch (error) { console.warn('Failed to get inherited data:', error); return null; } } /** * Initialize auto-tracking */ const initAutoTracking = () => { try { // Track clicks document.addEventListener('click', (e) => { if (!e?.target instanceof Element) return; const element = findClosestElement(e.target, '[data-track]'); if (!element) return; const trackType = element.dataset.track; if (trackType === 'true') { FlourishAnalytics.track(element); } else { FlourishAnalytics.track(element, { section_group: trackType }); } }); } catch (error) { console.warn('Failed to initialize auto-tracking:', error); } }; const initializeTracking = () => { initAutoTracking(); }; /** * Get all tracking data for an element */ const getTrackingData = (element) => { try { // Ensure we're working with a DOM element if (!(element instanceof Element)) { console.warn('Invalid element provided to getTrackingData'); return {}; } // Derive component name let component = element.dataset.component; if (!component) { if (element.tagName === 'A' && element.href) { // For links, use the last URL segment const path = element.getAttribute('href').replace(/\/$/, ''); const lastPart = path.split('/').pop(); component = lastPart || 'page'; } else if (element.tagName === 'BUTTON') { // For buttons, use text content or fallback const text = element.textContent?.trim().toLowerCase().replace(/[^a-z0-9]+/g, '_'); component = text || 'button'; } else { // Fallback for other elements component = element.id || 'interaction'; } } // Find closest container with section info let section = element.dataset.section; if (!section) { // Look for standard section containers const sectionContainer = element.closest('[class*="section"],[class*="container"],[id*="section"],[id*="container"]'); if (sectionContainer) { section = sectionContainer.id || sectionContainer.className.split(' ')[0] || 'main'; } else { section = 'main'; } } return { section: section, section_id: element.dataset.sectionId || getInheritedData(element, 'section-id'), section_group: element.dataset.sectionGroup || getInheritedData(element, 'section-group'), component: component, component_id: element.dataset.componentId || getInheritedData(element, 'component-id') }; } catch (error) { console.warn('Failed to get tracking data:', error); return {}; } } window.FlourishAnalytics = { // Track an interaction track: function (element, overrides = {}) { try { if (!window?.sp?.trackInteraction) { console.warn('Analytics tracking is not available'); return; } // Ensure we have a valid element if (!(element instanceof Element)) { console.warn('Invalid element provided to track'); return; } const params = { ...getTrackingData(element), interaction_type: overrides.interaction_type || 'click', ...overrides }; if (params.section && params.component) { window.sp.trackInteraction(params); } else { console.warn('Missing required tracking fields:', { section: params.section, component: params.component }); } } catch (error) { console.warn('Failed to track interaction:', error); } }, // For general clicks/interactions trackClick: function (element, options = {}) { this.track(element, { interaction_type: 'click', ...options }); }, // For form interactions trackForm: function (form, action = 'submit', options = {}) { if (!(form instanceof Element)) return; const formData = { form_id: form.id || undefined, form_name: form.getAttribute('name') || undefined, form_action: action, ...options }; window.sp.trackFormInteraction(formData); }, }; // Initialize auto-tracking initializeTracking(); </script> <!-- onclick is used to make hover states work on Safari --> <div class="row header not-logged-in" data-section="header"> <div class="row-inner"> <a href="/" class="logo clickable menu-item" data-track="click" data-component="logo"> <img data-target="home" id="logo" src="/images/Flourish_Logo_Black_small.png" alt="Flourish logo"> </a> <div class="menu-holder"> <div class="menu desktop-nav"> <div class="dropdown-menu sub-menu" id="main-menu"> <div class="dropdown-menu-item-wrapper"> <a class="dropdown-menu-item" href="/" id="blog-menu-item" data-track="click" data-component="blog_home"> <h1 class="menu-item">Data visualization and storytelling</h1> </a> </div> </div> <div id="account-menu"> <a class="btn log-in-link" target="_blank" rel="noopener" href="https://app.flourish.studio/login" data-track="click" data-component="login">Log in</a> <a class="btn sign-up-link" target="_blank" rel="noopener" href="https://app.flourish.studio/register" data-track="click" data-component="signup">Sign up</a> </div> </div> <div class="mobile-nav"> <div id="account-menu-blog"> <a class="btn sign-up-link" target="_blank" rel="noopener" href="https://app.flourish.studio/register" data-track="click" data-component="signup_mobile">Sign up</a> </div> </div> </div> </div> </div> <div class="content"> <div class="row static"> <div class="page page-" id="page-blog"> <div class="page-content-container"> <div class="row-inner"> <div class="social-buttons side"> <div class="social-button facebook round"><img class="social-icon" src="/images/icons/facebook-logo.svg"></div> <div class="social-button twitter round"><img class="social-icon" src="/images/icons/x-logo-black.svg"></div> <div class="social-button linkedin round"><img class="social-icon" src="/images/icons/linkedin-logo-black.svg"></div> <div class="social-button email round"><img class="social-icon" src="/images/icons/envelope-icon.svg"></div> </div> <div class="page-content-paragraphs"> <article class="article article-type-post"> <div class="article-inner"> <header class="article-header"> <h1 class="article-title" itemprop="name"> Unlock smarter decisions and enhance insights with live data visualizations </h1> <h2 class="subtitle"> Explore the benefits of creating real-time charts and maps from CSVs and Google Sheets </h2> <div class="article-meta text-width"> Last updated on <strong><time datetime="2024-03-12T00:00:00.000Z" itemprop="dateUpdated">12 March 2024</time></strong> </div> <div class="social-buttons top text-width"> <div class="social-button facebook round"><img class="social-icon" src="/images/icons/facebook-logo.svg"></div> <div class="social-button twitter round"><img class="social-icon" src="/images/icons/x-logo-black.svg"></i></div> <div class="social-button linkedin round"><img class="social-icon" src="/images/icons/linkedin-logo-black.svg"></div> <div class="social-button email round"><img class="social-icon" src="/images/icons/envelope-icon.svg"></div> </div> </header> <div class="article-entry"> <p>Struggling to keep your visualizations up to date? With Flourish, <strong>you can connect directly to an online CSV file or Google Sheet</strong>, instead of manually uploading your data to our platform. Whether it’s a file on a company server, a government statistical bulletin, or real-time election results, gone are the days of manual uploads! With Flourish, your charts and maps evolve as your data does.</p> <figure class="wide"> <div class="flourish-embed flourish-map" data-src="visualisation/16562635?654906"><script src="https://public.flourish.studio/resources/embed.js" data-ot-ignore></script></div> </figure> <figure class="text-width"><a target="_blank" rel="noopener" href="https://app.flourish.studio/templates#template-time-map"><div class="btn cta">Create your own »</div></a></figure> <h2 id="How-does-it-work"><a href="#How-does-it-work" class="headerlink" title="How does it work?"></a>How does it work?</h2><p>Live-updating data visualizations are directly linked to an external data source, such as a public CSV file. Rather than uploading datasets to Flourish manually, this technique enables <strong>automatic syncing.</strong> As a result, whenever the linked data source, like a Google sheet, is updated, the corresponding Flourish chart will also update in real time.</p> <figure class="wide"> <img src="https://public.flourish.studio/uploads/654906/f7db5308-eae7-40e0-8dd5-949b594614bb.png" alt="Flourish Data tab"> <p class="caption">Once imported, your data sheet will display greyed out to reflect that it is linked to a remote source so can’t be edited.</p> </figure> <h2 id="The-advantages-of-visualizing-data-as-it-happens"><a href="#The-advantages-of-visualizing-data-as-it-happens" class="headerlink" title="The advantages of visualizing data as it happens"></a>The advantages of visualizing data as it happens</h2><p>Real-time data visualization offers a wide range of benefits across various sectors. For example, it enables journalists to report on the latest developments promptly, allows sales teams to monitor and react to live sales data effectively, and assists researchers in monitoring real-time shifts in areas such as climate change.</p> <h3 id="1-Easily-maintain-accurate-data"><a href="#1-Easily-maintain-accurate-data" class="headerlink" title="1. Easily maintain accurate data"></a>1. Easily maintain accurate data</h3><figure class="small right"> <img src="https://public.flourish.studio/uploads/654906/9ff3094b-2359-4593-81f7-cffa2f1ac4b8.png" alt="Export and publish modal popup where users can adjust the auto-republishing interval"> </figure> <p>Flourish’s live data function is a game-changer in ensuring your data remains up-to-date. This is particularly beneficial under tight deadlines, such as on <a href="https://flourish.studio/resources/elections/">election night</a>, where manual updates would be not only time-consuming but also potentially impossible.</p> <p>Instead, this streamlined, automated process <strong>saves time, ensures accuracy,</strong> and <strong>reduces the chances of human error</strong>.</p> <p>Flourish also offers the flexibility to customize the <a href="#auto-updates">frequency of your chart updates</a>. Depending on your account tier, you can choose to <strong>republish data as often as every few minutes</strong>, tailoring this feature to your unique needs. <a href="https://flourish.studio/talk-to-us/">Our team is on hand</a> to explain further how this can positively impact your workflow and efficiency.</p> <h3 id="2-Incorporate-more-complex-data-wrangling"><a href="#2-Incorporate-more-complex-data-wrangling" class="headerlink" title="2. Incorporate more complex data wrangling"></a>2. Incorporate more complex data wrangling</h3><p>Unlike the basic method of just uploading or pasting data into Flourish, linking your visualizations to a Google Sheet allows you to <strong>leverage complex formulas</strong> directly where your data lives, enhancing your data analysis with advanced calculations.</p> <p>Besides, the live data feature is incredibly useful for projects that need collaborative spreadsheet editing or a detailed version history. It means you can collaborate in real-time and track changes easily, making your Flourish project not only more dynamic but also more transparent.</p> <h3 id="3-Improve-decision-making"><a href="#3-Improve-decision-making" class="headerlink" title="3. Improve decision-making"></a>3. Improve decision-making</h3><p>For businesses, access to real-time data leads to making more informed decisions. Whether it’s tracking a marketing campaign’s success or monitoring website traffic spikes, immediate insights lead to timely actions.</p> <p>AdKaora, a leading proximity marketing agency, <a href="https://flourish.studio/blog/adkaora-customer-story/">harnessed the capabilities of Flourish</a> to streamline and customize their reporting. This innovation allowed their clients to access up-to-the-minute data whenever needed. To cater to their specific requirement of very frequent updates (every minute), AdKaora <a target="_blank" rel="noopener" href="https://help.flourish.studio/article/163-how-to-connect-to-live-data-sources#api">utilized the Flourish API</a>, which effectively facilitated the creation of dynamic, constantly updating charts for their clients.</p> <p>However, for scenarios where less frequent updates are sufficient (such as hourly), <strong>the live data function stands as an equally robust solution</strong>. It offers a powerful and adaptable approach to real-time data visualization, equipping clients with a first-rate tool for gaining immediate insights.</p> <h2 id="Getting-started"><a href="#Getting-started" class="headerlink" title="Getting started"></a>Getting started</h2><figure class="small right"> <img src="https://public.flourish.studio/uploads/654906/60f63c2a-8883-4f53-b0e5-2c80b237a49b.png" alt="The Upload data file Flourish button which can be found in the Data tab"> </figure> <p>The powerful live data feature is available for users on our <a href="https://flourish.studio/pricing/">business plans</a>.</p> <p>Users with access to the feature can find it in the dropdown next to the <strong>Upload data file</strong> button in the <strong>Data tab</strong>. Choose <strong>Import from URL</strong>, click the button, and then enter the URL of a <a target="_blank" rel="noopener" href="https://help.flourish.studio/article/165-how-to-pull-through-data-from-a-google-sheet">publicly accessible CSV file</a>.</p> <p>Once imported, your datasheet will display greyed out to reflect that it is linked to a remote source so can’t be edited. However, you can still scroll the sheet to browse its contents and select the right columns. You can also “unlink” the data at any time to convert it to a normal editable Flourish data sheet.</p> <iframe width="560" height="394" src="https://www.youtube.com/embed/psWWkXJvg4A?si=YEKPIFRGka4TlUzV title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> <h2 id="auto-updates">Seamless automatic updates with Flourish</h2> <p>When you publish a visualization or story based on a live data source, you can optionally set Flourish to check the data regularly and <strong>republish the graphic automatically</strong> if there has been a change. The maximum republishing frequency depends on your account tier.</p> <p>The best thing about this design is that your underlying data source only gets “hit” each time Flourish checks for changes, not each time a viewer looks at the chart. That means you can publish <strong>live graphics for large audiences</strong> without worrying that the underlying data source might not be able to cope with lots of traffic. And if the data source ever goes offline, so Flourish can’t access it, the published graphic won’t break.</p> <p>Ready to bring your data to life? Dive into Flourish and start creating dynamic visualizations today!</p> <figure class="wide"> <div class="flourish-embed flourish-cards" data-src="visualisation/16150396?64721"><script src="https://public.flourish.studio/resources/embed.js" data-ot-ignore></script></div> </figure> </div> <footer class="article-footer"> <div class="article-newsletter"> <h3><span class="enjoyed">Enjoyed this blog post?</span></span> <span>Get the newsletter!</h3> <form action="https://studio.us13.list-manage.com/subscribe/post?u=a41ac2fe0fc0d1ab52f5df1b9&id=190848d56d" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate> <input type="email" style="display: inline-block;" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required> <!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups--> <div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_a41ac2fe0fc0d1ab52f5df1b9_190848d56d" tabindex="-1" value=""></div> <div class="clear" style="display: inline-block;"><input type="submit" value="Subscribe" name="subscribe" id="mc-embedded-subscribe" class="btn_mailchimp"></div> </form> <div class="smallprint" style="line-height: 1.4em;"> By clicking "Subscribe", you agree to receive news and updates about Flourish products and services (unsubscribe any time). Read our <a href="https://flourish.studio/privacy/" target="_blank">Privacy Policy</a>. Newsletter powered by Mailchimp (<a href="https://mailchimp.com/legal/" target="_blank">privacy</a>).</div> <!-- <div class="smallprint">Powered by Mailchimp (<a target="_blank" rel="noopener" href="https://mailchimp.com/legal/">privacy</a>).</div> --> </div> <nav id="article-nav"> <a href="/blog/3d-pointmap-regions/" id="article-nav-newer" class="article-nav-link-wrap"> <strong class="article-nav-caption">Next <i class="fa fa-arrow-right"></i></strong> <div class="article-nav-title"> You can now add regions to your high-performance WebGL-based data maps </div> </a> <a href="/blog/heatmap-template/" id="article-nav-older" class="article-nav-link-wrap"> <strong class="article-nav-caption"><i class="fa fa-arrow-left"></i> Previous</strong> <div class="article-nav-title">Unveiling patterns: how to master interactive heatmaps with Flourish 🔥</div> </a> </nav> </footer> </div> </article> </div> <div class="bottom-bar"> <div class="text-width bottom-bar-inner"> <a href="/blog" class="blog-home">≪ Blog home</a> <span class="social-buttons bottom"> <div class="clickable social-button facebook"><img class="social-icon" src="/images/icons/facebook-logo.svg"></div> <div class="clickable social-button twitter"><img class="social-icon" src="/images/icons/x-logo-black.svg"></div> <div class="clickable social-button linkedin"><img class="social-icon" src="/images/icons/linkedin-logo-black.svg"></div> <div class="clickable social-button email"><img class="social-icon" src="/images/icons/envelope-icon.svg"></div> </span> </div> </div> </div> </div> </div> </div> </div> <div class="row footer" data-section="footer"> <div class="row-contents"> <div class="row-inner"> <div class="footer-container"> <!-- Company section --> <div class="footer-section company" data-section-group="company"> <h4>Company</h4> <ul> <li><a href="/company" data-track="click" data-component="about">About us</a></li> <li><a target="_blank" rel="noopener" href="https://www.lifeatcanva.com/en/locations/united-kingdom/" data-track="click" data-component="careers">Careers</a></li> <li><a href="/security" data-track="click">Security</a></li> <li><a href="/pricing" data-track="click">Pricing</a></li> <li><a href="/terms" data-track="click">Terms</a></li> <li><a href="/privacy" data-track="click">Privacy policy</a></li> <li><a href="/resources/faq" data-track="click">FAQs</a></li> </ul> </div> <!-- Explore section --> <div class="footer-section explore" data-section-group="explore"> <h4>Explore</h4> <ul> <li><a href="/examples" data-track="click">Examples</a></li> <li><a href="/resources/elections" data-track="click">Elections & polls</a></li> <li><a href="/resources/sports" data-track="click">Sports & competitions</a></li> <li><a href="/visualisations/maps" data-track="click">Interactive maps</a></li> <li><a href="/resources/visualize-survey-data" data-track="click" data-component="survey">Survey responses</a></li> <li><a href="/visualisations/scrollytelling" data-track="click">Scrollytelling</a></li> <li><a href="/visualisations" data-track="click">Chart guides</a></li> <li><a href="/blog" data-track="click">Blog</a></li> </ul> </div> <!-- Solutions section --> <div class="footer-section solutions" data-section-group="solutions"> <h4>Solutions</h4> <ul> <li><a href="/solutions/financial-services" data-track="click" data-component="financial">Financial services</a></li> <li><a href="/solutions/professional-services" data-track="click" data-component="professional">Professional services</a></li> <li><a href="/solutions/newsrooms" data-track="click">Newsrooms</a></li> <li><a href="/solutions/marketing" data-track="click">Marketing</a></li> <li><a href="/solutions/not-for-profit" data-track="click" data-component="nonprofit">Nonprofits</a></li> <li><a href="/solutions/government" data-track="click">Government</a></li> <li><a href="/solutions/education" data-track="click">Education</a></li> </ul> </div> <!-- Resources section --> <div class="footer-section resources" data-section-group="resources"> <h4>Resources</h4> <ul> <li><a href="/whats-new" data-track="click" data-component="whats_new">What's new</a></li> <li><a target="_blank" rel="noopener" href="https://help.flourish.studio/" data-track="click" data-component="help_docs" onclick="FlourishAnalytics.trackOutbound('https://help.flourish.studio/', this)">Help docs</a></li> <li><a href="/resources/training" data-track="click">Training</a></li> <li><a href="/resources/webinar" data-track="click">Webinars</a></li> <li><a href="/resources/datasets" data-track="click">Datasets</a></li> <li><a href="/accessibility" data-track="click">Accessibility</a></li> <li><a href="/experts" data-track="click">Experts network</a></li> <li><a href="https://flourish.studio/developers" data-track="click" onclick="FlourishAnalytics.trackOutbound('https://flourish.studio/developers', this)">For developers</a></li> </ul> </div> <!-- Company info --> <div class="footer-section company-info"> <h4>Flourish</h4> <p class="break-text">Flourish is a registered trademark of <span>Canva UK Operations Ltd, UK</span></p> <p>company 08825531</p> <p>33 Hoxton Square</p> <p>London N1 6NN</p> </div> </div> </div> <!-- Stay in touch section --> <div class="footer-container-black"> <div class="row-inner"> <div class="footer-section stay-in-touch"> <h4>Stay in touch</h4> <div class="footer-row-items"> <div class="btn-social-container"> <a href="/newsletter" data-track="click" data-component="newsletter"> <div class="footer-btn">Subscribe to our newsletter</div> </a> <div class="social-links" data-section-group="social"> <a target="_blank" rel="noopener" href="https://x.com/f_l_o_u_r_i_s_h" aria-label="X" data-track="click" data-component="x"> <img class="icon" src="/images/icons/x-logo.svg"> </a> <a target="_blank" rel="noopener" href="https://www.instagram.com/madewithflourish/" aria-label="instagram" data-track="click" data-component="instagram"> <img class="icon" src="/images/icons/instagram-logo.svg"> </a> <a target="_blank" rel="noopener" href="https://www.linkedin.com/company/f-l-o-u-r-i-s-h" aria-label="LinkedIn" data-track="click" data-component="linkedin"> <img class="icon" src="/images/icons/linkedin-logo.svg"> </a> <a target="_blank" rel="noopener" href="https://www.youtube.com/channel/UCWTf4OgEH_MiDvfmjPdkTxg" aria-label="YouTube" data-track="click" data-component="youtube"> <img class="icon" src="/images/icons/youtube-logo.svg"> </a> </div> </div> <div class="footer-credit"> <p>© 2024 Flourish, a Canva UK Operations Limited brand. All rights reserved.</p> </div> </div> </div> </div> </div> </div> </div> <script src="/js/script.js?ddcb49de92eb2662628cec21b9bfeefd"></script> <script src="/js/store-inbound-fields.js"></script> <script src="/js/blog-post.js"></script> </body> </html>