<!doctype html>
<html lang="en" dir="ltr" class="docs-wrapper plugin-docs plugin-id-default docs-version-current docs-doc-page docs-doc-id-guides/custom-widgets" data-has-hydrated="false">
<head>
<meta charset="UTF-8">
<meta name="generator" content="Docusaurus v3.1.0">
<title data-rh="true">Custom Widgets | OpenC3 Docs</title><meta data-rh="true" name="viewport" content="width=device-width,initial-scale=1"><meta data-rh="true" name="twitter:card" content="summary_large_image"><meta data-rh="true" property="og:url" content="https://docs.openc3.com/tools/staticdocs/docs/guides/custom-widgets"><meta data-rh="true" property="og:locale" content="en"><meta data-rh="true" name="docusaurus_locale" content="en"><meta data-rh="true" name="docsearch:language" content="en"><meta data-rh="true" name="docusaurus_version" content="current"><meta data-rh="true" name="docusaurus_tag" content="docs-default-current"><meta data-rh="true" name="docsearch:version" content="current"><meta data-rh="true" name="docsearch:docusaurus_tag" content="docs-default-current"><meta data-rh="true" property="og:title" content="Custom Widgets | OpenC3 Docs"><meta data-rh="true" name="description" content="COSMOS allows you to build custom widgets which can be deployed with your plugin and used in Telemetry Viewer. Building custom widgets can utilitize any javascript frameworks but since COSMOS is written with Vue.js, we will use that framework in this tutorial. Please see the Widget Generator guide for information about generating the scaffolding for a custom widget."><meta data-rh="true" property="og:description" content="COSMOS allows you to build custom widgets which can be deployed with your plugin and used in Telemetry Viewer. Building custom widgets can utilitize any javascript frameworks but since COSMOS is written with Vue.js, we will use that framework in this tutorial. Please see the Widget Generator guide for information about generating the scaffolding for a custom widget."><link data-rh="true" rel="icon" href="/tools/staticdocs/img/favicon.png"><link data-rh="true" rel="canonical" href="https://docs.openc3.com/tools/staticdocs/docs/guides/custom-widgets"><link data-rh="true" rel="alternate" href="https://docs.openc3.com/tools/staticdocs/docs/guides/custom-widgets" hreflang="en"><link data-rh="true" rel="alternate" href="https://docs.openc3.com/tools/staticdocs/docs/guides/custom-widgets" hreflang="x-default"><link rel="stylesheet" href="/tools/staticdocs/assets/css/styles.a9c55efa.css">
<script src="/tools/staticdocs/assets/js/runtime~main.c6bb8b5e.js" defer="defer"></script>
<script src="/tools/staticdocs/assets/js/main.9ed8621d.js" defer="defer"></script>
</head>
<body class="navigation-with-keyboard">
<script>!function(){function t(t){document.documentElement.setAttribute("data-theme",t)}var e=function(){try{return new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}}()||function(){try{return localStorage.getItem("theme")}catch(t){}}();t(null!==e?e:"dark")}(),function(){try{const c=new URLSearchParams(window.location.search).entries();for(var[t,e]of c)if(t.startsWith("docusaurus-data-")){var a=t.replace("docusaurus-data-","data-");document.documentElement.setAttribute(a,e)}}catch(t){}}()</script><div id="__docusaurus"><div role="region" aria-label="Skip to main content"><a class="skipToContent_G6ar" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="navbar navbar--fixed-top"><div class="navbar__inner"><div class="navbar__items"><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" href="/tools/staticdocs/"><div class="navbar__logo"><img src="/tools/staticdocs/img/logo.svg" alt="OpenC3 Logo" class="themedComponent_DHUr themedComponent--light_DIHH"><img src="/tools/staticdocs/img/logo.svg" alt="OpenC3 Logo" class="themedComponent_DHUr themedComponent--dark_Bv2M"></div><b class="navbar__title text--truncate">OpenC3 Docs</b></a><a aria-current="page" class="navbar__item navbar__link navbar__link--active" href="/tools/staticdocs/docs">Documentation</a><a href="https://openc3.com/enterprise/" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">Enterprise</a></div><div class="navbar__items navbar__items--right"><div class="navbarSearchContainer_bmvg"><div class="navbar__search"><span aria-label="expand searchbar" role="button" class="search-icon" tabindex="0"></span><input id="search_input_react" type="search" placeholder="Loading..." aria-label="Search" class="navbar__search-input search-bar" disabled=""></div></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="main-wrapper mainWrapper_UyTV"><div class="docsWrapper_XLvK"><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_z1FD" type="button"></button><div class="docRoot_HciC"><aside class="theme-doc-sidebar-container docSidebarContainer_e5ai"><div class="sidebarViewport_N8x0"><div class="sidebar_vJCc"><nav aria-label="Docs sidebar" class="menu thin-scrollbar menu_qiME"><ul class="theme-doc-sidebar-menu menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/tools/staticdocs/docs">Introduction</a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist" aria-expanded="false" href="/tools/staticdocs/docs/getting-started">Getting Started</a><button aria-label="Expand sidebar category &#x27;Getting Started&#x27;" type="button" class="clean-btn menu__caret"></button></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist" aria-expanded="false" href="/tools/staticdocs/docs/configuration">Configuration</a><button aria-label="Expand sidebar category &#x27;Configuration&#x27;" type="button" class="clean-btn menu__caret"></button></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist" aria-expanded="false" href="/tools/staticdocs/docs/tools">Tools</a><button aria-label="Expand sidebar category &#x27;Tools&#x27;" type="button" class="clean-btn menu__caret"></button></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--active" aria-expanded="true" href="/tools/staticdocs/docs/guides">Guides</a><button aria-label="Collapse sidebar category &#x27;Guides&#x27;" type="button" class="clean-btn menu__caret"></button></div><ul style="display:block;overflow:visible;height:auto" class="menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/tools/staticdocs/docs/guides/bridges">Bridges</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/tools/staticdocs/docs/guides/cfs">COSMOS and NASA cFS</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link menu__link--active" aria-current="page" tabindex="0" href="/tools/staticdocs/docs/guides/custom-widgets">Custom Widgets</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/tools/staticdocs/docs/guides/little-endian-bitfields">Little Endian Bitfields</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/tools/staticdocs/docs/guides/local-mode">Local Mode</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/tools/staticdocs/docs/guides/logging">Logging</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/tools/staticdocs/docs/guides/monitoring">Monitoring</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/tools/staticdocs/docs/guides/performance">Performance</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/tools/staticdocs/docs/guides/raspberrypi">Raspberry Pi</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/tools/staticdocs/docs/guides/script-writing">Script Writing Guide</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/tools/staticdocs/docs/guides/scripting-api">Scripting API Guide</a></li></ul></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist" aria-expanded="false" href="/tools/staticdocs/docs/development">Development</a><button aria-label="Expand sidebar category &#x27;Development&#x27;" type="button" class="clean-btn menu__caret"></button></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist" aria-expanded="false" href="/tools/staticdocs/docs/meta">Meta</a><button aria-label="Expand sidebar category &#x27;Meta&#x27;" type="button" class="clean-btn menu__caret"></button></div></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/tools/staticdocs/docs/privacy">OpenC3, Inc. Privacy Policy</a></li></ul></nav></div></div></aside><main class="docMainContainer_namt"><div class="container padding-top--md padding-bottom--lg"><div class="row"><div class="col docItemCol_YAwJ"><div class="docItemContainer_Rv5Z"><article><nav class="theme-doc-breadcrumbs breadcrumbsContainer_zCmv" aria-label="Breadcrumbs"><ul class="breadcrumbs" itemscope="" itemtype="https://schema.org/BreadcrumbList"><li class="breadcrumbs__item"><a aria-label="Home page" class="breadcrumbs__link" href="/tools/staticdocs/"><svg viewBox="0 0 24 24" class="breadcrumbHomeIcon_JFrk"><path d="M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z" fill="currentColor"></path></svg></a></li><li itemscope="" itemprop="itemListElement" itemtype="https://schema.org/ListItem" class="breadcrumbs__item"><a class="breadcrumbs__link" itemprop="item" href="/tools/staticdocs/docs/guides"><span itemprop="name">Guides</span></a><meta itemprop="position" content="1"></li><li itemscope="" itemprop="itemListElement" itemtype="https://schema.org/ListItem" class="breadcrumbs__item breadcrumbs__item--active"><span class="breadcrumbs__link" itemprop="name">Custom Widgets</span><meta itemprop="position" content="2"></li></ul></nav><div class="tocCollapsible_O_Qc theme-doc-toc-mobile tocMobile_tjDr"><button type="button" class="clean-btn tocCollapsibleButton_htYj">On this page</button></div><div class="theme-doc-markdown markdown"><header><h1>Custom Widgets</h1></header><p>COSMOS allows you to build custom widgets which can be deployed with your <a href="/tools/staticdocs/docs/configuration/plugins">plugin</a> and used in <a href="/tools/staticdocs/docs/tools/tlm-viewer">Telemetry Viewer</a>. Building custom widgets can utilitize any javascript frameworks but since COSMOS is written with Vue.js, we will use that framework in this tutorial. Please see the <a href="../getting-started/generators#widget-generator">Widget Generator</a> guide for information about generating the scaffolding for a custom widget.</p>
<h2 id="custom-widgets">Custom Widgets</h2>
<p>We&#x27;re basically going to follow the COSMOS <a href="https://github.com/OpenC3/cosmos/tree/main/openc3-cosmos-init/plugins/packages/openc3-cosmos-demo">Demo</a> and explain how that custom widget was created.</p>
<p>If you look at the bottom of the Demo&#x27;s <a href="https://github.com/OpenC3/cosmos/blob/main/openc3-cosmos-init/plugins/packages/openc3-cosmos-demo/plugin.txt">plugin.txt</a> file you&#x27;ll see we declare the widgets:</p>
<pre><code class="language-ruby">WIDGET BIG
WIDGET HELLOWORLD
</code></pre>
<p>When the plugin is deployed this causes COSMOS to look for the as-built widgets. For the BIG widget it will look for the widget at <code>tools/widgets/BigWidget/BigWidget.umd.min.js</code>. Similarly it looks for HELLOWORLD at <code>tools/widgets/HelloworldWidget/HelloworldWidget.umd.min.js</code>. These directories and file names may seem mysterious but it&#x27;s all about how the widgets get built.</p>
<h3 id="helloworld-widget">Helloworld Widget</h3>
<p>The Helloworld Widget source code is found in the plugin&#x27;s src directory and is called <a href="https://github.com/OpenC3/cosmos/blob/main/openc3-cosmos-init/plugins/packages/openc3-cosmos-demo/src/HelloworldWidget.vue">HelloworldWidget.vue</a>. The basic structure is as follows:</p>
<pre><code class="language-vue">&lt;template&gt;
  &lt;!-- Implement widget here --&gt;
&lt;/template&gt;

&lt;script&gt;
import Widget from &quot;@openc3/tool-common/src/components/widgets/Widget&quot;;
export default {
  mixins: [Widget],
  data() {
    return {
      // Reactive data items
    };
  },
};
&lt;/script&gt;
&lt;style scoped&gt;
/* widget specific style */
&lt;/style&gt;
</code></pre>
<admonition title="Vue &amp; Vuetify" type="info"><p>For more information about how the COSMOS frontend is built (including all the Widgets) please check out <a href="https://vuejs.org">Vue.js</a> and <a href="https://vuetifyjs.com">Vuetify</a>.</p></admonition>
<p>To build this custom widget we changed the Demo <a href="https://github.com/OpenC3/cosmos/blob/main/openc3-cosmos-init/plugins/packages/openc3-cosmos-demo/Rakefile">Rakefile</a> to call <code>yarn run build</code> when the plugin is built. <code>yarn run XXX</code> looks for &#x27;scripts&#x27; to run in the <a href="https://github.com/OpenC3/cosmos/blob/main/openc3-cosmos-init/plugins/packages/openc3-cosmos-demo/package.json">package.json</a> file. If we open package.json we find the following:</p>
<pre><code class="language-json">  &quot;scripts&quot;: {
    &quot;build&quot;: &quot;vue-cli-service build --target lib --dest tools/widgets/HelloworldWidget --formats umd-min src/HelloworldWidget.vue --name HelloworldWidget &amp;&amp; vue-cli-service build --target lib --dest tools/widgets/BigWidget --formats umd-min src/BigWidget.vue --name BigWidget&quot;
  },
</code></pre>
<p>This uses the <code>vue-cli-service</code> to build the code found at <code>src/HelloworldWidget.vue</code> and formats as <code>umd-min</code> and puts it in the <code>tools/widgets/HelloworldWidget</code> directory. So this is why the plugin looks for the plugin at <code>tools/widgets/HelloworldWidget/HelloworldWidget.umd.min.js</code>. Click <a href="https://cli.vuejs.org/guide/cli-service.html#vue-cli-service-build">here</a> for the <code>vue-cli-service build</code> documentation.</p>
<p>If you look at the Demo plugin&#x27;s <a href="https://github.com/OpenC3/cosmos/blob/main/openc3-cosmos-init/plugins/packages/openc3-cosmos-demo/targets/INST/screens/simple.txt">simple.txt</a> screen you&#x27;ll see we&#x27;re using the widgets:</p>
<pre><code class="language-ruby">SCREEN AUTO AUTO 0.5
LABELVALUE &lt;%= target_name %&gt; HEALTH_STATUS CCSDSSEQCNT
HELLOWORLD
BIG &lt;%= target_name %&gt; HEALTH_STATUS TEMP1
</code></pre>
<p>Opening this screen in Telemetry Viewer results in the following:</p>
<p><img alt="Simple Screen" src="/tools/staticdocs/assets/images/simple_screen-e3de1ad836c0661d73a0ba970f991c64df8ecc7e23f9e944b6508a9a43fbc33c.png" width="681" height="210"></p>
<p>While this is a simple example the possibilities with custom widgets are limitless!</p></div><footer class="theme-doc-footer docusaurus-mt-lg"><div class="theme-doc-footer-edit-meta-row row"><div class="col"><a href="https://github.com/OpenC3/cosmos/tree/main/docs.openc3.com/docs/guides/custom-widgets.md" target="_blank" rel="noopener noreferrer" class="theme-edit-this-page"><svg fill="currentColor" height="20" width="20" viewBox="0 0 40 40" class="iconEdit_UohW" aria-hidden="true"><g><path d="m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"></path></g></svg>Edit this page</a></div><div class="col lastUpdated_T23F"></div></div></footer></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages"><a class="pagination-nav__link pagination-nav__link--prev" href="/tools/staticdocs/docs/guides/cfs"><div class="pagination-nav__sublabel">Previous</div><div class="pagination-nav__label">COSMOS and NASA cFS</div></a><a class="pagination-nav__link pagination-nav__link--next" href="/tools/staticdocs/docs/guides/little-endian-bitfields"><div class="pagination-nav__sublabel">Next</div><div class="pagination-nav__label">Little Endian Bitfields</div></a></nav></div></div><div class="col col--3"><div class="tableOfContents_TN1Q thin-scrollbar theme-doc-toc-desktop"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#custom-widgets" class="table-of-contents__link toc-highlight">Custom Widgets</a><ul><li><a href="#helloworld-widget" class="table-of-contents__link toc-highlight">Helloworld Widget</a></li></ul></li></ul></div></div></div></div></main></div></div></div><footer class="footer footer--dark"><div class="container container-fluid"><div class="row footer__links"><div class="col footer__col"><div class="footer__title">Homepage</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://openc3.com" target="_blank" rel="noopener noreferrer" class="footer__link-item">Home</a></li></ul></div><div class="col footer__col"><div class="footer__title">Docs</div><ul class="footer__items clean-list"><li class="footer__item"><a class="footer__link-item" href="/tools/staticdocs/docs">Documentation</a></li></ul></div><div class="col footer__col"><div class="footer__title">Community</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://www.linkedin.com/company/openc3" target="_blank" rel="noopener noreferrer" class="footer__link-item">LinkedIn<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_awgD"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">More</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://github.com/OpenC3/cosmos" target="_blank" rel="noopener noreferrer" class="footer__link-item">GitHub<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_awgD"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a class="footer__link-item" href="/tools/staticdocs/docs/privacy">Privacy</a></li></ul></div></div><div class="footer__bottom text--center"><div class="footer__copyright">Copyright © 2024 OpenC3, Inc.</div></div></div></footer></div>
</body>
</html>