iot-sol
Version:
Intel(r) IoT Services Orchestration Layer - HTML5 IDE + Node.js middleware to create and host distributed IoT Apps in minutes
315 lines (314 loc) • 32 kB
HTML
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta name="generator" content="pandoc" />
<meta name="author" content="Copyright 2015 Intel Corporation All Rights Reserved." />
<title>IoT Services Orchestration Layer</title>
<style type="text/css">code{white-space: pre;}</style>
<style type="text/css">
div.sourceCode { overflow-x: auto; }
table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
margin: 0; padding: 0; vertical-align: baseline; border: none; }
table.sourceCode { width: 100%; line-height: 100%; }
td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
td.sourceCode { padding-left: 5px; }
code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
code > span.dt { color: #902000; } /* DataType */
code > span.dv { color: #40a070; } /* DecVal */
code > span.bn { color: #40a070; } /* BaseN */
code > span.fl { color: #40a070; } /* Float */
code > span.ch { color: #4070a0; } /* Char */
code > span.st { color: #4070a0; } /* String */
code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
code > span.ot { color: #007020; } /* Other */
code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
code > span.fu { color: #06287e; } /* Function */
code > span.er { color: #ff0000; font-weight: bold; } /* Error */
code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
code > span.cn { color: #880000; } /* Constant */
code > span.sc { color: #4070a0; } /* SpecialChar */
code > span.vs { color: #4070a0; } /* VerbatimString */
code > span.ss { color: #bb6688; } /* SpecialString */
code > span.im { } /* Import */
code > span.va { color: #19177c; } /* Variable */
code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code > span.op { color: #666666; } /* Operator */
code > span.bu { } /* BuiltIn */
code > span.ex { } /* Extension */
code > span.pp { color: #bc7a00; } /* Preprocessor */
code > span.at { color: #7d9029; } /* Attribute */
code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
</style>
<link href="data:text/css;charset=utf-8,body%20%7B%0Amargin%3A%20auto%3B%0Apadding%2Dright%3A%201em%3B%0Apadding%2Dleft%3A%201em%3B%0Amax%2Dwidth%3A%2044em%3B%20border%2Dleft%3A%201px%20solid%20black%3B%0Aborder%2Dright%3A%201px%20solid%20black%3B%0Acolor%3A%20black%3B%0Afont%2Dfamily%3A%20Verdana%2C%20sans%2Dserif%3B%0Afont%2Dsize%3A%20100%25%3B%0Aline%2Dheight%3A%20140%25%3B%0Acolor%3A%20%23333%3B%20%7D%0Apre%20%7B%0Aborder%3A%201px%20dotted%20gray%3B%0Abackground%2Dcolor%3A%20%23ececec%3B%0Acolor%3A%20%231111111%3B%0Apadding%3A%200%2E5em%3B%0A%7D%0Acode%20%7B%0Afont%2Dfamily%3A%20monospace%3B%0A%7D%0Ah1%20a%2C%20h2%20a%2C%20h3%20a%2C%20h4%20a%2C%20h5%20a%20%7B%20text%2Ddecoration%3A%20none%3B%0Acolor%3A%20%237a5ada%3B%20%7D%0Ah1%2C%20h2%2C%20h3%2C%20h4%2C%20h5%20%7B%20font%2Dfamily%3A%20verdana%3B%0Afont%2Dweight%3A%20bold%3B%0Aborder%2Dbottom%3A%201px%20dotted%20black%3B%0Acolor%3A%20%237a5ada%3B%20%7D%0Ah1%20%7B%0Afont%2Dsize%3A%20130%25%3B%0A%7D%0Ah2%20%7B%0Afont%2Dsize%3A%20110%25%3B%0A%7D%0Ah3%20%7B%0Afont%2Dsize%3A%2095%25%3B%0A%7D%0Ah4%20%7B%0Afont%2Dsize%3A%2090%25%3B%0Afont%2Dstyle%3A%20italic%3B%0A%7D%0Ah5%20%7B%0Afont%2Dsize%3A%2090%25%3B%0Afont%2Dstyle%3A%20italic%3B%0A%7D%0Ah1%2Etitle%20%7B%0Afont%2Dsize%3A%20200%25%3B%0Afont%2Dweight%3A%20bold%3B%0Apadding%2Dtop%3A%200%2E2em%3B%0Apadding%2Dbottom%3A%200%2E2em%3B%0Atext%2Dalign%3A%20left%3B%0Aborder%3A%20none%3B%0A%7D%0Adt%20code%20%7B%0Afont%2Dweight%3A%20bold%3B%0A%7D%0Add%20p%20%7B%0Amargin%2Dtop%3A%200%3B%0A%7D%0A%23footer%20%7B%0Apadding%2Dtop%3A%201em%3B%0Afont%2Dsize%3A%2070%25%3B%0Acolor%3A%20gray%3B%0Atext%2Dalign%3A%20center%3B%0A%7D%0Apre%20%7B%0Abackground%2Dcolor%3A%20%23FDF6E3%0A%7D%0Aimg%20%7B%0Amax%2Dwidth%3A%2044em%3B%0A%7D%0A%2F%2F%20KeyWordTok%0A%2EsourceCode%20%2Ekw%20%7B%20color%3A%20%23268BD2%3B%20%7D%0A%2F%2F%20DataTypeTok%0A%2EsourceCode%20%2Edt%20%7B%20color%3A%20%23268BD2%3B%20%7D%0A%2F%2F%20DecValTok%20%28decimal%20value%29%2C%20BaseNTok%2C%20FloatTok%0A%2EsourceCode%20%2Edv%2C%20%2EsourceCode%20%2Ebn%2C%20%2EsourceCode%20%2Efl%20%7B%20color%3A%20%23D33682%3B%20%7D%0A%2F%2F%20CharTok%0A%2EsourceCode%20%2Ech%20%7B%20color%3A%20%23DC322F%3B%20%7D%0A%2F%2F%20StringTok%0A%2EsourceCode%20%2Est%20%7B%20color%3A%20%232AA198%3B%20%7D%0A%2F%2F%20CommentTok%0A%2EsourceCode%20%2Eco%20%7B%20color%3A%20%2393A1A1%3B%20%7D%0A%2F%2F%20OtherTok%0A%2EsourceCode%20%2Eot%20%7B%20color%3A%20%23A57800%3B%20%7D%0A%2F%2F%20AlertTok%0A%2EsourceCode%20%2Eal%20%7B%20color%3A%20%23CB4B16%3B%20font%2Dweight%3A%20bold%3B%20%7D%0A%2F%2F%20FunctionTok%0A%2EsourceCode%20%2Efu%20%7B%20color%3A%20%23268BD2%3B%20%7D%0A%2F%2F%20RegionMarkerTok%0A%2EsourceCode%20%2Ere%20%7B%20%7D%0A%2F%2F%20ErrorTok%0A%2EsourceCode%20%2Eer%20%7B%20color%3A%20%23D30102%3B%20font%2Dweight%3A%20bold%3B%20%7D%0A" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="header">
<h1 class="title">IoT Services Orchestration Layer</h1>
<h2 class="author">Copyright 2015 Intel Corporation All Rights Reserved.</h2>
</div>
<div id="TOC">
<ul>
<li><a href="#widget">Widget</a><ul>
<li><a href="#introduction-of-widget">Introduction of Widget</a></li>
<li><a href="#widget-class">Widget class</a><ul>
<li><a href="#methods">Methods</a></li>
</ul></li>
<li><a href="#spec">spec</a><ul>
<li><a href="#configurations">Configurations</a></li>
</ul></li>
<li><a href="#code-integration">Code integration</a></li>
<li><a href="#wrapping-third-party-as-builtin-widget">Wrapping third party as builtin widget</a></li>
<li><a href="#publish-to-npm">Publish to NPM</a></li>
<li><a href="#directory-layout">Directory Layout</a><ul>
<li><a href="#package.json">package.json</a></li>
<li><a href="#index.js">index.js</a></li>
</ul></li>
</ul></li>
</ul>
</div>
<h1 id="widget">Widget</h1>
<h2 id="introduction-of-widget">Introduction of Widget</h2>
<p>The <strong>Widget</strong> is the basic element that consists the UI of end users, its code base is shared by both <em>ui-dev</em> and <em>ui-user</em> projects.</p>
<p>Every UI divides up the screen as a grid with N rows and 12 columns, the width of each column is about 8.333% width of the browser, and the height of row is fixed to 60px (configurable). The number of rows (N) is dependent on the height of the browser.</p>
<p>Each initial instance of widgets occupies 1x1 size on the grid, developers can resize it by drag and drop.</p>
<h2 id="widget-class">Widget class</h2>
<p>All widgets should be derivatived from the <em>Widget</em> class, this base class encapsulates the infrastructure such as UI layout, data communication and event dispatching. You can find the builtin widgets under <em>ui-widget/widgets-jsx/</em>, and put your code there, so that we can processes it by unified building scripts.</p>
<p>For example, we create a sample widget as follows:</p>
<div class="sourceCode"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="im">export</span> <span class="im">default</span> <span class="kw">class</span> TextWidget <span class="kw">extends</span> Widget <span class="op">{</span>
<span class="co">// All widget must overwrite this method</span>
<span class="at">render</span>() <span class="op">{</span>
<span class="kw">var</span> text <span class="op">=</span> <span class="kw">this</span>.<span class="at">get_data</span>().<span class="at">map</span>((t<span class="op">,</span> i) <span class="op">=></span> <span class="op"><</span>div<span class="op">>{</span><span class="va">t</span>.<span class="at">text</span><span class="op">}<</span><span class="ss">/div></span><span class="sc">)</span><span class="ss">;</span>
<span class="ss"> return super.render</span><span class="sc">(</span>
<span class="ss"> <div>{text}</div</span><span class="op">></span>
)<span class="op">;</span>
<span class="op">}</span>
<span class="op">}</span></code></pre></div>
<h3 id="methods">Methods</h3>
<h4 id="get_data">get_data()</h4>
<p>This method get all the data cached from inports, returns an array of plain objects whose keys are inports’ name.</p>
<p><strong>Note</strong>: The size of the array is a configurable item(<code>data_cache_size</code>) in <em>spec</em>.</p>
<h4 id="get_height">get_height()</h4>
<p>This method returns the <code>height</code> of the instance in <strong>px</strong>.</p>
<h4 id="get_width">get_width()</h4>
<p>This method returns the <code>width</code> of the instance in <strong>px</strong>.</p>
<h4 id="set_cssid-css">set_css(id, css)</h4>
<p>This method inserts a <em>style</em> element into current HTML document</p>
<div class="sourceCode"><pre class="sourceCode html"><code class="sourceCode html"><span class="kw"><style</span><span class="ot"> id=</span><span class="st">"id"</span><span class="kw">></span>
css
<span class="kw"></style></span></code></pre></div>
<h4 id="send_dataout">send_data(out)</h4>
<p>This method sends the <code>out</code> into the outports, <code>out</code> is the key-value mapping of the outports, e.g. {<code>o1</code>: val1, <code>o2</code>: val2;},</p>
<p><strong>Note</strong>: the <code>o1</code>, <code>o2</code> is the name of outports</p>
<h4 id="switch_uiid">switch_ui(id)</h4>
<p>This method is used to switchs the UIs of the App.</p>
<h4 id="on_settings_changedprev-next">_on_settings_changed(prev, next)</h4>
<p>This is a callback function, implement it if you want to handle the event of <code>settings changed</code> which emited by property panel (inspector).</p>
<h2 id="spec">spec</h2>
<p><em>spec</em> is a textual description for <strong>Widget</strong>, such as how many <code>inports</code>, <code>outports</code> and <code>configurations</code>, and details.</p>
<p>Every widget should be described in <code>ui-widgets/specs.js</code>.</p>
<p>For example, following is the builtin spec of <em>Text</em> widget:</p>
<div class="sourceCode"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="op">{</span>
<span class="dt">id</span><span class="op">:</span> <span class="st">"hope/ui/text"</span><span class="op">,</span>
<span class="dt">catalog</span><span class="op">:</span> <span class="st">"basic"</span><span class="op">,</span>
<span class="dt">name</span><span class="op">:</span> <span class="st">"Text"</span><span class="op">,</span>
<span class="dt">description</span><span class="op">:</span> <span class="st">"Show Text"</span><span class="op">,</span>
<span class="dt">icon</span><span class="op">:</span> <span class="st">"text-width"</span><span class="op">,</span>
<span class="dt">use_ract</span><span class="op">:</span> <span class="kw">true</span><span class="op">,</span>
<span class="dt">data_cache_size</span><span class="op">:</span> <span class="dv">5</span><span class="op">,</span> <span class="co">// how many data items would be cached to show the widget </span>
<span class="co">// 0 for using default, -1 means unliminted</span>
<span class="dt">config</span><span class="op">:</span> [<span class="op">{</span>
<span class="dt">name</span><span class="op">:</span> <span class="st">"align"</span><span class="op">,</span>
<span class="dt">type</span><span class="op">:</span> <span class="st">"option"</span><span class="op">,</span>
<span class="dt">default</span><span class="op">:</span> <span class="st">"left"</span><span class="op">,</span>
<span class="dt">options</span><span class="op">:</span> [<span class="st">"left"</span><span class="op">,</span> <span class="st">"center"</span><span class="op">,</span> <span class="st">"right"</span>]
<span class="op">},</span> <span class="op">{</span>
<span class="dt">name</span><span class="op">:</span> <span class="st">"font_size"</span><span class="op">,</span>
<span class="dt">display</span><span class="op">:</span> <span class="st">"Font Size"</span><span class="op">,</span> <span class="co">// displaying label in property panel</span>
<span class="dt">type</span><span class="op">:</span> <span class="st">"string"</span>
<span class="op">}</span>]<span class="op">,</span>
<span class="kw">in</span><span class="op">:</span> <span class="op">{</span>
<span class="dt">ports</span><span class="op">:</span> [<span class="op">{</span>
<span class="dt">name</span><span class="op">:</span> <span class="st">"text"</span><span class="op">,</span>
<span class="dt">type</span><span class="op">:</span> <span class="st">"string"</span>
<span class="op">}</span>]
<span class="op">},</span>
<span class="dt">out</span><span class="op">:</span> <span class="op">{</span>
<span class="dt">ports</span><span class="op">:</span> []
<span class="op">}</span>
<span class="op">}</span></code></pre></div>
<h3 id="configurations">Configurations</h3>
<p>For a widget, all property of configuration is divided into two parts, the <strong>config</strong> group always is visible, and the <strong>extra</strong> group is hidden by default.</p>
<p>Supported data types of configuration item:</p>
<h4 id="boolean">boolean</h4>
<p><code>Boolean</code> property, corresponding to a <code>switch</code> button in the property panel.</p>
<h4 id="number">number</h4>
<p><code>Number</code> property, corresponding to an <code>editbox</code> in the property panel.</p>
<h4 id="int">int</h4>
<p><code>Integer</code> property, corresponding to an <code>editbox</code> in the property panel.</p>
<h4 id="string">string</h4>
<p><code>String</code> property, corresponding to an <code>editbox</code> in the property panel.</p>
<h4 id="option">option</h4>
<p><code>Option</code> property, corresponding to a <code>combox</code> in the property panel. Options are provided by <code>options</code> property, following three cases are supported:</p>
<ul>
<li><code>array</code> of keys, such as the <code>align</code> in spec of <code>hope/ui/text</code> widget.</li>
<li><p><code>array</code> of plain object, e.g.</p>
<div class="sourceCode"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="op">{</span>
<span class="dt">name</span><span class="op">:</span> <span class="st">"editor_type"</span><span class="op">,</span>
<span class="dt">type</span><span class="op">:</span> <span class="st">"option"</span><span class="op">,</span>
<span class="dt">options</span><span class="op">:</span> [<span class="op">{</span>
<span class="dt">name</span><span class="op">:</span> <span class="st">"Single Line"</span><span class="op">,</span>
<span class="dt">value</span><span class="op">:</span> <span class="st">"sle"</span>
<span class="op">},</span> <span class="op">{</span>
<span class="dt">name</span><span class="op">:</span> <span class="st">"Multiple Line"</span><span class="op">,</span>
<span class="dt">value</span><span class="op">:</span> <span class="st">"mle"</span>
<span class="op">}</span>]
<span class="op">}</span></code></pre></div></li>
<li><p><code>string</code>: only <code>__HOPE_APP_UI_LIST__</code> supported now, which will be replaced by a list of UIs in the App.</p></li>
</ul>
<h4 id="glyphicon">glyphicon</h4>
<p>A font icon, developers can easily pick one in the property panel, system now provides up to 576 icons.</p>
<h4 id="color">color</h4>
<p>‘Color’ property, corresponding to an circle <code>button</code> in the property panel, click the button will open a color dialog.</p>
<h2 id="code-integration">Code integration</h2>
<p>For a new widget, besides adding its <code>spec</code> in <code>ui-widgets/specs.js</code>, we also need to export it from <code>ui-widgets/index.js</code>.</p>
<p>Specifically, we should add one key-value pair in <code>widgets</code> object of <code>index.js</code>, and use the unique <code>id</code> of widget as key, and use the constructor of widget as value.</p>
<p>For example, the <code>text</code> widget is exported as following:</p>
<div class="sourceCode"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="va">exports</span>.<span class="at">widgets</span> <span class="op">=</span> <span class="op">{</span>
<span class="st">"hope/ui/text"</span><span class="op">:</span> <span class="at">require</span>(<span class="st">"./generated/text"</span>)<span class="op">;</span>
...
<span class="op">}</span></code></pre></div>
<h2 id="wrapping-third-party-as-builtin-widget">Wrapping third party as builtin widget</h2>
<p>For example, we want to import the <a href="http://bl.ocks.org/brattonc/5e5ce9beee483220e2f6">D3 Liquid Fill Gauge</a>.</p>
<p>At first, we download the source code <a href="http://bl.ocks.org/brattonc/5e5ce9beee483220e2f6#liquidFillGauge.js">liquidFillGauge.js</a> and save it to <code>ui-widgets/third_party/</code> with a little changes like follows:</p>
<div class="sourceCode"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="kw">var</span> d3 <span class="op">=</span> <span class="at">require</span>(<span class="st">"d3"</span>)<span class="op">;</span>
<span class="va">exports</span>.<span class="at">liquidFillGaugeDefaultSettings</span> <span class="op">=</span> <span class="kw">function</span>()<span class="op">{</span>
<span class="cf">return</span> <span class="op">{</span>
...
<span class="op">}</span>
<span class="va">exports</span>.<span class="at">loadLiquidFillGauge</span> <span class="op">=</span> <span class="kw">function</span>(elementId<span class="op">,</span> value<span class="op">,</span> config) <span class="op">{</span>
<span class="cf">if</span>(config <span class="op">==</span> <span class="kw">null</span>) config <span class="op">=</span> <span class="at">liquidFillGaugeDefaultSettings</span>()<span class="op">;</span>
...</code></pre></div>
<p>Secondly, we create a new React class to wrap this widget, and save the js file as <code>ui-widgets/widgets-jsx/lfg.js</code>:</p>
<div class="sourceCode"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="im">import</span> <span class="op">{</span>liquidFillGaugeDefaultSettings<span class="op">,</span> loadLiquidFillGauge<span class="op">}</span> <span class="im">from</span> <span class="st">"../third_party/liquidFillGauge.js"</span><span class="op">;</span>
<span class="im">export</span> <span class="im">default</span> <span class="kw">class</span> LFGWidget <span class="kw">extends</span> Widget <span class="op">{</span>
<span class="at">_on_settings_changed</span>() <span class="op">{</span>
<span class="kw">this</span>.<span class="at">init_gauge</span>()<span class="op">;</span>
<span class="op">}</span>
<span class="at">init_gauge</span>() <span class="op">{</span>
<span class="kw">var</span> w <span class="op">=</span> <span class="kw">this</span>.<span class="va">props</span>.<span class="at">widget</span><span class="op">;</span>
<span class="kw">var</span> size <span class="op">=</span> <span class="kw">this</span>.<span class="at">get_height</span>() <span class="op">-</span> <span class="dv">5</span><span class="op">;</span>
<span class="kw">var</span> svg <span class="op">=</span> <span class="st">"<svg id='"</span> <span class="op">+</span> <span class="va">w</span>.<span class="at">id</span> <span class="op">+</span> <span class="st">"' width='"</span> <span class="op">+</span> size <span class="op">+</span> <span class="st">"' height='"</span> <span class="op">+</span> size <span class="op">+</span> <span class="st">"'>"</span><span class="op">;</span>
<span class="kw">var</span> config <span class="op">=</span> <span class="at">liquidFillGaugeDefaultSettings</span>()<span class="op">;</span>
<span class="va">_</span>.<span class="at">merge</span>(config<span class="op">,</span> <span class="va">w</span>.<span class="at">config</span>)<span class="op">;</span>
<span class="at">$</span>(<span class="kw">this</span>.<span class="va">refs</span>.<span class="at">container</span>).<span class="at">empty</span>().<span class="at">append</span>(svg)<span class="op">;</span>
<span class="kw">this</span>.<span class="at">gauge_object</span> <span class="op">=</span> <span class="at">loadLiquidFillGauge</span>(<span class="va">w</span>.<span class="at">id</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> config)<span class="op">;</span>
<span class="op">}</span>
<span class="at">componentDidMount</span>() <span class="op">{</span>
<span class="kw">super</span>.<span class="at">componentDidMount</span>()<span class="op">;</span>
<span class="kw">this</span>.<span class="at">set_css</span>(<span class="st">"lfg-css"</span><span class="op">,</span> <span class="st">".liquidFillGaugeText { font-family: Helvetica; font-weight: bold; }"</span>)<span class="op">;</span>
<span class="kw">this</span>.<span class="at">init_gauge</span>()<span class="op">;</span>
<span class="op">}</span>
<span class="at">componentDidUpdate</span>() <span class="op">{</span>
<span class="kw">var</span> data <span class="op">=</span> <span class="kw">this</span>.<span class="at">get_data</span>()<span class="op">;</span>
<span class="cf">if</span> (<span class="va">_</span>.<span class="at">isArray</span>(data) <span class="op">&&</span> <span class="va">data</span>.<span class="at">length</span> <span class="op">></span> <span class="dv">0</span>) <span class="op">{</span>
<span class="kw">var</span> val <span class="op">=</span> <span class="at">parseFloat</span>(data[<span class="dv">0</span>].<span class="at">value</span>)<span class="op">;</span>
<span class="kw">this</span>.<span class="va">gauge_object</span>.<span class="at">update</span>(val)<span class="op">;</span>
<span class="op">}</span>
<span class="op">}</span>
<span class="at">render</span>() <span class="op">{</span>
<span class="cf">return</span> <span class="kw">super</span>.<span class="at">render</span>(<span class="op"><</span>div ref<span class="op">=</span><span class="st">"container"</span> <span class="ss">/></span><span class="sc">)</span><span class="ss">;</span>
<span class="ss"> }</span>
<span class="ss">}</span></code></pre></div>
<p>Then, we append following spec into <code>ui-widgets/specs.js</code>:</p>
<div class="sourceCode"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="op">{</span>
<span class="dt">id</span><span class="op">:</span> <span class="st">"hope/ui/lfg-gauge"</span><span class="op">,</span>
<span class="dt">catalog</span><span class="op">:</span> <span class="st">"basic"</span><span class="op">,</span>
<span class="dt">name</span><span class="op">:</span> <span class="st">"liquid Fill Gauge"</span><span class="op">,</span>
<span class="dt">description</span><span class="op">:</span> <span class="st">"liquid Fill Gauge"</span><span class="op">,</span>
<span class="dt">icon</span><span class="op">:</span> <span class="st">"dashboard"</span><span class="op">,</span>
<span class="dt">use_ract</span><span class="op">:</span> <span class="kw">true</span><span class="op">,</span>
<span class="dt">data_cache_size</span><span class="op">:</span> <span class="dv">1</span><span class="op">,</span>
<span class="dt">config</span><span class="op">:</span> [<span class="op">{</span>
<span class="dt">name</span><span class="op">:</span> <span class="st">"waveColor"</span><span class="op">,</span> <span class="co">// same name in liquidFillGaugeDefaultSettings</span>
<span class="dt">type</span><span class="op">:</span> <span class="st">"string"</span><span class="op">,</span> <span class="co">// TODO: add more configuration like this</span>
<span class="dt">default</span><span class="op">:</span> <span class="st">"#178BCA"</span>
<span class="op">}</span>]<span class="op">,</span>
<span class="kw">in</span><span class="op">:</span> <span class="op">{</span>
<span class="dt">ports</span><span class="op">:</span> [<span class="op">{</span>
<span class="dt">name</span><span class="op">:</span> <span class="st">"value"</span><span class="op">,</span>
<span class="dt">type</span><span class="op">:</span> <span class="st">"number"</span>
<span class="op">}</span>]
<span class="op">},</span>
<span class="dt">out</span><span class="op">:</span> <span class="op">{</span>
<span class="dt">ports</span><span class="op">:</span> []
<span class="op">}</span>
<span class="op">}</span></code></pre></div>
<p>Finally, we need to add a key-value pair into <code>ui-widgets/index.js</code> to export this widget, and run <code>gulp build</code> to rebuild the <code>ui-widgets</code> project.</p>
<div class="sourceCode"><pre class="sourceCode json"><code class="sourceCode json"><span class="er">"hope/ui/lfg-gauge":</span> <span class="er">require("./generated/lfg")</span></code></pre></div>
<h2 id="publish-to-npm">Publish to NPM</h2>
<p>In most cases, we want to publish the widget on internet. now we are using <a href="http://www.npmjs.com">NPM</a> to host our widget plugins.</p>
<p>Conventionally, We highly recommend that the name of npm package of widget should begin with “hope-widget-”, it’s a simple way for code integration. For example, if want to use <code>XYZ</code>, we just need execute following commands in <code>ui-widgets/</code> directory:</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"> $ <span class="kw">npm</span> install hope-widget-XYZ --save
$ <span class="kw">gulp</span> build</code></pre></div>
<h2 id="directory-layout">Directory Layout</h2>
<p>For example, we create a new npm package <code>ui-widgets/hope-widget-lfg/</code>, and its tree graph is as follows:</p>
<pre><code>hope-widget-lfg
|-- package.json
|-- index.js
|-- third_party
| `-- liquidFillGauge.js
`-- src
`-- lfg.js</code></pre>
<h3 id="package.json">package.json</h3>
<div class="sourceCode"><pre class="sourceCode json"><code class="sourceCode json"><span class="fu">{</span>
<span class="dt">"name"</span><span class="fu">:</span> <span class="st">"hope-widget-lfg"</span><span class="fu">,</span>
<span class="dt">"version"</span><span class="fu">:</span> <span class="st">"1.0.0"</span><span class="fu">,</span>
<span class="dt">"description"</span><span class="fu">:</span> <span class="st">"liquid Fill Gauge"</span><span class="fu">,</span>
<span class="dt">"main"</span><span class="fu">:</span> <span class="st">"index.js"</span><span class="fu">,</span>
<span class="dt">"scripts"</span><span class="fu">:</span> <span class="fu">{</span>
<span class="dt">"build"</span><span class="fu">:</span> <span class="st">"babel src --out-dir lib"</span><span class="fu">,</span>
<span class="dt">"prepublish"</span><span class="fu">:</span> <span class="st">"npm run build"</span>
<span class="fu">},</span>
<span class="dt">"dependencies"</span><span class="fu">:</span> <span class="fu">{},</span>
<span class="dt">"devDependencies"</span><span class="fu">:</span> <span class="fu">{},</span>
<span class="dt">"keywords"</span><span class="fu">:</span> <span class="ot">[</span><span class="st">"guage"</span><span class="ot">]</span><span class="fu">,</span>
<span class="dt">"author"</span><span class="fu">:</span> <span class="st">"Kanghua Yu"</span><span class="fu">,</span>
<span class="dt">"license"</span><span class="fu">:</span> <span class="st">"MIT"</span>
<span class="fu">}</span></code></pre></div>
<h3 id="index.js">index.js</h3>
<div class="sourceCode"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="va">exports</span>.<span class="at">specs</span> <span class="op">=</span> [<span class="op">{</span>
<span class="dt">id</span><span class="op">:</span> <span class="st">"hope/ui/lfg-gauge"</span><span class="op">,</span>
<span class="dt">catalog</span><span class="op">:</span> <span class="st">"basic"</span><span class="op">,</span>
<span class="dt">name</span><span class="op">:</span> <span class="st">"liquid Fill Gauge"</span><span class="op">,</span>
<span class="dt">description</span><span class="op">:</span> <span class="st">"liquid Fill Gauge"</span><span class="op">,</span>
<span class="dt">icon</span><span class="op">:</span> <span class="st">"dashboard"</span><span class="op">,</span>
<span class="dt">use_ract</span><span class="op">:</span> <span class="kw">true</span><span class="op">,</span>
<span class="dt">data_cache_size</span><span class="op">:</span> <span class="dv">1</span><span class="op">,</span>
<span class="dt">config</span><span class="op">:</span> [<span class="op">{</span>
<span class="dt">name</span><span class="op">:</span> <span class="st">"waveColor"</span><span class="op">,</span> <span class="co">// same name in liquidFillGaugeDefaultSettings</span>
<span class="dt">type</span><span class="op">:</span> <span class="st">"string"</span><span class="op">,</span> <span class="co">// TODO: add more configuration like this</span>
<span class="dt">default</span><span class="op">:</span> <span class="st">"#178BCA"</span>
<span class="op">}</span>]<span class="op">,</span>
<span class="kw">in</span><span class="op">:</span> <span class="op">{</span>
<span class="dt">ports</span><span class="op">:</span> [<span class="op">{</span>
<span class="dt">name</span><span class="op">:</span> <span class="st">"value"</span><span class="op">,</span>
<span class="dt">type</span><span class="op">:</span> <span class="st">"number"</span>
<span class="op">}</span>]
<span class="op">},</span>
<span class="dt">out</span><span class="op">:</span> <span class="op">{</span>
<span class="dt">ports</span><span class="op">:</span> []
<span class="op">}</span>
<span class="op">}</span>]<span class="op">;</span>
<span class="cf">if</span> (<span class="va">process</span>.<span class="at">browser</span>) <span class="op">{</span>
<span class="va">exports</span>.<span class="at">widgets</span> <span class="op">=</span> <span class="op">{</span>
<span class="st">"hope/ui/lfg-gauge"</span><span class="op">:</span> <span class="at">require</span>(<span class="st">"./lib/lfg"</span>)<span class="op">;</span>
...
<span class="op">}</span>
<span class="op">}</span></code></pre></div>
</body>
</html>