@tidepool/viz
Version:
Tidepool data visualization for diabetes device data.
753 lines (356 loc) • 27.3 kB
HTML
<html lang="" >
<head>
<meta charset="UTF-8">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>Trends view · GitBook</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="description" content="">
<meta name="generator" content="GitBook 3.2.2">
<link rel="stylesheet" href="../../gitbook/style.css">
<link rel="stylesheet" href="../../gitbook/gitbook-plugin-highlight/website.css">
<link rel="stylesheet" href="../../gitbook/gitbook-plugin-search/search.css">
<link rel="stylesheet" href="../../gitbook/gitbook-plugin-fontsettings/website.css">
<meta name="HandheldFriendly" content="true"/>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="../../gitbook/images/apple-touch-icon-precomposed-152.png">
<link rel="shortcut icon" href="../../gitbook/images/favicon.ico" type="image/x-icon">
<link rel="next" href="../Storybook.html" />
<link rel="prev" href="../../src/components/settings/" />
</head>
<body>
<div class="book">
<div class="book-summary">
<div id="book-search-input" role="search">
<input type="text" placeholder="Type to search" />
</div>
<nav role="navigation">
<ul class="summary">
<li class="chapter " data-level="1.1" data-path="../../">
<a href="../../">
Introduction
</a>
</li>
<li class="chapter " data-level="1.2" data-path="../StartHere.html">
<a href="../StartHere.html">
@tidepool/viz developer guide
</a>
<ul class="articles">
<li class="chapter " data-level="1.2.1" data-path="../Background.html">
<a href="../Background.html">
background
</a>
</li>
<li class="chapter " data-level="1.2.2" data-path="../FeatureOverview.html">
<a href="../FeatureOverview.html">
overview of features
</a>
</li>
<li class="chapter " data-level="1.2.3" data-path="../Architecture.html">
<a href="../Architecture.html">
planned architecture
</a>
</li>
<li class="chapter " data-level="1.2.4" data-path="../DirectoryStructure.html">
<a href="../DirectoryStructure.html">
app & directory structure
</a>
</li>
<li class="chapter " data-level="1.2.5" data-path="../CodeStyle.html">
<a href="../CodeStyle.html">
code style
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="1.3" data-path="./">
<a href="./">
per-view documentation
</a>
<ul class="articles">
<li class="chapter " data-level="1.3.1" data-path="../../src/components/settings/">
<a href="../../src/components/settings/">
Device Settings view
</a>
</li>
<li class="chapter active" data-level="1.3.2" data-path="Trends.html">
<a href="Trends.html">
Trends view
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="1.4" data-path="../Storybook.html">
<a href="../Storybook.html">
use of React Storybook
</a>
</li>
<li class="chapter " data-level="1.5" data-path="../deps/">
<a href="../deps/">
usage of dependencies
</a>
<ul class="articles">
<li class="chapter " data-level="1.5.1" data-path="../deps/D3.html">
<a href="../deps/D3.html">
D3
</a>
</li>
<li class="chapter " data-level="1.5.2" data-path="../deps/GSAP.html">
<a href="../deps/GSAP.html">
GSAP
</a>
</li>
<li class="chapter " data-level="1.5.3" data-path="../deps/Moment.html">
<a href="../deps/Moment.html">
Moment
</a>
</li>
<li class="chapter " data-level="1.5.4" data-path="../deps/React.html">
<a href="../deps/React.html">
React
</a>
</li>
<li class="chapter " data-level="1.5.5" data-path="../deps/ReactMotion.html">
<a href="../deps/ReactMotion.html">
React Motion
</a>
</li>
<li class="chapter " data-level="1.5.6" data-path="../deps/Redux.html">
<a href="../deps/Redux.html">
Redux
</a>
</li>
<li class="chapter " data-level="1.5.7" data-path="../deps/Webpack.html">
<a href="../deps/Webpack.html">
webpack
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="1.6" data-path="../../src/utils/">
<a href="../../src/utils/">
utilities
</a>
<ul class="articles">
<li class="chapter " data-level="1.6.1" data-path="../../src/utils/apidocs/">
<a href="../../src/utils/apidocs/">
API docs for utilities
</a>
<ul class="articles">
<li class="chapter " data-level="1.6.1.1" data-path="../../src/utils/apidocs/basal.html">
<a href="../../src/utils/apidocs/basal.html">
basal
</a>
</li>
<li class="chapter " data-level="1.6.1.2" data-path="../../src/utils/apidocs/bloodglucose.html">
<a href="../../src/utils/apidocs/bloodglucose.html">
blood glucose
</a>
</li>
<li class="chapter " data-level="1.6.1.3" data-path="../../src/utils/apidocs/bolus.html">
<a href="../../src/utils/apidocs/bolus.html">
bolus
</a>
</li>
<li class="chapter " data-level="1.6.1.4" data-path="../../src/utils/apidocs/datetime.html">
<a href="../../src/utils/apidocs/datetime.html">
datetime
</a>
</li>
<li class="chapter " data-level="1.6.1.5" data-path="../../src/utils/apidocs/format.html">
<a href="../../src/utils/apidocs/format.html">
format
</a>
</li>
<li class="chapter " data-level="1.6.1.6" data-path="../../src/utils/apidocs/misc.html">
<a href="../../src/utils/apidocs/misc.html">
misc
</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="chapter " data-level="1.7" data-path="../misc/">
<a href="../misc/">
misc
</a>
<ul class="articles">
<li class="chapter " data-level="1.7.1" data-path="../misc/CommonProps.html">
<a href="../misc/CommonProps.html">
Common props
</a>
</li>
<li class="chapter " data-level="1.7.2" data-path="../misc/Docs.html">
<a href="../misc/Docs.html">
Docs setup & publishing
</a>
</li>
<li class="chapter " data-level="1.7.3" data-path="../misc/TimeRenderingModes.html">
<a href="../misc/TimeRenderingModes.html">
Time-rendering modes
</a>
</li>
</ul>
</li>
<li class="divider"></li>
<li>
<a href="https://www.gitbook.com" target="blank" class="gitbook-link">
Published with GitBook
</a>
</li>
</ul>
</nav>
</div>
<div class="book-body">
<div class="body-inner">
<div class="book-header" role="navigation">
<!-- Title -->
<h1>
<i class="fa fa-circle-o-notch fa-spin"></i>
<a href="../.." >Trends view</a>
</h1>
</div>
<div class="page-wrapper" tabindex="-1" role="main">
<div class="page-inner">
<div id="book-search-results">
<div class="search-noresults">
<section class="normal markdown-section">
<h2 id="trends-view">Trends view</h2>
<p>Table of contents:</p>
<ul>
<li><a href="#user-experience">user experience</a></li>
<li><a href="#architecture">architecture</a><ul>
<li><a href="#component-hierarchy">component hierarchy</a></li>
</ul>
</li>
<li><a href="#layout">layout</a></li>
<li><a href="#tech-debt">tech debt</a></li>
</ul>
<h3 id="👱🏾-user-experience">👱🏾 User experience</h3>
<p>There are two versions of the Trends view, one for displaying trend information based on fingerstick blood glucose data and the other for displaying trend information based on CGM data. The BGM version was developed first, and the CGM version is a more recent addition. A 14-day span of data is the default for this view, although the user can toggle to 7 days or 28 days using selectors displayed in the upper left corner of the display. (In the upper right of the display, the user can toggle days of the week such as Monday, Tuesday, etc. or weekdays vs. weekends off and on.) Both the CGM and CGM versions group all data in the selected span of time by time of day in an effort to show how blood glucose varies for the PwD by time of day. On the BGM version where the data is quite sparse, the data is grouped into three-hour "bins," and on the CGM version thirty-minute bins are used.</p>
<p><strong>CGM Trends as of March, 2017</strong></p>
<p><img src="images/cgm_trends.png" alt="CGM Trends"></p>
<p><strong>BGM Trends as of March, 2017</strong></p>
<p><img src="images/bgm_trends.png" alt="BGM Trends"></p>
<p>Like on the Daily view, hovering over various items in the display will produce a tooltip with more information. In addition, hovering on a segment of a time slice on the CGM version will expose all of the CGM daily sensor traces that intersect with that segment after a short delay (i.e., the pointer must remain on the same segment for a threshold of milliseconds before the exposure of traces is triggered).</p>
<p><strong>BGM Date Line Hover</strong></p>
<p><img src="images/bgm_trends_date_line_hover.png" alt="BGM Date Line Hover"></p>
<p><strong>BGM Individual <code>smbg</code> Hover</strong></p>
<p><img src="images/bgm_trends_smbg_hover.png" alt="BGM Individual `smbg` Hover"></p>
<p><strong>BGM Range Box Hover</strong></p>
<p><img src="images/bgm_trends_range_hover.png" alt="BGM Range Box Hover"></p>
<p><strong>CGM Segment Hover</strong></p>
<p><img src="images/cgm_trends_segment_hover.gif" alt="CGM Segment Hover"></p>
<p><strong>CGM Segment Hover + Hold</strong></p>
<p><img src="images/cgm_trends_segment_hover_hold.png" alt="CGM Segment Hover + Hold"></p>
<p><strong>CGM Segment Hover + Hold on <code>cbg</code></strong></p>
<p><img src="images/cgm_trends_segment_hover_hold_cbg.png" alt="CGM Segment Hover + Hold on `cbg`"></p>
<h3 id="🏛️-architecture">🏛️ Architecture</h3>
<p>Currently only the data visualization itself for the BGM and CGM versions of the Trends view are implemented in this repository: code in blip is still being used for the 7, 14, and 28 days domain size selectors, the day of the week selectors, and of course the visualization sub-header that provides navigation between the views and along the datetime dimension. This makes the interface(s) between the blip and viz code a bit messier than they should be.</p>
<p><img src="images/trends_code_locations.png" alt="Trends view locations of code for elements"></p>
<h4 id="component-hierarchy">Component hierarchy</h4>
<p><strong>CGM Trends</strong></p>
<pre><code>└── PatientData (Redux-connected)
└── Trends
├── TidelineHeader
├── TrendsSubNav
├── <div className="patient-data-content">
│ ├── <div id="tidelineContainer">
│ │ └── TrendsContainer
│ │ └── TrendsSVGContainer (wrapped in DimensionsHOC)
│ │ ├── Background
│ │ ├── XAxisLabels
│ │ ├── XAxisTicks
│ │ ├── YAxisLabels
│ │ ├── <g id="cbgTrends">
│ │ │ ├── CBGSlicesContainer
│ │ │ │ └── <g id="cbgSlices">{48 CBGSliceAnimated, each wrapped in WithDefault HOC}</g>
│ │ │ └── CBGDateTracesAnimationContainer
│ │ │ └── ReactTransitionGroupPlus
│ │ │ └── <g id="cbgDateTraces">{n CBGDateTraceAnimated where n is number of exposed CGM sensor traces}</g>
│ │ └── TargetRangeLines
│ ├── CBGDateTraceLabel
│ └── FocusedRangeLabels
└── TidelineFooter
</code></pre><p><strong>BGM Trends</strong></p>
<pre><code>└── PatientData (Redux-connected)
└── Trends
├── TidelineHeader
├── TrendsSubNav
├── <div className="patient-data-content">
│ ├── <div id="tidelineContainer">
│ │ └── TrendsContainer
│ │ └── TrendsSVGContainer (wrapped in DimensionsHOC)
│ │ ├── Background
│ │ ├── XAxisLabels
│ │ ├── XAxisTicks
│ │ ├── YAxisLabels
│ │ ├── <g id="smbgTrends">
│ │ │ ├── SMBGRangeAvgContainer (for range behind smbgs)
│ │ │ │ └── <g className="smbgAggContainer">{up to 8 SMBGRangeAnimated (per default 3-hr binning), each wrapped in WithDefault}</g>
│ │ │ ├── SMBGsByDateContainer
│ │ │ │ └── <g id="smbgsByDateContainer">{up to n each of SMBGDateLineAnimated and SMBGDatePointsAnimated where n is # of days in view; all of these components are Redux-connected}</g>
│ │ │ │ └── <g id="">
│ │ │ └── SMBGRangeAvgContainer (for avg in front of smbgs)
│ │ │ │ └── <g className="smbgAggContainer">{up to 8 SMBGMeanAnimated (per default 3-hr binning), each wrapped in WithDefault}</g>
│ │ └── TargetRangeLines
│ └── FocusedRangeLabels
└── TidelineFooter
</code></pre><h3 id="📐-layout">📐 Layout</h3>
<p>The variables involved in the layout of the data display inside the Trends view—that is, the code for Trends view contained in this repository—are as follows, all originating in the <code>TrendsSVGContainer</code>:</p>
<ul>
<li><code>containerHeight</code> and <code>containerWidth</code> are the dimensions of the <code><div id="tidelineContainer"></code> that the data portion of every view is rendered within. These are provided on <code>TrendsSVGContainer</code> as props via the <code>Dimensions</code> higher-order component (HOC) that wraps the SVG container. This <code>Dimensions</code> HOC is an external dependency from the <a href="https://github.com/digidem/react-dimensions" title="GitHub: react-dimensions" target="_blank"><code>react-dimensions</code></a>.</li>
<li>The <code>MARGINS</code> (a constant of <code>top</code>, <code>bottom</code>, <code>left</code>, and <code>right</code> properties) are the space outside the data display area (gray box) that provide padding around the data display area and space for the x- and y-axis ticks and labels.</li>
<li>The <code>BUMPERS</code> (a constant of <code>top</code> and <code>bottom</code> properties) are the internal padding in the data display area.</li>
</ul>
<p>Altogether, in diagram form (though <strong>not to scale</strong>):</p>
<p><img src="images/tidelineContainer@2x.png" alt="Trends layout" title="Trends layout"></p>
<h3 id="💣-tech-debt">💣 Tech Debt</h3>
<ul>
<li>Because of where they need to be rendered in the component hierarchy, the hover tooltip component(s) are currently being rendered in blip, and so as an expedient way to share the hover state between the viz code and the blip code, we are using Redux actions to represent the hover focus on element(s). Since hover state is <strong>not</strong> the kind of state that it makes sense to persist when a user navigates away from the visualization part of the app before coming back, the Redux store is not the appropriate place to store this state. Rather, this state should probably be contained in the React component state of a high-level container component in Trends.</li>
<li>When you hover a date line on the smbg side of Trends, instead of properly pulling the line to the top we just render a second version of the line on top.</li>
</ul>
<h3 id="🚀-the-future">🚀 The Future</h3>
<p>At present the <code><div id="tidelineContainer"></code> is given a fixed size via blip's styling, but as we introduce responsiveness in blip, we will be able to leverage the behavior of the <code>Dimensions</code> HOC to make the dataviz responsive. <code>Dimensions</code> will update the <code>containerHeight</code> and <code>containerWidth</code> props on <code>TrendsSVGContainer</code> on window resize, and then by implementing a <code>componentWillReceiveProps</code> on <code>TrendsSVGContainer</code> we will be able to adjust the dimensions of the rendered SVG and the ranges of the x and y scales created with D3 to respond to the new viewport size.</p>
</section>
</div>
<div class="search-results">
<div class="has-results">
<h1 class="search-results-title"><span class='search-results-count'></span> results matching "<span class='search-query'></span>"</h1>
<ul class="search-results-list"></ul>
</div>
<div class="no-results">
<h1 class="search-results-title">No results matching "<span class='search-query'></span>"</h1>
</div>
</div>
</div>
</div>
</div>
</div>
<a href="../../src/components/settings/" class="navigation navigation-prev " aria-label="Previous page: Device Settings view">
<i class="fa fa-angle-left"></i>
</a>
<a href="../Storybook.html" class="navigation navigation-next " aria-label="Next page: use of React Storybook">
<i class="fa fa-angle-right"></i>
</a>
</div>
<script>
var gitbook = gitbook || [];
gitbook.push(function() {
gitbook.page.hasChanged({"page":{"title":"Trends view","level":"1.3.2","depth":2,"next":{"title":"use of React Storybook","level":"1.4","depth":1,"path":"docs/Storybook.md","ref":"docs/Storybook.md","articles":[]},"previous":{"title":"Device Settings view","level":"1.3.1","depth":2,"path":"src/components/settings/README.md","ref":"src/components/settings/README.md","articles":[]},"dir":"ltr"},"config":{"gitbook":"*","theme":"default","variables":{},"plugins":[],"pluginsConfig":{"highlight":{},"search":{},"lunr":{"maxIndexSize":1000000,"ignoreSpecialCharacters":false},"sharing":{"facebook":true,"twitter":true,"google":false,"weibo":false,"instapaper":false,"vk":false,"all":["facebook","google","twitter","weibo","instapaper"]},"fontsettings":{"theme":"white","family":"sans","size":2},"theme-default":{"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"showLevel":false}},"structure":{"langs":"LANGS.md","readme":"README.md","glossary":"GLOSSARY.md","summary":"SUMMARY.md"},"pdf":{"pageNumbers":true,"fontSize":12,"fontFamily":"Arial","paperSize":"a4","chapterMark":"pagebreak","pageBreaksBefore":"/","margin":{"right":62,"left":62,"top":56,"bottom":56}},"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"}},"file":{"path":"docs/views/Trends.md","mtime":"2017-05-23T17:51:07.000Z","type":"markdown"},"gitbook":{"version":"3.2.2","time":"2017-05-31T15:26:30.892Z"},"basePath":"../..","book":{"language":""}});
});
</script>
</div>
<script src="../../gitbook/gitbook.js"></script>
<script src="../../gitbook/theme.js"></script>
<script src="../../gitbook/gitbook-plugin-search/search-engine.js"></script>
<script src="../../gitbook/gitbook-plugin-search/search.js"></script>
<script src="../../gitbook/gitbook-plugin-lunr/lunr.min.js"></script>
<script src="../../gitbook/gitbook-plugin-lunr/search-lunr.js"></script>
<script src="../../gitbook/gitbook-plugin-sharing/buttons.js"></script>
<script src="../../gitbook/gitbook-plugin-fontsettings/fontsettings.js"></script>
</body>
</html>