diff --git a/docs/smartchart/404.html b/docs/smartchart/404.html new file mode 100644 index 0000000..4542223 --- /dev/null +++ b/docs/smartchart/404.html @@ -0,0 +1,54 @@ + + + + + + + + + + + + + +404 Page not found | Smartchart开发手册 + + + + + + + + + + + + + + +
+
+

404

+

Page Not Found

+

+ Smartchart开发手册 +

+
+
+ + + + + diff --git a/docs/smartchart/book.min.c58292d36b18b675680ab9baea2029204537b839ea72f258746ec0f32ce8d6c8.css b/docs/smartchart/book.min.c58292d36b18b675680ab9baea2029204537b839ea72f258746ec0f32ce8d6c8.css new file mode 100644 index 0000000..77f54b8 --- /dev/null +++ b/docs/smartchart/book.min.c58292d36b18b675680ab9baea2029204537b839ea72f258746ec0f32ce8d6c8.css @@ -0,0 +1 @@ +@charset "UTF-8";:root{--gray-100:#f8f9fa;--gray-200:#e9ecef;--gray-500:#adb5bd;--color-link:#0055bb;--color-visited-link:#8440f1;--body-background:white;--body-font-color:black;--icon-filter:none;--hint-color-info:#6bf;--hint-color-warning:#fd6;--hint-color-danger:#f66}/*!normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css*/html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}.flex{display:flex}.flex-auto{flex:auto}.flex-even{flex:1 1}.flex-wrap{flex-wrap:wrap}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.align-center{align-items:center}.mx-auto{margin:0 auto}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.hidden{display:none}input.toggle{height:0;width:0;overflow:hidden;opacity:0;position:absolute}.clearfix::after{content:"";display:table;clear:both}html{font-size:16px;scroll-behavior:smooth;touch-action:manipulation}body{min-width:20rem;color:var(--body-font-color);background:var(--body-background);letter-spacing:.33px;font-weight:400;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;box-sizing:border-box}body *{box-sizing:inherit}h1,h2,h3,h4,h5{font-weight:400}a{text-decoration:none;color:var(--color-link)}img{vertical-align:baseline}:focus{outline-style:auto;outline-color:currentColor;outline-color:-webkit-focus-ring-color}aside nav ul{padding:0;margin:0;list-style:none}aside nav ul li{margin:1em 0;position:relative}aside nav ul a{display:block}aside nav ul a:hover{opacity:.5}aside nav ul ul{padding-inline-start:1rem}ul.pagination{display:flex;justify-content:center;list-style-type:none;padding-inline-start:0}ul.pagination .page-item a{padding:1rem}.container{max-width:80rem;margin:0 auto}.book-icon{filter:var(--icon-filter)}.book-brand{margin-top:0;margin-bottom:1rem}.book-brand img{height:1.5em;width:1.5em;margin-inline-end:.5rem}.book-menu{flex:0 0 16rem;font-size:.875rem}.book-menu .book-menu-content{width:16rem;padding:1rem;background:var(--body-background);position:fixed;top:0;bottom:0;overflow-x:hidden;overflow-y:auto}.book-menu a,.book-menu label{color:inherit;cursor:pointer;word-wrap:break-word}.book-menu a.active{color:var(--color-link)}.book-menu input.toggle+label+ul{display:none}.book-menu input.toggle:checked+label+ul{display:block}.book-menu input.toggle+label::after{content:"▸"}.book-menu input.toggle:checked+label::after{content:"▾"}body[dir=rtl] .book-menu input.toggle+label::after{content:"◂"}body[dir=rtl] .book-menu input.toggle:checked+label::after{content:"▾"}.book-section-flat{margin:2rem 0}.book-section-flat>a,.book-section-flat>span,.book-section-flat>label{font-weight:bolder}.book-section-flat>ul{padding-inline-start:0}.book-page{min-width:20rem;flex-grow:1;padding:1rem}.book-post{margin-bottom:3rem}.book-header{display:none;margin-bottom:1rem}.book-header label{line-height:0}.book-header img.book-icon{height:1.5em;width:1.5em}.book-search{position:relative;margin:1rem 0;border-bottom:1px solid transparent}.book-search input{width:100%;padding:.5rem;border:0;border-radius:.25rem;background:var(--gray-100);color:var(--body-font-color)}.book-search input:required+.book-search-spinner{display:block}.book-search .book-search-spinner{position:absolute;top:0;margin:.5rem;margin-inline-start:calc(100% - 1.5rem);width:1rem;height:1rem;border:1px solid transparent;border-top-color:var(--body-font-color);border-radius:50%;animation:spin 1s ease infinite}@keyframes spin{100%{transform:rotate(360deg)}}.book-search small{opacity:.5}.book-toc{flex:0 0 16rem;font-size:.75rem}.book-toc .book-toc-content{width:16rem;padding:1rem;position:fixed;top:0;bottom:0;overflow-x:hidden;overflow-y:auto}.book-toc img{height:1em;width:1em}.book-toc nav>ul>li:first-child{margin-top:0}.book-footer{padding-top:1rem;font-size:.875rem}.book-footer img{height:1em;width:1em;margin-inline-end:.5rem}.book-comments{margin-top:1rem}.book-languages{margin-block-end:2rem}.book-languages .book-icon{height:1em;width:1em;margin-inline-end:.5em}.book-languages ul{padding-inline-start:1.5em}.book-menu-content,.book-toc-content,.book-page,.book-header aside,.markdown{transition:.2s ease-in-out;transition-property:transform,margin,opacity,visibility;will-change:transform,margin,opacity}@media screen and (max-width:56rem){#menu-control,#toc-control{display:inline}.book-menu{visibility:hidden;margin-inline-start:-16rem;font-size:16px;z-index:1}.book-toc{display:none}.book-header{display:block}#menu-control:focus~main label[for=menu-control]{outline-style:auto;outline-color:currentColor;outline-color:-webkit-focus-ring-color}#menu-control:checked~main .book-menu{visibility:initial}#menu-control:checked~main .book-menu .book-menu-content{transform:translateX(16rem);box-shadow:0 0 .5rem rgba(0,0,0,.1)}#menu-control:checked~main .book-page{opacity:.25}#menu-control:checked~main .book-menu-overlay{display:block;position:absolute;top:0;bottom:0;left:0;right:0}#toc-control:focus~main label[for=toc-control]{outline-style:auto;outline-color:currentColor;outline-color:-webkit-focus-ring-color}#toc-control:checked~main .book-header aside{display:block}body[dir=rtl] #menu-control:checked~main .book-menu .book-menu-content{transform:translateX(-16rem)}}@media screen and (min-width:80rem){.book-page,.book-menu .book-menu-content,.book-toc .book-toc-content{padding:2rem 1rem}}@font-face{font-family:roboto;font-style:normal;font-weight:400;font-display:swap;src:local(""),url(fonts/roboto-v27-latin-regular.woff2)format("woff2"),url(fonts/roboto-v27-latin-regular.woff)format("woff")}@font-face{font-family:roboto;font-style:normal;font-weight:700;font-display:swap;src:local(""),url(fonts/roboto-v27-latin-700.woff2)format("woff2"),url(fonts/roboto-v27-latin-700.woff)format("woff")}@font-face{font-family:roboto mono;font-style:normal;font-weight:400;font-display:swap;src:local(""),url(fonts/roboto-mono-v13-latin-regular.woff2)format("woff2"),url(fonts/roboto-mono-v13-latin-regular.woff)format("woff")}body{font-family:roboto,sans-serif}code{font-family:roboto mono,monospace}@media print{.book-menu,.book-footer,.book-toc{display:none}.book-header,.book-header aside{display:block}main{display:block!important}}.markdown{line-height:1.6}.markdown>:first-child{margin-top:0}.markdown h1,.markdown h2,.markdown h3,.markdown h4,.markdown h5,.markdown h6{font-weight:400;line-height:1;margin-top:1.5em;margin-bottom:1rem}.markdown h1 a.anchor,.markdown h2 a.anchor,.markdown h3 a.anchor,.markdown h4 a.anchor,.markdown h5 a.anchor,.markdown h6 a.anchor{opacity:0;font-size:.75em;vertical-align:middle;text-decoration:none}.markdown h1:hover a.anchor,.markdown h1 a.anchor:focus,.markdown h2:hover a.anchor,.markdown h2 a.anchor:focus,.markdown h3:hover a.anchor,.markdown h3 a.anchor:focus,.markdown h4:hover a.anchor,.markdown h4 a.anchor:focus,.markdown h5:hover a.anchor,.markdown h5 a.anchor:focus,.markdown h6:hover a.anchor,.markdown h6 a.anchor:focus{opacity:initial}.markdown h4,.markdown h5,.markdown h6{font-weight:bolder}.markdown h5{font-size:.875em}.markdown h6{font-size:.75em}.markdown b,.markdown optgroup,.markdown strong{font-weight:bolder}.markdown a{text-decoration:none}.markdown a:hover{text-decoration:underline}.markdown a:visited{color:var(--color-visited-link)}.markdown img{max-width:100%;height:auto}.markdown code{padding:0 .25rem;background:var(--gray-200);border-radius:.25rem;font-size:.875em}.markdown pre{padding:1rem;background:var(--gray-100);border-radius:.25rem;overflow-x:auto}.markdown pre code{padding:0;background:0 0}.markdown p{word-wrap:break-word}.markdown blockquote{margin:1rem 0;padding:.5rem 1rem .5rem .75rem;border-inline-start:.25rem solid var(--gray-200);border-radius:.25rem}.markdown blockquote :first-child{margin-top:0}.markdown blockquote :last-child{margin-bottom:0}.markdown table{overflow:auto;display:block;border-spacing:0;border-collapse:collapse;margin-top:1rem;margin-bottom:1rem}.markdown table tr th,.markdown table tr td{padding:.5rem 1rem;border:1px solid var(--gray-200)}.markdown table tr:nth-child(2n){background:var(--gray-100)}.markdown hr{height:1px;border:none;background:var(--gray-200)}.markdown ul,.markdown ol{padding-inline-start:2rem}.markdown dl dt{font-weight:bolder;margin-top:1rem}.markdown dl dd{margin-inline-start:0;margin-bottom:1rem}.markdown .highlight table tr td:nth-child(1) pre{margin:0;padding-inline-end:0}.markdown .highlight table tr td:nth-child(2) pre{margin:0;padding-inline-start:0}.markdown details{padding:1rem;border:1px solid var(--gray-200);border-radius:.25rem}.markdown details summary{line-height:1;padding:1rem;margin:-1rem;cursor:pointer}.markdown details[open] summary{margin-bottom:0}.markdown figure{margin:1rem 0}.markdown figure figcaption p{margin-top:0}.markdown-inner>:first-child{margin-top:0}.markdown-inner>:last-child{margin-bottom:0}.markdown .book-expand{margin-top:1rem;margin-bottom:1rem;border:1px solid var(--gray-200);border-radius:.25rem;overflow:hidden}.markdown .book-expand .book-expand-head{background:var(--gray-100);padding:.5rem 1rem;cursor:pointer}.markdown .book-expand .book-expand-content{display:none;padding:1rem}.markdown .book-expand input[type=checkbox]:checked+.book-expand-content{display:block}.markdown .book-tabs{margin-top:1rem;margin-bottom:1rem;border:1px solid var(--gray-200);border-radius:.25rem;overflow:hidden;display:flex;flex-wrap:wrap}.markdown .book-tabs label{display:inline-block;padding:.5rem 1rem;border-bottom:1px transparent;cursor:pointer}.markdown .book-tabs .book-tabs-content{order:999;width:100%;border-top:1px solid var(--gray-100);padding:1rem;display:none}.markdown .book-tabs input[type=radio]:checked+label{border-bottom:1px solid var(--color-link)}.markdown .book-tabs input[type=radio]:checked+label+.book-tabs-content{display:block}.markdown .book-tabs input[type=radio]:focus+label{outline-style:auto;outline-color:currentColor;outline-color:-webkit-focus-ring-color}.markdown .book-columns{margin-left:-1rem;margin-right:-1rem}.markdown .book-columns>div{margin:1rem 0;min-width:10rem;padding:0 1rem}.markdown a.book-btn{display:inline-block;font-size:.875rem;color:var(--color-link);line-height:2rem;padding:0 1rem;border:1px solid var(--color-link);border-radius:.25rem;cursor:pointer}.markdown a.book-btn:hover{text-decoration:none}.markdown .book-hint.info{border-color:#6bf;background-color:rgba(102,187,255,.1)}.markdown .book-hint.warning{border-color:#fd6;background-color:rgba(255,221,102,.1)}.markdown .book-hint.danger{border-color:#f66;background-color:rgba(255,102,102,.1)} \ No newline at end of file diff --git a/docs/smartchart/categories/index.html b/docs/smartchart/categories/index.html new file mode 100644 index 0000000..b8835cc --- /dev/null +++ b/docs/smartchart/categories/index.html @@ -0,0 +1,1661 @@ + + + + + + + + + + + + +Categories | Smartchart开发手册 + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Categories + + +
+ + + + + + +
+ + + + + + + + + +
+ +
+ + + + + +
+ + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/categories/index.xml b/docs/smartchart/categories/index.xml new file mode 100644 index 0000000..bc59f4f --- /dev/null +++ b/docs/smartchart/categories/index.xml @@ -0,0 +1,9 @@ + + + + Categories on Smartchart开发手册 + https://smartchart.gitee.io/categories/ + Recent content in Categories on Smartchart开发手册 + Hugo -- gohugo.io + + diff --git a/docs/smartchart/categories/page/1/index.html b/docs/smartchart/categories/page/1/index.html new file mode 100644 index 0000000..7447981 --- /dev/null +++ b/docs/smartchart/categories/page/1/index.html @@ -0,0 +1,10 @@ + + + + https://smartchart.gitee.io/categories/ + + + + + + diff --git a/docs/smartchart/docs/1.基础操作/VUE相关/DataV应用/index.html b/docs/smartchart/docs/1.基础操作/VUE相关/DataV应用/index.html new file mode 100644 index 0000000..2d735ef --- /dev/null +++ b/docs/smartchart/docs/1.基础操作/VUE相关/DataV应用/index.html @@ -0,0 +1,1644 @@ + + + + + + + + + + + + + + +Data V应用 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Data V应用 + + +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/1.基础操作/VUE相关/ElementUI/index.html b/docs/smartchart/docs/1.基础操作/VUE相关/ElementUI/index.html new file mode 100644 index 0000000..2250b66 --- /dev/null +++ b/docs/smartchart/docs/1.基础操作/VUE相关/ElementUI/index.html @@ -0,0 +1,1738 @@ + + + + + + + + + + + + + + +Element Ui | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Element Ui + + +
+ + + + + + +
+ + + +

+ 应用场景 + # +

+
    +
  • 非大屏场景应用
  • +
  • 有较多交互场景的报表, 如筛选,表格,分页,下载等
  • +
+

+ 使用方法 + # +

+

如下图, base.html 改为 basevue.html +将自动开启加载vue和elementui + + 输入图片说明 +注意vue的变量引用在 模板编辑界面中, 写法变更为 {[ ]}

+

+ ElementUI组件说明 + + 视屏参考

+

+ 参考样列 + # +

+

新增一个数据集(点击金色的新增按钮, 这样会新增一个可拖拽的数据集) +修改相应的数据集及图形 +数据集端

+
select  H1, H2, qty, rate from smartdemo2 limit 100
+

图形端

+
let dataset = __dataset__;
+let tableData = ds_createMap_all(dataset);
+
+vapp.d0={
+    tableData: tableData
+}
+

模板Body区端

+
<div class="smtdrag" id="id_1639824145817">
+    <template>
+    <el-table
+    stripe
+    border
+    height="100%"
+      :data="d0.tableData"
+      style="width: 100%">
+     <el-table-column label="hero">
+      <el-table-column
+        prop="H1"
+        label="H1"
+        fixed
+        :default-sort = "{prop: 'H2', order: 'descending'}"
+        width="180">
+      </el-table-column>
+      <el-table-column
+        prop="H2"
+        label="H2"
+        sortable
+        width="180">
+      </el-table-column>
+     </el-table-column>
+     
+      <el-table-column
+        sortable
+        prop="qty"
+        label="qty">
+      </el-table-column>
+      <el-table-column
+        prop="rate"
+        label="rate">
+      </el-table-column>
+    </el-table>
+    </template>
+  </div>
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/1.基础操作/VUE相关/index.html b/docs/smartchart/docs/1.基础操作/VUE相关/index.html new file mode 100644 index 0000000..ab754ae --- /dev/null +++ b/docs/smartchart/docs/1.基础操作/VUE相关/index.html @@ -0,0 +1,1626 @@ + + + + + + + + + + + + +Vue相关 | Smartchart开发手册 + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Vue相关 + + +
+ + + + + + +
+ + + +
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/1.基础操作/VUE相关/index.xml b/docs/smartchart/docs/1.基础操作/VUE相关/index.xml new file mode 100644 index 0000000..84b57c2 --- /dev/null +++ b/docs/smartchart/docs/1.基础操作/VUE相关/index.xml @@ -0,0 +1,43 @@ + + + + Smartchart开发手册 + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/VUE%E7%9B%B8%E5%85%B3/ + Recent content on Smartchart开发手册 + Hugo -- gohugo.io + + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/VUE%E7%9B%B8%E5%85%B3/%E4%BD%BF%E7%94%A8VUE/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/VUE%E7%9B%B8%E5%85%B3/%E4%BD%BF%E7%94%A8VUE/ + 使用场景 # 报表中涉及交互场景较多, 需要数据与页面绑定 开发者熟悉vue 常见绑定 # //显示变量message &lt;p&gt;{[ message ]}&lt;/p&gt; //循环产生li,变量sites &lt;ol&gt; &lt;li v-for=&#34;site in sites&#34;&gt; {[ site.name ]} &lt;/li&gt; &lt;/ol&gt; //绑定输入值变量use &lt;input type=&#34;checkbox&#34; v-model=&#34;use&#34;&gt; //显示控制 &lt;p v-if=&#34;seen&#34;&gt;现在你看到我了&lt;/p&gt; &lt;p v-show=&#34;seen&#34;&gt;现在你看到我了&lt;/p&gt; //绑定属性 &lt;a :href=&#34;url&#34;&gt;&lt;/a&gt; &lt;div :style=&#34;{ color: activeColor, fontSize: fontSize + &#39;px&#39; }&#34;&gt;&lt;/div&gt; &lt;div :class=&#34;[errorClass ,isActive ? activeClass : &#39;&#39;]&#34;&gt;&lt;/div&gt; //绑定点击方法 &lt;a @click=&#34;doSomething&#34;&gt;&lt;/a&gt; 开启VUE # 需要在高级中加入“dv”:2,即可开启vue模式 你可以在图形编辑器中给vue的变量赋值,我们内置了17个变量,从d0, d1&hellip; d16 赋值方式 vapp.d0 = xxxx 你可以将d0赋值为字典, 如: vapp.d0 = { &lsquo;index1&rsquo;: 100, &lsquo;index2&rsquo;: 300} + + + + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/VUE%E7%9B%B8%E5%85%B3/ElementUI/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/VUE%E7%9B%B8%E5%85%B3/ElementUI/ + 应用场景 # 非大屏场景应用 有较多交互场景的报表, 如筛选,表格,分页,下载等 使用方法 # 如下图, base.html 改为 basevue.html 将自动开启加载vue和elementui 注意vue的变量引用在 模板编辑界面中, 写法变更为 {[ ]} +ElementUI组件说明 视屏参考 +参考样列 # 新增一个数据集(点击金色的新增按钮, 这样会新增一个可拖拽的数据集) 修改相应的数据集及图形 数据集端 +select H1, H2, qty, rate from smartdemo2 limit 100 图形端 +let dataset = __dataset__; let tableData = ds_createMap_all(dataset); vapp.d0={ tableData: tableData } 模板Body区端 +&lt;div class=&#34;smtdrag&#34; id=&#34;id_1639824145817&#34;&gt; &lt;template&gt; &lt;el-table stripe border height=&#34;100%&#34; :data=&#34;d0.tableData&#34; style=&#34;width: 100%&#34;&gt; &lt;el-table-column label=&#34;hero&#34;&gt; &lt;el-table-column prop=&#34;H1&#34; label=&#34;H1&#34; fixed :default-sort = &#34;{prop: &#39;H2&#39;, order: &#39;descending&#39;}&#34; width=&#34;180&#34;&gt; &lt;/el-table-column&gt; &lt;el-table-column prop=&#34;H2&#34; label=&#34;H2&#34; sortable width=&#34;180&#34;&gt; &lt;/el-table-column&gt; &lt;/el-table-column&gt; &lt;el-table-column sortable prop=&#34;qty&#34; label=&#34;qty&#34;&gt; &lt;/el-table-column&gt; &lt;el-table-column prop=&#34;rate&#34; label=&#34;rate&#34;&gt; &lt;/el-table-column&gt; &lt;/el-table&gt; &lt;/template&gt; &lt;/div&gt; + + + + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/VUE%E7%9B%B8%E5%85%B3/DataV%E5%BA%94%E7%94%A8/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/VUE%E7%9B%B8%E5%85%B3/DataV%E5%BA%94%E7%94%A8/ + 需要在高级中加入“dv”:1,即可开启datav模式 +参考视屏 1. DataV基础应用 2. DataV翻盘器 +DataV配置方法文档: 图表 + + + + diff --git a/docs/smartchart/docs/1.基础操作/VUE相关/使用VUE/index.html b/docs/smartchart/docs/1.基础操作/VUE相关/使用VUE/index.html new file mode 100644 index 0000000..e61ae6f --- /dev/null +++ b/docs/smartchart/docs/1.基础操作/VUE相关/使用VUE/index.html @@ -0,0 +1,1723 @@ + + + + + + + + + + + + + + +使用 Vue | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 使用 Vue + + +
+ + + + + + +
+ + + +

+ 使用场景 + # +

+
    +
  • 报表中涉及交互场景较多, 需要数据与页面绑定
  • +
  • 开发者熟悉vue
  • +
+

+ 常见绑定 + # +

+
//显示变量message
+<p>{[ message ]}</p>
+//循环产生li,变量sites
+<ol>
+<li v-for="site in sites">
+  {[ site.name ]}
+</li>
+</ol>
+//绑定输入值变量use
+<input type="checkbox" v-model="use">
+//显示控制
+<p v-if="seen">现在你看到我了</p>
+<p v-show="seen">现在你看到我了</p>
+//绑定属性
+<a :href="url"></a>
+<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
+<div :class="[errorClass ,isActive ? activeClass : '']"></div>
+//绑定点击方法
+<a @click="doSomething"></a>
+

+ 开启VUE + # +

+

需要在高级中加入“dv”:2,即可开启vue模式 + + 输入图片说明 +你可以在图形编辑器中给vue的变量赋值,我们内置了17个变量,从d0, d1… d16 +赋值方式 vapp.d0 = xxxx + + 输入图片说明

+

你可以将d0赋值为字典, 如: +vapp.d0 = { ‘index1’: 100, ‘index2’: 300}

+
+

注意,我们修改了vue的默认引用方式, 你需要采用如下方法引用: +{[d0.index1]}

+
+

+ 使用模板可以更方便使用VUE + # +

+

你也可以在 模板开发中 使用VUE +开启方法, 首先你需要在高级设定中 , 设定 “template”:“diy”, +然后你可以看到 模板 的菜单, 进入编辑器

+

如果你需要更多自定义的方法, 例如加入方法, 你可以在模板的script中加入自定义代码

+
<script>
+    var vapp = new Vue({el: '#vue_app', delimiters: ['{[', ']}'], 
+      data: {
+              tableData:''
+        },
+      methods: {
+          formatter(row, column) {
+            return row.address;
+        }
+    }
+    });
+</script>
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/1.基础操作/index.html b/docs/smartchart/docs/1.基础操作/index.html new file mode 100644 index 0000000..0a2b434 --- /dev/null +++ b/docs/smartchart/docs/1.基础操作/index.html @@ -0,0 +1,1626 @@ + + + + + + + + + + + + +1.基础操作 | Smartchart开发手册 + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 1.基础操作 + + +
+ + + + + + +
+ + + +
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/1.基础操作/index.xml b/docs/smartchart/docs/1.基础操作/index.xml new file mode 100644 index 0000000..4db3cdc --- /dev/null +++ b/docs/smartchart/docs/1.基础操作/index.xml @@ -0,0 +1,85 @@ + + + + Smartchart开发手册 + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/ + Recent content on Smartchart开发手册 + Hugo -- gohugo.io + + 专业版本说明 + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E4%B8%93%E4%B8%9A%E7%89%88%E8%AF%B4%E6%98%8E/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E4%B8%93%E4%B8%9A%E7%89%88%E8%AF%B4%E6%98%8E/ + 版权声明 # 为项目能持续维护,并保持稳定的模式,按照社区投票的意见, 开始区分免费版本和专业版本 目前免费版本无需激活, 你可以使用到常用的功能,我们也会保持持续的更新 为保持项目的健康发展,如需进行商用,您需提供使用方并知会作者进行授权 +免费版使用者必须保留SmartChart相关版权标识及LOGO,禁止对其进行修改和删除 如果违反,将保留对侵权者追究责任的权利 +激活方式 # 您在初次安装Smartchart后会自动免费激活20天的专业版本, 之后专业版本功能会限制使用 请务必仔细阅读免费版本与专业版本的区别, 避免带来的不便 后续如果您还需要继续体验专业版本, 点击查看激活试用方式, 如果您是企业用途,建意使用专业版,获取更快的开发效率,可视化效果, 可靠性的保障及极速的查询体验 +针对个人独立开发者,你可以采用廉价的专业版仪表盘激活方案, 可满足小项目的可视化要求 如果需要永久激活专业版,可关注公众号与客服联系,或扫码联系微信客服了解, 非诚勿扰 +微信客服不提供技术咨询, 如有使用方法的疑惑,建意加QQ群:476715246 进行沟通 +免费版本与专业版本对比: # 功能 免费版 专业版 中台版 栅格布局 V V V DATAV V V V 拖拽布局 V V 自由开发 V V 切换图表主题 V V 主题自由设计 V V 引入JS V V 引入CSS V V 上传静态资源 V V 使用VUE V V V 数据集开发 V V V 所有数据源 V V V 图形开发 V V V 图形商店 V V V 普通模板应用 V V V 专业模板应用 V V 复制仪表盘 V V V 钻取 V V V 联动 V V V 筛选 V V V 单点登录 V V V 嵌入认证 V V LDAP认证 V V Juypter V V V 快捷存档 V V 数据加速 V V 数据API服务 V V 后台API刷新 V V 仪表盘同步 V V 仪表盘版本管理 V V 数据填报 V V 报表Portal V V 多级项目菜单 V 商业授权 V V 优先咨询 V V 专业边框背景 V V 3D场景 V V 中国式报表 V V 生产部署文档 V V 个性化修改 V V 授权书 V V 低代码ETL V 调度平台 V 智慧BI V 数据资产 V 数据血缘 V 租户管理 V + + + + 快速开始 + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B/ + 开发前你可以先观看操作方面的 :exclamation: 操作视屏教程 :exclamation: 5.0变更操作视屏教程 :exclamation: 开发系列合集,关注作者持续更新 +由于版本的变更, 一些图标可能会有一些变化, 但位置无太大的变化 +安装Python环境 # 环境准备: 官方 最新Python下载链接,可以到 淘宝镜象下载,也可以下载 WINDOWS64位安装版, MAC电脑安装版 +Window平台安装视屏介绍,注意: Windows安装Python时需选中&quot;Add to Path&quot; Linux安装可参考文档下方的部署说明, Linux安装说明 +安装SmartChart # 在Shell或CMD命令行执行 +pip3 install smartchart 如果安装过程慢,建意使用 pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple smartchart -U 升级方法: pip3 install smartchart -U (升级) 启动smartchart # 本地命令行启动: smartchart 如果你是服务器部署,远程访问,服务端启动方式: smartchart runserver 0.0.0.0:8000 --insecure --noreload 如果出现套接字,端口被占用, 可修改端口号启动, 如 smartchart runserver 0.0.0.0:8001 --insecure --noreload 一般本地启动后访问: http://127.0.0.1:8000 管理员帐号密码: admin/admin, 请及时更改密码 +如果忘记密码, 可以使用此命令重置 smartchart changepassword 用户名 鼠标滑动,点击如下图DEV图标, 切换为开发模式,这样才可以看到开发相关菜单,后打开demo页面 注意: 不切换是正常的用户报表浏览模式! + + + + 第一个仪表盘 + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E7%AC%AC%E4%B8%80%E4%B8%AA%E4%BB%AA%E8%A1%A8%E7%9B%98/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E7%AC%AC%E4%B8%80%E4%B8%AA%E4%BB%AA%E8%A1%A8%E7%9B%98/ + 由于版本的变更, 一些图标可能会有一些变化, 但位置无太大的变化 +新建仪表盘 # 在开发模式下,滑动“开发管理” -&gt;&ldquo;仪表盘&rdquo;-&gt; &ldquo;新增Dashboard&rdquo; 填写相应信息后点击“保存” 点击进入仪表盘开发, 注意点击 &ldquo;E&rdquo; 字!! 点击新增(注意拖拽布局功能为PRO版本, 后续免费版本中将无法使用), 如果你坚持使用免费版本功能, 请使用左边的蓝色颜色的新增, 具体布局方式参考 数据集编辑 # 点开“数据集” 输入以下SQL后,点击“保存并刷新”, 关闭数据集编辑界面 select H1 as heroname, sum(qty) as 出场数 from smartdemo2 group by H1 order by sum(qty) desc 图形编辑 # 点开“图形编辑” 点击“云图标”,第一次使用可能要你进行登记,按提示操作即可, 在商店中找到合适的图形点击,会自动复制到剪贴板 贴粘到图形编辑器后,点击保存, 关闭图形编辑框 拖拽布局 # 重复以上步骤,再新增一个, 你可以使用拖拽的方式, 移动到不同的地方 + + + + 创建连接池 + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E5%88%9B%E5%BB%BA%E8%BF%9E%E6%8E%A5%E6%B1%A0/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E5%88%9B%E5%BB%BA%E8%BF%9E%E6%8E%A5%E6%B1%A0/ + 如何新增数据源 # 在开发模式下,点击“开发管理”-&gt;数据源-&gt;新增 配置连接池参数,注意数据库填写是备注中有写的名称 你可以通过新建一个数据集来测试连接池的连通性 +点击“保存” 后,回到数据集列表 点击如下图标&quot;E&quot;,进入数据集开发界面 在开发界面调试 安全控制 # 你可以在“参数”中设定安全控制,可避免用户误操作导致前后端卡死 limit: 可限定最大返回数据数量(但实际数据库查询无limit,需通过mode控制) mode: 控制用户查询行为,默认为模式1 +模式 说明 0 严格模式,每次查询向数据库都会增加limit,MPP类型数据库可能会排序失效 1 开发模式,仅调试查询数据库都会增加limit,调试时MPP类型数据库可能会排序失效,但不影响实际 2 宽松模式,查询都不带limit, 仅控制返回limit,需开发者避免大查询 支持的数据源: # 数据库 驱动填写 需安装 使用说明 Mysql mysql 默认支持 Mysql连接池 mysqlpool Sqlite sqlite 默认支持 连接地址填写绝对路径 API 任意 默认支持 参考数据集说明文档 EXCEL 任意 默认支持 参考数据集说明文档 SQL Server mssql 需安装 pip install pymssql SQL Server连接池 mssqlpool ORACLE oracle pip install cx_Oracle ORACLE连接池 oraclepool PostgreSql gp pip install psycopg2 GP gp pip install psycopg2 Impala impala pip install impyla Hive hive pip install impyla DB2 db2 pip install ibm_db 达梦 dm pip install dmPython Python python pip install pandas, openpyxl 参考数据集-&gt;特殊数据源 Redis redis pip install redis 参考数据集-&gt;特殊数据源 Mongodb mongodb pip install pymongo 参考数据集-&gt;特殊数据源 Clickhouse clickhouse pip install clickhouse_driver Elasticsearch es pip install elasticsearch==7. + + + + 应用模板 + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E5%BA%94%E7%94%A8%E6%A8%A1%E6%9D%BF/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E5%BA%94%E7%94%A8%E6%A8%A1%E6%9D%BF/ + 应用场景 # 你可以快速应用开发好的模板,极大的提高你的开发和学习效率 +应用本地模板 # 你可以快速应用本地备份的模板, 我们内置了一个 通用的数据查询和下载模板 , 你可以尝试 +新建一个全新的dashboard, 不要放任何报表, 点击保存且编辑后, 下方可以看到下载链接, 然后点击下载即可直接应用 输入&quot;01_SMARTCHART&quot;, 点击本地恢复即可 更多本地备份恢复参考 +应用商店模板 # 方法同上&quot;应用本地模板&quot;, 注意应用商店模板为收费增值服务 +你可以点击 模板查询, 查看相应的价格后在 TB购买即可获取下载密钥 如果是全新的仪表盘, 直接输入下载密钥, 点击&quot; 商城下载 &ldquo;即可 如果仪表盘中有数据集且不再需要, 可以在下载密钥前面加上FORCE即可自动清空已有数据集后自动下载 注意模板太廉价,购买后并没有咨询服务,请务必自行了解如何使用 +资源文件放置路径 有些资源会离线打包提供给你, 只需上传即可, 上传方法参考 +如果不清楚可以观看视屏说明 使用方法可参考视屏: 一键应用模板 + + + + 权限管理 + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E6%9D%83%E9%99%90%E7%AE%A1%E7%90%86/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E6%9D%83%E9%99%90%E7%AE%A1%E7%90%86/ + 目前的权限管理,大概如下: +开发者权限 # 你点击DEV后, 才会出进入后台的图标, 在后台中你可以控制用户的开发权限 新建用户默认是没有开发权限的, 在首页也看不到任何开发相关的菜单 +如果你需要给用户开发权限, 需要设定如下: Dashboard报表查看权限 # 你可以在 仪表盘设定 中进行权限管理 全局编辑或查看权限 由平台用户组或用户权限配置, 如果用户需要查看报表, 需先分配到有查看权限的组中, 默认加入集团组可以具备查看权限 在dashboard设定页面中可针对人员来分配 编辑权限, 有编辑权限同时也会满足查看权限 在dashboard设定页面中可针对组来分配 查看权限 未上线 的报表, 只会在编辑页面中出现, 可以预览 公开 的报表, 如没有分配编辑权限,在编辑页面中不出现, 但在查看页面所有人可见,你可以共享给所有人,访问url: http://xxxxx:8000/echart?type=你的仪表盘名称 手机端过滤, 你可以通过 &ldquo;全端&rdquo;,&ldquo;电脑端&rdquo; 选项实现, 当勾选 &ldquo;全端&rdquo; 时, 手机端电脑端都会显示, 当未勾选 全端, 也不勾选 电脑端时, 只会在 手机显示, 反之只在电脑端显示 总结 # 在编辑入口只会显示 有按人员分配编辑权限的报表清单, 在查看入口中会显示已启用且上线且(已分配查看权限或编辑权限或公开)的报表 所以你可以么这么搭配: 对于通用报表可以所有人访问的, 但你又不想让他在清单中显示, 你可以将他设为公开但不上线 对于开发中的报表, 你可以设为未上线 + + + + diff --git a/docs/smartchart/docs/1.基础操作/不太重要/index.html b/docs/smartchart/docs/1.基础操作/不太重要/index.html new file mode 100644 index 0000000..bf47fe8 --- /dev/null +++ b/docs/smartchart/docs/1.基础操作/不太重要/index.html @@ -0,0 +1,1626 @@ + + + + + + + + + + + + +不太重要 | Smartchart开发手册 + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 不太重要 + + +
+ + + + + + +
+ + + +
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/1.基础操作/不太重要/index.xml b/docs/smartchart/docs/1.基础操作/不太重要/index.xml new file mode 100644 index 0000000..7e048b9 --- /dev/null +++ b/docs/smartchart/docs/1.基础操作/不太重要/index.xml @@ -0,0 +1,28 @@ + + + + Smartchart开发手册 + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E4%B8%8D%E5%A4%AA%E9%87%8D%E8%A6%81/ + Recent content on Smartchart开发手册 + Hugo -- gohugo.io + + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E4%B8%8D%E5%A4%AA%E9%87%8D%E8%A6%81/%E4%B8%BB%E9%A2%98%E5%BA%94%E7%94%A8PRO/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E4%B8%8D%E5%A4%AA%E9%87%8D%E8%A6%81/%E4%B8%BB%E9%A2%98%E5%BA%94%E7%94%A8PRO/ + 点击smartchart图标,切换到菜单固定模式, 你可看到主题的选择 + + + + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E4%B8%8D%E5%A4%AA%E9%87%8D%E8%A6%81/%E5%A4%8D%E5%88%B6%E4%BB%AA%E8%A1%A8%E7%9B%98/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E4%B8%8D%E5%A4%AA%E9%87%8D%E8%A6%81/%E5%A4%8D%E5%88%B6%E4%BB%AA%E8%A1%A8%E7%9B%98/ + 复制仪表盘 # 好不容易开发好了一个仪表盘, 想再做一个类似的, 或者想要一个测试用, 还需要一个个数据集, 图形复制粘贴么, 不, 你仅仅只需要点击下, 将给你复制出一个全新的仪表盘 注意: 复制出来的仪表盘, 数据集是与原仪表盘公用的!! +如果你想将数据集独立出来, 可以按下图操作, 进入数据集设定, 点击磁铁, 将为你自动创建一个全新的数据集 + + + + diff --git a/docs/smartchart/docs/1.基础操作/不太重要/主题应用PRO/index.html b/docs/smartchart/docs/1.基础操作/不太重要/主题应用PRO/index.html new file mode 100644 index 0000000..3e9f031 --- /dev/null +++ b/docs/smartchart/docs/1.基础操作/不太重要/主题应用PRO/index.html @@ -0,0 +1,1636 @@ + + + + + + + + + + + + + + +主题应用 Pro | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 主题应用 Pro + + +
+ + + + + + +
+ + + +

点击smartchart图标,切换到菜单固定模式, 你可看到主题的选择 + + 输入图片说明

+

+ 输入图片说明

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/1.基础操作/不太重要/复制仪表盘/index.html b/docs/smartchart/docs/1.基础操作/不太重要/复制仪表盘/index.html new file mode 100644 index 0000000..6bc6bb3 --- /dev/null +++ b/docs/smartchart/docs/1.基础操作/不太重要/复制仪表盘/index.html @@ -0,0 +1,1672 @@ + + + + + + + + + + + + + + +复制仪表盘 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 复制仪表盘 + + +
+ + + + + + +
+ + + +

+ 复制仪表盘 + # +

+
    +
  • 好不容易开发好了一个仪表盘, 想再做一个类似的, 或者想要一个测试用, 还需要一个个数据集, 图形复制粘贴么, 不, 你仅仅只需要点击下, 将给你复制出一个全新的仪表盘 + + 输入图片说明
  • +
+

注意: 复制出来的仪表盘, 数据集是与原仪表盘公用的!!

+
    +
  • 如果你想将数据集独立出来, 可以按下图操作, 进入数据集设定, 点击磁铁, 将为你自动创建一个全新的数据集 + + 输入图片说明
  • +
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/1.基础操作/专业版说明/index.html b/docs/smartchart/docs/1.基础操作/专业版说明/index.html new file mode 100644 index 0000000..15a39d2 --- /dev/null +++ b/docs/smartchart/docs/1.基础操作/专业版说明/index.html @@ -0,0 +1,1994 @@ + + + + + + + + + + + + + + +专业版本说明 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 专业版本说明 + + +
+ + + + + + +
+ + + +

+ 版权声明 + # +

+

为项目能持续维护,并保持稳定的模式,按照社区投票的意见, 开始区分免费版本和专业版本 +目前免费版本无需激活, 你可以使用到常用的功能,我们也会保持持续的更新 +为保持项目的健康发展,如需进行商用,您需提供使用方并知会作者进行授权

+
+

免费版使用者必须保留SmartChart相关版权标识及LOGO,禁止对其进行修改和删除 +如果违反,将保留对侵权者追究责任的权利

+
+

+ 激活方式 + # +

+

您在初次安装Smartchart后会自动免费激活20天的专业版本, 之后专业版本功能会限制使用 +请务必仔细阅读免费版本与专业版本的区别, 避免带来的不便 +后续如果您还需要继续体验专业版本, + 点击查看激活试用方式, +如果您是企业用途,建意使用专业版,获取更快的开发效率,可视化效果, 可靠性的保障及极速的查询体验

+
+

针对个人独立开发者,你可以采用廉价的专业版仪表盘激活方案, 可满足小项目的可视化要求 +如果需要永久激活专业版,可关注公众号与客服联系,或扫码联系微信客服了解, 非诚勿扰

+
+

+

微信客服不提供技术咨询, 如有使用方法的疑惑,建意加QQ群:476715246 进行沟通

+

+ 免费版本与专业版本对比: + # +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
功能免费版专业版中台版
栅格布局VVV
DATAVVVV
拖拽布局VV
自由开发VV
切换图表主题VV
主题自由设计VV
引入JSVV
引入CSSVV
上传静态资源VV
使用VUEVVV
数据集开发VVV
所有数据源VVV
图形开发VVV
图形商店VVV
普通模板应用VVV
专业模板应用VV
复制仪表盘VVV
钻取VVV
联动VVV
筛选VVV
单点登录VVV
嵌入认证VV
LDAP认证VV
JuypterVVV
快捷存档VV
数据加速VV
数据API服务VV
后台API刷新VV
仪表盘同步VV
仪表盘版本管理VV
数据填报VV
报表PortalVV
多级项目菜单V
商业授权VV
优先咨询VV
+ 专业边框背景VV
3D场景VV
中国式报表VV
生产部署文档VV
个性化修改VV
授权书VV
低代码ETLV
调度平台V
智慧BIV
数据资产V
数据血缘V
租户管理V
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/1.基础操作/创建连接池/index.html b/docs/smartchart/docs/1.基础操作/创建连接池/index.html new file mode 100644 index 0000000..346ba5f --- /dev/null +++ b/docs/smartchart/docs/1.基础操作/创建连接池/index.html @@ -0,0 +1,1873 @@ + + + + + + + + + + + + + + +创建连接池 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 创建连接池 + + +
+ + + + + + +
+ + + +

+ 如何新增数据源 + # +

+
    +
  • +

    在开发模式下,点击“开发管理”->数据源->新增 +

    +
  • +
  • +

    配置连接池参数,注意数据库填写是备注中有写的名称 +

    +
  • +
  • +

    你可以通过新建一个数据集来测试连接池的连通性

    +
  • +
  • +

    点击“保存” 后,回到数据集列表 点击如下图标"E",进入数据集开发界面 +

    +
  • +
  • +

    在开发界面调试 +

    +
  • +
+

+ 安全控制 + # +

+

你可以在“参数”中设定安全控制,可避免用户误操作导致前后端卡死 + + 输入图片说明 +limit: 可限定最大返回数据数量(但实际数据库查询无limit,需通过mode控制) +mode: 控制用户查询行为,默认为模式1

+ + + + + + + + + + + + + + + + + + + + + +
模式说明
0严格模式,每次查询向数据库都会增加limit,MPP类型数据库可能会排序失效
1开发模式,仅调试查询数据库都会增加limit,调试时MPP类型数据库可能会排序失效,但不影响实际
2宽松模式,查询都不带limit, 仅控制返回limit,需开发者避免大查询
+

+ 支持的数据源: + # +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
数据库驱动填写需安装使用说明
Mysqlmysql默认支持
Mysql连接池mysqlpool
Sqlitesqlite默认支持连接地址填写绝对路径
API任意默认支持参考数据集说明文档
EXCEL任意默认支持参考数据集说明文档
SQL Servermssql需安装 pip install pymssql
SQL Server连接池mssqlpool
ORACLEoraclepip install cx_Oracle
ORACLE连接池oraclepool
PostgreSqlgppip install psycopg2
GPgppip install psycopg2
Impalaimpalapip install impyla
Hivehivepip install impyla
DB2db2pip install ibm_db
达梦dmpip install dmPython
Pythonpythonpip install pandas, openpyxl参考数据集->特殊数据源
Redisredispip install redis参考数据集->特殊数据源
Mongodbmongodbpip install pymongo参考数据集->特殊数据源
Clickhouseclickhousepip install clickhouse_driver
Elasticsearchespip install elasticsearch==7.13.0参考数据集->特殊数据源
Sqlalchemysqlalchemypip install sqlalchemy参考数据集->特殊数据源
JDBCjdbcpip install JayDeBeApi参考数据集->特殊数据源
自定义自定义用户自由定义参考数据集->特殊数据源
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/1.基础操作/应用模板/index.html b/docs/smartchart/docs/1.基础操作/应用模板/index.html new file mode 100644 index 0000000..338dbce --- /dev/null +++ b/docs/smartchart/docs/1.基础操作/应用模板/index.html @@ -0,0 +1,1718 @@ + + + + + + + + + + + + + + +应用模板 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 应用模板 + + +
+ + + + + + +
+ + + +

+ 应用场景 + # +

+

你可以快速应用开发好的模板,极大的提高你的开发和学习效率

+

+ 应用本地模板 + # +

+

你可以快速应用本地备份的模板, 我们内置了一个 通用的数据查询和下载模板 , 你可以尝试

+
    +
  • +

    新建一个全新的dashboard, 不要放任何报表, 点击保存且编辑后, 下方可以看到下载链接, 然后点击下载即可直接应用 +

    +
  • +
  • +

    输入"01_SMARTCHART", 点击本地恢复即可 +

    +
  • +
+

+ 更多本地备份恢复参考

+

+ 应用商店模板 + # +

+

方法同上"应用本地模板", 注意应用商店模板为收费增值服务

+
    +
  • 你可以点击 + 模板查询, 查看相应的价格后在 + TB购买即可获取下载密钥
  • +
  • 如果是全新的仪表盘, 直接输入下载密钥, 点击" 商城下载 “即可
  • +
+
+

如果仪表盘中有数据集且不再需要, 可以在下载密钥前面加上FORCE即可自动清空已有数据集后自动下载 +注意模板太廉价,购买后并没有咨询服务,请务必自行了解如何使用

+
+
+

资源文件放置路径 +有些资源会离线打包提供给你, 只需上传即可, + 上传方法参考

+
+
+

如果不清楚可以观看视屏说明 +使用方法可参考视屏: + 一键应用模板

+
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/1.基础操作/快速开始/index.html b/docs/smartchart/docs/1.基础操作/快速开始/index.html new file mode 100644 index 0000000..4eece6a --- /dev/null +++ b/docs/smartchart/docs/1.基础操作/快速开始/index.html @@ -0,0 +1,1741 @@ + + + + + + + + + + + + + + +快速开始 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 快速开始 + + +
+ + + + + + +
+ + + +

开发前你可以先观看操作方面的 +:exclamation: + 操作视屏教程 :exclamation: + 5.0变更操作视屏教程 +:exclamation: + 开发系列合集,关注作者持续更新

+

由于版本的变更, 一些图标可能会有一些变化, 但位置无太大的变化

+

+ 安装Python环境 + # +

+ +

+ 安装SmartChart + # +

+

在Shell或CMD命令行执行

+
   pip3 install smartchart
+   
+   如果安装过程慢,建意使用
+   pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple smartchart -U
+
+   升级方法:
+   pip3 install smartchart -U (升级)
+

+ 启动smartchart + # +

+
   本地命令行启动: 
+   smartchart
+   如果你是服务器部署,远程访问,服务端启动方式: 
+   smartchart runserver 0.0.0.0:8000 --insecure --noreload
+   如果出现套接字,端口被占用, 可修改端口号启动, 如
+   smartchart runserver 0.0.0.0:8001 --insecure --noreload
+

一般本地启动后访问: http://127.0.0.1:8000 +管理员帐号密码: admin/admin, 请及时更改密码

+
如果忘记密码, 可以使用此命令重置
+smartchart changepassword 用户名
+
    +
  • 鼠标滑动,点击如下图DEV图标, 切换为开发模式,这样才可以看到开发相关菜单,后打开demo页面
  • +
+
+

注意: 不切换是正常的用户报表浏览模式!! + + 输入图片说明 +仅管理员或开发人员能看到DEV菜单,用户只会有报表菜单页面

+
+
    +
  • 尝试熟悉编辑菜单 + + 输入图片说明
  • +
  • 尝试点开数据集查看SQL写法, 图形编辑器, 容器等
  • +
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/1.基础操作/权限管理/index.html b/docs/smartchart/docs/1.基础操作/权限管理/index.html new file mode 100644 index 0000000..33e418d --- /dev/null +++ b/docs/smartchart/docs/1.基础操作/权限管理/index.html @@ -0,0 +1,1702 @@ + + + + + + + + + + + + + + +权限管理 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 权限管理 + + +
+ + + + + + +
+ + + +

目前的权限管理,大概如下:

+

+ 开发者权限 + # +

+

你点击DEV后, 才会出进入后台的图标, 在后台中你可以控制用户的开发权限 + + 输入图片说明

+

+ 输入图片说明 +新建用户默认是没有开发权限的, 在首页也看不到任何开发相关的菜单

+

如果你需要给用户开发权限, 需要设定如下: + + 输入图片说明 + + 输入图片说明

+

+ Dashboard报表查看权限 + # +

+

你可以在 仪表盘设定 中进行权限管理 + + 输入图片说明

+
    +
  • 全局编辑或查看权限 由平台用户组或用户权限配置, 如果用户需要查看报表, 需先分配到有查看权限的组中, 默认加入集团组可以具备查看权限
  • +
  • 在dashboard设定页面中可针对人员来分配 编辑权限, 有编辑权限同时也会满足查看权限
  • +
  • 在dashboard设定页面中可针对组来分配 查看权限
  • +
  • 未上线 的报表, 只会在编辑页面中出现, 可以预览
  • +
  • 公开 的报表, 如没有分配编辑权限,在编辑页面中不出现, 但在查看页面所有人可见,你可以共享给所有人,访问url: http://xxxxx:8000/echart?type=你的仪表盘名称
  • +
  • 手机端过滤, 你可以通过 “全端”,“电脑端” 选项实现, 当勾选 “全端” 时, 手机端电脑端都会显示, 当未勾选 全端, 也不勾选 电脑端时, 只会在 手机显示, 反之只在电脑端显示
  • +
+

+ 总结 + # +

+

在编辑入口只会显示 有按人员分配编辑权限的报表清单, 在查看入口中会显示已启用且上线且(已分配查看权限或编辑权限或公开)的报表 +所以你可以么这么搭配: +对于通用报表可以所有人访问的, 但你又不想让他在清单中显示, 你可以将他设为公开但不上线 +对于开发中的报表, 你可以设为未上线

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/1.基础操作/第一个仪表盘/index.html b/docs/smartchart/docs/1.基础操作/第一个仪表盘/index.html new file mode 100644 index 0000000..c9e7534 --- /dev/null +++ b/docs/smartchart/docs/1.基础操作/第一个仪表盘/index.html @@ -0,0 +1,1729 @@ + + + + + + + + + + + + + + +第一个仪表盘 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 第一个仪表盘 + + +
+ + + + + + +
+ + + +

由于版本的变更, 一些图标可能会有一些变化, 但位置无太大的变化

+

+ 新建仪表盘 + # +

+
    +
  • 在开发模式下,滑动“开发管理” ->“仪表盘”-> “新增Dashboard” + + 输入图片说明
  • +
  • 填写相应信息后点击“保存” + + 输入图片说明
  • +
  • 点击进入仪表盘开发, 注意点击 “E” 字!! + + 输入图片说明
  • +
  • 点击新增(注意拖拽布局功能为PRO版本, 后续免费版本中将无法使用), +如果你坚持使用免费版本功能, 请使用左边的蓝色颜色的新增, + 具体布局方式参考 + + 输入图片说明
  • +
+

+ 数据集编辑 + # +

+
    +
  • 点开“数据集” + + 输入图片说明
  • +
  • 输入以下SQL后,点击“保存并刷新”, 关闭数据集编辑界面
  • +
+
select H1 as heroname, sum(qty) as 出场数 from smartdemo2
+group by H1
+order by sum(qty) desc
+

+ 输入图片说明

+

+ 图形编辑 + # +

+
    +
  • +

    点开“图形编辑” + + 输入图片说明

    +
  • +
  • +

    点击“云图标”,第一次使用可能要你进行登记,按提示操作即可, 在商店中找到合适的图形点击,会自动复制到剪贴板 + + 输入图片说明

    +
  • +
  • +

    贴粘到图形编辑器后,点击保存, 关闭图形编辑框 + + 输入图片说明

    +
  • +
+

+ 拖拽布局 + # +

+
    +
  • 重复以上步骤,再新增一个, 你可以使用拖拽的方式, 移动到不同的地方 + + 输入图片说明
  • +
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/10.其它/FAQ/index.html b/docs/smartchart/docs/10.其它/FAQ/index.html new file mode 100644 index 0000000..17595b0 --- /dev/null +++ b/docs/smartchart/docs/10.其它/FAQ/index.html @@ -0,0 +1,1694 @@ + + + + + + + + + + + + + + +Faq | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Faq + + +
+ + + + + + +
+ + + +

+ FAQ + # +

+
    +
  • +

    启动显示 以一种访问权限不允许的方式做了一个访问套接字的尝试 +出现这种情况在Windows中很常见,就是端口被占用,酷狗音乐会占用8000端口 +使用netstat -ano|findstr 8000 找到进程号 +使用taskkill /pid 进程号 /F

    +
  • +
  • +

    输入命令找不到smartchart +检查你是否有安装多个python环境出现环境变量冲突,请卸载一个或取消一个环境变量

    +
  • +
  • +

    如法安装pip +请确认在安装python时,有没有加入环境变量, 可自行加入, 或卸载重装

    +
  • +
  • +

    关于mac版本安装后的各种问题 +目前来看最大的可能是,/Library/Developer/CommandLineTools这个目录下有python3,应该是在某一个版本的Xcode command line tools安装时生成的 +可以先把python3全部卸载,再重新按说明安装,命令行中输入python3 和 pip3, 找不到command时才说明完全卸载成功

    +
    sudo rm -rf /Library/Developer/CommandLineTools
    +sudo rm -f /usr/bin/python3
    +
  • +
  • +

    如果密码忘记了怎么办 +命令行输入smartchart changepassword 你的用户名

    +
  • +
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/10.其它/index.html b/docs/smartchart/docs/10.其它/index.html new file mode 100644 index 0000000..906f868 --- /dev/null +++ b/docs/smartchart/docs/10.其它/index.html @@ -0,0 +1,1626 @@ + + + + + + + + + + + + +10.其它 | Smartchart开发手册 + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 10.其它 + + +
+ + + + + + +
+ + + +
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/10.其它/index.xml b/docs/smartchart/docs/10.其它/index.xml new file mode 100644 index 0000000..f825d2e --- /dev/null +++ b/docs/smartchart/docs/10.其它/index.xml @@ -0,0 +1,31 @@ + + + + Smartchart开发手册 + https://smartchart.gitee.io/docs/10.%E5%85%B6%E5%AE%83/ + Recent content on Smartchart开发手册 + Hugo -- gohugo.io + + + https://smartchart.gitee.io/docs/10.%E5%85%B6%E5%AE%83/FAQ/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/10.%E5%85%B6%E5%AE%83/FAQ/ + FAQ # 启动显示 以一种访问权限不允许的方式做了一个访问套接字的尝试 出现这种情况在Windows中很常见,就是端口被占用,酷狗音乐会占用8000端口 使用netstat -ano|findstr 8000 找到进程号 使用taskkill /pid 进程号 /F +输入命令找不到smartchart 检查你是否有安装多个python环境出现环境变量冲突,请卸载一个或取消一个环境变量 +如法安装pip 请确认在安装python时,有没有加入环境变量, 可自行加入, 或卸载重装 +关于mac版本安装后的各种问题 目前来看最大的可能是,/Library/Developer/CommandLineTools这个目录下有python3,应该是在某一个版本的Xcode command line tools安装时生成的 可以先把python3全部卸载,再重新按说明安装,命令行中输入python3 和 pip3, 找不到command时才说明完全卸载成功 +sudo rm -rf /Library/Developer/CommandLineTools sudo rm -f /usr/bin/python3 如果密码忘记了怎么办 命令行输入smartchart changepassword 你的用户名 + + + + + https://smartchart.gitee.io/docs/10.%E5%85%B6%E5%AE%83/%E8%AF%95%E7%94%A8%E6%BF%80%E6%B4%BB%E8%AF%B4%E6%98%8E/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/10.%E5%85%B6%E5%AE%83/%E8%AF%95%E7%94%A8%E6%BF%80%E6%B4%BB%E8%AF%B4%E6%98%8E/ + 试用专业版激活码需要每3天激活一次,激活方式: 由于开发很忙, 文档可能会写得有不尽之处, 多多包涵 + + + + diff --git a/docs/smartchart/docs/10.其它/试用激活说明/index.html b/docs/smartchart/docs/10.其它/试用激活说明/index.html new file mode 100644 index 0000000..78daa7f --- /dev/null +++ b/docs/smartchart/docs/10.其它/试用激活说明/index.html @@ -0,0 +1,1634 @@ + + + + + + + + + + + + + + +试用激活说明 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 试用激活说明 + + +
+ + + + + + +
+ + + +

试用专业版激活码需要每3天激活一次,激活方式: + +由于开发很忙, 文档可能会写得有不尽之处, 多多包涵

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/11.部署指南/Linux/SQLite3版本错误/index.html b/docs/smartchart/docs/11.部署指南/Linux/SQLite3版本错误/index.html new file mode 100644 index 0000000..926a161 --- /dev/null +++ b/docs/smartchart/docs/11.部署指南/Linux/SQLite3版本错误/index.html @@ -0,0 +1,1669 @@ + + + + + + + + + + + + + + +Sqlite3版本错误 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Sqlite3版本错误 + + +
+ + + + + + +
+ + + +

SQLite3版本错误 +在部分操作系统下(比如CentOS 7)使用SQLite3数据库运行会出现如下的错误提示:

+
django.core.exceptions.ImproperlyConfigured: SQLite 3.8.3 or later is required (found 3.7.17).
+

这表明操作系统自带的sqlite3版本过低,需要将系统的sqlite3进行升级。

+

以下是一种方法,来自于 StackOverlow:

+

1、下载新版本的SQLite3

+
wget https://www.sqlite.org/2019/sqlite-autoconf-3290000.tar.gz
+

2、解压文件

+
tar zxvf sqlite-autoconf-3290000.tar.gz
+

3、进行解压后的目录

+
cd sqlite-autoconf-3290000
+

4、配置安装目录

+
./configure --prefix=$HOME/opt/sqlite
+

5、编译安装

+
make && make install
+

6、指定环境变量

+
export PATH=$HOME/opt/sqlite/bin:$PATH
+export LD_LIBRARY_PATH=$HOME/opt/sqlite/lib
+export LD_RUN_PATH=$HOME/opt/sqlite/lib
+

完成之后可以运行sqlite3 –version 命令来查看当前的SQLite3版本。

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/11.部署指南/Linux/index.html b/docs/smartchart/docs/11.部署指南/Linux/index.html new file mode 100644 index 0000000..0aaa179 --- /dev/null +++ b/docs/smartchart/docs/11.部署指南/Linux/index.html @@ -0,0 +1,1626 @@ + + + + + + + + + + + + +Linux | Smartchart开发手册 + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Linux + + +
+ + + + + + +
+ + + +
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/11.部署指南/Linux/index.xml b/docs/smartchart/docs/11.部署指南/Linux/index.xml new file mode 100644 index 0000000..60980f3 --- /dev/null +++ b/docs/smartchart/docs/11.部署指南/Linux/index.xml @@ -0,0 +1,45 @@ + + + + Smartchart开发手册 + https://smartchart.gitee.io/docs/11.%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97/Linux/ + Recent content on Smartchart开发手册 + Hugo -- gohugo.io + + + https://smartchart.gitee.io/docs/11.%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97/Linux/%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/11.%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97/Linux/%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B/ + 涉及的基础环境和版本: # * Centos 7 * Python 3.9 /data/smartchart/ 项目主目录 /data/smartchart/tools 项目相关软件 下述内容中,凡是涉及到/data/smartchart路径的,都可以将其修改为你自己系统上的路径。 安装环境 # 安装Python # cd /data/smartchart/tools yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel libffi-devel 下载https://npm.taobao.org/mirrors/python/3.9.0/ 上传服务器,放入安装目录解压 或者 Wget https://npm.taobao.org/mirrors/python/3.9.0/Python-3.9.0.tgz tar -zxvf Python-3.9.0.tgz 进行源码目录 配置安装路径 ./Python-3.9.0/configure --prefix=/data/smartchart/tools/python3 编译安装 make &amp;&amp; make install 建立软链接 ln -s /data/smartchart/tools/python3/bin/python3.9 /usr/bin/python3 ln -s /data/smartchart/tools/python3/bin/pip3.9 /usr/bin/pip3 测试是否安装成功 python3 --version 建立python虚拟环境 # python3 -m venv myvenv cd myvenv source bin/activate 在虚拟环境中安装smartchart # pip3 install -i https://pypi. + + + + + https://smartchart.gitee.io/docs/11.%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97/Linux/SQLite3%E7%89%88%E6%9C%AC%E9%94%99%E8%AF%AF/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/11.%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97/Linux/SQLite3%E7%89%88%E6%9C%AC%E9%94%99%E8%AF%AF/ + SQLite3版本错误 在部分操作系统下(比如CentOS 7)使用SQLite3数据库运行会出现如下的错误提示: +django.core.exceptions.ImproperlyConfigured: SQLite 3.8.3 or later is required (found 3.7.17). 这表明操作系统自带的sqlite3版本过低,需要将系统的sqlite3进行升级。 +以下是一种方法,来自于 StackOverlow: +1、下载新版本的SQLite3 +wget https://www.sqlite.org/2019/sqlite-autoconf-3290000.tar.gz 2、解压文件 +tar zxvf sqlite-autoconf-3290000.tar.gz 3、进行解压后的目录 +cd sqlite-autoconf-3290000 4、配置安装目录 +./configure --prefix=$HOME/opt/sqlite 5、编译安装 +make &amp;&amp; make install 6、指定环境变量 +export PATH=$HOME/opt/sqlite/bin:$PATH export LD_LIBRARY_PATH=$HOME/opt/sqlite/lib export LD_RUN_PATH=$HOME/opt/sqlite/lib 完成之后可以运行sqlite3 &ndash;version 命令来查看当前的SQLite3版本。 + + + + + https://smartchart.gitee.io/docs/11.%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97/Linux/%E7%94%9F%E4%BA%A7%E9%83%A8%E7%BD%B2/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/11.%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97/Linux/%E7%94%9F%E4%BA%A7%E9%83%A8%E7%BD%B2/ + 购买专业版本,提供企业生产部署及无网离线部署方案 + + + + diff --git a/docs/smartchart/docs/11.部署指南/Linux/快速开始/index.html b/docs/smartchart/docs/11.部署指南/Linux/快速开始/index.html new file mode 100644 index 0000000..b48602a --- /dev/null +++ b/docs/smartchart/docs/11.部署指南/Linux/快速开始/index.html @@ -0,0 +1,1714 @@ + + + + + + + + + + + + + + +快速开始 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 快速开始 + + +
+ + + + + + +
+ + + +

+ 涉及的基础环境和版本: + # +

+
* Centos 7
+* Python 3.9
+/data/smartchart/   项目主目录
+/data/smartchart/tools  项目相关软件
+下述内容中,凡是涉及到/data/smartchart路径的,都可以将其修改为你自己系统上的路径。
+

+ 安装环境 + # +

+

+ 安装Python + # +

+
cd /data/smartchart/tools
+yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel libffi-devel
+下载https://npm.taobao.org/mirrors/python/3.9.0/
+上传服务器,放入安装目录解压 或者
+Wget https://npm.taobao.org/mirrors/python/3.9.0/Python-3.9.0.tgz
+tar -zxvf Python-3.9.0.tgz
+
+进行源码目录
+配置安装路径
+./Python-3.9.0/configure --prefix=/data/smartchart/tools/python3
+编译安装
+make && make install
+建立软链接
+ln -s /data/smartchart/tools/python3/bin/python3.9 /usr/bin/python3
+ln -s /data/smartchart/tools/python3/bin/pip3.9 /usr/bin/pip3
+测试是否安装成功
+python3  --version
+

+ 建立python虚拟环境 + # +

+
python3 -m venv myvenv
+cd myvenv
+source bin/activate
+

+ 在虚拟环境中安装smartchart + # +

+
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple smartchart -U
+

+ 启动smartchart(测试部署), 企业部署方式可有尝咨询 + # +

+
smartchart runserver 0.0.0.0:8000 --insecure --noreload
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/11.部署指南/Linux/生产部署/index.html b/docs/smartchart/docs/11.部署指南/Linux/生产部署/index.html new file mode 100644 index 0000000..3b22d35 --- /dev/null +++ b/docs/smartchart/docs/11.部署指南/Linux/生产部署/index.html @@ -0,0 +1,1632 @@ + + + + + + + + + + + + + + +生产部署 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 生产部署 + + +
+ + + + + + +
+ + + +

购买专业版本,提供企业生产部署及无网离线部署方案

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/11.部署指南/index.html b/docs/smartchart/docs/11.部署指南/index.html new file mode 100644 index 0000000..60a1fb6 --- /dev/null +++ b/docs/smartchart/docs/11.部署指南/index.html @@ -0,0 +1,1626 @@ + + + + + + + + + + + + +11.部署指南 | Smartchart开发手册 + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 11.部署指南 + + +
+ + + + + + +
+ + + +
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/11.部署指南/index.xml b/docs/smartchart/docs/11.部署指南/index.xml new file mode 100644 index 0000000..71952bc --- /dev/null +++ b/docs/smartchart/docs/11.部署指南/index.xml @@ -0,0 +1,9 @@ + + + + Smartchart开发手册 + https://smartchart.gitee.io/docs/11.%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97/ + Recent content on Smartchart开发手册 + Hugo -- gohugo.io + + diff --git a/docs/smartchart/docs/2.数据集说明/EXCEL数据/index.html b/docs/smartchart/docs/2.数据集说明/EXCEL数据/index.html new file mode 100644 index 0000000..f9d99aa --- /dev/null +++ b/docs/smartchart/docs/2.数据集说明/EXCEL数据/index.html @@ -0,0 +1,1626 @@ + + + + + + + + + + + + +Excel数据 | Smartchart开发手册 + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Excel数据 + + +
+ + + + + + +
+ + + +
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/2.数据集说明/EXCEL数据/index.xml b/docs/smartchart/docs/2.数据集说明/EXCEL数据/index.xml new file mode 100644 index 0000000..1798c05 --- /dev/null +++ b/docs/smartchart/docs/2.数据集说明/EXCEL数据/index.xml @@ -0,0 +1,29 @@ + + + + Smartchart开发手册 + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/EXCEL%E6%95%B0%E6%8D%AE/ + Recent content on Smartchart开发手册 + Hugo -- gohugo.io + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/EXCEL%E6%95%B0%E6%8D%AE/%E4%BB%8EEXCEL%E7%B2%98%E8%B4%B4%E6%95%B0%E6%8D%AE/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/EXCEL%E6%95%B0%E6%8D%AE/%E4%BB%8EEXCEL%E7%B2%98%E8%B4%B4%E6%95%B0%E6%8D%AE/ + 固定数据集 # 有一些场景, 比如已有一些固定的筛选器,或是需要测试用,或者Demo,或者其它图形需要用到一些共用的已确定好的数据 这样我们可以不需要通过查询数据库的方式, 而直接写入数据集, 支持数组和字典的格式 你只需要在数据集中起始写入 dataset= , 这样就是默认是固定数据 +如何快速的输入固定数据集, 你可以通过直接从EXCEL复制到数据集编辑器(以下图片非目前编辑器, 供参考),保存以后会自动生成: 固定数据集也支持之前提到传参数, 魔术方法, 缓存等所有数据集的功能 + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/EXCEL%E6%95%B0%E6%8D%AE/%E6%95%B0%E6%8D%AE%E4%B8%8A%E4%BC%A0/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/EXCEL%E6%95%B0%E6%8D%AE/%E6%95%B0%E6%8D%AE%E4%B8%8A%E4%BC%A0/ + 用户如何上传文件 # smartchart默认是不自带文件上传功能 但是smartchart是可以自已创造上传页面, 在模板商店中你可以找到相关模板进行购买 然后通过模板下载的方式下载后进行操作 这样每一个页面是可以单独使用权限控制的,就和控制报表权限一样,你还可能按需随意定制页面 关于上传文件的路径 # 默认的上传主目录是在项目的log的文件夹下面, 你可以在setting.py(自定义django) 或 config.ini中设定UPLOAD_PATH来修改你的上传目录 比如你上传页面的报表ID是23, 那么文件将会被上传到UPLOAD_PATH/23/你的文件名 +如何使用上传的文件 # 你需要使用 python连接器, 来操作你的上传的数据, 内置了变量ds_path为你的上传目录, 所以可以更方便的读取上传的文件,如上文件 df = pd.read_excel(ds_path+&rsquo;/23/文件名') + + + + diff --git a/docs/smartchart/docs/2.数据集说明/EXCEL数据/从EXCEL粘贴数据/index.html b/docs/smartchart/docs/2.数据集说明/EXCEL数据/从EXCEL粘贴数据/index.html new file mode 100644 index 0000000..a57a29c --- /dev/null +++ b/docs/smartchart/docs/2.数据集说明/EXCEL数据/从EXCEL粘贴数据/index.html @@ -0,0 +1,1678 @@ + + + + + + + + + + + + + + +从 Excel粘贴数据 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 从 Excel粘贴数据 + + +
+ + + + + + +
+ + + +

+ 固定数据集 + # +

+

有一些场景, 比如已有一些固定的筛选器,或是需要测试用,或者Demo,或者其它图形需要用到一些共用的已确定好的数据 +这样我们可以不需要通过查询数据库的方式, 而直接写入数据集, 支持数组和字典的格式 +你只需要在数据集中起始写入 dataset= , 这样就是默认是固定数据

+
    +
  • +

    如何快速的输入固定数据集, 你可以通过直接从EXCEL复制到数据集编辑器(以下图片非目前编辑器, 供参考),保存以后会自动生成: + + 输入图片说明 + + 输入图片说明

    +
  • +
  • +

    固定数据集也支持之前提到传参数, 魔术方法, 缓存等所有数据集的功能 + + 输入图片说明

    +
  • +
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/2.数据集说明/EXCEL数据/数据上传/index.html b/docs/smartchart/docs/2.数据集说明/EXCEL数据/数据上传/index.html new file mode 100644 index 0000000..c65baef --- /dev/null +++ b/docs/smartchart/docs/2.数据集说明/EXCEL数据/数据上传/index.html @@ -0,0 +1,1685 @@ + + + + + + + + + + + + + + +数据上传 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 数据上传 + + +
+ + + + + + +
+ + + +

+ 用户如何上传文件 + # +

+

smartchart默认是不自带文件上传功能 +但是smartchart是可以自已创造上传页面, 在模板商店中你可以找到相关模板进行购买 +然后通过模板下载的方式下载后进行操作 +这样每一个页面是可以单独使用权限控制的,就和控制报表权限一样,你还可能按需随意定制页面 + + 输入图片说明

+

+ 关于上传文件的路径 + # +

+

默认的上传主目录是在项目的log的文件夹下面, +你可以在setting.py(自定义django) 或 config.ini中设定UPLOAD_PATH来修改你的上传目录 +比如你上传页面的报表ID是23, 那么文件将会被上传到UPLOAD_PATH/23/你的文件名

+

+ 如何使用上传的文件 + # +

+

你需要使用 + python连接器, 来操作你的上传的数据, 内置了变量ds_path为你的上传目录, 所以可以更方便的读取上传的文件,如上文件 +df = pd.read_excel(ds_path+’/23/文件名')

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/2.数据集说明/SQL数据集/index.html b/docs/smartchart/docs/2.数据集说明/SQL数据集/index.html new file mode 100644 index 0000000..c544c91 --- /dev/null +++ b/docs/smartchart/docs/2.数据集说明/SQL数据集/index.html @@ -0,0 +1,1871 @@ + + + + + + + + + + + + + + +Sql数据集 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Sql数据集 + + +
+ + + + + + +
+ + + +

SmartChart标准数据集你可以想象为一个EXCEL的二维表, 有行和列 +你直接在数据集开发界面填写SQL即可

+

+ 标准图形的数据表类型 + # +

+

+ A类数据源 + # +

+
比如你的原始数据库中表的格式如下, 表名tb_name:
+城市    户型    数量
+长沙    A       12
+长沙    A       23
+上海    B       19
+
+查询的sql: select 城市,户型,sum(数量) AS 数量 from tb_name group by 城市,户型
+正常的查询的结果为:
+[['城市','户型','数量'],
+ ['长沙','A',35],
+ ['上海','B ',19]]
+由于生成的数据格式第二行是 [字符,字符,数值], 后台会自动进行转列动作, 
+生成图表更容易使用格式:
+[['Categroy','A','B'],
+ ['长沙',     35, 0],
+ ['上海',     0, 19]]
+

+ B类数据源 + # +

+
再比如我们有一个表的数据格式, 指标是展开的:
+城市    A     B
+长沙    10    12
+上海    11    19
+长沙    9     10
+
+我们可以写的sql是:
+select 城市, sum(A) as A, sum(B) as B from tb_name group by 城市
+这样得到的结果是:
+[['城市','A','B'],
+ ['长沙', 19, 22],
+ ['上海', 11, 19]]
+和我们的标准格式也是一样的
+

+ SQL多段查询 + # +

+

有时你一个数据集可能只用一个SQL查询还不够,比如你需要一个清单数据,同时你需要一个汇总数据做为说明在图形中显示,这样你就需要使用多条SQL语句,在数据集中的写法你只需要用分号隔开,如:

+
select ... from xxx;
+select ..... from xxxxxxx
+
+传递到图形中的格式为:
+{"df0":[[...]]. "df1":[[......]]}
+df0, df1分别对应的是第一段和第二段查询
+

+ 多段查询使用视屏参考

+

+ 支持的数据源: + # +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
数据库驱动填写需安装使用说明
Mysqlmysql默认支持
Mysql连接池mysqlpool
Sqlitesqlite默认支持连接地址填写绝对路径
API任意默认支持参考数据集说明文档
EXCEL任意默认支持参考数据集说明文档
SQL Servermssql需安装 pip install pymssql
SQL Server连接池mssqlpool
ORACLEoraclepip install cx_Oracle
ORACLE连接池oraclepool
PostgreSqlgppip install psycopg2
GPgppip install psycopg2
Impalaimpalapip install impyla
Hivehivepip install impyla
DB2db2pip install ibm_db
达梦dmpip install dmPython
Pythonpythonpip install pandas, openpyxl参考数据集->特殊数据源
Redisredispip install redis参考数据集->特殊数据源
Mongodbmongodbpip install pymongo参考数据集->特殊数据源
Clickhouseclickhousepip install clickhouse_driver
Elasticsearchespip install elasticsearch==7.13.0参考数据集->特殊数据源
Sqlalchemysqlalchemypip install sqlalchemy参考数据集->特殊数据源
JDBCjdbcpip install JayDeBeApi参考数据集->特殊数据源
自定义自定义用户自由定义参考数据集->特殊数据源
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/2.数据集说明/index.html b/docs/smartchart/docs/2.数据集说明/index.html new file mode 100644 index 0000000..1a5fea6 --- /dev/null +++ b/docs/smartchart/docs/2.数据集说明/index.html @@ -0,0 +1,1626 @@ + + + + + + + + + + + + +2.数据集说明 | Smartchart开发手册 + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 2.数据集说明 + + +
+ + + + + + +
+ + + +
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/2.数据集说明/index.xml b/docs/smartchart/docs/2.数据集说明/index.xml new file mode 100644 index 0000000..1af80ba --- /dev/null +++ b/docs/smartchart/docs/2.数据集说明/index.xml @@ -0,0 +1,63 @@ + + + + Smartchart开发手册 + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/ + Recent content on Smartchart开发手册 + Hugo -- gohugo.io + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E6%95%B0%E6%8D%AE%E9%9B%86%E5%BC%80%E5%8F%91%E7%95%8C%E9%9D%A2/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E6%95%B0%E6%8D%AE%E9%9B%86%E5%BC%80%E5%8F%91%E7%95%8C%E9%9D%A2/ + 开发前建意先观看视屏, 了解基础说明, 视屏有点老和现在界面不一样, 目前很多功能已经做成可视化配置, 理解过程即可, 具体以文档为准 +Smartchart数据集与图形 从仪表盘界面中进入简易开发界面 # + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/SQL%E6%95%B0%E6%8D%AE%E9%9B%86/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/SQL%E6%95%B0%E6%8D%AE%E9%9B%86/ + SmartChart标准数据集你可以想象为一个EXCEL的二维表, 有行和列 你直接在数据集开发界面填写SQL即可 +标准图形的数据表类型 # A类数据源 # 比如你的原始数据库中表的格式如下, 表名tb_name: 城市 户型 数量 长沙 A 12 长沙 A 23 上海 B 19 查询的sql: select 城市,户型,sum(数量) AS 数量 from tb_name group by 城市,户型 正常的查询的结果为: [[&#39;城市&#39;,&#39;户型&#39;,&#39;数量&#39;], [&#39;长沙&#39;,&#39;A&#39;,35], [&#39;上海&#39;,&#39;B &#39;,19]] 由于生成的数据格式第二行是 [字符,字符,数值], 后台会自动进行转列动作, 生成图表更容易使用格式: [[&#39;Categroy&#39;,&#39;A&#39;,&#39;B&#39;], [&#39;长沙&#39;, 35, 0], [&#39;上海&#39;, 0, 19]] B类数据源 # 再比如我们有一个表的数据格式, 指标是展开的: 城市 A B 长沙 10 12 上海 11 19 长沙 9 10 我们可以写的sql是: select 城市, sum(A) as A, sum(B) as B from tb_name group by 城市 这样得到的结果是: [[&#39;城市&#39;,&#39;A&#39;,&#39;B&#39;], [&#39;长沙&#39;, 19, 22], [&#39;上海&#39;, 11, 19]] 和我们的标准格式也是一样的 SQL多段查询 # 有时你一个数据集可能只用一个SQL查询还不够,比如你需要一个清单数据,同时你需要一个汇总数据做为说明在图形中显示,这样你就需要使用多条SQL语句,在数据集中的写法你只需要用分号隔开,如: + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E5%85%B1%E4%BA%AB%E6%95%B0%E6%8D%AE%E9%9B%86/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E5%85%B1%E4%BA%AB%E6%95%B0%E6%8D%AE%E9%9B%86/ + 应用场景 # 优化查询, 可一个数据集查询完所有数据进行分发 减少重复查询的浪费, 同一个数据只查询一次 使用方法 # 在数据开发界面点击按钮就可以切换成共享数据集/普通数据集 切换完成, 你会发现数据集消失,然后图标跑到菜单上面去了, 你可以在此修改你的查询 在”高级“ 中配置 这样1,2号图形都映射到了共享数据集的数据 你也可以在数据集中写多个SQL查询 在”高级“ 设定中进行数据映射 观察1,2 号图形的变化 + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E6%95%B0%E6%8D%AE%E9%9B%86%E6%95%B0%E6%8D%AE%E5%88%B7%E6%96%B0/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E6%95%B0%E6%8D%AE%E9%9B%86%E6%95%B0%E6%8D%AE%E5%88%B7%E6%96%B0/ + 数据刷新设定方法 # smartchart提供非常精细的数据刷新功能,及内存加速功能 你可以在数据集开发界面,点击连接的图标,进行设定 定时刷新 # 你可以设定前端页面数据集向后端请求刷新的时间间隔,单位秒 +如果你发现定时刷新,数据并没有变化,可能原因是您数据的缓存时间设定大于定时刷新的时间 +数据集缓存加速(PRO) # smartchart专业版提供内存加速技术,对数据库仅需请求一次,之后都是毫秒级响应 +间隔时间刷新,单位分钟,如设定 间隔时间为0.5, 则如果下一次访问时间超过30秒, 即触发数据刷新 固定时点刷新, 如设定 间隔时间 为-1, 则固定时点刷新, 即访问的时间超过固定的时点时(如下图每天09:25), 触发数据刷新 强制刷新, 访问url加上&amp;refresh=Y, 则强制刷新数据, 此刷新不会影响间隔或固定刷新的时间, 不会更新下次同步时间 后台触发强制刷新 (PRO) # 请参考文档 后台主动触发刷新 + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E6%95%B0%E6%8D%AE%E9%9B%86%E6%87%92%E5%8A%A0%E8%BD%BD/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E6%95%B0%E6%8D%AE%E9%9B%86%E6%87%92%E5%8A%A0%E8%BD%BD/ + 应用场景 # 类似于前后端开发, 后端会提供一些接口给前端, 但前端不一定需要在一打开页面就进行查询接口, 而是当有需要时再查询, 比如数据下载, 只有当用户有下载需求时再加载, 再比如有些与后台的数据联动, 我们只需要第一次加载时只显示第一层级, 点击时再加载其它层级 +开启数据集懒加载 # 你可以点击数据集的开发界面的&quot;连接&quot; 图标, 将&quot;前端刷新(秒)&quot; 修改为-1 这时当打开仪表盘时, 此数据集不会被加载 +应用 # 一般懒加载数据集主要是用来做数据查询的, 所以并不太需要显示图形, 所以我们主要是用于在图形中进行赋值操作 比如先在模板中定义一个全局变量: 然后修改图形编辑中的代码: 即刷新数据集时会进行变量赋值 如果您使用VUE, 那么会更方便, 你可以直接使用vapp.变量名 = dataset进行赋值 +查询数据 # 你可以随时手动触发数据集的刷新, 比如懒加载的数据集序号为0 你可以在你需要触发刷新的地方调用ds_refresh(0)即可刷新0号数据集并执行0号数据集中的JS代码 +TIPS 可以将懒加载的数据集同时转化为共享数据集(参考上文), 懒加载数据集将移到菜单栏显示 + + + + diff --git a/docs/smartchart/docs/2.数据集说明/共享数据集/index.html b/docs/smartchart/docs/2.数据集说明/共享数据集/index.html new file mode 100644 index 0000000..017e1b4 --- /dev/null +++ b/docs/smartchart/docs/2.数据集说明/共享数据集/index.html @@ -0,0 +1,1706 @@ + + + + + + + + + + + + + + +共享数据集 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 共享数据集 + + +
+ + + + + + +
+ + + +

+ 应用场景 + # +

+
    +
  • 优化查询, 可一个数据集查询完所有数据进行分发
  • +
  • 减少重复查询的浪费, 同一个数据只查询一次
  • +
+

+ 使用方法 + # +

+
    +
  • +

    在数据开发界面点击按钮就可以切换成共享数据集/普通数据集 + + 输入图片说明

    +
  • +
  • +

    切换完成, 你会发现数据集消失,然后图标跑到菜单上面去了, 你可以在此修改你的查询 + + 输入图片说明

    +
  • +
  • +

    在”高级“ 中配置 + + 输入图片说明

    +
  • +
  • +

    这样1,2号图形都映射到了共享数据集的数据 + + 输入图片说明

    +
  • +
  • +

    你也可以在数据集中写多个SQL查询 + + 输入图片说明

    +
  • +
  • +

    在”高级“ 设定中进行数据映射 + + 输入图片说明

    +
  • +
  • +

    观察1,2 号图形的变化 + + 输入图片说明

    +
  • +
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/2.数据集说明/数据集开发界面/index.html b/docs/smartchart/docs/2.数据集说明/数据集开发界面/index.html new file mode 100644 index 0000000..7140584 --- /dev/null +++ b/docs/smartchart/docs/2.数据集说明/数据集开发界面/index.html @@ -0,0 +1,1669 @@ + + + + + + + + + + + + + + +数据集开发界面 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 数据集开发界面 + + +
+ + + + + + +
+ + + +

开发前建意先观看视屏, 了解基础说明, 视屏有点老和现在界面不一样, +目前很多功能已经做成可视化配置, 理解过程即可, 具体以文档为准

+ +

+ 从仪表盘界面中进入简易开发界面 + # +

+

+ 输入图片说明

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/2.数据集说明/数据集懒加载/index.html b/docs/smartchart/docs/2.数据集说明/数据集懒加载/index.html new file mode 100644 index 0000000..4304d4d --- /dev/null +++ b/docs/smartchart/docs/2.数据集说明/数据集懒加载/index.html @@ -0,0 +1,1705 @@ + + + + + + + + + + + + + + +数据集懒加载 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 数据集懒加载 + + +
+ + + + + + +
+ + + +

+ 应用场景 + # +

+

类似于前后端开发, 后端会提供一些接口给前端, 但前端不一定需要在一打开页面就进行查询接口, 而是当有需要时再查询, +比如数据下载, 只有当用户有下载需求时再加载, +再比如有些与后台的数据联动, 我们只需要第一次加载时只显示第一层级, 点击时再加载其它层级

+

+ 开启数据集懒加载 + # +

+

你可以点击数据集的开发界面的"连接" 图标, 将"前端刷新(秒)" 修改为-1 +这时当打开仪表盘时, 此数据集不会被加载

+

+ 应用 + # +

+

一般懒加载数据集主要是用来做数据查询的, 所以并不太需要显示图形, 所以我们主要是用于在图形中进行赋值操作 +比如先在模板中定义一个全局变量: + + 输入图片说明 +然后修改图形编辑中的代码: + + 输入图片说明 +即刷新数据集时会进行变量赋值 +如果您使用VUE, 那么会更方便, 你可以直接使用vapp.变量名 = dataset进行赋值

+

+ 查询数据 + # +

+

你可以随时手动触发数据集的刷新, 比如懒加载的数据集序号为0 +你可以在你需要触发刷新的地方调用ds_refresh(0)即可刷新0号数据集并执行0号数据集中的JS代码

+
+

TIPS +可以将懒加载的数据集同时转化为共享数据集(参考上文), 懒加载数据集将移到菜单栏显示

+
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/2.数据集说明/数据集数据刷新/index.html b/docs/smartchart/docs/2.数据集说明/数据集数据刷新/index.html new file mode 100644 index 0000000..4af3587 --- /dev/null +++ b/docs/smartchart/docs/2.数据集说明/数据集数据刷新/index.html @@ -0,0 +1,1699 @@ + + + + + + + + + + + + + + +数据集数据刷新 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 数据集数据刷新 + + +
+ + + + + + +
+ + + +

+ 数据刷新设定方法 + # +

+

smartchart提供非常精细的数据刷新功能,及内存加速功能 +你可以在数据集开发界面,点击连接的图标,进行设定 + + 输入图片说明

+

+ 定时刷新 + # +

+

你可以设定前端页面数据集向后端请求刷新的时间间隔,单位秒

+
+

如果你发现定时刷新,数据并没有变化,可能原因是您数据的缓存时间设定大于定时刷新的时间

+
+

+ 数据集缓存加速(PRO) + # +

+

smartchart专业版提供内存加速技术,对数据库仅需请求一次,之后都是毫秒级响应

+
    +
  • 间隔时间刷新,单位分钟,如设定 间隔时间为0.5, 则如果下一次访问时间超过30秒, 即触发数据刷新
  • +
  • 固定时点刷新, 如设定 间隔时间 为-1, 则固定时点刷新, 即访问的时间超过固定的时点时(如下图每天09:25), 触发数据刷新
  • +
  • 强制刷新, 访问url加上&refresh=Y, 则强制刷新数据, 此刷新不会影响间隔或固定刷新的时间, 不会更新下次同步时间
  • +
+

+ 后台触发强制刷新 (PRO) + # +

+

请参考文档 + 后台主动触发刷新

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/2.数据集说明/特殊数据源/API数据集/index.html b/docs/smartchart/docs/2.数据集说明/特殊数据源/API数据集/index.html new file mode 100644 index 0000000..1aed6db --- /dev/null +++ b/docs/smartchart/docs/2.数据集说明/特殊数据源/API数据集/index.html @@ -0,0 +1,1665 @@ + + + + + + + + + + + + + + +Api数据集 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Api数据集 + + +
+ + + + + + +
+ + + +

对接外部API取数, 注意返回一定要是JSON格式 +你只需要在数据集编辑框中如下输入

+
-- GET 方法:
+dataset= {
+"url":"https://www.smartchart.cn/smartdata/api/?i=loaddataset1&j=1"
+}
+
+-- POST 方法:
+dataset= {
+"url":"https://www.smartchart.cn/smartdata/api",
+"method":"POST",
+"data":{"i":"loaddataset1", "j":"1"}
+ ...
+}
+

例如你可以传入参数做出联动效果

+
dataset= {
+"url":"https://www.smartchart.cn/smartdata/api",
+"method":"POST",
+"data":{"i":"loaddataset1", "j":"/*$参数名*/"}
+...
+}
+

你也可以增加header等认证方式

+
dataset= {
+"url":"https://www.smartchart.cn/smartdata/api",
+"method":"GET",
+"headers":{"Cookie":"xxxxxxx"}
+...
+}
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/2.数据集说明/特殊数据源/Elasticsearch数据源/index.html b/docs/smartchart/docs/2.数据集说明/特殊数据源/Elasticsearch数据源/index.html new file mode 100644 index 0000000..04b8abe --- /dev/null +++ b/docs/smartchart/docs/2.数据集说明/特殊数据源/Elasticsearch数据源/index.html @@ -0,0 +1,1790 @@ + + + + + + + + + + + + + + +Elasticsearch数据源 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Elasticsearch数据源 + + +
+ + + + + + +
+ + + +

+ 数据源配置方法 + # +

+

+ 输入图片说明

+

+ 查询方法 + # +

+

+ 输入图片说明

+
+ 更多查询方法参考 + # +
+
模糊查询
+body = {
+    'query': {  # 查询命令
+        'match': {  # 查询方法:模糊查询(会被分词)。比如此代码,会查到只包含:“我爱你”, “中国”的内容
+            'name': '刘'
+        }
+    },
+  'size': 20  # 不指定默认是10,最大值不超过10000(可以修改,但是同时会增加数据库压力)
+}
+
+term,精准单值查询
+# 注:此方法只能查询一个字段,且只能指定一个值。类似于mysql中的where ziduan='a'
+body ={   
+    'query':{
+        'term':{
+            'ziduan1.keyword': '刘婵'  # 查询内容等于“我爱你中国的”的数据。查询中文,在字段后面需要加上.keyword
+         # 'ziduan2': 'liuchan'
+        }
+    }
+}
+erms,精准多值查询
+#此方法只能查询一个字段,但可以同时指定多个值。类似于mysql中的where ziduan in (a, b,c...)
+body ={   
+    "query":{
+        "terms":{
+            "ziduan1.keyword": ["刘婵", "赵云"]  # 查询ziduan1="刘婵"或=赵云...的数据
+        }
+    }
+}
+multi_match,多字段查询
+# 查询多个字段中都包含指定内容的数据
+body = {
+    "query":{
+        "multi_match":{
+            "query":"我爱你中国",  # 指定查询内容,注意:会被分词
+            "fields":["ziduan1", "ziduan2"]  # 指定字段
+        }
+    }
+}
+
+prefix,前缀查询
+body = {
+    'query': {
+        'prefix': { 
+            'ziduan.keyword': '我爱你'  # 查询前缀是指定字符串的数据
+        }
+    }
+}
+
+# 注:英文不需要加keyword
+
+wildcard,通配符查询
+body = {
+    'query': {
+        'wildcard': {
+            'ziduan1.keyword': '?刘婵*'  # ?代表一个字符,*代表0个或多个字符
+        }
+    }
+}
+# 注:此方法只能查询单一格式的(都是英文字符串,或者都是汉语字符串)。两者混合不能查询出来。
+
+regexp,正则匹配
+body = {
+    'query': {
+        'regexp': {
+            'ziduan1': 'W[0-9].+'   # 使用正则表达式查询
+        }
+    }
+}
+bool,多条件查询
+# must:[] 各条件之间是and的关系
+body = {
+        "query":{
+            "bool":{
+                'must': [{"term":{'ziduan1.keyword': '我爱你中国'}},
+                         {'terms': {'ziduan2': ['I love', 'China']}}]
+            }
+        }
+    }
+
+# should: [] 各条件之间是or的关系
+body = {
+        "query":{
+            "bool":{
+                'should': [{"term":{'ziduan1.keyword': '我爱你中国'}},
+                         {'terms': {'ziduan2': ['I love', 'China']}}]
+            }
+        }
+    }
+
+# must_not:[]各条件都不满足
+body = {
+        "query":{
+            "bool":{
+                'must_not': [{"term":{'ziduan1.keyword': '我爱你中国'}},
+                         {'terms': {'ziduan2': ['I love', 'China']}}]
+            }
+        }
+    }
+
+
+
+# bool嵌套bool
+# ziduan1、ziduan2条件必须满足的前提下,ziduan3、ziduan4满足一个即可
+body = {
+    "query":{
+        "bool":{
+            "must":[{"term":{"ziduan1":"China"}},  #  多个条件并列  ,注意:must后面是[{}, {}],[]里面的每个条件外面有个{}
+                    {"term":{"ziduan2.keyword": '我爱你中国'}},
+                    {'bool': {
+                        'should': [
+                            {'term': {'ziduan3': 'Love'}},
+                            {'term': {'ziduan4': 'Like'}}
+                        ]
+                    }}
+            ]
+        }
+    }
+}
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/2.数据集说明/特殊数据源/JDBC数据源/index.html b/docs/smartchart/docs/2.数据集说明/特殊数据源/JDBC数据源/index.html new file mode 100644 index 0000000..8c50d8d --- /dev/null +++ b/docs/smartchart/docs/2.数据集说明/特殊数据源/JDBC数据源/index.html @@ -0,0 +1,1680 @@ + + + + + + + + + + + + + + +Jdbc数据源 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Jdbc数据源 + + +
+ + + + + + +
+ + + +
+ 应用场景 + # +
+

当无法在python中找到连接库时, 你还可以采用jdbc的连接方式

+
+ 使用方法 + # +
+
    +
  • 首先您需要安装jdbc的包
  • +
+
pip install JayDeBeApi
+
    +
  • 在任意的一个仪表盘的 “模板” 编辑器中, 点击上传资源的图标上传相应的jdbc JAR包即可
  • +
+

+ 输入图片说明

+
    +
  • 新建连接的方式, 以下使用impala为例 + + 输入图片说明
  • +
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/2.数据集说明/特殊数据源/Python数据集/index.html b/docs/smartchart/docs/2.数据集说明/特殊数据源/Python数据集/index.html new file mode 100644 index 0000000..e776f06 --- /dev/null +++ b/docs/smartchart/docs/2.数据集说明/特殊数据源/Python数据集/index.html @@ -0,0 +1,1704 @@ + + + + + + + + + + + + + + +Python数据集 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Python数据集 + + +
+ + + + + + +
+ + + +

+ 应用场景 + # +

+

当SQL查询无法满足你的需求, 你需要对查询后的结果进行处理, 或者你需要使用Excel的数据源, 甚至你需要对不同系统的数据进行查询, Python连接器可以帮到你 +我们又称他为万能数据集, 你可以使用任何python语法, +需要把数据集的结果赋值给ds变量!!

+

首先你需要新建python连接器, 由于安全控制只允许超级管理员建立 + + 输入图片说明

+
# 内置函数说明
+ds_get(id)    #输入目标数据集的id名, 可以获取目标数据集
+ds_df(id)     #输入目标数据集的id名, 转化成pandas的df对象
+ds_sql(conn_name, sql_str)     #输入连接池中的名称, SQL语句, 获取数据集
+ds_list(df)   #将pandas的df对象转化成数据集
+
+ 使用方法样列说明 + # +
+
# 读取Excel数据处理, 如需上传页面可参考"数据上传"说明
+import pandas as pd
+df = pd.read_excel('/Users/../smartdemo.xlsx', 'demo')
+df = df.groupby('c3').agg({'qty':'sum'}).reset_index()
+ds = ds_list(df)
+
+#从数据集获取数据
+ds=ds_get(12)
+ds=ds[:15]
+
+#从数据集获取数据转化成pandas对象处理
+df = ds_df(12)
+df = df.sort_values(by="出场数", ascending=False)
+ds = ds_list(df)
+
+#可以生成字典格式的数据集供多个图形使用
+import pandas as pd
+df = pd.read_excel('/Users/../smartdemo.xlsx', 'demo')
+df1 = df.groupby('c3').agg({'qty':'sum'}).reset_index()
+df2 = df.groupby(['province','c3']).agg({'qty':'sum'}).reset_index()
+ds = {'df1': ds_list(df1), 'df2': ds_list(df2)}
+
+#可以直接执行SQL
+sql_str = '''select H1 as heroname, sum(qty) as 出场数 from T
+/* where H2 = '$H2' */
+group by H1 order by sum(qty) desc'''
+ds = ds_sql('XXX', sql_str)
+ds = ds[:10]
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/2.数据集说明/特殊数据源/Redis数据源/index.html b/docs/smartchart/docs/2.数据集说明/特殊数据源/Redis数据源/index.html new file mode 100644 index 0000000..063d2b2 --- /dev/null +++ b/docs/smartchart/docs/2.数据集说明/特殊数据源/Redis数据源/index.html @@ -0,0 +1,1702 @@ + + + + + + + + + + + + + + +Redis数据源 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Redis数据源 + + +
+ + + + + + +
+ + + +

+ 应用场景 + # +

+

你可能会有这样的一些需求, 展示数据是要通过外部的程序计算好,如一些实时的计算场景,用spark计算好的数据 或爬虫爬取的数据, 然后写入redis或nosql的数据库,最后由前端图形直接展示或数据下载,SmartChart支持这一块的应用

+

+ 使用方法 + # +

+

你可以创建一个redis的连接池, 然后按照通用的方法建立数据集 +不同的是, 数据集的SQL区不再是写sql代码, 而只需要写redis中的keyname

+

如redis中存储的数据是keyname 为 “指标A”, 数据 ‘{“长沙”:1,“上海”:2}’ +这样我们只需要在数据集中写上

+
指标A
+

即可, +最后你会得到{“长沙”:1,“上海”:2}的返回结果

+

如果你需要的是表格格式, 那么你只需要往redis中存入一个二维数组, 比如: +[[“省份”,“数量”],[“长沙”,1],[“上海”,2]]

+
+

注意数据存入redis为字符串格式,你可使用python的json.dumps来生成字符串格式存入

+
+
+ 当然我们也支持同一个数据中获取多个keyname + # +
+

比如还有一个"指标B", 数据是'12345' +我们可以同时写上两个指标,用分号隔开:

+
指标A;指标B
+

最后你会得到的结果是: +{ +“指标A”:{“长沙”:1,“上海”:2}, +“指标B”:12345 +}

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/2.数据集说明/特殊数据源/index.html b/docs/smartchart/docs/2.数据集说明/特殊数据源/index.html new file mode 100644 index 0000000..2e57bd8 --- /dev/null +++ b/docs/smartchart/docs/2.数据集说明/特殊数据源/index.html @@ -0,0 +1,1626 @@ + + + + + + + + + + + + +特殊数据源 | Smartchart开发手册 + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 特殊数据源 + + +
+ + + + + + +
+ + + +
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/2.数据集说明/特殊数据源/index.xml b/docs/smartchart/docs/2.数据集说明/特殊数据源/index.xml new file mode 100644 index 0000000..37c69fe --- /dev/null +++ b/docs/smartchart/docs/2.数据集说明/特殊数据源/index.xml @@ -0,0 +1,109 @@ + + + + Smartchart开发手册 + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/ + Recent content on Smartchart开发手册 + Hugo -- gohugo.io + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/API%E6%95%B0%E6%8D%AE%E9%9B%86/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/API%E6%95%B0%E6%8D%AE%E9%9B%86/ + 对接外部API取数, 注意返回一定要是JSON格式 你只需要在数据集编辑框中如下输入 +-- GET 方法: dataset= { &#34;url&#34;:&#34;https://www.smartchart.cn/smartdata/api/?i=loaddataset1&amp;j=1&#34; } -- POST 方法: dataset= { &#34;url&#34;:&#34;https://www.smartchart.cn/smartdata/api&#34;, &#34;method&#34;:&#34;POST&#34;, &#34;data&#34;:{&#34;i&#34;:&#34;loaddataset1&#34;, &#34;j&#34;:&#34;1&#34;} ... } 例如你可以传入参数做出联动效果 +dataset= { &#34;url&#34;:&#34;https://www.smartchart.cn/smartdata/api&#34;, &#34;method&#34;:&#34;POST&#34;, &#34;data&#34;:{&#34;i&#34;:&#34;loaddataset1&#34;, &#34;j&#34;:&#34;/*$参数名*/&#34;} ... } 你也可以增加header等认证方式 +dataset= { &#34;url&#34;:&#34;https://www.smartchart.cn/smartdata/api&#34;, &#34;method&#34;:&#34;GET&#34;, &#34;headers&#34;:{&#34;Cookie&#34;:&#34;xxxxxxx&#34;} ... } + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/Python%E6%95%B0%E6%8D%AE%E9%9B%86/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/Python%E6%95%B0%E6%8D%AE%E9%9B%86/ + 应用场景 # 当SQL查询无法满足你的需求, 你需要对查询后的结果进行处理, 或者你需要使用Excel的数据源, 甚至你需要对不同系统的数据进行查询, Python连接器可以帮到你 我们又称他为万能数据集, 你可以使用任何python语法, 需要把数据集的结果赋值给ds变量!! +首先你需要新建python连接器, 由于安全控制只允许超级管理员建立 # 内置函数说明 ds_get(id) #输入目标数据集的id名, 可以获取目标数据集 ds_df(id) #输入目标数据集的id名, 转化成pandas的df对象 ds_sql(conn_name, sql_str) #输入连接池中的名称, SQL语句, 获取数据集 ds_list(df) #将pandas的df对象转化成数据集 使用方法样列说明 # # 读取Excel数据处理, 如需上传页面可参考&#34;数据上传&#34;说明 import pandas as pd df = pd.read_excel(&#39;/Users/../smartdemo.xlsx&#39;, &#39;demo&#39;) df = df.groupby(&#39;c3&#39;).agg({&#39;qty&#39;:&#39;sum&#39;}).reset_index() ds = ds_list(df) #从数据集获取数据 ds=ds_get(12) ds=ds[:15] #从数据集获取数据转化成pandas对象处理 df = ds_df(12) df = df.sort_values(by=&#34;出场数&#34;, ascending=False) ds = ds_list(df) #可以生成字典格式的数据集供多个图形使用 import pandas as pd df = pd.read_excel(&#39;/Users/../smartdemo.xlsx&#39;, &#39;demo&#39;) df1 = df. + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/%E8%87%AA%E5%AE%9A%E4%B9%89%E6%95%B0%E6%8D%AE%E6%BA%90/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/%E8%87%AA%E5%AE%9A%E4%B9%89%E6%95%B0%E6%8D%AE%E6%BA%90/ + smartchart已实现大部分常用的数据源连接, 对于其它的, 您也可以使用python数据源进行处理 但是使用python数据源有一定的缺陷, 需要在dataset上写python代码, 不能复用 对于一些带连接信息的还需要重复写入 所以你还可以使用自定义数据源 +应用场景 # 未内置的数据源, 如需要使用sparkSQL, ES等 标准处理满足不了要求, 需要对数据进行预处理的情况 需要刷新时触发预警等自定义动作 需要自定义写入方法, 个性化查询需求, 甚至是实时爬取数据 使用方法 # 首先你需要新建一个python脚本文件, 如diy_conn.py 复制以下代码到这个文件, 然后编写你的自定义查询方法 def dataset(*args, **kwargs): &#34;&#34;&#34; 返回查询数据集 :return: 二维数组或JSON字典 &#34;&#34;&#34; sqlList = args[0] # 数据集编辑界面的输入已按分号拆分成数组 [sql1, sql2...] config = args[1] # 相关的配置字典{&#39;host&#39;,&#39;port&#39;,&#39;user&#39;,&#39;password&#39;,&#39;db&#39;} # 插入你的数据查询及处理代码, 生成result即可 result = [[]] return result def insert_dataset(*args, **kwargs): &#34;&#34;&#34; 数据填表实现 &#34;&#34;&#34; contents = args[0] # 传入的数据集二维数组格式 table = args[1] # 配置中的表名 config = args[3] # 相关的配置字典{&#39;host&#39;,&#39;port&#39;,&#39;user&#39;,&#39;password&#39;,&#39;db&#39;} # 插入你的写入数据逻辑代码 在任意的仪表盘开发界面中 &ldquo;模板&rdquo; &ndash;&gt; 点击上传图标, 将这个python文件上传即可 新建数据源, 驱动填写之前上传过的文件名, 比如我们这个是diy_conn, 其它参数按照你自定义的需求填写, 会自动传入你的自定义函数 之后你可以正常使用这个自定义数据源了 + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/Elasticsearch%E6%95%B0%E6%8D%AE%E6%BA%90/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/Elasticsearch%E6%95%B0%E6%8D%AE%E6%BA%90/ + 数据源配置方法 # 查询方法 # 更多查询方法参考 # 模糊查询 body = { &#39;query&#39;: { # 查询命令 &#39;match&#39;: { # 查询方法:模糊查询(会被分词)。比如此代码,会查到只包含:“我爱你”, “中国”的内容 &#39;name&#39;: &#39;刘&#39; } }, &#39;size&#39;: 20 # 不指定默认是10,最大值不超过10000(可以修改,但是同时会增加数据库压力) } term,精准单值查询 # 注:此方法只能查询一个字段,且只能指定一个值。类似于mysql中的where ziduan=&#39;a&#39; body ={ &#39;query&#39;:{ &#39;term&#39;:{ &#39;ziduan1.keyword&#39;: &#39;刘婵&#39; # 查询内容等于“我爱你中国的”的数据。查询中文,在字段后面需要加上.keyword # &#39;ziduan2&#39;: &#39;liuchan&#39; } } } erms,精准多值查询 #此方法只能查询一个字段,但可以同时指定多个值。类似于mysql中的where ziduan in (a, b,c...) body ={ &#34;query&#34;:{ &#34;terms&#34;:{ &#34;ziduan1.keyword&#34;: [&#34;刘婵&#34;, &#34;赵云&#34;] # 查询ziduan1=&#34;刘婵&#34;或=赵云...的数据 } } } multi_match,多字段查询 # 查询多个字段中都包含指定内容的数据 body = { &#34;query&#34;:{ &#34;multi_match&#34;:{ &#34;query&#34;:&#34;我爱你中国&#34;, # 指定查询内容,注意:会被分词 &#34;fields&#34;:[&#34;ziduan1&#34;, &#34;ziduan2&#34;] # 指定字段 } } } prefix,前缀查询 body = { &#39;query&#39;: { &#39;prefix&#39;: { &#39;ziduan. + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/JDBC%E6%95%B0%E6%8D%AE%E6%BA%90/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/JDBC%E6%95%B0%E6%8D%AE%E6%BA%90/ + 应用场景 # 当无法在python中找到连接库时, 你还可以采用jdbc的连接方式 +使用方法 # 首先您需要安装jdbc的包 pip install JayDeBeApi 在任意的一个仪表盘的 &ldquo;模板&rdquo; 编辑器中, 点击上传资源的图标上传相应的jdbc JAR包即可 新建连接的方式, 以下使用impala为例 + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/kafka%E6%95%B0%E6%8D%AE%E6%BA%90/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/kafka%E6%95%B0%E6%8D%AE%E6%BA%90/ + 用于获取kafka指定分区的最后一条记录, 用于实时场景 使用方法参考&quot;自定义数据源&quot; 以下为参考代码: +def dataset(*args, **kwargs): &#34;&#34;&#34; 返回查询数据集 :return: 二维数组或JSON字典 &#34;&#34;&#34; from kafka import KafkaConsumer, TopicPartition import json sqlList = args[0] # 数据集编辑界面的输入已按分号拆分成数组 [sql1, sql2...] config = args[1] # 相关的配置字典{&#39;host&#39;,&#39;port&#39;,&#39;user&#39;,&#39;password&#39;,&#39;db&#39;} # 插入你的数据查询及处理代码, 生成result即可 result = {} consumer = KafkaConsumer(sasl_mechanism=&#39;PLAIN&#39;, security_protocol=&#39;SASL_PLAINTEXT&#39;, sasl_plain_username=config[&#39;user&#39;], sasl_plain_password=config[&#39;password&#39;], bootstrap_servers=config[&#39;host&#39;], auto_offset_reset=&#39;earliest&#39;, api_version=(1, 0, 0), consumer_timeout_ms=50, value_deserializer=lambda v: json.loads(v.decode(&#39;utf-8&#39;)), ) topic = sqlList[0] partition = int(config[&#39;db&#39;]) tp = TopicPartition(topic=topic, partition=partition) consumer.assign([tp]) end_offsets = consumer.end_offsets([tp]).get(tp) # 获取当前消费者最大偏移量 consumer.seek(tp, offset=end_offsets-1) for message in consumer: result = message. + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/mongodb%E6%95%B0%E6%8D%AE%E6%BA%90/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/mongodb%E6%95%B0%E6%8D%AE%E6%BA%90/ + 使用方法 # 连接池正常配置即可 数据集开发中,填写查询需求: {&#34;db&#34;: &#34;db1&#34;, &#34;table&#34;: &#34;tb1&#34;, &#34;filter&#34;: {&#34;name&#34;: &#34;Zarten&#34;}, &#34;projection&#34;: {&#34;_id&#34;: 0}, &#34;sort&#34;: [[&#34;_id&#34;, 1]], &#34;limit&#34;: 10} 由于返回的字典格式, 如需转化成二维数组, 可使图形中的转化函数ds_mapToList +let dataset=ds_mapToList(__dataset__); 参数说明: # 除table,其它都为可选参数 +参数 说明 样列 db 数库名,默认连接设定中db名 table 表名[必填] filter 筛选项,具体用法参考下文 {&ldquo;name&rdquo;: &ldquo;Zarten&rdquo;,&ldquo;date&rdquo;:&ldquo;2020-10-01&rdquo;} projection 显示列 {&ldquo;name&rdquo;: 1,&ldquo;date&rdquo;:1} sort 排序,-1为降序 [[&ldquo;date&rdquo;, -1]] limit 限定返回数量 filter条件说明 # 且条件 +{&#34;age&#34;:{&#34;$gt&#34;:22}, &#34;name&#34;:{&#34;$regex&#34;:&#34;user&#34;}} 或条件 +{ &#34;$or&#34;: [ {&#34;age&#34;: {&#34;$gt&#34;: 22}}, {&#34;name&#34;: {&#34;$regex&#34;: &#34;user&#34;}} ] } 比较查询 $lt和&lt;,$lte和&lt;=,$gt和&gt;,gte和&gt;=,ne和!=是一一对应的 {&#34;field_name&#34;: {&#34;$lt&#34;: value, &#34;$gt&#34;: value}} 关联查询$in和$nin {&#34;field_name&#34;: {&#34;$in&#34;: [1,5,8]}} $regex为模糊查询的字符串提供正则表达式功能 {&#34;$or&#34;: [{&#34;field_name&#34;: {&#39;$regex&#39;: value}},{&#34;field_name2&#34;: {&#34;$regex&#34;: value}}]} + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/Redis%E6%95%B0%E6%8D%AE%E6%BA%90/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/Redis%E6%95%B0%E6%8D%AE%E6%BA%90/ + 应用场景 # 你可能会有这样的一些需求, 展示数据是要通过外部的程序计算好,如一些实时的计算场景,用spark计算好的数据 或爬虫爬取的数据, 然后写入redis或nosql的数据库,最后由前端图形直接展示或数据下载,SmartChart支持这一块的应用 +使用方法 # 你可以创建一个redis的连接池, 然后按照通用的方法建立数据集 不同的是, 数据集的SQL区不再是写sql代码, 而只需要写redis中的keyname +如redis中存储的数据是keyname 为 &ldquo;指标A&rdquo;, 数据 &lsquo;{&ldquo;长沙&rdquo;:1,&ldquo;上海&rdquo;:2}&rsquo; 这样我们只需要在数据集中写上 +指标A 即可, 最后你会得到{&ldquo;长沙&rdquo;:1,&ldquo;上海&rdquo;:2}的返回结果 +如果你需要的是表格格式, 那么你只需要往redis中存入一个二维数组, 比如: [[&ldquo;省份&rdquo;,&ldquo;数量&rdquo;],[&ldquo;长沙&rdquo;,1],[&ldquo;上海&rdquo;,2]] +注意数据存入redis为字符串格式,你可使用python的json.dumps来生成字符串格式存入 +当然我们也支持同一个数据中获取多个keyname # 比如还有一个&quot;指标B&quot;, 数据是'12345' 我们可以同时写上两个指标,用分号隔开: +指标A;指标B 最后你会得到的结果是: { &ldquo;指标A&rdquo;:{&ldquo;长沙&rdquo;:1,&ldquo;上海&rdquo;:2}, &ldquo;指标B&rdquo;:12345 } + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/sqlalchemy%E8%BF%9E%E6%8E%A5/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/sqlalchemy%E8%BF%9E%E6%8E%A5/ + 常规的连接池的设定, 大家应该都很清楚了, Smartchart也支持sqlalchemy连接, 对于一些smartchart不支持的数据源可以使用此方法 配置方法: 只用填以上内容, 其它可留空 连接地址的写法参考sqlalchemy说明: +可选参数。一个标准的链接URL是这样的: dialect+driver://username:password@host:port/database dialect,是数据库类型,大概包括:sqlite, mysql, postgresql, oracle, or mssql. driver,是使用的数据库API,驱动,连接包,随便叫什么吧。 username,用户名 password,密码 host,网络地址,可以用ip,域名,计算机名,当然是你能访问到的。 port,数据库端口。 databas,数据库名。 其实这些也就dialect和dirver需要解释。 二:连接sqlite3 1,驱动 sqlite3是个文件数据库,不需要什么驱动,或者说python内置了驱动。 2,标准连接参数 # sqlite://&lt;nohostname&gt;/&lt;path&gt; 没有hostname 3,各种链接参数 # 相对路径,就是这个python文件同目录下foo.db engine = create_engine(&#39;sqlite:///foo.db&#39;) #绝对路径 #Unix/Mac下用四条////表示 engine = create_engine(&#39;sqlite:////absolute/path/to/foo.db&#39;) #Windows下用三条///加盘符路径用两条\\ engine = create_engine(&#39;sqlite:///C:\\path\\to\\foo.db&#39;) #Windows 也可以这么用三条///加盘符路径用一条\ engine = create_engine(r&#39;sqlite:///C:\path\to\foo.db&#39;) #数据库建在内存里。URI保持为空即可 engine = create_engine(&#39;sqlite://&#39;) 三:连接mysql(mariadb) sqlalchemy默认使用mysql-python作为链接驱动,既default模式 选哪种驱动,就装哪个包。 1,default默认链接方式 engine = create_engine(&#39;mysql://scott:tiger@localhost/foo&#39;) 2,# mysql-python,声明使用mysql-python驱动 engine = create_engine(&#39;mysql+mysqldb://scott:tiger@localhost/foo&#39;) 3,MySQL-connector-python 声明使用MySQL-connector-python驱动(推荐使用) engine = create_engine(&#39;mysql+mysqlconnector://scott:tiger@localhost/foo&#39;) 4,OurSQL 声明使用OurSQL驱动 engine = create_engine(&#39;mysql+oursql://scott:tiger@localhost/foo&#39;) 四:连接Microsoft SQL Server sqlalchemy默认使用 pyodbc作为链接驱动。 1,pyodbc engine = create_engine(&#39;mssql+pyodbc://scott:tiger@mydsn&#39;) 2,pymssql engine = create_engine(&#39;mssql+pymssql://scott:tiger@hostname:port/dbname&#39;) 五:连接PostgreSQL PostgreSQL默认使用 psycopg2作为链接驱动,既default模式 1, default engine = create_engine(&#39;postgresql://scott:tiger@localhost/mydatabase&#39;) 2,psycopg2 engine = create_engine(&#39;postgresql+psycopg2://scott:tiger@localhost/mydatabase&#39;) 3, pg8000 engine = create_engine(&#39;postgresql+pg8000://scott:tiger@localhost/mydatabase&#39;) 六:连接Oracle Oracle可能只有 cx_oracle一个驱动包,既default模式和声明模式一样。 1,default engine = create_engine(&#39;oracle://scott:tiger@127. + + + + diff --git a/docs/smartchart/docs/2.数据集说明/特殊数据源/kafka数据源/index.html b/docs/smartchart/docs/2.数据集说明/特殊数据源/kafka数据源/index.html new file mode 100644 index 0000000..5442f15 --- /dev/null +++ b/docs/smartchart/docs/2.数据集说明/特殊数据源/kafka数据源/index.html @@ -0,0 +1,1688 @@ + + + + + + + + + + + + + + +Kafka数据源 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Kafka数据源 + + +
+ + + + + + +
+ + + +

用于获取kafka指定分区的最后一条记录, 用于实时场景 +使用方法参考"自定义数据源" +以下为参考代码:

+
def dataset(*args, **kwargs):
+    """
+    返回查询数据集
+    :return: 二维数组或JSON字典
+    """
+    from kafka import  KafkaConsumer, TopicPartition
+    import json
+
+    sqlList = args[0]   # 数据集编辑界面的输入已按分号拆分成数组 [sql1, sql2...]
+    config = args[1]    # 相关的配置字典{'host','port','user','password','db'}
+    # 插入你的数据查询及处理代码, 生成result即可
+    result = {}
+    consumer = KafkaConsumer(sasl_mechanism='PLAIN',
+                             security_protocol='SASL_PLAINTEXT',
+                             sasl_plain_username=config['user'],
+                             sasl_plain_password=config['password'],
+                             bootstrap_servers=config['host'],
+                             auto_offset_reset='earliest',
+                             api_version=(1, 0, 0),
+                             consumer_timeout_ms=50,
+                             value_deserializer=lambda v: json.loads(v.decode('utf-8')),
+                             )
+    topic = sqlList[0]
+    partition = int(config['db'])
+    tp = TopicPartition(topic=topic, partition=partition)
+    consumer.assign([tp])
+    end_offsets = consumer.end_offsets([tp]).get(tp)  # 获取当前消费者最大偏移量
+    consumer.seek(tp, offset=end_offsets-1)
+    for message in consumer:
+        result = message.value
+        break
+    return result
+
+def insert_dataset(*args, **kwargs):
+    """
+    数据填报实现
+    """
+    from kafka import KafkaProducer
+    import json
+
+    contents = args[0]  # 传入的数据集二维数组格式
+    table = args[1]   # 配置中的表名
+    config = args[3]  # 相关的配置字典{'host','port','user','password','db'}
+    # 插入你的写入数据逻辑代码
+    producer = KafkaProducer(sasl_mechanism='PLAIN',
+                             security_protocol='SASL_PLAINTEXT',
+                             sasl_plain_username=config['user'],
+                             sasl_plain_password=config['password'],
+                             bootstrap_servers=config['host'],
+                             value_serializer=lambda v: json.dumps(v).encode('utf-8')
+                             )
+    producer.send(table, value=contents, partition=int(config['db']))
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/2.数据集说明/特殊数据源/mongodb数据源/index.html b/docs/smartchart/docs/2.数据集说明/特殊数据源/mongodb数据源/index.html new file mode 100644 index 0000000..04ee23d --- /dev/null +++ b/docs/smartchart/docs/2.数据集说明/特殊数据源/mongodb数据源/index.html @@ -0,0 +1,1736 @@ + + + + + + + + + + + + + + +Mongodb数据源 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Mongodb数据源 + + +
+ + + + + + +
+ + + +

+ 使用方法 + # +

+

连接池正常配置即可 +数据集开发中,填写查询需求: + + 输入图片说明

+
{"db": "db1", "table": "tb1", "filter": {"name": "Zarten"}, 
+"projection": {"_id": 0}, "sort": [["_id", 1]], "limit": 10}
+

由于返回的字典格式, 如需转化成二维数组, 可使图形中的转化函数ds_mapToList

+
let dataset=ds_mapToList(__dataset__);
+

+ 参数说明: + # +

+

除table,其它都为可选参数

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
参数说明样列
db数库名,默认连接设定中db名
table表名[必填]
filter筛选项,具体用法参考下文{“name”: “Zarten”,“date”:“2020-10-01”}
projection显示列{“name”: 1,“date”:1}
sort排序,-1为降序[[“date”, -1]]
limit限定返回数量
+

+ filter条件说明 + # +

+

且条件

+
{"age":{"$gt":22}, "name":{"$regex":"user"}}
+

或条件

+
{ "$or": [ {"age": {"$gt": 22}}, {"name": {"$regex": "user"}} ] }
+
比较查询
+$lt和<,$lte和<=,$gt和>,gte和>=,ne和!=是一一对应的
+{"field_name": {"$lt": value, "$gt": value}}
+关联查询$in和$nin
+{"field_name": {"$in": [1,5,8]}}
+$regex为模糊查询的字符串提供正则表达式功能
+{"$or": [{"field_name": {'$regex': value}},{"field_name2": {"$regex": value}}]}
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/2.数据集说明/特殊数据源/sqlalchemy连接/index.html b/docs/smartchart/docs/2.数据集说明/特殊数据源/sqlalchemy连接/index.html new file mode 100644 index 0000000..ea810de --- /dev/null +++ b/docs/smartchart/docs/2.数据集说明/特殊数据源/sqlalchemy连接/index.html @@ -0,0 +1,1705 @@ + + + + + + + + + + + + + + +Sqlalchemy连接 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Sqlalchemy连接 + + +
+ + + + + + +
+ + + +

常规的连接池的设定, 大家应该都很清楚了, +Smartchart也支持sqlalchemy连接, 对于一些smartchart不支持的数据源可以使用此方法 +配置方法: + + 输入图片说明 +只用填以上内容, 其它可留空 +连接地址的写法参考sqlalchemy说明:

+
可选参数。一个标准的链接URL是这样的:
+dialect+driver://username:password@host:port/database
+dialect,是数据库类型,大概包括:sqlite, mysql, postgresql, oracle, or mssql.
+driver,是使用的数据库API,驱动,连接包,随便叫什么吧。
+username,用户名
+password,密码
+host,网络地址,可以用ip,域名,计算机名,当然是你能访问到的。
+port,数据库端口。
+databas,数据库名。
+其实这些也就dialect和dirver需要解释。
+
+二:连接sqlite3
+1,驱动
+sqlite3是个文件数据库,不需要什么驱动,或者说python内置了驱动。
+2,标准连接参数
+# sqlite://<nohostname>/<path>
+没有hostname
+3,各种链接参数
+# 相对路径,就是这个python文件同目录下foo.db
+engine = create_engine('sqlite:///foo.db')
+#绝对路径
+#Unix/Mac下用四条////表示
+engine = create_engine('sqlite:////absolute/path/to/foo.db')
+#Windows下用三条///加盘符路径用两条\\
+engine = create_engine('sqlite:///C:\\path\\to\\foo.db')
+#Windows 也可以这么用三条///加盘符路径用一条\
+engine = create_engine(r'sqlite:///C:\path\to\foo.db')
+#数据库建在内存里。URI保持为空即可
+engine = create_engine('sqlite://')
+
+三:连接mysql(mariadb)
+sqlalchemy默认使用mysql-python作为链接驱动,既default模式
+选哪种驱动,就装哪个包。
+1,default默认链接方式
+engine = create_engine('mysql://scott:tiger@localhost/foo')
+2,# mysql-python,声明使用mysql-python驱动
+engine = create_engine('mysql+mysqldb://scott:tiger@localhost/foo')
+3,MySQL-connector-python 声明使用MySQL-connector-python驱动(推荐使用)
+engine = create_engine('mysql+mysqlconnector://scott:tiger@localhost/foo')
+4,OurSQL 声明使用OurSQL驱动
+engine = create_engine('mysql+oursql://scott:tiger@localhost/foo')
+
+四:连接Microsoft SQL Server
+sqlalchemy默认使用 pyodbc作为链接驱动。
+1,pyodbc
+engine = create_engine('mssql+pyodbc://scott:tiger@mydsn')
+2,pymssql
+engine = create_engine('mssql+pymssql://scott:tiger@hostname:port/dbname')
+
+ 
+五:连接PostgreSQL
+PostgreSQL默认使用 psycopg2作为链接驱动,既default模式
+1, default
+engine = create_engine('postgresql://scott:tiger@localhost/mydatabase')
+2,psycopg2
+engine = create_engine('postgresql+psycopg2://scott:tiger@localhost/mydatabase')
+3, pg8000
+engine = create_engine('postgresql+pg8000://scott:tiger@localhost/mydatabase')
+
+ 六:连接Oracle
+Oracle可能只有 cx_oracle一个驱动包,既default模式和声明模式一样。
+1,default
+engine = create_engine('oracle://scott:tiger@127.0.0.1:1521/sidname')
+2,cx_oracle
+engine = create_engine('oracle+cx_oracle://scott:tiger@tnsname')
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/2.数据集说明/特殊数据源/自定义数据源/index.html b/docs/smartchart/docs/2.数据集说明/特殊数据源/自定义数据源/index.html new file mode 100644 index 0000000..8a3c3a7 --- /dev/null +++ b/docs/smartchart/docs/2.数据集说明/特殊数据源/自定义数据源/index.html @@ -0,0 +1,1713 @@ + + + + + + + + + + + + + + +自定义数据源 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 自定义数据源 + + +
+ + + + + + +
+ + + +

smartchart已实现大部分常用的数据源连接, 对于其它的, 您也可以使用python数据源进行处理 +但是使用python数据源有一定的缺陷, 需要在dataset上写python代码, 不能复用 +对于一些带连接信息的还需要重复写入 +所以你还可以使用自定义数据源

+

+ 应用场景 + # +

+
    +
  • 未内置的数据源, 如需要使用sparkSQL, ES等
  • +
  • 标准处理满足不了要求, 需要对数据进行预处理的情况
  • +
  • 需要刷新时触发预警等自定义动作
  • +
  • 需要自定义写入方法, 个性化查询需求, 甚至是实时爬取数据
  • +
+

+ 使用方法 + # +

+
    +
  • 首先你需要新建一个python脚本文件, 如diy_conn.py
  • +
  • 复制以下代码到这个文件, 然后编写你的自定义查询方法
  • +
+
def dataset(*args, **kwargs):
+    """
+    返回查询数据集
+    :return: 二维数组或JSON字典
+    """
+    sqlList = args[0]   # 数据集编辑界面的输入已按分号拆分成数组 [sql1, sql2...]
+    config = args[1]    # 相关的配置字典{'host','port','user','password','db'}
+    # 插入你的数据查询及处理代码, 生成result即可
+    result = [[]]
+
+    return result
+
+def insert_dataset(*args, **kwargs):
+    """
+    数据填表实现
+    """
+    contents = args[0]  # 传入的数据集二维数组格式
+    table = args[1]   # 配置中的表名
+    config = args[3]  # 相关的配置字典{'host','port','user','password','db'}
+    # 插入你的写入数据逻辑代码
+
    +
  • +

    在任意的仪表盘开发界面中 “模板” –> 点击上传图标, 将这个python文件上传即可 + + 输入图片说明

    +
  • +
  • +

    新建数据源, 驱动填写之前上传过的文件名, 比如我们这个是diy_conn, 其它参数按照你自定义的需求填写, 会自动传入你的自定义函数 + + 输入图片说明

    +
  • +
+

之后你可以正常使用这个自定义数据源了

+

如果你对python不熟悉, 也可按需定制, 你只需上传即可使用

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/3.图形开发/Echarts组件/index.html b/docs/smartchart/docs/3.图形开发/Echarts组件/index.html new file mode 100644 index 0000000..5e7626c --- /dev/null +++ b/docs/smartchart/docs/3.图形开发/Echarts组件/index.html @@ -0,0 +1,1782 @@ + + + + + + + + + + + + + + +Echarts组件 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Echarts组件 + + +
+ + + + + + +
+ + + +

+ 应用场景 + # +

+

Smartchart提供了很多通用的图形,你可以在商店中直接使用 +如果要个性化需要你进行自定义, 比如你可能需要在同一个图上展示柱形图和线性图

+

开发前建意先观看视屏, 了解基础说明, 视屏有点老和现在界面不一样, +目前很多功能已经做成可视化配置, 理解过程即可, 具体以文档为准

+ +

+ 获取原生echarts图形 + # +

+

首先我们在ECHART官网可能找一个你喜欢的图形, 如下简单柱形图链接: + + + 输入图片说明

+

打开我们可以看对应的option:

+
option = {
+    xAxis: {
+        type: 'category',
+        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
+    },
+    yAxis: {
+        type: 'value'
+    },
+    series: [{
+        data: [120, 200, 150, 80, 70, 110, 130],
+        type: 'bar'
+    }]
+};
+

+ 转化为smartchart图形 + # +

+

复制到Smartchart图形编辑器, 点击"刀叉“ 图标(目前是魔法梆), 会自动进行初步转化 + + 输入图片说明

+

接下来我们就进行下改造, 请注意对比, 你只需照着复制即可

+
let dataset = __dataset__ //传入dataset
+let legend_label = ds_rowname(dataset) //可选, 自动获取legend
+let xlabel = dataset[0].splice(1) //x轴的标签列
+dataset = ds_createMap(dataset) //转化成KV格式
+
+//初始化series
+var series=[];
+series.push({
+        data: dataset[legend_label[0]], //对应的第一个图列
+        type: 'bar'
+    });
+series.push({
+        data: dataset[legend_label[1]], //对应的第二个图列
+        type: 'line'
+    });
+
+option__name__  = {
+    xAxis: {
+        type: 'category',
+        data: xlabel //X轴的标签
+    },
+    yAxis: {
+        type: 'value'
+    },
+    series:series,
+};
+charts.push(myChart__name__);
+

这样一个柱形+线性图就出来了 + + + 线柱混合图

+

当然一个图形还有很多其它的元素, 比如标题, legend, 等等 更多option的配置项, 可以点击”!“号图标查看,你可以直接参考echarts的设定, 完全一样!!

+

以下我们做了些简单的修改

+
option__name__  = {
+    title: {
+        text: '自定义图示例',
+        left: 'center'
+    }, //定义标题的显示
+    tooltip: {
+        trigger: 'item',
+        formatter: '{a} <br/>{b} : {c}'  //鼠标移动提示的格式
+    },
+    legend: {
+        left: 'left',
+        data: legend_label
+    }, //定义图例的显示
+    xAxis: {
+        type: 'category',
+        data: xlabel
+    }, //定义X轴的显示
+    yAxis: {
+        type: 'value'
+    },
+	//图例定义
+    series:series,
+};
+
//关于自动化series, 可以参考以下代码
+var series =[];
+for (var i=1;i<dataset[0].length;i++){
+    series.push({type: 'bar'})
+}
+

是不是非常简单 Smartchart让你使用echarts没有门槛

+
+

TIPS:

+
    +
  • 如果你在图形编辑器中可以显示图形, 但是保存后在dashboard中无法, 首先检查下所有的mychart, option是否都有转化成带__name__, 如果都有,可能原因是你的代码中有mychart.setoption, 这样你可以在代码下方加上myChart__name__.setOption(option__name__);即可
  • +
  • 如果你在开发界面的仪表盘能看到图形显示,但预览仪表盘时,不显示图形,一般都是因为你图形代码中js结束需加分号的地方没有添加导致的
  • +
+
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/3.图形开发/ElementUI组件/index.html b/docs/smartchart/docs/3.图形开发/ElementUI组件/index.html new file mode 100644 index 0000000..13838a4 --- /dev/null +++ b/docs/smartchart/docs/3.图形开发/ElementUI组件/index.html @@ -0,0 +1,1626 @@ + + + + + + + + + + + + +Element Ui组件 | Smartchart开发手册 + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Element Ui组件 + + +
+ + + + + + +
+ + + +
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/3.图形开发/ElementUI组件/index.xml b/docs/smartchart/docs/3.图形开发/ElementUI组件/index.xml new file mode 100644 index 0000000..fec7e43 --- /dev/null +++ b/docs/smartchart/docs/3.图形开发/ElementUI组件/index.xml @@ -0,0 +1,18 @@ + + + + Smartchart开发手册 + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/ElementUI%E7%BB%84%E4%BB%B6/ + Recent content on Smartchart开发手册 + Hugo -- gohugo.io + + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/ElementUI%E7%BB%84%E4%BB%B6/%E5%B8%A6%E5%88%86%E9%A1%B5%E7%9A%84%E8%A1%A8%E6%A0%BC/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/ElementUI%E7%BB%84%E4%BB%B6/%E5%B8%A6%E5%88%86%E9%A1%B5%E7%9A%84%E8%A1%A8%E6%A0%BC/ + 模式开启 # 需要开启模板开发模式, 并开启basevue模板 在Body加入组件 # &lt;!--表格--&gt; &lt;div class=&#34;smtdrag&#34; id=&#34;id_1654907858638&#34;&gt; &lt;el-table :data=&#34;tableData.slice((currentPage-1)*pageSize, currentPage*pageSize)&#34; height=&#34;100%&#34; size=&#34;mini&#34; header-cell-class-name=&#34;tablehead&#34; border style=&#34;width: 100%&#34;&gt; &lt;el-table-column v-for=&#34;item in tableHead&#34; :label=&#34;item.label&#34; :property=&#34;item.prop&#34; sortable&gt; &lt;/el-table-column&gt; &lt;/el-table&gt; &lt;!--表格结束--&gt; &lt;!--分页控件--&gt; &lt;el-pagination align=&#39;center&#39; @size-change=&#34;handlerSizeChange&#34; @current-change=&#34;handlerCurrentChange&#34; :current-page=&#34;currentPage&#34; :page-size=&#34;pageSize&#34; layout=&#34;total,sizes,prev,pager,next,jumper&#34; :total=&#34;tableData.length&#34; &gt;&lt;/el-pagination&gt; &lt;!--分页控件结束--&gt; &lt;/div&gt; 在JS区域加入 # var vapp = new Vue({el: &#39;#vue_app&#39;, delimiters: [&#39;{[&#39;, &#39;]}&#39;], data: { tableData:[], //表数据 tableHead:[], //表头 currentPage:1, total:20, pageSize:10 }, methods: { //处理分页数量 handlerSizeChange(val){ this.currentPage = 1; this. + + + + diff --git a/docs/smartchart/docs/3.图形开发/ElementUI组件/带分页的表格/index.html b/docs/smartchart/docs/3.图形开发/ElementUI组件/带分页的表格/index.html new file mode 100644 index 0000000..433e74e --- /dev/null +++ b/docs/smartchart/docs/3.图形开发/ElementUI组件/带分页的表格/index.html @@ -0,0 +1,1756 @@ + + + + + + + + + + + + + + +带分页的表格 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 带分页的表格 + + +
+ + + + + + +
+ + + +

+ 模式开启 + # +

+

需要开启模板开发模式, 并开启basevue模板 + + 输入图片说明

+

+ 在Body加入组件 + # +

+
   <!--表格-->
+    <div class="smtdrag" id="id_1654907858638">
+    <el-table
+    :data="tableData.slice((currentPage-1)*pageSize, currentPage*pageSize)"
+    height="100%"
+    size="mini"
+    header-cell-class-name="tablehead"
+    border
+    style="width: 100%">
+    <el-table-column v-for="item in tableHead" :label="item.label" :property="item.prop" sortable>
+    </el-table-column>
+    </el-table>
+    <!--表格结束-->
+    <!--分页控件-->
+    <el-pagination align='center'
+      @size-change="handlerSizeChange"
+      @current-change="handlerCurrentChange"
+      :current-page="currentPage"
+      :page-size="pageSize"
+      layout="total,sizes,prev,pager,next,jumper"
+      :total="tableData.length"
+    ></el-pagination>
+    <!--分页控件结束-->
+    </div>
+

+ 在JS区域加入 + # +

+
var vapp = new Vue({el: '#vue_app', delimiters: ['{[', ']}'], 
+     data: {
+         tableData:[],  //表数据
+         tableHead:[],  //表头
+         currentPage:1,
+         total:20,
+         pageSize:10
+         
+     },
+     methods: {
+         //处理分页数量
+         handlerSizeChange(val){
+             this.currentPage = 1;
+             this.pageSize=val;
+         },
+         //处理页选择
+         handlerCurrentChange(val){
+             this.currentPage = val;
+         }
+     }
+     
+    });
+

+ 新增一个数据集 + # +

+
select * from smartdemo2
+limit /*  $limit -- */ 100
+

+ 图形开发中修改 + # +

+
let df0 = __dataset__;
+//处理表头
+let columnsDict = {'c1':'渠道','qty':'数量'};
+let tableHead = [];
+let tableHeadLabel;
+for (let i=0;i<df0[0].length;i++){
+    if(columnsDict.hasOwnProperty(df0[0][i])){
+        df0[0][i] = columnsDict[df0[0][i]]
+    }
+    tableHeadLabel=df0[0][i];
+    tableHead.push({label: tableHeadLabel, prop:df0[0][i]});
+}
+
+//VUE赋值
+vapp.tableHead = tableHead;
+vapp.tableData=ds_createMap_all(df0);
+

+ 输入图片说明

+
+

smartchart内置了这个查询模板, 你可以通过 + 本地模板恢复快速应用

+
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/3.图形开发/HTML组件/index.html b/docs/smartchart/docs/3.图形开发/HTML组件/index.html new file mode 100644 index 0000000..d411152 --- /dev/null +++ b/docs/smartchart/docs/3.图形开发/HTML组件/index.html @@ -0,0 +1,1716 @@ + + + + + + + + + + + + + + +Html组件 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Html组件 + + +
+ + + + + + +
+ + + +

+ 应用场景 + # +

+
    +
  • 输入控件,如输入框,筛选器,多选,按钮…
  • +
  • 显示组件, 文本, 图片, 视屏…
  • +
  • 表格组件
  • +
+
+

如果你还不熟悉html, 建意先花几分钟看下文档, 推荐 + HTML基础 +实际应用中有不熟悉的组件, 你都可以通过baidu搜索到, 如时间选择器 + + 输入图片说明

+
+

+ 如何将html组件转化为smartchart组件 + # +

+

比如我们要实现一个有多选项和按钮的网页元素 + + 输入图片说明

+

从各大搜索平台上我们可以找到html的代码是:

+
<label><input type="checkbox">孙尚香</label>
+.....
+<button id='id_select0'>提交</button>
+

那么我们可以直接在图形编辑器写上

+
let dataset=__dataset__;
+let table = '';
+table = `<label><input type="checkbox">孙一香</label>
+         <label><input type="checkbox">孙二香</label>
+         <label><input type="checkbox">孙三香</label>`
+table = table + "<button id='id_select0'>提交</button>"
+
+dom__name__.innerHTML=table;
+

但是由于我们是要通过传入的数据动态变化的,所以只需要做简单修改

+
let dataset=__dataset__;
+let table = '';
+for (let i=1;i<dataset.length;i++){
+    table = `${table}<label><input type="checkbox"/>${dataset[i][0]}</label> `
+}
+table = table + "<button id='id_select__name__'>提交</button>"
+
+dom__name__.innerHTML=table;
+

所有html你都可以进行转化成smartchart组件, +你可以通过学习”万能表格系列视屏“ 来了解通用组件开发 + + 第一波 + + 第二波 + + 第三波

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/3.图形开发/index.html b/docs/smartchart/docs/3.图形开发/index.html new file mode 100644 index 0000000..feccd71 --- /dev/null +++ b/docs/smartchart/docs/3.图形开发/index.html @@ -0,0 +1,1626 @@ + + + + + + + + + + + + +3.图形开发 | Smartchart开发手册 + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 3.图形开发 + + +
+ + + + + + +
+ + + +
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/3.图形开发/index.xml b/docs/smartchart/docs/3.图形开发/index.xml new file mode 100644 index 0000000..6b59e3e --- /dev/null +++ b/docs/smartchart/docs/3.图形开发/index.xml @@ -0,0 +1,65 @@ + + + + Smartchart开发手册 + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/ + Recent content on Smartchart开发手册 + Hugo -- gohugo.io + + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E5%9F%BA%E7%A1%80%E5%9B%BE%E5%BD%A2/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E5%9F%BA%E7%A1%80%E5%9B%BE%E5%BD%A2/ + 快速应用基础图形组件 # 你可使用如下方式选择常规的图形一键进行应用(我们只放了基础图形,因为你可以通过简单修改配置转化为各种图形,如线性面积图, 柱形堆叠图..) 你也可以在图形商店中找到更多已转化好的Smartchart图形 配置项完全和Echarts原生一样 +注意: 对于一些特殊图形如地图js在图形编辑中需要进行动态加载, 如果你使用了非常规图形, 你可在图形编辑器使用ds_loadjs(&lsquo;smt_china’)加载中国地图, 同理我们有 &lsquo;smt_wordcloud&rsquo;, &lsquo;smt_world&rsquo;, &lsquo;smt_ecStat&rsquo;, ‘smt_liquidfill’ 有些图形可能同时需要在模板中加载, 更多特殊图形加载说明参考 特殊图形模板加载 + + + + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%AE%A1%E7%90%86%E5%9B%BE%E5%BD%A2/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%AE%A1%E7%90%86%E5%9B%BE%E5%BD%A2/ + 应用场景 # 如何快速复用已开发好的组件 +本地管理自定义组件 # 如下图,点击图形编辑器中的菜单,即可管理和查看自定义图形列表 点击&quot;加入样列&quot;即可把当前图形加入到样列清单, 点击&quot;取消样列&quot;即可将所选样列移除样列清单 云管理,在图形商店中保存你的图形 # 这样你就可以在图形商店看到你的图形进行重复利用 + + + + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/Echarts%E7%BB%84%E4%BB%B6/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/Echarts%E7%BB%84%E4%BB%B6/ + 应用场景 # Smartchart提供了很多通用的图形,你可以在商店中直接使用 如果要个性化需要你进行自定义, 比如你可能需要在同一个图上展示柱形图和线性图 +开发前建意先观看视屏, 了解基础说明, 视屏有点老和现在界面不一样, 目前很多功能已经做成可视化配置, 理解过程即可, 具体以文档为准 +Smartchart数据库与图形的对话 Smartchart图形开发一 Smartchart图形开发二 获取原生echarts图形 # 首先我们在ECHART官网可能找一个你喜欢的图形, 如下简单柱形图链接: 打开我们可以看对应的option: +option = { xAxis: { type: &#39;category&#39;, data: [&#39;Mon&#39;, &#39;Tue&#39;, &#39;Wed&#39;, &#39;Thu&#39;, &#39;Fri&#39;, &#39;Sat&#39;, &#39;Sun&#39;] }, yAxis: { type: &#39;value&#39; }, series: [{ data: [120, 200, 150, 80, 70, 110, 130], type: &#39;bar&#39; }] }; 转化为smartchart图形 # 复制到Smartchart图形编辑器, 点击&quot;刀叉“ 图标(目前是魔法梆), 会自动进行初步转化 接下来我们就进行下改造, 请注意对比, 你只需照着复制即可 +let dataset = __dataset__ //传入dataset let legend_label = ds_rowname(dataset) //可选, 自动获取legend let xlabel = dataset[0]. + + + + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/HTML%E7%BB%84%E4%BB%B6/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/HTML%E7%BB%84%E4%BB%B6/ + 应用场景 # 输入控件,如输入框,筛选器,多选,按钮&hellip; 显示组件, 文本, 图片, 视屏&hellip; 表格组件 如果你还不熟悉html, 建意先花几分钟看下文档, 推荐 HTML基础 实际应用中有不熟悉的组件, 你都可以通过baidu搜索到, 如时间选择器 如何将html组件转化为smartchart组件 # 比如我们要实现一个有多选项和按钮的网页元素 从各大搜索平台上我们可以找到html的代码是: +&lt;label&gt;&lt;input type=&#34;checkbox&#34;&gt;孙尚香&lt;/label&gt; ..... &lt;button id=&#39;id_select0&#39;&gt;提交&lt;/button&gt; 那么我们可以直接在图形编辑器写上 +let dataset=__dataset__; let table = &#39;&#39;; table = `&lt;label&gt;&lt;input type=&#34;checkbox&#34;&gt;孙一香&lt;/label&gt; &lt;label&gt;&lt;input type=&#34;checkbox&#34;&gt;孙二香&lt;/label&gt; &lt;label&gt;&lt;input type=&#34;checkbox&#34;&gt;孙三香&lt;/label&gt;` table = table + &#34;&lt;button id=&#39;id_select0&#39;&gt;提交&lt;/button&gt;&#34; dom__name__.innerHTML=table; 但是由于我们是要通过传入的数据动态变化的,所以只需要做简单修改 +let dataset=__dataset__; let table = &#39;&#39;; for (let i=1;i&lt;dataset.length;i++){ table = `${table}&lt;label&gt;&lt;input type=&#34;checkbox&#34;/&gt;${dataset[i][0]}&lt;/label&gt; ` } table = table + &#34;&lt;button id=&#39;id_select__name__&#39;&gt;提交&lt;/button&gt;&#34; dom__name__.innerHTML=table; 所有html你都可以进行转化成smartchart组件, 你可以通过学习”万能表格系列视屏“ 来了解通用组件开发 第一波 第二波 第三波 + + + + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E8%B0%83%E8%AF%95%E6%97%A5%E5%BF%97/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E8%B0%83%E8%AF%95%E6%97%A5%E5%BF%97/ + 关于页面日志查看 # 大家可能比较熟悉使用F12来查看网页日志, 但有的同学会觉得这不够方便, 所以 在5.1.11后, smartchart加入了可以页面直接显示日志的功能 +在仪表盘中显示 # 你只需要点击如下菜单, 即可切换是否显示日志 当在刷新页面或执行时, 日志将直接显示在右上角中, 而且还能显示出对应出错的图表序号 在图形中显示 # smartchart基于python的使用习惯, 重定义的专用的日志打印函数print 你可以在图形编辑器中使用些函数即可打印日志 比如看看鼠标放在echarts图上params, 在编辑界面和console中都能看到日志, 方便你进行调试 不仅仅这些, 你可能会想写太多打印日志, 上线了不好 smartchart已为你想到这些, 如果你在仪表盘中没有开启日志显示, print函数是不会打印任何日志 +有了仪表盘日志显示, 我们还能做更多的事情, 比如实时显示你拖拽的坐标, 让你精确定位 + + + + diff --git a/docs/smartchart/docs/3.图形开发/函数方法/Jquery遍历方法/index.html b/docs/smartchart/docs/3.图形开发/函数方法/Jquery遍历方法/index.html new file mode 100644 index 0000000..ff88c74 --- /dev/null +++ b/docs/smartchart/docs/3.图形开发/函数方法/Jquery遍历方法/index.html @@ -0,0 +1,1735 @@ + + + + + + + + + + + + + + +Jquery遍历方法 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Jquery遍历方法 + + +
+ + + + + + +
+ + + +

在做自定义html组件的时候你可能需要用得上:

+

一、向上遍历

+
    +
  1. parent() 获取元素的直接父元素
  2. +
+
$("span").parent().css({
+	"color":"red",
+	"border":"1px solid red"
+})
+
    +
  1. parents() 获取元素的祖先元素,直到根元素html
  2. +
+
$("span").parents().css({
+	"color":"red",
+	"border":"1px solid red"
+})
+
    +
  1. parentsUntil() 向上查找直到遇见某个祖先元素为止
  2. +
+
 $("span").parentsUntil("div").css({	//向上查找直到遇见div元素为止
+	"color":"red",
+	"border":"1px solid red"
+})
+

二、向下遍历

+
1. children() 查找子元素[按照从属关系]
+
+$("ul").children("li:first-child")
+
+2. find() 按照指定的条件向下查找
+
+$("ul").find("span")
+

三、水平遍历

+
1. siblings() 获取元素的所有兄弟元素
+
+$(".start").siblings().css({color:"red",border:"2px solid red"})
+
+2. next() 获取元素的下一个兄弟元素
+
+$(".start").next().css({color:"red",border:"2px solid red"})
+
+3. nextAll() 获取其后的所有兄弟元素
+
+$(".start").nextAll().css({color:"red",border:"2px solid red"})
+
+4. nextUntil() 查找后面所有的兄弟元素,直到遇见某个元素为止
+
+$(".start").nextUntil("li:last-child").css({color:"red",border:"2px solid red"})
+
+5. prev() 查找上一个兄弟元素
+
+$("li.start").prev().css({color:"red",border:"2px solid red"})
+
+6. prevAll() 查找上面所有的兄弟元素
+
+$("li.start").prevAll().css({color:"red",border:"2px solid red"})
+
+prevUntil() 查找上面所有的兄弟元素,直到遇见某个元素为止
+$(".start").prevUntil("li:first").css({"color":"red","border":"2px solid red"})
+

四、过滤

+
1. first() 获取第一个元素
+
+$("li").first().css("color","red");
+
+2. last() 获取最后一个元素
+
+$("li").last().css("color","red");
+
+3. not() 获取不是…的元素
+
+$("li").not(":eq(2)").css("font-size","26px");
+
+4. eq(n) 获取索引为n的元素
+
+$("li").eq(3).css("background","green");
+
+5. has() 检测某个子元素是否存在
+
+$("li").eq(1).has("span").length)
+
+6. filter() 筛选出与符合条件的DOM元素
+
+$("div")..filter(".middle")
+
+7. is() 用来判断是否符合条件
+
+$("p").parent().is("div")	//判断p的父元素是不是div,是就返回true,不是就返回false
+

五、each遍历

+
1. each() 方法为每个匹配元素规定要运行的函数。
+
+$(selector).each(function(index,element){
+	.....
+})
+//index 表示当前遍历元素的索引
+  element 当前的元素(也可使用 "this" 选择器)
+
+2. $.each(obj,function( index,value){})
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/3.图形开发/函数方法/index.html b/docs/smartchart/docs/3.图形开发/函数方法/index.html new file mode 100644 index 0000000..7433ec3 --- /dev/null +++ b/docs/smartchart/docs/3.图形开发/函数方法/index.html @@ -0,0 +1,1626 @@ + + + + + + + + + + + + +函数方法 | Smartchart开发手册 + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 函数方法 + + +
+ + + + + + +
+ + + +
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/3.图形开发/函数方法/index.xml b/docs/smartchart/docs/3.图形开发/函数方法/index.xml new file mode 100644 index 0000000..b11fb0c --- /dev/null +++ b/docs/smartchart/docs/3.图形开发/函数方法/index.xml @@ -0,0 +1,33 @@ + + + + Smartchart开发手册 + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E5%87%BD%E6%95%B0%E6%96%B9%E6%B3%95/ + Recent content on Smartchart开发手册 + Hugo -- gohugo.io + + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E5%87%BD%E6%95%B0%E6%96%B9%E6%B3%95/%E5%9B%BE%E5%BD%A2%E7%AB%AF%E6%95%B0%E6%8D%AE%E5%87%BD%E6%95%B0/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E5%87%BD%E6%95%B0%E6%96%B9%E6%B3%95/%E5%9B%BE%E5%BD%A2%E7%AB%AF%E6%95%B0%E6%8D%AE%E5%87%BD%E6%95%B0/ + 应用场景 # 在图形开发中,我们可能需要使用js对传递过来的数据进行处理 +原始数据格式 # 假设dataset的格式是, SQL = Select 维度1,维度2,数据 from xxxx, 生成的数据集如下 +dataset = [[&#39;category&#39;,&#39;C1&#39;,&#39;C2&#39;], [&#39;R1&#39;, 12, 18], [&#39;R2&#39;, 10, 17] ] 转化函数 # 生成字典表示为key-&gt;[], 常用于定制化高的图形 # result = ds_createMap(dataset) 结果 = {&#34;category&#34;:[&#39;C1&#39;,&#39;C2&#39;], &#34;R1&#34; : [12, 10], &#34;R2&#34; : [18, 17]} 生成非常多前端组件要求的格式 # result = ds_createMap_all(dataset) 结果 = [{&#34;category&#34;:&#34;R1&#34;, &#34;C1&#34;: 12, &#34;C2&#34;: 18}, {&#34;category&#34;:&#34;R2&#34;, &#34;C1&#34;: 10, &#34;C2&#34;: 17}] 获取列名list, 用于获取系列名 # result = ds_rowname(dataset) 结果 = [&#39;R1&#39;,&#39;R2&#39;] 将数据集行列转化, 一般用于坐标轴翻转 # result = ds_transform(dataset) 结果 = [[&#39;category&#39;,&#39;R1&#39;,&#39;R2&#39;], [&#39;C1&#39;, 12, 10], [&#39;C2&#39;, 18, 17]] 两个数据集左关联, 常用于将两段查询数据合并 # 假设需要关联的数据集格式: dataset2 = [[&#39;category&#39;,&#39;C3&#39;], [&#39;R1&#39;, 38], [&#39;R6&#39;, 13]] 处理后的结果: result = ds_leftjoin(dataset, dataset2) 结果 = [[&#39;category&#39;,&#39;C1&#39;,&#39;C2&#39;,&#39;C3&#39;], [&#39;R1&#39;, 12, 18, 38], [&#39;R2&#39;, 10, 17, 0] ] 数据集旋转,在excel中叫透视表 # 比如需要将dataset3的户型变成指标 dataset3 = [[&#39;城市&#39;,&#39;户型&#39;,&#39;数量&#39;], [&#39;长沙&#39;,&#39;A&#39;,35], [&#39;上海&#39;,&#39;B&#39;,19]] 处理后的结果: result = ds_pivot(dataset3) 结果 = [[&#34;城市&#34;,&#34;A&#34;,&#34;B&#34;], [&#34;长沙&#34;,35,0], [&#34;上海&#34;,0,19]] 移除数据集中的某几列 # 比如移除第1列(序号0) result=ds_remove_column(dataset,remove_list=[0]) 结果 = [[&#39;R1&#39;,&#39;R2&#39;], [12, 10], [18, 17] ] smartchart图形中可用的转化函数 # 函数名 函数说明 样列 ds_transform(dataset) 行列替换 ds_split(data,sep=&rsquo;,&rsquo;,head_add=[]) 将第一列拆分成多个字段,默认逗号分隔, 如果不传表头,取SQL中的字段名拆分 ds_createMap(data) data表示传入的二位数组,生成结果表示为key-&gt;[], 常用于echarts指定数据 ds_createMap_all(data) data表示传入的二维数组,生成结果表示为[{A:A1,B:B1,C:C1},{A:A2,B:B2,C:C2}&hellip;] ds_mapToList(data) 将createMap_all的格式还原成二维数组, 常用于将nosql(mongodb,es. + + + + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E5%87%BD%E6%95%B0%E6%96%B9%E6%B3%95/Jquery%E9%81%8D%E5%8E%86%E6%96%B9%E6%B3%95/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E5%87%BD%E6%95%B0%E6%96%B9%E6%B3%95/Jquery%E9%81%8D%E5%8E%86%E6%96%B9%E6%B3%95/ + 在做自定义html组件的时候你可能需要用得上: +一、向上遍历 +parent() 获取元素的直接父元素 $(&#34;span&#34;).parent().css({ &#34;color&#34;:&#34;red&#34;, &#34;border&#34;:&#34;1px solid red&#34; }) parents() 获取元素的祖先元素,直到根元素html $(&#34;span&#34;).parents().css({ &#34;color&#34;:&#34;red&#34;, &#34;border&#34;:&#34;1px solid red&#34; }) parentsUntil() 向上查找直到遇见某个祖先元素为止 $(&#34;span&#34;).parentsUntil(&#34;div&#34;).css({ //向上查找直到遇见div元素为止 &#34;color&#34;:&#34;red&#34;, &#34;border&#34;:&#34;1px solid red&#34; }) 二、向下遍历 +1. children() 查找子元素[按照从属关系] $(&#34;ul&#34;).children(&#34;li:first-child&#34;) 2. find() 按照指定的条件向下查找 $(&#34;ul&#34;).find(&#34;span&#34;) 三、水平遍历 +1. siblings() 获取元素的所有兄弟元素 $(&#34;.start&#34;).siblings().css({color:&#34;red&#34;,border:&#34;2px solid red&#34;}) 2. next() 获取元素的下一个兄弟元素 $(&#34;.start&#34;).next().css({color:&#34;red&#34;,border:&#34;2px solid red&#34;}) 3. nextAll() 获取其后的所有兄弟元素 $(&#34;.start&#34;).nextAll().css({color:&#34;red&#34;,border:&#34;2px solid red&#34;}) 4. nextUntil() 查找后面所有的兄弟元素,直到遇见某个元素为止 $(&#34;.start&#34;).nextUntil(&#34;li:last-child&#34;).css({color:&#34;red&#34;,border:&#34;2px solid red&#34;}) 5. prev() 查找上一个兄弟元素 $(&#34;li.start&#34;).prev().css({color:&#34;red&#34;,border:&#34;2px solid red&#34;}) 6. prevAll() 查找上面所有的兄弟元素 $(&#34;li. + + + + diff --git a/docs/smartchart/docs/3.图形开发/函数方法/图形端数据函数/index.html b/docs/smartchart/docs/3.图形开发/函数方法/图形端数据函数/index.html new file mode 100644 index 0000000..eb5d22d --- /dev/null +++ b/docs/smartchart/docs/3.图形开发/函数方法/图形端数据函数/index.html @@ -0,0 +1,1913 @@ + + + + + + + + + + + + + + +图形端数据函数 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 图形端数据函数 + + +
+ + + + + + +
+ + + +

+ 应用场景 + # +

+

在图形开发中,我们可能需要使用js对传递过来的数据进行处理

+

+ 原始数据格式 + # +

+

假设dataset的格式是, SQL = Select 维度1,维度2,数据 from xxxx, 生成的数据集如下

+
dataset = [['category','C1','C2'],
+           ['R1',       12,  18],
+	   ['R2',       10,  17] ]
+

+ 转化函数 + # +

+

+ 生成字典表示为key->[], 常用于定制化高的图形 + # +

+
result = ds_createMap(dataset)
+结果 = {"category":['C1','C2'],
+           "R1" : [12, 10],
+	   "R2" : [18,  17]}
+

+ 生成非常多前端组件要求的格式 + # +

+
result = ds_createMap_all(dataset)
+结果 = [{"category":"R1", "C1": 12, "C2": 18},
+       {"category":"R2", "C1": 10, "C2": 17}]
+

+ 获取列名list, 用于获取系列名 + # +

+
result = ds_rowname(dataset)
+结果 = ['R1','R2']
+

+ 将数据集行列转化, 一般用于坐标轴翻转 + # +

+
result = ds_transform(dataset)
+结果  = [['category','R1','R2'],
+         ['C1',       12,  10],
+	 ['C2',       18,  17]]
+

+ 两个数据集左关联, 常用于将两段查询数据合并 + # +

+
假设需要关联的数据集格式:
+dataset2 = [['category','C3'],
+           ['R1',       38],
+	   ['R6',       13]]
+处理后的结果:
+result = ds_leftjoin(dataset, dataset2)
+结果  = [['category','C1','C2','C3'],
+         ['R1',       12,  18, 38],
+	 ['R2',       10,  17, 0] ]
+

+ 数据集旋转,在excel中叫透视表 + # +

+
比如需要将dataset3的户型变成指标
+dataset3 = [['城市','户型','数量'],
+             ['长沙','A',35],
+             ['上海','B',19]]
+处理后的结果:
+result = ds_pivot(dataset3)
+结果  = [["城市","A","B"],
+         ["长沙",35,0],
+         ["上海",0,19]]
+

+ 移除数据集中的某几列 + # +

+
比如移除第1列(序号0)
+result=ds_remove_column(dataset,remove_list=[0]) 
+ 结果 =    [['R1','R2'],
+           [12,  10],
+	   [18,  17] ]
+

+ smartchart图形中可用的转化函数 + # +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
函数名函数说明样列
ds_transform(dataset)行列替换
ds_split(data,sep=’,’,head_add=[])将第一列拆分成多个字段,默认逗号分隔, 如果不传表头,取SQL中的字段名拆分
ds_createMap(data)data表示传入的二位数组,生成结果表示为key->[], 常用于echarts指定数据
ds_createMap_all(data)data表示传入的二维数组,生成结果表示为[{A:A1,B:B1,C:C1},{A:A2,B:B2,C:C2}…]
ds_mapToList(data)将createMap_all的格式还原成二维数组, 常用于将nosql(mongodb,es..)数据源数据处理
ds_fontSize(rem)基于分辨率自动转字体大小, 参数rem
ds_rowname(dataset,start_row=1,column=0)获取指定列的数据, 默认取第一列从第二行(序号1)开始的数据,常用于获取维度
ds_remove_column(dataset,remove_list=[0])默认移除第一列, 也要移除指定的多个列
ds_toThousands(num)转逗号分隔的千分位
ds_distinct(a, b=[])对单个或多个二维数组去重
ds_leftjoin(a,b,withhead=true,type=1)两个数组join [[1,2,3,4],[2,3,4,5]] ,[[2,3,4]], 如果带头,合并头
ds_crossjoin(a,b,withhead=true)
ds_fulljoin(a,b,withhead=true)
ds_union(a,b,withhead=true)合并两个数据集, 可选是否带头, 取第一个数据集的头, 去除第二个头
ds_pivot(arr)传入一下二维数组(维度, 维度, 值), 进行透视
ds_sort(arr, index=0, asc=true)指定二维数组列序号排序,默认升序,index参数也可以是函数,如(a,b)=>{return a.qty - b.qty}
getUndefined(param,defaultValue)获取value值,如果为空,null,undefined给默认值
ds_round(num,qty=2)小数点处理, 默认保留两位小数
ds_param(name)传入参数名,获取图形点击时传递来的参数值
ds_setParam(‘参数名’, 参数值)设定全局参数, 此方法将自动判断当参数值为空时, 删除参数回到初始未传参状态
ds_refresh(id, param=filter_param)刷新图形, id为图形序号,默认采取全局参数刷新,也可指定param,参数为字典{“参数名”:“值”,…}
+

+ 多维度的数据透视 + # +

+
常规数据集中提到 A类数据源的情况, 格式都是: 
+维度A   维度B  数据
+但还有情况比如你有一个数据格式是:
+维度A   维度B  维度C  数据
+你需要在表格中将 A,B维度做维度, C做透视为指标名进行展示
+由于我们的数据透视只支持"字符, 字符, 数值"SQL写法, 
+所以如果要多维, 我们需要做下转变, 可以写成:
+select concat_ws(',',维度A,维度B) AS 维度,维度C,SUM(数据) AS 度量 
+   from tablename group by 维度, 维度C
+得到的数据样式
+dataset=[['维度','C1','C2'....]
+	,['A1,B1',1,1...]
+	,['A2,B2',2,2...]]
+最终在图形数据集处理中, 我们可以使用如下函数进行转化:
+dataset = ds_split(dataset,',',['维度A','维度B'])
+',' : 参数为分隔符
+['维度A','维度B'] : 指第一个字段需要拆分的表头名称
+
+最终得到的数据就是多维度透视
+[['维度A','维度B','C1','C2'....]
+,['A1','B1',1,1...]
+,['A2','B2',2,2...]]
+

+ 常用JS原生函数 + # +

+
//数组追加
+dataset.push(item)
+//数组前方插入
+dataset.unshit(item)
+//切片
+dataset = dataset.slice(1) 从序号1个开始到最最后一个
+dataset = dataset.slice(5, 10) 从第序号5开始截取到第10个
+dataset = dataset.slice(-3) 截取最后三个元素
+//循环遍历
+for最快但可读性比较差(smartchart推荐)
+forEach比较快能够控制内容
+for...in比较慢不方便
+for(let i=0; i<dataset.length; i++){
+  
+}
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/3.图形开发/基础图形/index.html b/docs/smartchart/docs/3.图形开发/基础图形/index.html new file mode 100644 index 0000000..fcc22ca --- /dev/null +++ b/docs/smartchart/docs/3.图形开发/基础图形/index.html @@ -0,0 +1,1677 @@ + + + + + + + + + + + + + + +基础图形 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 基础图形 + + +
+ + + + + + +
+ + + +

+ 快速应用基础图形组件 + # +

+
    +
  • 你可使用如下方式选择常规的图形一键进行应用(我们只放了基础图形,因为你可以通过简单修改配置转化为各种图形,如线性面积图, 柱形堆叠图..)
  • +
  • 你也可以在图形商店中找到更多已转化好的Smartchart图形
  • +
+

+ 输入图片说明 +配置项完全和Echarts原生一样

+
+

注意: +对于一些特殊图形如地图js在图形编辑中需要进行动态加载, 如果你使用了非常规图形, +你可在图形编辑器使用ds_loadjs(‘smt_china’)加载中国地图, 同理我们有 ‘smt_wordcloud’, ‘smt_world’, ‘smt_ecStat’, ‘smt_liquidfill’ + + 输入图片说明 +有些图形可能同时需要在模板中加载, 更多特殊图形加载说明参考 + 特殊图形模板加载

+
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/3.图形开发/特殊图形/LineUp图形/index.html b/docs/smartchart/docs/3.图形开发/特殊图形/LineUp图形/index.html new file mode 100644 index 0000000..bbb40d4 --- /dev/null +++ b/docs/smartchart/docs/3.图形开发/特殊图形/LineUp图形/index.html @@ -0,0 +1,1669 @@ + + + + + + + + + + + + + + +Line Up图形 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Line Up图形 + + +
+ + + + + + +
+ + + +

Smartchart内置了LineUp图形 +LineUp is an interactive technique designed to create, visualize and explore rankings of items based on a set of heterogeneous attributes. + + 输入图片说明

+

LineUp图形参考

+
ds_loadcss('smt_LineUp');
+ds_loadjs('smt_LineUp');
+let dataset = __dataset__;
+dataset = ds_createMap_all(dataset);
+try{Ljs__name__.destroy()}catch{}
+Ljs__name__ = LineUpJS.asTaggle(dom__name__, dataset);
+
+// 点击选中行响应动作
+Ljs__name__.on(LineUpJS.LineUp.EVENT_SELECTION_CHANGED, (selection) => {
+   console.log(Ljs__name__.data._data[selection]);
+  //通过以上log可以查看到数据格式, 以下就是标准的联动写法
+  filter_param['LineupParam'] = Ljs__name__.data._data[selection].xx
+  ds_refresh(2);
+});
+
+//更多响应动作
+Ljs__name__.on(LineUpJS.LineUp.EVENT_HIGHLIGHT_CHANGED, (highlight) => {
+});
+
+// document.querySelector('button#select').addEventListener('click', () => {
+//   Ljs__name__.setSelection([1, 2, 3]);
+// });
+
+// document.querySelector('button#highlight').addEventListener('click', () => {
+//   Ljs__name__.setHighlight(50);
+// });
+
+// 获取筛选后的数据并下载(来源与"路阳" 赞助开发)
+outputStr=Ljs__name__.data.exportTable(Ljs__name__.data.getRankings()[0], {});
+outputStr = outputStr.replace(/\t/g, ',');
+ds_download('abc.csv', outputStr);
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/3.图形开发/特殊图形/index.html b/docs/smartchart/docs/3.图形开发/特殊图形/index.html new file mode 100644 index 0000000..c81fb01 --- /dev/null +++ b/docs/smartchart/docs/3.图形开发/特殊图形/index.html @@ -0,0 +1,1626 @@ + + + + + + + + + + + + +特殊图形 | Smartchart开发手册 + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 特殊图形 + + +
+ + + + + + +
+ + + +
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/3.图形开发/特殊图形/index.xml b/docs/smartchart/docs/3.图形开发/特殊图形/index.xml new file mode 100644 index 0000000..a105500 --- /dev/null +++ b/docs/smartchart/docs/3.图形开发/特殊图形/index.xml @@ -0,0 +1,52 @@ + + + + Smartchart开发手册 + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2/ + Recent content on Smartchart开发手册 + Hugo -- gohugo.io + + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2/LineUp%E5%9B%BE%E5%BD%A2/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2/LineUp%E5%9B%BE%E5%BD%A2/ + Smartchart内置了LineUp图形 LineUp is an interactive technique designed to create, visualize and explore rankings of items based on a set of heterogeneous attributes. LineUp图形参考 +ds_loadcss(&#39;smt_LineUp&#39;); ds_loadjs(&#39;smt_LineUp&#39;); let dataset = __dataset__; dataset = ds_createMap_all(dataset); try{Ljs__name__.destroy()}catch{} Ljs__name__ = LineUpJS.asTaggle(dom__name__, dataset); // 点击选中行响应动作 Ljs__name__.on(LineUpJS.LineUp.EVENT_SELECTION_CHANGED, (selection) =&gt; { console.log(Ljs__name__.data._data[selection]); //通过以上log可以查看到数据格式, 以下就是标准的联动写法 filter_param[&#39;LineupParam&#39;] = Ljs__name__.data._data[selection].xx ds_refresh(2); }); //更多响应动作 Ljs__name__.on(LineUpJS.LineUp.EVENT_HIGHLIGHT_CHANGED, (highlight) =&gt; { }); // document.querySelector(&#39;button#select&#39;).addEventListener(&#39;click&#39;, () =&gt; { // Ljs__name__.setSelection([1, 2, 3]); // }); // document.querySelector(&#39;button#highlight&#39;).addEventListener(&#39;click&#39;, () =&gt; { // Ljs__name__. + + + + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2/%E4%BD%BF%E7%94%A8%E5%9B%BE%E6%A0%87/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2/%E4%BD%BF%E7%94%A8%E5%9B%BE%E6%A0%87/ + 在&quot;模板&quot;中加载图标资源 使用方法, 可参考 font-awesome菜鸟教程 V5图标名称参考, 也可以 图标样列查询 + + + + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2/%E6%97%A0%E7%BC%9D%E6%BB%9A%E5%8A%A8/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2/%E6%97%A0%E7%BC%9D%E6%BB%9A%E5%8A%A8/ + 通用滚动 # 例如你的html如下 +&lt;div id=&#34;smtid&#34; style=&#34;height:100%&#34;&gt; &lt;ul&gt; &lt;li&gt;smartchart&lt;/li&gt; &lt;li&gt;bigdata&lt;/li&gt; &lt;li&gt;echarts&lt;/li&gt; &lt;li&gt;make it great&lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; 你只需要使用以下函数, 即可实现在无缝滚动 由于smtid是ID, 则使用 ds_liMarquee(&rsquo;#smtid&rsquo;) 即可开启自动滚动 如果 class=&ldquo;smtclass&rdquo;, 那么也可以使用类选择器 ds_liMarquee(&rsquo;.smtclass') +我们也可以使用更多的配置方法 +marconfig={ playtime: 3000, //滚动3秒 pausetime: 3000, //停3秒 config:{ direction: &#39;up&#39;,//向上滚动 runshort: false,//内容不足时不滚动 scrollamount: 20//速度 } } 可以使用 ds_liMarquee(&rsquo;#smtid&rsquo;, marconfig) 传入配置 +更多config说明: +名称 类型 默认值 说明 direction 字符串 left 滚动方向,可选 left / right / up / down loop 整数 -1 循环次数,-1 为无限循环 scrolldelay 整数 0 每次重复之前的延迟 scrollamount 整数 50 滚动速度,越大越快 circular 布尔值 true 无缝滚动,如果为 false,则和 marquee 效果一样 drag 布尔值 true 鼠标可拖动 runshort 布尔值 true 内容不足是否滚动 hoverstop 布尔值 true 鼠标悬停暂停 xml 布尔值 false 加载xml 文件 inverthover 布尔值 false 反向,即默认不滚动,鼠标悬停滚动 内置滚动表格 # smartchart内置了滚动表格, 可以一键生成 如果你需要修改表格的样式, 如字体,颜色等, 你可以在模板中重定义样式 具体样式的写法, 参考 样式快速入门 + + + + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2%E5%8A%A0%E8%BD%BD/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2%E5%8A%A0%E8%BD%BD/ + smartchart默认只会引echarts的基础图形 如果你需要使用到更多图形, 你可以自行引用,可以写在模板的javascript标签中 +中国地图 &lt;script src=&#34;/static/smartchart/opt/smt_china.js&#34;&gt;&lt;/script&gt; 世界地图 &lt;script src=&#34;/static/smartchart/opt/smt_world.js&#34;&gt;&lt;/script&gt; 统计图 &lt;script src=&#34;/static/smartchart/opt/smt_ecStat.js&#34;&gt;&lt;/script&gt; 水球图 &lt;script src=&#34;/static/smartchart/opt/smt_liquidfill.js&#34;&gt;&lt;/script&gt; 词云 &lt;script src=&#34;/static/smartchart/opt/smt_wordcloud.js&#34;&gt;&lt;/script&gt; 百度地图 &lt;script type=&#34;text/javascript&#34; src=&#34;https://fastly.jsdelivr.net/npm/echarts@5/dist/extension/bmap.min.js&#34;&gt;&lt;/script&gt; + + + + diff --git a/docs/smartchart/docs/3.图形开发/特殊图形/使用图标/index.html b/docs/smartchart/docs/3.图形开发/特殊图形/使用图标/index.html new file mode 100644 index 0000000..0f0a1e6 --- /dev/null +++ b/docs/smartchart/docs/3.图形开发/特殊图形/使用图标/index.html @@ -0,0 +1,1646 @@ + + + + + + + + + + + + + + +使用图标 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 使用图标 + + +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/3.图形开发/特殊图形/无缝滚动/index.html b/docs/smartchart/docs/3.图形开发/特殊图形/无缝滚动/index.html new file mode 100644 index 0000000..9f606b3 --- /dev/null +++ b/docs/smartchart/docs/3.图形开发/特殊图形/无缝滚动/index.html @@ -0,0 +1,1820 @@ + + + + + + + + + + + + + + +无缝滚动 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 无缝滚动 + + +
+ + + + + + +
+ + + +

+ 通用滚动 + # +

+

例如你的html如下

+
<div id="smtid" style="height:100%">
+    <ul>
+        <li>smartchart</li>
+        <li>bigdata</li>
+        <li>echarts</li>
+        <li>make it great</li>
+    </ul>
+</div>
+

你只需要使用以下函数, 即可实现在无缝滚动 +由于smtid是ID, 则使用 ds_liMarquee(’#smtid’) 即可开启自动滚动 +如果 class=“smtclass”, 那么也可以使用类选择器 ds_liMarquee(’.smtclass')

+

我们也可以使用更多的配置方法

+
 marconfig={
+    playtime: 3000, //滚动3秒
+    pausetime: 3000, //停3秒
+    config:{
+        direction: 'up',//向上滚动
+        runshort: false,//内容不足时不滚动
+        scrollamount: 20//速度
+    }
+ }
+

可以使用 ds_liMarquee(’#smtid’, marconfig) 传入配置

+

更多config说明:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
名称类型默认值说明
direction字符串left滚动方向,可选 left / right / up / down
loop整数-1循环次数,-1 为无限循环
scrolldelay整数0每次重复之前的延迟
scrollamount整数50滚动速度,越大越快
circular布尔值true无缝滚动,如果为 false,则和 marquee 效果一样
drag布尔值true鼠标可拖动
runshort布尔值true内容不足是否滚动
hoverstop布尔值true鼠标悬停暂停
xml布尔值false加载xml 文件
inverthover布尔值false反向,即默认不滚动,鼠标悬停滚动
+

+ 内置滚动表格 + # +

+

smartchart内置了滚动表格, 可以一键生成 +如果你需要修改表格的样式, 如字体,颜色等, 你可以在模板中重定义样式 +具体样式的写法, 参考 + 样式快速入门

+
如下例修改表头高度为5rem, 内容单元格高度3rem 及背景字体等
+/*表头样式*/
+.smtlisthead{
+    background: #fff2cc;
+    color: red;
+    height: 5rem;
+}
+
+.smtlisthead span{
+    height: 5rem;
+}
+
+/*表格本体样式*/
+.smtlistnav{
+    height: calc(100% - 5rem);
+    color: red;
+    overflow: auto;
+}
+
+.smtlistnav li span{
+    height: 3rem;
+}
+
+
+/*修改奇数行背景*/
+.smtlistnav ul li:nth-child(odd){ background: rgba(100,100,100,.1);}
+偶数行将odd改为even
+
+/*指定某单独格宽度对齐*/
+<span>
+  <span style="width:32rem;height:100%;flex-shrink:0;justify-content:left"><span>
+</span>
+
+/*单元格点击响应*/
+let lastClickDom;
+let lastDomColor;
+$('#smtlist__name__, li').click(function(params){
+    try{lastClickDom.css('background', lastDomColor)}catch{}
+    lastDomColor = $(this).css('background');
+    $(this).css('background', 'yellow');
+    lastClickDom = $(this);
+    let myparam = $(this).children('span').eq(0).text(); //获取点击的参数
+    //以下加入你的action
+    
+});
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/3.图形开发/特殊图形/特殊图形加载/index.html b/docs/smartchart/docs/3.图形开发/特殊图形/特殊图形加载/index.html new file mode 100644 index 0000000..80bb0d0 --- /dev/null +++ b/docs/smartchart/docs/3.图形开发/特殊图形/特殊图形加载/index.html @@ -0,0 +1,1649 @@ + + + + + + + + + + + + + + +特殊图形加载 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 特殊图形加载 + + +
+ + + + + + +
+ + + +

smartchart默认只会引echarts的基础图形 +如果你需要使用到更多图形, 你可以自行引用,可以写在模板的javascript标签中

+
中国地图
+<script src="/static/smartchart/opt/smt_china.js"></script>
+世界地图
+<script src="/static/smartchart/opt/smt_world.js"></script>
+统计图
+<script src="/static/smartchart/opt/smt_ecStat.js"></script>
+水球图
+<script src="/static/smartchart/opt/smt_liquidfill.js"></script>
+词云
+<script src="/static/smartchart/opt/smt_wordcloud.js"></script>
+百度地图
+<script type="text/javascript" src="https://fastly.jsdelivr.net/npm/echarts@5/dist/extension/bmap.min.js"></script>
+

+ 输入图片说明

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/3.图形开发/管理图形/index.html b/docs/smartchart/docs/3.图形开发/管理图形/index.html new file mode 100644 index 0000000..48e8326 --- /dev/null +++ b/docs/smartchart/docs/3.图形开发/管理图形/index.html @@ -0,0 +1,1681 @@ + + + + + + + + + + + + + + +管理图形 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 管理图形 + + +
+ + + + + + +
+ + + +

+ 应用场景 + # +

+

如何快速复用已开发好的组件

+

+ 本地管理自定义组件 + # +

+

如下图,点击图形编辑器中的菜单,即可管理和查看自定义图形列表 +点击"加入样列"即可把当前图形加入到样列清单, 点击"取消样列"即可将所选样列移除样列清单 + + 输入图片说明

+

+ 云管理,在图形商店中保存你的图形 + # +

+

这样你就可以在图形商店看到你的图形进行重复利用 + + 输入图片说明

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/3.图形开发/调试日志/index.html b/docs/smartchart/docs/3.图形开发/调试日志/index.html new file mode 100644 index 0000000..ed77800 --- /dev/null +++ b/docs/smartchart/docs/3.图形开发/调试日志/index.html @@ -0,0 +1,1691 @@ + + + + + + + + + + + + + + +调试日志 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 调试日志 + + +
+ + + + + + +
+ + + +

+ 关于页面日志查看 + # +

+

大家可能比较熟悉使用F12来查看网页日志, 但有的同学会觉得这不够方便, 所以 +在5.1.11后, smartchart加入了可以页面直接显示日志的功能

+

+ 在仪表盘中显示 + # +

+

你只需要点击如下菜单, 即可切换是否显示日志 + + 输入图片说明 +当在刷新页面或执行时, 日志将直接显示在右上角中, 而且还能显示出对应出错的图表序号 + + 输入图片说明

+

+ 在图形中显示 + # +

+

smartchart基于python的使用习惯, 重定义的专用的日志打印函数print +你可以在图形编辑器中使用些函数即可打印日志 +比如看看鼠标放在echarts图上params, 在编辑界面和console中都能看到日志, 方便你进行调试 + + 输入图片说明

+

不仅仅这些, 你可能会想写太多打印日志, 上线了不好 +smartchart已为你想到这些, 如果你在仪表盘中没有开启日志显示, print函数是不会打印任何日志

+

有了仪表盘日志显示, 我们还能做更多的事情, 比如实时显示你拖拽的坐标, 让你精确定位 + + 输入图片说明

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/4.布局说明/index.html b/docs/smartchart/docs/4.布局说明/index.html new file mode 100644 index 0000000..d3dac77 --- /dev/null +++ b/docs/smartchart/docs/4.布局说明/index.html @@ -0,0 +1,1626 @@ + + + + + + + + + + + + +4.布局说明 | Smartchart开发手册 + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 4.布局说明 + + +
+ + + + + + +
+ + + +
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/4.布局说明/index.xml b/docs/smartchart/docs/4.布局说明/index.xml new file mode 100644 index 0000000..3a86f8d --- /dev/null +++ b/docs/smartchart/docs/4.布局说明/index.xml @@ -0,0 +1,38 @@ + + + + Smartchart开发手册 + https://smartchart.gitee.io/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/ + Recent content on Smartchart开发手册 + Hugo -- gohugo.io + + + https://smartchart.gitee.io/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E5%B8%83%E5%B1%80%E6%8C%87%E5%BC%95/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E5%B8%83%E5%B1%80%E6%8C%87%E5%BC%95/ + 整理一份完整的SmartChart布局说明 # 推荐先观看视屏了解 smartchart布局方式 +容器说明 # 容器 说明 定位容器 用于图形定位, 有拖拽和栅格两种. 在界面上新增时会自带;在模板编辑中新增图形时需自行加入容器 图形容器 用于图形选择, 使用id选择器, 如序号为2的容器, 选择器为#container_2 图形 可视化的实际单位, 如选择图形中的table标签, 可使用#container_2 table 响应式布局 # 一般移动端报表推荐使用响应式布局, 一次布局可以同时满足电脑端/移动端的需求 当你新增一个数据集时, smartchart会给你一段默认的代码 +&lt;div class=&#34;el-col-xs-24 el-col-md-24&#34; style=&#34;padding:0.2rem;height:50%;&#34; &gt; &lt;div style=&#34;height:100%;&#34; id=&#34;container_{name}&#34;&gt;&lt;/div&gt; &lt;/div&gt; el-col-md-24 : 电脑端宽度设定 控制图形父容器的宽度, 整行分成24个栅格, 如果你想让图形占一半, 就可以改成el-col-md-12 el-col-xs-24 :移动端宽度设定 padding:0.5% 0.5%: 控制图形的上下, 左右内边距, padding: 上 右 下 左 比如你想要图形在容器中往下走一点, 你可写成 padding: 1% 0 0 0 height:50%; 盒子的高度, 相对于父容器的高度, 最外层即浏览器高度 大屏开发推荐使用拖拽布局(PRO) # 大家如果开发大屏, 只是用响应式布局可能对于复杂的布局不是很方便, 你也可以采用拖拽绝对定位的方法, 这样你可以随意指定图形的所在位置. + + + + + https://smartchart.gitee.io/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E6%8B%96%E6%8B%BD%E8%87%AA%E5%8A%A8%E5%AF%B9%E9%BD%90/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E6%8B%96%E6%8B%BD%E8%87%AA%E5%8A%A8%E5%AF%B9%E9%BD%90/ + 拖拽很方便, 但是精确对齐还是有些手抖, 所以smartchart增加了自动对齐的功能 你可以在&quot;模板&quot; &ndash;&gt; &ldquo;转化&rdquo; 中找到这个功能 首先我们随意拖拽了一些组件 然后选中拖拽代码段, 点&quot;拖拽对齐&quot; 后 点&quot;保存&quot; 就可以查看对齐后的效果了, 再进行下拖拽微调, 重复以上动作到满意 + + + + + https://smartchart.gitee.io/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E5%88%A0%E9%99%A4%E5%AE%B9%E5%99%A8/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E5%88%A0%E9%99%A4%E5%AE%B9%E5%99%A8/ + 对于仪表盘中不再使用的数据集,你可能会考虑删除 首先smartchart推荐你不做删除,因为你可以保留他, 当你下次有新增数据集的需求时再拿出来 所以优先推荐使用隐藏的方法,你可以在数据集编辑界面找到他 如果你实在需要删除,可以在“报表”界面先中不需要容器后,选中删除,后保存 + + + + diff --git a/docs/smartchart/docs/4.布局说明/不常用/index.html b/docs/smartchart/docs/4.布局说明/不常用/index.html new file mode 100644 index 0000000..2762d60 --- /dev/null +++ b/docs/smartchart/docs/4.布局说明/不常用/index.html @@ -0,0 +1,1626 @@ + + + + + + + + + + + + +不常用 | Smartchart开发手册 + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 不常用 + + +
+ + + + + + +
+ + + +
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/4.布局说明/不常用/index.xml b/docs/smartchart/docs/4.布局说明/不常用/index.xml new file mode 100644 index 0000000..6258fe3 --- /dev/null +++ b/docs/smartchart/docs/4.布局说明/不常用/index.xml @@ -0,0 +1,30 @@ + + + + Smartchart开发手册 + https://smartchart.gitee.io/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E4%B8%8D%E5%B8%B8%E7%94%A8/ + Recent content on Smartchart开发手册 + Hugo -- gohugo.io + + + https://smartchart.gitee.io/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E4%B8%8D%E5%B8%B8%E7%94%A8/%E4%BB%A3%E7%A0%81%E8%BD%AC%E5%8C%96%E5%B8%83%E5%B1%80/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E4%B8%8D%E5%B8%B8%E7%94%A8/%E4%BB%A3%E7%A0%81%E8%BD%AC%E5%8C%96%E5%B8%83%E5%B1%80/ + 由于我们移除了boostrap的布局方式, 此布局不再做推荐! 初次学习的同学, 可能会需要一个拖拉拽的布局方式(3.9.9.13以上才支持), 所以下面介绍的是smartchart的辅助布局方法 +你可以在&quot;布局&quot; 中找到入口 进入编辑器后, 你可以拖拉拽的方式进行布局, 注意我们建意你一个column(C)容器只放一个smartchart的图形便于标准化 点击&quot;生成&quot;, 复制相关代码 回到仪表盘&quot;布局&quot;, 粘贴到编辑器, 点击 &ldquo;闪电&rdquo; 图标, 进行转化, 可能会提示你数据集不够,这样你需要新增足够数量的数据集后再点转化 注: 代码转化布局你可以不用可视化辅助, 可以用其它任意每三方布局工具生成代码后粘过来生成, 需要注意的格式是: 在你需要数据集的地方使用以下代码即可: +&lt;div style=&#34;height:100%&#34; id=&#34;container_{name}&#34;&gt;&lt;/div&gt; 转化完成后, 点击保存即可应用布局 + + + + + https://smartchart.gitee.io/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E4%B8%8D%E5%B8%B8%E7%94%A8/%E5%AE%B9%E5%99%A8%E7%AE%A1%E7%90%86%E7%95%8C%E9%9D%A2/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E4%B8%8D%E5%B8%B8%E7%94%A8/%E5%AE%B9%E5%99%A8%E7%AE%A1%E7%90%86%E7%95%8C%E9%9D%A2/ + 容器管理 # 你可以单独对一个容器进行编辑,或者在全局进行编辑 全局编辑器 移动图形 +你有两种方法移动数据集 可以在“报表” 中直接暴力修改序号 也可以在数据集编辑器中移动, 可选择插入(带着容器一起动),替换(容器不动,就是整体布局不变化, 只移动数据和图形) + + + + diff --git a/docs/smartchart/docs/4.布局说明/不常用/代码转化布局/index.html b/docs/smartchart/docs/4.布局说明/不常用/代码转化布局/index.html new file mode 100644 index 0000000..5d217fc --- /dev/null +++ b/docs/smartchart/docs/4.布局说明/不常用/代码转化布局/index.html @@ -0,0 +1,1669 @@ + + + + + + + + + + + + + + +代码转化布局 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 代码转化布局 + + +
+ + + + + + +
+ + + +

由于我们移除了boostrap的布局方式, 此布局不再做推荐! +初次学习的同学, 可能会需要一个拖拉拽的布局方式(3.9.9.13以上才支持), 所以下面介绍的是smartchart的辅助布局方法

+
    +
  • +

    你可以在"布局" 中找到入口 + + 输入图片说明

    +
  • +
  • +

    进入编辑器后, 你可以拖拉拽的方式进行布局, 注意我们建意你一个column(C)容器只放一个smartchart的图形便于标准化 + + 输入图片说明

    +
  • +
  • +

    点击"生成", 复制相关代码 + + 输入图片说明

    +
  • +
  • +

    回到仪表盘"布局", 粘贴到编辑器, 点击 “闪电” 图标, 进行转化, 可能会提示你数据集不够,这样你需要新增足够数量的数据集后再点转化 + + 输入图片说明

    +
  • +
+

注: 代码转化布局你可以不用可视化辅助, 可以用其它任意每三方布局工具生成代码后粘过来生成, 需要注意的格式是: +在你需要数据集的地方使用以下代码即可:

+
<div style="height:100%"  id="container_{name}"></div>
+
    +
  • 转化完成后, 点击保存即可应用布局 + + 输入图片说明
  • +
+

+ 输入图片说明

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/4.布局说明/不常用/容器管理界面/index.html b/docs/smartchart/docs/4.布局说明/不常用/容器管理界面/index.html new file mode 100644 index 0000000..28ca02e --- /dev/null +++ b/docs/smartchart/docs/4.布局说明/不常用/容器管理界面/index.html @@ -0,0 +1,1690 @@ + + + + + + + + + + + + + + +容器管理界面 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 容器管理界面 + + +
+ + + + + + +
+ + + +

+ 容器管理 + # +

+
    +
  • 你可以单独对一个容器进行编辑,或者在全局进行编辑
  • +
+

+ 输入图片说明

+
    +
  • +

    全局编辑器 + + 输入图片说明

    +
  • +
  • +

    移动图形

    +
  • +
+
    +
  1. +

    你有两种方法移动数据集 +可以在“报表” 中直接暴力修改序号 + + 输入图片说明

    +
  2. +
  3. +

    也可以在数据集编辑器中移动, +可选择插入(带着容器一起动),替换(容器不动,就是整体布局不变化, 只移动数据和图形) + + 输入图片说明

    +
  4. +
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/4.布局说明/删除容器/index.html b/docs/smartchart/docs/4.布局说明/删除容器/index.html new file mode 100644 index 0000000..8fbdd0c --- /dev/null +++ b/docs/smartchart/docs/4.布局说明/删除容器/index.html @@ -0,0 +1,1639 @@ + + + + + + + + + + + + + + +删除容器 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 删除容器 + + +
+ + + + + + +
+ + + +

对于仪表盘中不再使用的数据集,你可能会考虑删除 +首先smartchart推荐你不做删除,因为你可以保留他, 当你下次有新增数据集的需求时再拿出来 +所以优先推荐使用隐藏的方法,你可以在数据集编辑界面找到他 + + 输入图片说明 +如果你实在需要删除,可以在“报表”界面先中不需要容器后,选中删除,后保存

+

+ 输入图片说明

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/4.布局说明/布局指引/index.html b/docs/smartchart/docs/4.布局说明/布局指引/index.html new file mode 100644 index 0000000..5b4da32 --- /dev/null +++ b/docs/smartchart/docs/4.布局说明/布局指引/index.html @@ -0,0 +1,1732 @@ + + + + + + + + + + + + + + +布局指引 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 布局指引 + + +
+ + + + + + +
+ + + +

+ 整理一份完整的SmartChart布局说明 + # +

+

推荐先观看视屏了解 + smartchart布局方式

+

+ 容器说明 + # +

+ + + + + + + + + + + + + + + + + + + + + + +
容器说明
定位容器用于图形定位, 有拖拽和栅格两种. 在界面上新增时会自带;在模板编辑中新增图形时需自行加入容器
图形容器用于图形选择, 使用id选择器, 如序号为2的容器, 选择器为#container_2
图形可视化的实际单位, 如选择图形中的table标签, 可使用#container_2 table
+

+ 响应式布局 + # +

+

一般移动端报表推荐使用响应式布局, 一次布局可以同时满足电脑端/移动端的需求 +当你新增一个数据集时, smartchart会给你一段默认的代码

+
<div class="el-col-xs-24 el-col-md-24" style="padding:0.2rem;height:50%;" >
+  <div style="height:100%;" id="container_{name}"></div>
+</div>
+
+el-col-md-24 : 电脑端宽度设定
+控制图形父容器的宽度, 整行分成24个栅格, 如果你想让图形占一半, 就可以改成el-col-md-12
+el-col-xs-24 :移动端宽度设定
+padding:0.5% 0.5%:
+控制图形的上下, 左右内边距,  padding: 上 右 下 左
+比如你想要图形在容器中往下走一点, 你可写成 padding: 1% 0 0 0
+height:50%;
+盒子的高度, 相对于父容器的高度, 最外层即浏览器高度
+

+ 大屏开发推荐使用拖拽布局(PRO) + # +

+

大家如果开发大屏, 只是用响应式布局可能对于复杂的布局不是很方便, 你也可以采用拖拽绝对定位的方法, 这样你可以随意指定图形的所在位置. +方法可参考视屏 + 拖拽说明 +你可以配合使用 ”模板开发“ 来实现高度定制化的效果, 参考 + 模板开发指引

+

+ 混合布局(PRO) + # +

+

你可以考虑先用响应式布局把整体框架画出来, 如果要加一下装饰的情况, 可以用绝对定位(拖拽布局)来实现

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/4.布局说明/拖拽自动对齐/index.html b/docs/smartchart/docs/4.布局说明/拖拽自动对齐/index.html new file mode 100644 index 0000000..fd1a189 --- /dev/null +++ b/docs/smartchart/docs/4.布局说明/拖拽自动对齐/index.html @@ -0,0 +1,1642 @@ + + + + + + + + + + + + + + +拖拽自动对齐 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 拖拽自动对齐 + + +
+ + + + + + +
+ + + +

拖拽很方便, 但是精确对齐还是有些手抖, 所以smartchart增加了自动对齐的功能 +你可以在"模板" –> “转化” 中找到这个功能 +首先我们随意拖拽了一些组件 + + 输入图片说明 +然后选中拖拽代码段, 点"拖拽对齐" 后 点"保存" + + 拖拽对齐 +就可以查看对齐后的效果了, 再进行下拖拽微调, 重复以上动作到满意 + + 输入图片说明

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/5.参数及联动钻取/index.html b/docs/smartchart/docs/5.参数及联动钻取/index.html new file mode 100644 index 0000000..dfcd3f5 --- /dev/null +++ b/docs/smartchart/docs/5.参数及联动钻取/index.html @@ -0,0 +1,1626 @@ + + + + + + + + + + + + +5.参数及联动钻取 | Smartchart开发手册 + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 5.参数及联动钻取 + + +
+ + + + + + +
+ + + +
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/5.参数及联动钻取/index.xml b/docs/smartchart/docs/5.参数及联动钻取/index.xml new file mode 100644 index 0000000..46a4b7f --- /dev/null +++ b/docs/smartchart/docs/5.参数及联动钻取/index.xml @@ -0,0 +1,59 @@ + + + + Smartchart开发手册 + https://smartchart.gitee.io/docs/5.%E5%8F%82%E6%95%B0%E5%8F%8A%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/ + Recent content on Smartchart开发手册 + Hugo -- gohugo.io + + + https://smartchart.gitee.io/docs/5.%E5%8F%82%E6%95%B0%E5%8F%8A%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/%E5%8F%82%E6%95%B0%E7%BC%96%E5%86%99%E6%96%B9%E6%B3%95/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/5.%E5%8F%82%E6%95%B0%E5%8F%8A%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/%E5%8F%82%E6%95%B0%E7%BC%96%E5%86%99%E6%96%B9%E6%B3%95/ + 使用场景 # 需要使用图表联动效果 数据服务接口开发 使用魔法方法(smartchart独创,拒绝抄袭) # 基础原理 # - $参数名, 当有传递参数时将替换相关的值 - /* ... $参数 ... */, 当参数写在这个区间时, 如果外部没有传入参数, 会自动忽略这一段代码 - -- 标识之后单行的代码会被忽略 常见组合应用 # 理解以下样列后, 可录活使用组合出各种可能的需求 +默认参数: 实现在不传参数时默认参数是当前月份 select xx from tablename where calmonth =/*&#39;$calmonth&#39; -- */ to_char(sysdate,&#39;YYYYMM&#39;) 多个参数: 注意使用1=1及and的位置 select xx from tablename where 1=1 /* and city = &#39;$city&#39; */ /* and calmonth =&#39;$calmonth&#39;*/ 维度变化: 将字段当成参数 select /*$calmonth,*/ city, count(1) as qty from tablename group by /*$calmonth,*/ city 维度变化: 当传入月份条件时, 按城市,月份的数据, 不传参数时只看按城市的总数 select /*月份, -- $Month */ 城市, sum(度量) from tablename where 1=1 /* and 月份 &gt; &#39;$Month&#39; */ group by 城市 /*,月份 -- $Month*/ 高级开关应用 # 以上应用可以通过参数是否有传递来实现开关代码段的效果, 有些场景可能还希望通过参数值来进行代码段的开关 如下代码可以实现当传递参数type=1 或 type=2 时执行不同的代码段 使用 &ldquo;$参数__值&rdquo; 的方式做为开关 + + + + + https://smartchart.gitee.io/docs/5.%E5%8F%82%E6%95%B0%E5%8F%8A%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/%E5%9B%BE%E5%BD%A2%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/5.%E5%8F%82%E6%95%B0%E5%8F%8A%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/%E5%9B%BE%E5%BD%A2%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/ + 数据集准备 # 首先在需要进行联动的数据集中SQL的写法如下, 比如对应2号图形: +注意 /* ... */的写法, 当参数写在这个区间时, 如果外部没有传入参数, 会自动忽略这一段代码, 这样对于联动来说非常重要, 初始时全部显示, 点击其它图形时传入参数进行动态联动 select xxx,xxx,xxx from tablename /* where xxxx = &#39;$参数名&#39; */ .... 建意观看视屏比较容易理解: 数据联动说明 +常规方法 # 比如你需要点击0号图形, 指定其它图形联动 你只需要打开0号图形的数据集编辑页面, 点击标题的位置 然后输入相关的参数即可, 以下为sample 参数值设定的方法, 你可以先留空, 然后保存, F12打浏览器调试方法 点击0号图形你需要点击的动作, 你可以右调试窗口的console看到输入的log 比如我们需要传递的参数值是&quot;廉颇&quot;, 那么取数据的方法就是data.name, 你把这个填入即可 这样就实现按所选数据或所选系列钻取/联动了, 重新点击当前所选, 恢复原来的 如何在图形开发中获取参数值 +图形编辑器中, 你可以使用函数 ds_param(&#39;参数名&#39;) 来获取传入的参数值 高级定制方法 # 如果有更多个性化需求,可以在需要点击的图形的编辑器中加入以下代码,你仅仅需要修改的是序号和参数名 +//比如传入多个参数进行联动 myChart__name__.on(&#39;click&#39;, function(params){ let myparam = params.seriesName; //获取点击的值 filter_param[&#39;参数名&#39;] = myparam; //填写你的数据集的SQL设定中对应的参数名 filter_param[&#39;参数名2&#39;] = myparam2; //你可以赋值给多个参数 ds_refresh(3); //3 为你要刷新图形序号 }); 你也可以使用更方便的参数赋值方法(5. + + + + + https://smartchart.gitee.io/docs/5.%E5%8F%82%E6%95%B0%E5%8F%8A%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/%E7%AD%9B%E9%80%89%E5%99%A8%E6%8C%87%E5%8D%97/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/5.%E5%8F%82%E6%95%B0%E5%8F%8A%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/%E7%AD%9B%E9%80%89%E5%99%A8%E6%8C%87%E5%8D%97/ + 通用实现方式 # SMARTCHART实现筛选最简单的方法只需要配一个控件即可: +建立一个筛选清单数据集, 自动获取筛选的列表,那么可以这么写 +Select xxxx as city from tablename..... 则会生成一个如下的数据集: [[&#39;city&#39;],[选项1],[选项2],..] 良好的习惯, 先保存在数据集 然后在筛选器数据集中的js编辑器(图形编辑器),填下如下代码: +//如要要美化, 自已加样式, 只要保证id=&#34;id_select__name__&#34; let dataset=__dataset__; let table =&#39;&lt;span&gt;标题&lt;/span&gt;&lt;select id=&#34;id_select__name__&#34;&gt;&#39;; table = table + &#39;&lt;option value=&#34;&#34; selected&gt;----&lt;/option&gt;&#39;; for(let i=1;i&lt;dataset.length;i++){ table = table + &#39;&lt;option&gt;&#39; + dataset[i][0] + &#39;&lt;/option&gt;&#39;; } table = table + &#39;&lt;/select&gt;&lt;/div&gt;&lt;/div&gt;&#39; dom__name__.innerHTML=table; 这个时候你已经可以看到筛选器了 现在我们来设定联动效果 +假设需要被筛选的数据集的SQL这样写,数据集的序号是0 +//那么在需要被联动的数据集中,如使用pcity做为参数写查询, 比如: select xx, xx, xx from tablename /* where xx = &#39;$pcity&#39; */ 现在回到我们筛选器数据集,点击标题的位置, 我们需要使0号图形被筛选器联动, 设置如下即可: 然后你就可以看到筛选效果了, 非常的简单方便, 需要多个图形被联动, 只需用逗号分隔即可 比如: 0, 2, 4 + + + + + https://smartchart.gitee.io/docs/5.%E5%8F%82%E6%95%B0%E5%8F%8A%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/%E7%BB%84%E4%BB%B6%E8%87%AA%E5%AE%9A%E4%B9%89%E8%81%94%E5%8A%A8/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/5.%E5%8F%82%E6%95%B0%E5%8F%8A%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/%E7%BB%84%E4%BB%B6%E8%87%AA%E5%AE%9A%E4%B9%89%E8%81%94%E5%8A%A8/ + 应用场景 # Smartchart对于单项筛选有通用的组件, 可以直接配置即可,但对于个性化的筛选,需要你进行一些简单的定制化,以下就针对多项筛选联动的需求来介绍如何定制化你的筛选联动效果 通过此例,你可以了解如何自定义任意的联动效果 样列参考 # 以我们内置的仪表盘为例, +第一步,新建一个数据集 +第二步,在新的数据集中编写查询 +select distinct H1 as heroname from smartdemo2 limit 10 第三步,编辑此数据集的图形,可复制以下代码 +//select distinct xx from tablename let dataset=__dataset__; let table = &#39;&#39;; for (let i=1;i&lt;dataset.length;i++){ table = `${table}&lt;label&gt;&lt;input name=&#34;select__name__&#34; type=&#34;checkbox&#34; value=&#34;${dataset[i][0]}&#34; /&gt;${dataset[i][0]}&lt;/label&gt; `; } table = table + &#34;&lt;button id=&#39;id_select__name__&#39;&gt;提交&lt;/button&gt;&#34;; dom__name__.innerHTML=table; $(&#39;#id_select__name__&#39;).click( function(){ let res = []; $(&#34;input[name=&#39;select__name__&#39;]:checked&#34;).each(function(i){ res.push(&#34;&#39;&#34; + $(this).val() + &#34;&#39;&#34;); }); filter_param[&#39;H1&#39;] = res.toString(); //参数赋值 ds_refresh(1); //刷新1号图形 } ) 第四步,在你要联动刷新数据集中增加代码 + + + + diff --git a/docs/smartchart/docs/5.参数及联动钻取/参数编写方法/index.html b/docs/smartchart/docs/5.参数及联动钻取/参数编写方法/index.html new file mode 100644 index 0000000..2fd8265 --- /dev/null +++ b/docs/smartchart/docs/5.参数及联动钻取/参数编写方法/index.html @@ -0,0 +1,1765 @@ + + + + + + + + + + + + + + +参数编写方法 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 参数编写方法 + + +
+ + + + + + +
+ + + +

+ 使用场景 + # +

+
    +
  • 需要使用图表联动效果
  • +
  • 数据服务接口开发
  • +
+

+ 使用魔法方法(smartchart独创,拒绝抄袭) + # +

+

+ 基础原理 + # +

+
-  $参数名, 当有传递参数时将替换相关的值
+-  /* ... $参数 ... */, 当参数写在这个区间时, 如果外部没有传入参数, 会自动忽略这一段代码
+-  -- 标识之后单行的代码会被忽略
+

+ 常见组合应用 + # +

+

理解以下样列后, 可录活使用组合出各种可能的需求

+
    +
  • 默认参数: 实现在不传参数时默认参数是当前月份
  • +
+
select xx from tablename where
+calmonth =/*'$calmonth' -- */ to_char(sysdate,'YYYYMM')
+
    +
  • 多个参数: 注意使用1=1及and的位置
  • +
+
select xx from tablename where 1=1 /* and city = '$city' */ 
+/* and calmonth ='$calmonth'*/
+
    +
  • 维度变化: 将字段当成参数
  • +
+
select /*$calmonth,*/ city, count(1) as qty from tablename 
+group by /*$calmonth,*/ city
+
    +
  • 维度变化: 当传入月份条件时, 按城市,月份的数据, 不传参数时只看按城市的总数
  • +
+
select /*月份, -- $Month */  
+城市, sum(度量) from tablename 
+where 1=1
+/* and 月份 > '$Month' */
+group by 城市  
+/*,月份 -- $Month*/
+

+ 高级开关应用 + # +

+

以上应用可以通过参数是否有传递来实现开关代码段的效果, 有些场景可能还希望通过参数值来进行代码段的开关 +如下代码可以实现当传递参数type=1 或 type=2 时执行不同的代码段 +使用 “$参数__值” 的方式做为开关

+
/* select count(1) as qty from tablename1  $type__1*/
+/* select count(1) as qty from tablename2  $type__2*/
+

再比如 +当参数D传值为"月份"时是统计2022年按月的统计, +传"日期"时统计的是2022年10月按天的统计

+
select $D, count(1) as qty from tablename
+where 1 = 1
+/* and year='2022'    -- $D__日期  $D__月份 */
+/* and month='10'      $D__日期 */
+group by
+$D
+
+

加了"–“是为了避免语法错误

+
+

+ 数据集开发调试参数方法 + # +

+
对于开发人员来说, 带参数的SQL调试不方便, 所以支持你在sql中写入默认参数
+方法如下格式, 你可以在sql编辑器的最上方写上 /* {xxxxxx} */, 
+会默认在开发调试模式下取这些参数, 在用户模式下会忽略
+/* {"月份":"202009","城市":"中山"} */
+select xxx from table xxx
+

+ 数据权限行级别控制 + # +

+
    +
  • 当你在sql查询中加上’$username’, 会自动替换成登录用户的用户名
  • +
  • 如果你是嵌入到第三方系统, 你可以通过url传递参数id, 在后台会转化为参数_id, 在sql中配置$_id即可控制数据权限
  • +
  • 可以采用此做数据权限关联后台权限mapping表进行数据权限控制实现不同人看不同的数据
  • +
+

+ 参数的传递方式 + # +

+
    +
  • 你可以从url传入参数, 在url上加入 &param={“参数名”:“参数值”}
  • +
  • 在图形联动的点击过程中会自动传递参数, 具体参考联动相关文档
  • +
+
+

TIPS +当设定参数后, 联动过程dataset的缓存功能失效, 所以不要让带参数的查询设计得太慢 +参数如果存在一些非法字符可能会有问题, 比如参数中不可以有#号

+
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/5.参数及联动钻取/图形联动钻取/index.html b/docs/smartchart/docs/5.参数及联动钻取/图形联动钻取/index.html new file mode 100644 index 0000000..9c3553c --- /dev/null +++ b/docs/smartchart/docs/5.参数及联动钻取/图形联动钻取/index.html @@ -0,0 +1,1727 @@ + + + + + + + + + + + + + + +图形联动钻取 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 图形联动钻取 + + +
+ + + + + + +
+ + + +

+ 数据集准备 + # +

+

首先在需要进行联动的数据集中SQL的写法如下, 比如对应2号图形:

+
注意 /* ... */的写法, 当参数写在这个区间时, 如果外部没有传入参数, 
+会自动忽略这一段代码, 这样对于联动来说非常重要, 
+初始时全部显示, 点击其它图形时传入参数进行动态联动
+
+select xxx,xxx,xxx from tablename /* where xxxx = '$参数名' */ .... 
+

建意观看视屏比较容易理解: + + 数据联动说明

+

+ 常规方法 + # +

+

比如你需要点击0号图形, 指定其它图形联动 +你只需要打开0号图形的数据集编辑页面, 点击标题的位置 + + 输入图片说明 +然后输入相关的参数即可, 以下为sample + + 输入图片说明 +参数值设定的方法, 你可以先留空, 然后保存, F12打浏览器调试方法 +点击0号图形你需要点击的动作, 你可以右调试窗口的console看到输入的log +比如我们需要传递的参数值是"廉颇", 那么取数据的方法就是data.name, 你把这个填入即可 + + 输入图片说明

+

这样就实现按所选数据或所选系列钻取/联动了, 重新点击当前所选, 恢复原来的 +如何在图形开发中获取参数值

+
图形编辑器中, 
+你可以使用函数 ds_param('参数名') 来获取传入的参数值
+

+ 高级定制方法 + # +

+

如果有更多个性化需求,可以在需要点击的图形的编辑器中加入以下代码,你仅仅需要修改的是序号参数名

+
//比如传入多个参数进行联动
+myChart__name__.on('click', function(params){
+     let myparam = params.seriesName;  //获取点击的值
+     filter_param['参数名'] = myparam;  //填写你的数据集的SQL设定中对应的参数名
+     filter_param['参数名2'] = myparam2;  //你可以赋值给多个参数
+     ds_refresh(3);   //3 为你要刷新图形序号
+});
+

你也可以使用更方便的参数赋值方法(5.6以上)

+
//使用方法
+ds_setParam('参数名', 参数值)
+此方法将自动判断当参数值为空时, 删除参数回到初始未传参状态
+

你还可以实现钻取到另外一个报表

+
myChart__name__.on('click', function (params) {
+ let myparam = `&param={"参数名": "${params.seriesName}"}`;
+ //拼成url并传参,具体参考数据集说明中的数据联动url传参的方法
+ let myurl='http://localhost:8000/echart/?type=目标报表名'+ myparam;
+ window.open(myurl,'_blank','toolbar=no,scrollbar=no,top=100,left=100,width=800,height=500');
+});
+
+

TIPS +如果你的参数中存在非法字符如&=, 你可以使用encodeURIComponent函数进行转义后赋值

+
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/5.参数及联动钻取/筛选器指南/index.html b/docs/smartchart/docs/5.参数及联动钻取/筛选器指南/index.html new file mode 100644 index 0000000..ac5a18c --- /dev/null +++ b/docs/smartchart/docs/5.参数及联动钻取/筛选器指南/index.html @@ -0,0 +1,1697 @@ + + + + + + + + + + + + + + +筛选器指南 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 筛选器指南 + + +
+ + + + + + +
+ + + +

+ 通用实现方式 + # +

+

SMARTCHART实现筛选最简单的方法只需要配一个控件即可:
+建立一个筛选清单数据集, 自动获取筛选的列表,那么可以这么写

+
 Select xxxx as city from tablename..... 
+ 则会生成一个如下的数据集: 
+ [['city'],[选项1],[选项2],..]
+

良好的习惯, 先保存在数据集 +然后在筛选器数据集中的js编辑器(图形编辑器),填下如下代码:

+
//如要要美化, 自已加样式, 只要保证id="id_select__name__"
+let dataset=__dataset__;
+let table ='<span>标题</span><select  id="id_select__name__">';
+table = table + '<option value="" selected>----</option>';
+ for(let i=1;i<dataset.length;i++){ 
+  table = table + '<option>' + dataset[i][0] + '</option>';
+ }
+table = table + '</select></div></div>'
+
+dom__name__.innerHTML=table;
+

这个时候你已经可以看到筛选器了 + + 输入图片说明

+

现在我们来设定联动效果

+

假设需要被筛选的数据集的SQL这样写,数据集的序号是0

+
//那么在需要被联动的数据集中,如使用pcity做为参数写查询, 比如:
+select xx, xx, xx from tablename /* where xx = '$pcity' */
+

现在回到我们筛选器数据集,点击标题的位置, 我们需要使0号图形被筛选器联动, 设置如下即可: + + 输入图片说明

+

然后你就可以看到筛选效果了, 非常的简单方便, 需要多个图形被联动, 只需用逗号分隔即可 比如: 0, 2, 4

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/5.参数及联动钻取/组件自定义联动/index.html b/docs/smartchart/docs/5.参数及联动钻取/组件自定义联动/index.html new file mode 100644 index 0000000..0db3cdb --- /dev/null +++ b/docs/smartchart/docs/5.参数及联动钻取/组件自定义联动/index.html @@ -0,0 +1,1720 @@ + + + + + + + + + + + + + + +组件自定义联动 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 组件自定义联动 + + +
+ + + + + + +
+ + + +

+ 应用场景 + # +

+

Smartchart对于单项筛选有通用的组件, 可以直接配置即可,但对于个性化的筛选,需要你进行一些简单的定制化,以下就针对多项筛选联动的需求来介绍如何定制化你的筛选联动效果 +通过此例,你可以了解如何自定义任意的联动效果 + + 输入图片说明

+

+ 样列参考 + # +

+

以我们内置的仪表盘为例,

+

第一步,新建一个数据集

+

第二步,在新的数据集中编写查询

+
select distinct H1 as heroname  from smartdemo2 limit 10
+

第三步,编辑此数据集的图形,可复制以下代码

+
//select distinct xx  from tablename
+let dataset=__dataset__;
+let table = '';
+for (let i=1;i<dataset.length;i++){
+    table = `${table}<label><input name="select__name__" type="checkbox" value="${dataset[i][0]}" />${dataset[i][0]}</label> `;
+}
+table = table + "<button id='id_select__name__'>提交</button>";
+
+dom__name__.innerHTML=table;
+
+$('#id_select__name__').click(
+    function(){
+        let res = [];
+        $("input[name='select__name__']:checked").each(function(i){
+            res.push("'" + $(this).val() + "'");
+        });
+		
+        filter_param['H1'] = res.toString();  //参数赋值
+        ds_refresh(1);  //刷新1号图形
+
+    }
+)
+

第四步,在你要联动刷新数据集中增加代码

+
select H1 as heroname, sum(qty) as 出场数 from smartdemo2
+where 1=1
+/* and H1 in ($H1) */      --此处来新增
+group by H1
+order by sum(qty) desc
+

这样就完成了,任何其他需求,都可以采用类似方法自定义

+
+

TIPS +如果你这个点击的图形又可能被其它图形来点击联动, 你需要加入如下unbind否则会触发多次刷新 +$(’#id_select__name__’).unbind(‘click’).click(…..

+
+
+

如果你想取消联动,恢复到初始效果, 你需要删除参数, 如: +delete filter_param[‘H1’]

+
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/6.Jupyter应用/Jupyter中使用指引/index.html b/docs/smartchart/docs/6.Jupyter应用/Jupyter中使用指引/index.html new file mode 100644 index 0000000..bfa9653 --- /dev/null +++ b/docs/smartchart/docs/6.Jupyter应用/Jupyter中使用指引/index.html @@ -0,0 +1,1807 @@ + + + + + + + + + + + + + + +Jupyter中使用指引 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Jupyter中使用指引 + + +
+ + + + + + +
+ + + +

+ 应用场景 + # +

+
+

你需要在jupyter中通过smartchart分享的数据集获取数据进行分析 +你有很多线下数据需要进行个性化分析, 然后制做仪表盘 +在Jupyter的数据分析过程中, 你需要快速生成图形 +大屏或报表有部分数据集是需要能过复杂的分析生成的

+
+

Smartchart支持像pyecharts, Matplotlib 等python绘图工具一样在Jupyter中使用, +但她更加方便, 更加炫酷 和 通用化, +不仅仅是一个绘图工具, 而且是一个平台

+

我们有什么特色:

+
+

使用上手非常简单, 仅仅只有两个命令, get and set, 配置项采用原生的Echarts配置, 无重复学习成本, 使用顺滑 +支持Echarts所有功能, 可定制化程度高, 显示效果好, 可嵌入也可以弹出窗口显示, 也可以dashboard中显示 +数据可以固化存储, 采用smartchart Portal可以直接拼接炫酷大屏

+
+

+ Smartchart与Pandas + + Smartchart与Jupyter + + SmartChart大屏新思路

+

+ 输入图片说明

+

+ 安装使用方法 + # +

+
你需要在jupyter相同的python环境中安装smartchart客户端
+pip install smartchart
+或pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple smartchart
+
+如果你只是需要连接已部署好的smartchart服务端, 本地无需启动smartchart
+

+ 快速开始 + # +

+

初始化认证: +第一次使用时, 打开jupyter后, 需要设定默认用户和smartchart服务端url +同一个环境, 只需初始化一次, 后面无需再设定

+
from smart_chart import Smart
+Smart().set_auth('用户名', '密码',url = 'http://xxxxx')
+

如果smartchart服务端在本地, 可以省略url

+
Smart().set_auth('用户名', '密码')
+

使用方法:

+
from smart_chart import Smart
+mysmart = Smart()
+dataset = [['A','B','C'],[12,34,23],[22,33,37]]
+#把数据写入临时数据集并显示图形
+mysmart.set(1,dataset)
+#随意命名临时数据集, 不一定需要smartchart中数据集已有的
+mysmart.set('DD', dataset)
+
+#从已有的数据集中获取数据(格式参考smartchart数据集)
+ds1 = mysmart.get(1)
+ds2 = mysmart.get('DD')
+

+ 修改图形显示 + # +

+

方法一: 你可以在图形菜单中选择内置图形或主题 +方法二: set默认是表格显示,你也可通过名称加前缀 bar, line, pie进行修改

+
mysmart.set('barxxx', dataset)  #显示柱形图, 另外还有linexxx, piexxx
+

方法三: 简单图形,可能无法满足你的个性化要求, 你可以采用实例化数据集的方式后做出炫酷的自定义图形

+
mysmart.set('myds_1', dataset, push=1)  #参数push=1, 将实例化数据集
+

实例化的数据集, 在图形编辑区点击, 可以进入定制化图形开发, 可使用原生的Echarts配置和实时调试,或直接使用社区图形(第一次使用,有一个登记的过程, 按提示进行) + + 输入图片说明

+

方法四: 如何在非实例化的数据集中使用自定义图形进行临时显示 +假如你已经实例化并自定义了图形, 比如 ‘myds_1’, 你可以直接用它的名称来set

+
#不加push, 将使用新的数据采用myds_1的图形临时显示, 而不会改变原myds_1的数据
+mysmart.set('myds_1', dataset) 
+

+ 显示设定参数 + # +

+

你可以通过参数来设定图形的高宽, 是否嵌入等个性化要求

+
# width, height指定图形嵌入显示的宽高
+# embed 默认不嵌入, embed=1 嵌入, embed=0 不嵌入
+# editor 是否显示图形菜单, 1显示, 0不显示
+# push 是否持久化数据集 push=1, 无则新建有则保存数据
+# url 报表访问的url,默认是localhost
+
+#可以全局初始化设定
+mysmart = Smart(width=xx, height=xx, embed=1, editor='')
+#也可以全局单独进行设定
+mysmart.url = 'http://ip:8000'
+mysmart.embed = 1
+
+#也可以针对单独的一个图形设定
+mysmart.set(1,dataset,embed=1,height=200,editor=0)
+

+ SmartChart与Pandas + # +

+

Smartchart的set支持直接set Pandas的dataframe对象

+
from smart_chart import Smart
+import pandas as pd
+mysmart = Smart()
+df = pd.read_excel('manual_smartdemo.xlsx', 'sheet1')
+mysmart.set('excelsample', df.sample(10))
+
+
+df1 = df.groupby('province').agg({'qty':'sum'}).reset_index()
+mysmart.set('ec_df1', df1, push=1)
+
+df2 = df.groupby('c1').agg({'qty':'sum'}).reset_index()
+mysmart.set('ec_df2', df2, push=1)
+
+df4 = df.groupby('province').agg({'qty':'count'}).reset_index()
+mysmart.set('ec_df4', df1, push=1)
+
+
+df3 = df.groupby('c3').agg({'qty':'sum'}).reset_index()
+print(df3)
+df3.loc[1, 'qty'] = df3.loc[1, 'qty'] * 100
+print(df3)
+
+mysmart.set('ec_df3', df3, push=1)
+
+#mysmart.set('pie0', df1)
+#df2 = df.groupby(['province','c3']).agg({'qty':'sum'}).reset_index()
+#print(df2)
+#mysmart.set('ssss', df2)
+#print(mysmart.get(15))
+

+ 输入图片说明

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/6.Jupyter应用/index.html b/docs/smartchart/docs/6.Jupyter应用/index.html new file mode 100644 index 0000000..b0bd84e --- /dev/null +++ b/docs/smartchart/docs/6.Jupyter应用/index.html @@ -0,0 +1,1626 @@ + + + + + + + + + + + + +6. Jupyter应用 | Smartchart开发手册 + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 6. Jupyter应用 + + +
+ + + + + + +
+ + + +
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/6.Jupyter应用/index.xml b/docs/smartchart/docs/6.Jupyter应用/index.xml new file mode 100644 index 0000000..61d3990 --- /dev/null +++ b/docs/smartchart/docs/6.Jupyter应用/index.xml @@ -0,0 +1,24 @@ + + + + Smartchart开发手册 + https://smartchart.gitee.io/docs/6.Jupyter%E5%BA%94%E7%94%A8/ + Recent content on Smartchart开发手册 + Hugo -- gohugo.io + + + https://smartchart.gitee.io/docs/6.Jupyter%E5%BA%94%E7%94%A8/Jupyter%E4%B8%AD%E4%BD%BF%E7%94%A8%E6%8C%87%E5%BC%95/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/6.Jupyter%E5%BA%94%E7%94%A8/Jupyter%E4%B8%AD%E4%BD%BF%E7%94%A8%E6%8C%87%E5%BC%95/ + 应用场景 # 你需要在jupyter中通过smartchart分享的数据集获取数据进行分析 你有很多线下数据需要进行个性化分析, 然后制做仪表盘 在Jupyter的数据分析过程中, 你需要快速生成图形 大屏或报表有部分数据集是需要能过复杂的分析生成的 +Smartchart支持像pyecharts, Matplotlib 等python绘图工具一样在Jupyter中使用, 但她更加方便, 更加炫酷 和 通用化, 不仅仅是一个绘图工具, 而且是一个平台 +我们有什么特色: +使用上手非常简单, 仅仅只有两个命令, get and set, 配置项采用原生的Echarts配置, 无重复学习成本, 使用顺滑 支持Echarts所有功能, 可定制化程度高, 显示效果好, 可嵌入也可以弹出窗口显示, 也可以dashboard中显示 数据可以固化存储, 采用smartchart Portal可以直接拼接炫酷大屏 +Smartchart与Pandas Smartchart与Jupyter SmartChart大屏新思路 +安装使用方法 # 你需要在jupyter相同的python环境中安装smartchart客户端 pip install smartchart 或pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple smartchart 如果你只是需要连接已部署好的smartchart服务端, 本地无需启动smartchart 快速开始 # 初始化认证: 第一次使用时, 打开jupyter后, 需要设定默认用户和smartchart服务端url 同一个环境, 只需初始化一次, 后面无需再设定 +from smart_chart import Smart Smart().set_auth(&#39;用户名&#39;, &#39;密码&#39;,url = &#39;http://xxxxx&#39;) 如果smartchart服务端在本地, 可以省略url + + + + diff --git a/docs/smartchart/docs/7.报表嵌入/index.html b/docs/smartchart/docs/7.报表嵌入/index.html new file mode 100644 index 0000000..8660331 --- /dev/null +++ b/docs/smartchart/docs/7.报表嵌入/index.html @@ -0,0 +1,1626 @@ + + + + + + + + + + + + +7.报表嵌入 | Smartchart开发手册 + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 7.报表嵌入 + + +
+ + + + + + +
+ + + +
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/7.报表嵌入/index.xml b/docs/smartchart/docs/7.报表嵌入/index.xml new file mode 100644 index 0000000..bb61bc6 --- /dev/null +++ b/docs/smartchart/docs/7.报表嵌入/index.xml @@ -0,0 +1,42 @@ + + + + Smartchart开发手册 + https://smartchart.gitee.io/docs/7.%E6%8A%A5%E8%A1%A8%E5%B5%8C%E5%85%A5/ + Recent content on Smartchart开发手册 + Hugo -- gohugo.io + + + https://smartchart.gitee.io/docs/7.%E6%8A%A5%E8%A1%A8%E5%B5%8C%E5%85%A5/%E7%AE%80%E5%8D%95%E5%B5%8C%E5%85%A5/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/7.%E6%8A%A5%E8%A1%A8%E5%B5%8C%E5%85%A5/%E7%AE%80%E5%8D%95%E5%B5%8C%E5%85%A5/ + 你可能需要把Smartchart生成的图形嵌入到其它系统 首先,所有smartchart设计出来的仪表盘都有一个访问url 你可以直接访问: +http://localhost:8000/echart?type=仪表盘名称 如:http://localhost:8000/echart?type=demo 但是smartchart默认是有权限管理的,所以如果你需要嵌入你自已的系统又不考虑权限,你可以在“设定” &ndash;&gt; 公开 然后在你的网页就可以直接iframe了 +&lt;iframe src=&#34;http://localhost:8000/echart?type=demo&#34; style=&#34;width:100%;height:100%&#34;&gt;&lt;/iframe&gt; + + + + + https://smartchart.gitee.io/docs/7.%E6%8A%A5%E8%A1%A8%E5%B5%8C%E5%85%A5/%E5%8D%95%E7%82%B9%E7%99%BB%E5%BD%95/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/7.%E6%8A%A5%E8%A1%A8%E5%B5%8C%E5%85%A5/%E5%8D%95%E7%82%B9%E7%99%BB%E5%BD%95/ + 单点登录的方式与smartchart进行对接嵌入 # &#39;/echart/smart_login?id=xxx&amp;stamp=xxx&amp;token=xxx&amp;url=https://smartchart.gitee.io/&#39; &#39;&#39;&#39; 参数说明: id: 用户名(在smartchart平台中管理) stamp: 时间戳(1970年1月1日到生成时间的毫秒数) token: 采用sha1加密, token=SHA1(链接秘钥+stamp+id) 请在安装smartchart的这台机器上设定环境变量SMART_KEY = 链接秘钥 url: 登录成功后跳转链接 &#39;&#39;&#39; Python后台样列: # import time import hashlib import os &#34;&#34;&#34; 参数说明: id: 用户名(在smartchart平台中管理) stamp: 时间戳(1970年1月1日到生成时间的毫秒数) token: 采用sha1加密, token=SHA1(链接秘钥+stamp+id) url: 登录成功后跳转链接 &#34;&#34;&#34; SMART_CHART_URL = &#39;http://127.0.0.1:8000&#39; LOGIN_URL = SMART_CHART_URL + &#39;/echart/smart_login?id={id}&amp;stamp={stamp}&amp;token={token}&amp;url={url}&#39; SMART_KEY = 链接秘钥 def get_smarturl(username, url=&#39;/&#39;): stamp = int(time.time() * 1000) id = username res = SMART_KEY + str(stamp) + id token = hashlib. + + + + + https://smartchart.gitee.io/docs/7.%E6%8A%A5%E8%A1%A8%E5%B5%8C%E5%85%A5/%E5%8D%95%E9%A1%B5%E9%9D%A2%E5%B5%8C%E5%85%A5/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/7.%E6%8A%A5%E8%A1%A8%E5%B5%8C%E5%85%A5/%E5%8D%95%E9%A1%B5%E9%9D%A2%E5%B5%8C%E5%85%A5/ + 嵌入报表 # 与单点登录类似, 单点登录用于直接登录到平台访问报表 但对于只嵌入报表, 用此方法更合适(需升级到5.3.11以上) +嵌入的url: &#39;/echart/?type={reportName}&amp;visitor={visitor}&amp;token={token}&amp;stamp={stamp}&#39; 参数说明: reportName: 报表名或报表ID visitor: 用户名(在smartchart平台中管理) stamp: 时间戳(1970年1月1日到生成时间的毫秒数) token: 采用sha1加密, token=SHA1(链接秘钥+stamp+visitor+reportName) 用户名和秘钥设定参考 数据服务API的config文件 +同时你需要将visitor加入到对应的报表权限查看访问 +python样列 # 以下为python版的url生成样列,你可以转化成你对应的开发语言 +import time import hashlib import os SMART_CHART_URL = &#39;http://127.0.0.1:8000&#39; reportID = &#39;报表ID&#39; LOGIN_URL = SMART_CHART_URL + &#39;/echart/?type={reportID}&amp;visitor={visitor}&amp;token={token}&amp;stamp={stamp}&#39; TOKEN = 链接秘钥 def get_smarturl(username, reportName): stamp = int(time.time() * 1000) visitor = username res = TOKEN + str(stamp) + visitor + reportID token = hashlib.sha1(res.encode(&#39;utf-8&#39;)).hexdigest() VISIT_DICT = { &#34;visitor&#34;: id, &#34;stamp&#34;: stamp, &#34;token&#34;: token, &#34;reportID&#34;: reportName } # 拼接好的url,直接访问 visit_url = LOGIN_URL. + + + + diff --git a/docs/smartchart/docs/7.报表嵌入/单点登录/index.html b/docs/smartchart/docs/7.报表嵌入/单点登录/index.html new file mode 100644 index 0000000..17444d2 --- /dev/null +++ b/docs/smartchart/docs/7.报表嵌入/单点登录/index.html @@ -0,0 +1,1706 @@ + + + + + + + + + + + + + + +单点登录 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 单点登录 + + +
+ + + + + + +
+ + + +

+ 单点登录的方式与smartchart进行对接嵌入 + # +

+
'/echart/smart_login?id=xxx&stamp=xxx&token=xxx&url=/'
+'''
+参数说明:
+id: 用户名(在smartchart平台中管理)
+stamp: 时间戳(1970年1月1日到生成时间的毫秒数)
+token: 采用sha1加密, token=SHA1(链接秘钥+stamp+id)
+       请在安装smartchart的这台机器上设定环境变量SMART_KEY = 链接秘钥
+url: 登录成功后跳转链接
+'''
+

+ Python后台样列: + # +

+
import time
+import hashlib
+import os
+
+"""
+参数说明:
+id: 用户名(在smartchart平台中管理)
+stamp: 时间戳(1970年1月1日到生成时间的毫秒数)
+token: 采用sha1加密, token=SHA1(链接秘钥+stamp+id)
+url: 登录成功后跳转链接
+"""
+
+SMART_CHART_URL = 'http://127.0.0.1:8000'
+LOGIN_URL = SMART_CHART_URL + '/echart/smart_login?id={id}&stamp={stamp}&token={token}&url={url}'
+SMART_KEY = 链接秘钥
+
+
+def get_smarturl(username, url='/'):
+    stamp = int(time.time() * 1000)
+    id = username
+    res = SMART_KEY + str(stamp) + id
+    token = hashlib.sha1(res.encode('utf-8')).hexdigest()
+    LOGIN_DICT = {
+        "id": id,
+        "stamp": stamp,
+        "token": token,
+        "url": url
+    }
+
+    # 拼接好的url,直接访问
+    visit_url = LOGIN_URL.format(**LOGIN_DICT)
+    return visit_url
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/7.报表嵌入/单页面嵌入/index.html b/docs/smartchart/docs/7.报表嵌入/单页面嵌入/index.html new file mode 100644 index 0000000..4b0be3c --- /dev/null +++ b/docs/smartchart/docs/7.报表嵌入/单页面嵌入/index.html @@ -0,0 +1,1731 @@ + + + + + + + + + + + + + + +单页面嵌入 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 单页面嵌入 + + +
+ + + + + + +
+ + + +

+ 嵌入报表 + # +

+

与单点登录类似, 单点登录用于直接登录到平台访问报表 +但对于只嵌入报表, 用此方法更合适(需升级到5.3.11以上)

+
嵌入的url: '/echart/?type={reportName}&visitor={visitor}&token={token}&stamp={stamp}'
+参数说明:
+reportName: 报表名或报表ID
+visitor: 用户名(在smartchart平台中管理)
+stamp: 时间戳(1970年1月1日到生成时间的毫秒数)
+token: 采用sha1加密, token=SHA1(链接秘钥+stamp+visitor+reportName)
+

用户名和秘钥设定参考 + 数据服务API的config文件

+

同时你需要将visitor加入到对应的报表权限查看访问

+

+ python样列 + # +

+

以下为python版的url生成样列,你可以转化成你对应的开发语言

+
import time
+import hashlib
+import os
+
+SMART_CHART_URL = 'http://127.0.0.1:8000'
+reportID = '报表ID'
+LOGIN_URL = SMART_CHART_URL + '/echart/?type={reportID}&visitor={visitor}&token={token}&stamp={stamp}'
+TOKEN = 链接秘钥
+
+
+def get_smarturl(username, reportName):
+    stamp = int(time.time() * 1000)
+    visitor = username
+    res = TOKEN + str(stamp) + visitor + reportID
+    token = hashlib.sha1(res.encode('utf-8')).hexdigest()
+    VISIT_DICT = {
+        "visitor": id,
+        "stamp": stamp,
+        "token": token,
+        "reportID": reportName
+    }
+
+    # 拼接好的url,直接访问
+    visit_url = LOGIN_URL.format(** VISIT_DICT)
+    return visit_url
+

+ 数据权限加密方法 + # +

+
如果你需要对用户进行一些数据权限控制, 可以避免用户越权访问
+可以通过传入参数"id", 如/echart/?type=xxx&visitor=xx&token=xx&stamp=xxxxx&id=xxx
+后台会把这个id转化为参数名"_id"给对应的查询来进行数据权限控制
+加密参数需把id加入, 例如id=john
+那么 token=SHA1(链接秘钥+stamp+visitor+reportName+id)
+

+ 全参数加密方法 + # +

+
如果需要将参数也加入认证中, 为保持兼容性, 我们把param这个参数改为params(具体参考参数文档中param的写法)
+'/echart/?type={reportName}&visitor={visitor}&token={token}&stamp={stamp}&params=xxxx'
+加密参数把params加入, 例如params为 {"a":"1","b":2"}
+res = TOKEN + str(stamp) + visitor + reportName + '{"a":"1","b":2"}'
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/7.报表嵌入/简单嵌入/index.html b/docs/smartchart/docs/7.报表嵌入/简单嵌入/index.html new file mode 100644 index 0000000..e7be683 --- /dev/null +++ b/docs/smartchart/docs/7.报表嵌入/简单嵌入/index.html @@ -0,0 +1,1646 @@ + + + + + + + + + + + + + + +简单嵌入 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 简单嵌入 + + +
+ + + + + + +
+ + + +

你可能需要把Smartchart生成的图形嵌入到其它系统 +首先,所有smartchart设计出来的仪表盘都有一个访问url +你可以直接访问:

+
http://localhost:8000/echart?type=仪表盘名称
+
+如:http://localhost:8000/echart?type=demo
+

但是smartchart默认是有权限管理的,所以如果你需要嵌入你自已的系统又不考虑权限,你可以在“设定” –> 公开 + + 输入图片说明

+

然后在你的网页就可以直接iframe了

+
<iframe src="http://localhost:8000/echart?type=demo" style="width:100%;height:100%"></iframe>
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/8.Django应用/FAQ/index.html b/docs/smartchart/docs/8.Django应用/FAQ/index.html new file mode 100644 index 0000000..a465bc3 --- /dev/null +++ b/docs/smartchart/docs/8.Django应用/FAQ/index.html @@ -0,0 +1,1670 @@ + + + + + + + + + + + + + + +Faq | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Faq + + +
+ + + + + + +
+ + + +

+ FAQ + # +

+
+

如果你想对smartchart前端二次开发或关闭debug模式后找不到资源 +在settings中加入

+
STATIC_ROOT = os.path.join(BASE_DIR, "static")
+

执行以下命令将静态文件静态文件克隆到根目录

+
python3 manage.py collectstatic
+

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/8.Django应用/index.html b/docs/smartchart/docs/8.Django应用/index.html new file mode 100644 index 0000000..28a9a44 --- /dev/null +++ b/docs/smartchart/docs/8.Django应用/index.html @@ -0,0 +1,1626 @@ + + + + + + + + + + + + +8. Django应用 | Smartchart开发手册 + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 8. Django应用 + + +
+ + + + + + +
+ + + +
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/8.Django应用/index.xml b/docs/smartchart/docs/8.Django应用/index.xml new file mode 100644 index 0000000..795d4cd --- /dev/null +++ b/docs/smartchart/docs/8.Django应用/index.xml @@ -0,0 +1,32 @@ + + + + Smartchart开发手册 + https://smartchart.gitee.io/docs/8.Django%E5%BA%94%E7%94%A8/ + Recent content on Smartchart开发手册 + Hugo -- gohugo.io + + + https://smartchart.gitee.io/docs/8.Django%E5%BA%94%E7%94%A8/%E5%B5%8C%E5%85%A5Django-Apps/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/8.Django%E5%BA%94%E7%94%A8/%E5%B5%8C%E5%85%A5Django-Apps/ + 应用场景 # 你可以在你的django项目中直接使用smartchart做为插件的方式 你可以查看相关视屏 +使用方法 # 在你的setting.py的INSTALL_APPS中加入&rsquo;smart_chart.echart' 如果你需要simpleui, 你可以在最上行加入我们适配好的&rsquo;smart_chart.smartui&rsquo; INSTALLED_APPS = [ &#39;smart_chart.smartui&#39;, .... .... &#39;smart_chart.echart&#39; ] MIDDLEWARE 中注释掉XFrameOptionsMiddleware +检查确保在Templates的设定处有DIRS的相关设定 +TEMPLATES = [ { &#39;BACKEND&#39;: &#39;django.template.backends.django.DjangoTemplates&#39;, &#39;DIRS&#39;: [BASE_DIR / &#39;templates&#39;], #此处需要有 &#39;APP_DIRS&#39;: True, #也要有 ..... }, ] setting.py中设定为中国时区, 支持中文基础平台建设! LANGUAGE_CODE = &#39;zh-hans&#39; TIME_ZONE = &#39;Asia/Shanghai&#39; USE_I18N = True USE_L10N = True USE_TZ = False # 此处必须为False 在你的url.py中加入引用 from django.conf.urls import include from django.views.generic import RedirectView url.py的urlpatterns中加入路由 path(&#39;echart/&#39;, include(&#39;smart_chart.echart.urls&#39;)), path(&#39;&#39;, RedirectView. + + + + + https://smartchart.gitee.io/docs/8.Django%E5%BA%94%E7%94%A8/FAQ/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/8.Django%E5%BA%94%E7%94%A8/FAQ/ + FAQ # 如果你想对smartchart前端二次开发或关闭debug模式后找不到资源 在settings中加入 +STATIC_ROOT = os.path.join(BASE_DIR, &#34;static&#34;) 执行以下命令将静态文件静态文件克隆到根目录 +python3 manage.py collectstatic + + + + diff --git a/docs/smartchart/docs/8.Django应用/嵌入Django-Apps/index.html b/docs/smartchart/docs/8.Django应用/嵌入Django-Apps/index.html new file mode 100644 index 0000000..b7a801c --- /dev/null +++ b/docs/smartchart/docs/8.Django应用/嵌入Django-Apps/index.html @@ -0,0 +1,1741 @@ + + + + + + + + + + + + + + +嵌入 Django Apps | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 嵌入 Django Apps + + +
+ + + + + + +
+ + + +

+ 应用场景 + # +

+

你可以在你的django项目中直接使用smartchart做为插件的方式 + + 你可以查看相关视屏

+

+ 使用方法 + # +

+
    +
  1. 在你的setting.py的INSTALL_APPS中加入’smart_chart.echart' +如果你需要simpleui, 你可以在最上行加入我们适配好的’smart_chart.smartui’
  2. +
+
INSTALLED_APPS = [
+    'smart_chart.smartui',
+    ....
+    ....
+    'smart_chart.echart'
+]
+
    +
  1. +

    MIDDLEWARE 中注释掉XFrameOptionsMiddleware

    +
  2. +
  3. +

    检查确保在Templates的设定处有DIRS的相关设定

    +
  4. +
+
TEMPLATES = [
+    {
+        'BACKEND': 'django.template.backends.django.DjangoTemplates',
+        'DIRS': [BASE_DIR / 'templates'],   #此处需要有
+        'APP_DIRS': True,   #也要有
+        .....
+    },
+]
+
    +
  1. setting.py中设定为中国时区, 支持中文基础平台建设!
  2. +
+
    LANGUAGE_CODE = 'zh-hans'
+    TIME_ZONE = 'Asia/Shanghai'
+    USE_I18N = True
+    USE_L10N = True
+    USE_TZ = False  # 此处必须为False
+
    +
  1. 在你的url.py中加入引用
  2. +
+
    from django.conf.urls import include
+    from django.views.generic import RedirectView
+
    +
  1. url.py的urlpatterns中加入路由
  2. +
+
    path('echart/', include('smart_chart.echart.urls')),
+    path('', RedirectView.as_view(url='echart/index/')),  #首页,可自定义路由
+
    +
  1. 初始化DB, 命令行输入:
  2. +
+
    python manage.py makemigrations
+    python manage.py migrate
+
    +
  1. 建立管理员帐号, 如果已有可忽略
  2. +
+
   python manage.py createsuperuser
+
    +
  1. 启动服务
  2. +
+
   python manage.py runserver
+

10. 点击首页的组件升级进行初始化 :cupid: !!!! 重要!!! +

+

+ 注意 + # +

+

一般来说如果你使用django遇到的问题,都不是smartchart导致的, +作者也很难给你解答, 建议你可以进行有偿问答

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/9.进阶开发PRO/index.html b/docs/smartchart/docs/9.进阶开发PRO/index.html new file mode 100644 index 0000000..913d739 --- /dev/null +++ b/docs/smartchart/docs/9.进阶开发PRO/index.html @@ -0,0 +1,1626 @@ + + + + + + + + + + + + +9.进阶开发 Pro | Smartchart开发手册 + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 9.进阶开发 Pro + + +
+ + + + + + +
+ + + +
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/9.进阶开发PRO/index.xml b/docs/smartchart/docs/9.进阶开发PRO/index.xml new file mode 100644 index 0000000..8e1d508 --- /dev/null +++ b/docs/smartchart/docs/9.进阶开发PRO/index.xml @@ -0,0 +1,92 @@ + + + + Smartchart开发手册 + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/ + Recent content on Smartchart开发手册 + Hugo -- gohugo.io + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E5%AE%9E%E6%88%98%E5%A4%A7%E5%B1%8F%E6%A8%A1%E6%9D%BF%E8%BD%AC%E5%8C%96/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E5%AE%9E%E6%88%98%E5%A4%A7%E5%B1%8F%E6%A8%A1%E6%9D%BF%E8%BD%AC%E5%8C%96/ + 应用场景 # 已有开发好的非smartchart静态大屏模板(这种模板非常多, 不要上当) 对js, css及smartchart已有初始了解 业务需求展示有合适的模板, 变化不大 如何使用 # 请观看系列视屏, 相信人人都会 头条视屏: 大屏模板转化系列 B站视屏: 大屏模板转化系列 + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%95%B0%E6%8D%AE%E6%9C%8D%E5%8A%A1API/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%95%B0%E6%8D%AE%E6%9C%8D%E5%8A%A1API/ + SmartChart的数据集功能, 可以非常方便的实现数据对外微服务 # 权限设定 # 如果你使用的是自已搭建的django项目, 你需要在项目的根目录下新建一个JSON文件, 如果是使用smartchart启动的, 配置文件在项目的安装目录下可以找到 名为apiconfig.json, 比如需要调用API的用户名为test 和 test2,用户名需要是在你的用户设定中存在的,内容如下: { &#34;test&#34;: { &#34;token&#34;: &#34;smartchart&#34; }, &#34;test2&#34;: { &#34;token&#34;: &#34;smartchartxxx&#34;, &#34;host&#34;: [&#34;10.10.10.10&#34;,&#34;10.10.10.23&#34;], &#34;limit&#39;: 60, &#34;log&#34;:1, &#34;cors&#34;: 1 } } 可选设定参考test2 host:API白名单配置,limit:一分钟内可调用次数, log:日志记录方式. cors:永许跨域访问 +然后你只需要将你的数据集中的权限设定给对应的用户即可 请求方式 # 加密接口请求方式(推荐) # GET 请求 # #接口请求格式: url: /echart/dataset_api/?visitor=xxx&amp;token=xxx&amp;type=xxx&amp;stamp=xxxxx&amp;param={&#34;xx&#34;:&#34;xxx&#34;,&#34;xx&#34;:&#34;xxxx&#34;} # 参数说明 visitor: 用户名 type: 接口数据集ID stamp: 时间戳(1970年1月1日到生成时间的毫秒数) token: 采用sha1加密, token=SHA1(秘钥 + stamp + Visitor + Type) param: 传入的参数值(可选),格式json字符串,如多个参数: &#39;{&#34;参数A&#34;:&#34;xxxx&#34;, &#34;参数B&#34;:&#34;xxxx&#34;}&#39; # 接口返回格式 Json: { &#34;data&#34;:[[]], &#34;result&#34;:&#34;success&#34;, &#34;maxpg&#34;:1, &#34;pg&#34;:1 } 返回值说明: data : 二维数组,第一行为表头, 样列数据 [[&#34;heroname&#34;, &#34;qty&#34;],[&#34;镜&#34;,658],[&#34;猪八戒&#34;,591]] result : success 或 error maxpg/pg : GET请求固定为1不分页 POST请求(适用于后台定时同步数据,查询请用GET请求方法) # #接口请求格式: url: /echart/dataset_api/ # 请求参数说明 data: { &#34;visitor&#34;:&#34;xxx&#34;, &#34;token&#34;:&#34;xxx&#34;, &#34;stamp&#34;:xxxxx, &#34;type&#34;:&#34;xxx&#34;, &#34;pagesize&#34;:&#34;xxx&#34;, &#34;pg&#34;:&#34;xxx&#34;, &#34;param&#34;:&#39;{&#34;xxx&#34;:&#34;xxxx&#34;}&#39; } # 参数说明 visitor: 用户名 type: 接口数据集ID stamp: 时间戳(1970年1月1日到生成时间的毫秒数) token: 采用sha1加密, token=SHA1(秘钥 + stamp + Visitor + Type) Pagesize: 采用分页,每页的数据量大小 pg: 返回第几页 param: 传入的参数值,格式json字符串,如多个参数 &#39;{&#34;参数A&#34;:&#34;xxxx&#34;, &#34;参数B&#34;:&#34;xxxx&#34;}&#39; #接口返回格式 Json: { &#34;data&#34;:[[]], &#34;result&#34;:&#34;success&#34;, &#34;maxpg&#34;:xxx, #最大页数 &#34;pg&#34;:xx, #当前页数 &#34;casheflag&#34;: xx, #如果是999说明命中缓存 &#34;total&#34;:xx, #总条数 } 注意: 只有post是分页的, 第一页是带标题的, 后面页不带标题 由于post方式会使用缓存进行分页,如命中缓存传参不会生效,小数据量请使用get方式请求 不要请求大数据量,大量数据请采用limit, offset传参方式进行分页 + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E5%A4%87%E4%BB%BD%E6%81%A2%E5%A4%8D%E5%8F%8A%E7%89%88%E6%9C%AC/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E5%A4%87%E4%BB%BD%E6%81%A2%E5%A4%8D%E5%8F%8A%E7%89%88%E6%9C%AC/ + 应用场景 # 本地仪表盘的备份恢复,版本管理 开发测试生产机之间的同步 具体使用方法请观看视屏 版本控制使用说明视屏 +使用方法 # 快速备份 # 可以在模板-&gt;点击如下图标, 完成快速备份(注意会覆盖历史), 备份号统一为:SNAPSHOT 指定备份 # 你也可以在设定-&gt;备份恢复 中进行按版本备份 查询备份 # 当不输入KEY值, 点击 本地备份时,可以查询此仪表盘已有的备份 备份恢复 # 备份可以在任意的仪表盘中进行恢复,如果是当前仪表盘, 仅输入KEY即可,比如:V01, 如果是跨仪表盘恢复, KEY需要带上仪表盘的编号如13_V01 +备份恢复参数说明 # 可以支持多种恢复模式, 只需要在KEY前面加上前缀即可, 如FORCEV01, FORCE13_V01.. FORCE: 删除自身所有数据集及高级设定,模板等,完全恢复备份 DATASET:只更新数据集及图形,模板,适用于测试上线正式 CHART: 只更新图形及模板,适用于前端变更上线 +跨服务器间同步 # 具体方法购买专业版本后提供 +使用以下流程, 可以使企业在使用最少资源做出最专业的可视化项目 # 前提条件: # 公司内部有技术人员(熟悉数据, 会写SQL) 服务器安装smartchart专业版 开发流程: # 由于公司内部人员是对业务最熟悉, 一般也都是后台数据管理相关的人员, 一般不太会有专职的前端开发和UI 所以数据开发人员可以使用smartchart开发仪表盘数据集, 并使用拖拽功能完成一个粗糙一点的框架和图形设计 一般情况下已经可以满足数据可视化的需求 +如果需要达到更专业的可视化效果, 可以外包前端/UI或在smartchart社区咨询, 由于需求变得非常简单 而前端开发又是一个通用技能, 可以使用非常廉价的费用获得最大的效果 +专业的事情专业来做, 才能达到效益最大化, 这是smartchart的设计理念 不管用什么工具, 在同等资源的投入下, 数据分析人员开发的可视化效果很难达到专业前端UI的效果 另外BI/数据开发人员的费用可是比前端高的, 也更稀缺 + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%95%B0%E6%8D%AE%E4%B8%8B%E8%BD%BD/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%95%B0%E6%8D%AE%E4%B8%8B%E8%BD%BD/ + 应用场景: # 需要要下载数据集的数据到本地 +样例: # 可在&quot;模板&quot; 中新建一个下载按钮, 并指定一个ID,如id_down1, 拖拽到你需要的位置 在任意一个图形开发或js代码段中加入以下代码即可 +$(&#39;#id_down1&#39;).click(()=&gt;{ ds_download(&#39;报表数据.csv&#39;, dataset); }); 这样就可以实现点击按钮下载数据了 +仅需要录活使用ds_download这个函数, 你可以开发出非常个性化的下载功能 +ds_download(name, dataset) 参数说明: name: 文件名称 dataset: 可以是二维数组也可以是字符串 + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%95%B0%E6%8D%AE%E5%A1%AB%E6%8A%A5/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%95%B0%E6%8D%AE%E5%A1%AB%E6%8A%A5/ + 应用场景 # 收集用户端录入的数据 前端处理好的数据回写到任意系统 制做问卷系统 埋点应用 使用方法 # 新建数据集设定,格式如下: 只用指定表名 dataset={ &#34;table&#34;:&#34;表名&#34; } 你也可以指定字段, 比如 dataset={ &#34;table&#34;:&#34;表名(字段1, 字段2)&#34; } 在&quot;容器&quot;管理, 取消这个数据集激活, 并记录下来此数据集的ID, 比如132 在&quot;模板&quot;中编写录入组件代码, 具体可参考视屏 +&lt;h1 class=&#34;smtdrag&#34; id=&#34;id_1648895680659&#34;&gt;数据填报&lt;/h1&gt; &lt;div class=&#34;smtdrag&#34; id=&#34;id_1648895855760&#34;&gt; &lt;label&gt;用户&lt;/label&gt;&lt;input id=&#34;id_visitor&#34;&gt; &lt;/div&gt; &lt;div class=&#34;smtdrag&#34; id=&#34;id_1648895859160&#34;&gt; &lt;label&gt;动作&lt;/label&gt;&lt;input id=&#34;id_action&#34;&gt; &lt;/div&gt; &lt;div class=&#34;smtdrag&#34; id=&#34;id_1648895956207&#34;&gt; &lt;button id=&#34;idbtn01&#34;&gt;提交&lt;/button&gt; &lt;/div&gt; 在&quot;模板&quot; 中编写JS代码 $(&#39;#idbtn01&#39;).click(function(){ let visitor = $(&#39;#id_visitor&#39;).val(); let action = $(&#39;#id_action&#39;).val(); let dataset = [visitor, action]; print(ds_save(132, dataset)); //132数据集ID, dataset要写入的数据 }) 更多关于写入数据库的数据集格式说明 # 只写入一行数据, 样列如下: dataset = [&#39;a&#39;,&#39;b&#39;] 同时写入多行数据: dataset = [[], [&#39;a1&#39;,&#39;b1&#39;],[&#39;a2&#39;, &#39;b2]] 如果需要自动记录写入者用户名: dataset = [&#39;$username&#39;, &#39;b&#39;] mongodb写入方式 + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E5%90%8E%E5%8F%B0API%E5%88%B7%E6%96%B0/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E5%90%8E%E5%8F%B0API%E5%88%B7%E6%96%B0/ + 应用场景 # 有ETL流程,需要等待后台数据刷新完成后,再触发仪表盘的刷新,数据未完成刷新,仪表盘不刷新 针对有一些耗时的查询, 虽然smartchart有缓存加速, 但是在第一次刷新时可能不能达到极速 用户需要随时都能体验到极速的打开效果 使用后台API刷新,建意将仪表盘中数据集的缓存时间设置长一些,比如2天(2880分钟) +后台数据主动刷新接口 # (购买专业版本后支持) +你需要在setting.py中设定API_TOKEN API_TOKEN = &#39;xxxxxxxx&#39; 找到你要刷新的仪表盘编码, 你可以在打开的仪表盘url上面找到这个type id +后台访问如下api url即可 +http://ip:端口/echart/refresh_ds/?type=你的报表ID&amp;token=你设定的API_TOKEN 关于定时刷新 # 为保持产品的轻量化及坚持专业的产品做专业的事情, 归一化统一化的架构设计, 我们不会集成相关调度系统, 一般我们推荐使用您自有的调度工具或平台, 如airflow, 我们也有相关的配套产品 +如果您仅仅是简单应用, 也无需使用专用调度来增加运维复杂度, 可以使用linux自带的即可 +新建一个sh文件, 假设目录在/data/smartchart vim refresh_smartchart.sh 写入需要刷新的脚本 echo start refresh $(date &#34;+%Y-%m-%d %H:%M:%S&#34;) curl http://ip:端口/echart/?type=你的报表ID1&amp;token=你设定的API_TOKEN curl http://ip:端口/echart/?type=你的报表ID2&amp;token=你设定的API_TOKEN echo end refresh $(date &#34;+%Y-%m-%d %H:%M:%S&#34;) 如果你的网址是https, 可如下方法使用curl +curl -k --insecure &#34;https://www.baidu.com” 修改为可执行文件 chmod 775 refresh_smartchart.sh 使用crontab来定时执行 # 编辑crontab crontab -e # 比如需要每天晚上5点10分执行 10 5 * * * /data/smartchart/refresh_smartchart. + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/webSocket%E6%96%B9%E5%BC%8F/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/webSocket%E6%96%B9%E5%BC%8F/ + 应用场景 # 对于实时程度要求比较高的情况下, 如果你后端已有实现websocket的接口, smartchart也可以很方便的接入 参考以下步骤即可 +在&quot;模板&quot;中定义一个全局变量, 如ws_data 编写连接和接收代码段逻辑 在接收代码段加入ds_refresh, 如要刷新0号图形, 则加入ds_refresh(0) 在&quot;高级&quot;设定中加入共享数据集设定, 把ws_data映射到0号图形即可 代码段参考 # let ws_data = [[&#39;初始化&#39;,&#39;V&#39;],[&#39;A&#39;,&#39;2&#39;]]; let ws = null; if(&#39;webSocket&#39; in window){ print(&#39;支持webSocket&#39;); ws = new webSocket(&#39;ws://127.0.0.1:2222/abc&#39;); //连接成功 ws.onopen = function(){ print(&#39;ws连接成功&#39;); } //接收消息 ws.onmessage = function(evt){ ws_data = evt.data; ds_refresh(0); } } else{ print(&#39;浏览器不支持ws&#39;) } + + + + diff --git a/docs/smartchart/docs/9.进阶开发PRO/webSocket方式/index.html b/docs/smartchart/docs/9.进阶开发PRO/webSocket方式/index.html new file mode 100644 index 0000000..5f0af45 --- /dev/null +++ b/docs/smartchart/docs/9.进阶开发PRO/webSocket方式/index.html @@ -0,0 +1,1696 @@ + + + + + + + + + + + + + + +Web Socket方式 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Web Socket方式 + + +
+ + + + + + +
+ + + +

+ 应用场景 + # +

+

对于实时程度要求比较高的情况下, 如果你后端已有实现websocket的接口, smartchart也可以很方便的接入 +参考以下步骤即可

+
    +
  1. 在"模板"中定义一个全局变量, 如ws_data
  2. +
  3. 编写连接和接收代码段逻辑
  4. +
  5. 在接收代码段加入ds_refresh, 如要刷新0号图形, 则加入ds_refresh(0)
  6. +
  7. 在"高级"设定中加入共享数据集设定, 把ws_data映射到0号图形即可
  8. +
+

+ 输入图片说明

+

+ 代码段参考 + # +

+
    let ws_data = [['初始化','V'],['A','2']];
+    let ws = null;
+    
+    if('webSocket' in window){
+        print('支持webSocket');
+        ws = new webSocket('ws://127.0.0.1:2222/abc');
+        //连接成功
+        ws.onopen = function(){
+            print('ws连接成功');
+        }
+        //接收消息
+        ws.onmessage = function(evt){
+            ws_data = evt.data;
+            ds_refresh(0);
+        }
+    }
+    else{
+        print('浏览器不支持ws')
+    }
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/9.进阶开发PRO/后台API刷新/index.html b/docs/smartchart/docs/9.进阶开发PRO/后台API刷新/index.html new file mode 100644 index 0000000..12a7eb4 --- /dev/null +++ b/docs/smartchart/docs/9.进阶开发PRO/后台API刷新/index.html @@ -0,0 +1,1746 @@ + + + + + + + + + + + + + + +后台 Api刷新 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 后台 Api刷新 + + +
+ + + + + + +
+ + + +

+ 应用场景 + # +

+
    +
  • 有ETL流程,需要等待后台数据刷新完成后,再触发仪表盘的刷新,数据未完成刷新,仪表盘不刷新
  • +
  • 针对有一些耗时的查询, 虽然smartchart有缓存加速, 但是在第一次刷新时可能不能达到极速
  • +
  • 用户需要随时都能体验到极速的打开效果
  • +
+
+

使用后台API刷新,建意将仪表盘中数据集的缓存时间设置长一些,比如2天(2880分钟)

+
+

+ 后台数据主动刷新接口 + # +

+

(购买专业版本后支持)

+
    +
  1. 你需要在setting.py中设定API_TOKEN
  2. +
+
API_TOKEN = 'xxxxxxxx'
+
    +
  1. +

    找到你要刷新的仪表盘编码, 你可以在打开的仪表盘url上面找到这个type id

    +
  2. +
  3. +

    后台访问如下api url即可

    +
  4. +
+
http://ip:端口/echart/refresh_ds/?type=你的报表ID&token=你设定的API_TOKEN
+

+ 关于定时刷新 + # +

+

为保持产品的轻量化及坚持专业的产品做专业的事情, 归一化统一化的架构设计, 我们不会集成相关调度系统, +一般我们推荐使用您自有的调度工具或平台, 如airflow, 我们也有相关的配套产品

+

如果您仅仅是简单应用, 也无需使用专用调度来增加运维复杂度, 可以使用linux自带的即可

+
    +
  • 新建一个sh文件, 假设目录在/data/smartchart
  • +
+
vim refresh_smartchart.sh
+
    +
  • 写入需要刷新的脚本
  • +
+
echo  start refresh $(date "+%Y-%m-%d %H:%M:%S")
+curl  http://ip:端口/echart/?type=你的报表ID1&token=你设定的API_TOKEN
+curl  http://ip:端口/echart/?type=你的报表ID2&token=你设定的API_TOKEN
+echo  end refresh $(date "+%Y-%m-%d %H:%M:%S")
+
+

如果你的网址是https, 可如下方法使用curl

+
+
curl -k --insecure "https://www.baidu.com”
+
    +
  • 修改为可执行文件
  • +
+
chmod 775 refresh_smartchart.sh
+
    +
  • 使用crontab来定时执行
  • +
+
# 编辑crontab
+crontab -e
+# 比如需要每天晚上5点10分执行
+10 5 * * * /data/smartchart/refresh_smartchart.sh >>/data/smartchart/log.txt 2>&1
+
+# 定时参数说明
+*    *    *    *    *
+-    -    -    -    -
+|    |    |    |    |
+|    |    |    |    +----- 星期中星期几 (0 - 6) (星期天 为0)
+|    |    |    +---------- 月份 (1 - 12) 
+|    |    +--------------- 一个月中的第几天 (1 - 31)
+|    +-------------------- 小时 (0 - 23)
++------------------------- 分钟 (0 - 59)
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/9.进阶开发PRO/备份恢复及版本/index.html b/docs/smartchart/docs/9.进阶开发PRO/备份恢复及版本/index.html new file mode 100644 index 0000000..af2e270 --- /dev/null +++ b/docs/smartchart/docs/9.进阶开发PRO/备份恢复及版本/index.html @@ -0,0 +1,1759 @@ + + + + + + + + + + + + + + +备份恢复及版本 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 备份恢复及版本 + + +
+ + + + + + +
+ + + +

+ 应用场景 + # +

+
    +
  • 本地仪表盘的备份恢复,版本管理
  • +
  • 开发测试生产机之间的同步
  • +
+

具体使用方法请观看视屏 + 版本控制使用说明视屏

+

+ 使用方法 + # +

+

+ 快速备份 + # +

+

可以在模板->点击如下图标, 完成快速备份(注意会覆盖历史), 备份号统一为:SNAPSHOT + + 输入图片说明

+

+ 指定备份 + # +

+

你也可以在设定->备份恢复 中进行按版本备份 + + 输入图片说明

+

+ 查询备份 + # +

+

当不输入KEY值, 点击 本地备份时,可以查询此仪表盘已有的备份 + + 输入图片说明

+

+ 备份恢复 + # +

+

备份可以在任意的仪表盘中进行恢复,如果是当前仪表盘, 仅输入KEY即可,比如:V01, +如果是跨仪表盘恢复, KEY需要带上仪表盘的编号如13_V01

+

+ 备份恢复参数说明 + # +

+

可以支持多种恢复模式, 只需要在KEY前面加上前缀即可, 如FORCEV01, FORCE13_V01.. +FORCE: 删除自身所有数据集及高级设定,模板等,完全恢复备份 +DATASET:只更新数据集及图形,模板,适用于测试上线正式 +CHART: 只更新图形及模板,适用于前端变更上线

+

+ 跨服务器间同步 + # +

+

具体方法购买专业版本后提供

+

+ 使用以下流程, 可以使企业在使用最少资源做出最专业的可视化项目 + # +

+

+ 前提条件: + # +

+
    +
  1. 公司内部有技术人员(熟悉数据, 会写SQL)
  2. +
  3. 服务器安装smartchart专业版
  4. +
+

+ 开发流程: + # +

+

由于公司内部人员是对业务最熟悉, 一般也都是后台数据管理相关的人员, 一般不太会有专职的前端开发和UI +所以数据开发人员可以使用smartchart开发仪表盘数据集, 并使用拖拽功能完成一个粗糙一点的框架和图形设计 +一般情况下已经可以满足数据可视化的需求

+

如果需要达到更专业的可视化效果, 可以外包前端/UI或在smartchart社区咨询, 由于需求变得非常简单 +而前端开发又是一个通用技能, 可以使用非常廉价的费用获得最大的效果

+
+

专业的事情专业来做, 才能达到效益最大化, 这是smartchart的设计理念 +不管用什么工具, 在同等资源的投入下, 数据分析人员开发的可视化效果很难达到专业前端UI的效果 +另外BI/数据开发人员的费用可是比前端高的, 也更稀缺

+
+
    +
  • 前端开发只需本地安装smartchart, 而无需接触到公司数据库或数据接口, 开发完全解耦, 数据安全保障
  • +
  • smartchart可以将数据开发人员开发的仪表盘直接同步到前端开发的本地smartchart(仅会保留demo数据)
  • +
  • 前端进行一些简单的美化工作即可, 无需对业务和数据进行理解, 花费的时间非常之少
  • +
  • 前端开发完成后可以一键同步到smartchart服务端, 且可以只同步可视化部分
  • +
  • 由于数据和展示是分离的, 所以数据开发和前端美化是可以同步进行
  • +
  • 由于smartchart是一个平台化产品, 数据开发人员不熟悉前端也能在前端开发完成的基础上进行样式和图形的修改
  • +
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/9.进阶开发PRO/实战大屏模板转化/index.html b/docs/smartchart/docs/9.进阶开发PRO/实战大屏模板转化/index.html new file mode 100644 index 0000000..dc94656 --- /dev/null +++ b/docs/smartchart/docs/9.进阶开发PRO/实战大屏模板转化/index.html @@ -0,0 +1,1675 @@ + + + + + + + + + + + + + + +实战大屏模板转化 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 实战大屏模板转化 + + +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/9.进阶开发PRO/数据下载/index.html b/docs/smartchart/docs/9.进阶开发PRO/数据下载/index.html new file mode 100644 index 0000000..0cfd299 --- /dev/null +++ b/docs/smartchart/docs/9.进阶开发PRO/数据下载/index.html @@ -0,0 +1,1693 @@ + + + + + + + + + + + + + + +数据下载 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 数据下载 + + +
+ + + + + + +
+ + + +

+ 应用场景: + # +

+

需要要下载数据集的数据到本地

+

+ 样例: + # +

+
    +
  1. +

    可在"模板" 中新建一个下载按钮, 并指定一个ID,如id_down1, 拖拽到你需要的位置 + + 输入图片说明

    +
  2. +
  3. +

    在任意一个图形开发或js代码段中加入以下代码即可

    +
  4. +
+
$('#id_down1').click(()=>{
+    ds_download('报表数据.csv', dataset);
+});
+

这样就可以实现点击按钮下载数据了

+

仅需要录活使用ds_download这个函数, 你可以开发出非常个性化的下载功能

+
ds_download(name, dataset)
+参数说明:
+name: 文件名称
+dataset: 可以是二维数组也可以是字符串
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/9.进阶开发PRO/数据填报/index.html b/docs/smartchart/docs/9.进阶开发PRO/数据填报/index.html new file mode 100644 index 0000000..672c140 --- /dev/null +++ b/docs/smartchart/docs/9.进阶开发PRO/数据填报/index.html @@ -0,0 +1,1730 @@ + + + + + + + + + + + + + + +数据填报 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 数据填报 + + +
+ + + + + + +
+ + + +

+ 应用场景 + # +

+
    +
  • 收集用户端录入的数据
  • +
  • 前端处理好的数据回写到任意系统
  • +
  • 制做问卷系统
  • +
  • 埋点应用
  • +
+

+ 使用方法 + # +

+
    +
  • 新建数据集设定,格式如下:
  • +
+
只用指定表名
+dataset={
+    "table":"表名"
+}
+你也可以指定字段, 比如
+dataset={
+    "table":"表名(字段1, 字段2)"
+}
+
    +
  • +

    在"容器"管理, 取消这个数据集激活, 并记录下来此数据集的ID, 比如132 + + 输入图片说明

    +
  • +
  • +

    在"模板"中编写录入组件代码, + 具体可参考视屏

    +
  • +
+
    <h1 class="smtdrag" id="id_1648895680659">数据填报</h1>
+    
+    <div class="smtdrag" id="id_1648895855760">
+        <label>用户</label><input id="id_visitor">
+    </div>
+    <div class="smtdrag" id="id_1648895859160">
+        <label>动作</label><input id="id_action">
+    </div>
+    <div class="smtdrag" id="id_1648895956207">
+        <button id="idbtn01">提交</button>
+    </div>
+

+ 输入图片说明

+
    +
  • 在"模板" 中编写JS代码
  • +
+
   $('#idbtn01').click(function(){
+       let visitor = $('#id_visitor').val();
+       let action = $('#id_action').val();
+       let dataset = [visitor, action];
+       print(ds_save(132, dataset));  //132数据集ID, dataset要写入的数据
+   })
+

+ 更多关于写入数据库的数据集格式说明 + # +

+
只写入一行数据, 样列如下:
+dataset = ['a','b']
+同时写入多行数据:
+dataset = [[], ['a1','b1'],['a2', 'b2]]
+如果需要自动记录写入者用户名:
+dataset = ['$username', 'b']
+

mongodb写入方式

+
ds_save(419, {"h1":123, "h2":"bb"});
+ds_save(419, [[],{"h1":123, "h2":"aa"},{"h1":1234, "h2":"dd"}]);
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/9.进阶开发PRO/数据服务API/index.html b/docs/smartchart/docs/9.进阶开发PRO/数据服务API/index.html new file mode 100644 index 0000000..5bb91cc --- /dev/null +++ b/docs/smartchart/docs/9.进阶开发PRO/数据服务API/index.html @@ -0,0 +1,1814 @@ + + + + + + + + + + + + + + +数据服务 API | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 数据服务 API + + +
+ + + + + + +
+ + + +

+ SmartChart的数据集功能, 可以非常方便的实现数据对外微服务 + # +

+

+ 权限设定 + # +

+
    +
  • 如果你使用的是自已搭建的django项目, 你需要在项目的根目录下新建一个JSON文件, +如果是使用smartchart启动的, 配置文件在项目的安装目录下可以找到 +名为apiconfig.json,
  • +
  • 比如需要调用API的用户名为test 和 test2,用户名需要是在你的用户设定中存在的,内容如下:
  • +
+
{
+  "test": {
+    "token": "smartchart"
+  },
+  "test2": {
+   "token": "smartchartxxx",
+   "host": ["10.10.10.10","10.10.10.23"],
+   "limit': 60,
+   "log":1,
+   "cors": 1
+ }
+}
+
+

可选设定参考test2 +host:API白名单配置,limit:一分钟内可调用次数, log:日志记录方式. +cors:永许跨域访问

+
+
    +
  • 然后你只需要将你的数据集中的权限设定给对应的用户即可
  • +
+

+ 请求方式 + # +

+

+ 加密接口请求方式(推荐) + # +

+

+ GET 请求 + # +

+
#接口请求格式: 
+url: /echart/dataset_api/?visitor=xxx&token=xxx&type=xxx&stamp=xxxxx&param={"xx":"xxx","xx":"xxxx"}
+# 参数说明
+visitor: 用户名
+type: 接口数据集ID
+stamp: 时间戳(1970年1月1日到生成时间的毫秒数)
+token: 采用sha1加密, token=SHA1(秘钥 + stamp + Visitor + Type)
+param: 传入的参数值(可选)格式json字符串如多个参数: '{"参数A":"xxxx", "参数B":"xxxx"}'
+# 接口返回格式
+Json: 
+{
+"data":[[]],
+"result":"success",
+"maxpg":1,
+"pg":1
+}
+返回值说明
+data : 二维数组第一行为表头 样列数据
+[["heroname", "qty"],["镜",658],["猪八戒",591]]
+result : success 或 error
+maxpg/pg : GET请求固定为1不分页
+

+ POST请求(适用于后台定时同步数据,查询请用GET请求方法) + # +

+
#接口请求格式:
+url: /echart/dataset_api/
+# 请求参数说明
+data: 
+{
+"visitor":"xxx",
+"token":"xxx",
+"stamp":xxxxx,
+"type":"xxx",     
+"pagesize":"xxx",  
+"pg":"xxx",       
+"param":'{"xxx":"xxxx"}'  
+}
+# 参数说明
+visitor: 用户名
+type: 接口数据集ID
+stamp: 时间戳(1970年1月1日到生成时间的毫秒数)
+token: 采用sha1加密, token=SHA1(秘钥 + stamp + Visitor + Type)
+Pagesize: 采用分页每页的数据量大小
+pg: 返回第几页
+param: 传入的参数值格式json字符串如多个参数
+'{"参数A":"xxxx", "参数B":"xxxx"}'
+
+
+#接口返回格式
+Json: 
+{
+"data":[[]],
+"result":"success",
+"maxpg":xxx,  #最大页数
+"pg":xx,  #当前页数
+"casheflag": xx,  #如果是999说明命中缓存
+"total":xx,   #总条数
+}
+
+

注意: +只有post是分页的, 第一页是带标题的, 后面页不带标题 +由于post方式会使用缓存进行分页,如命中缓存传参不会生效,小数据量请使用get方式请求 +不要请求大数据量,大量数据请采用limit, offset传参方式进行分页

+
+

+ 不加密请求方式(简单但不安全) + # +

+
GET 请求
+#接口请求格式: 
+url: /echart/dataset_api/?visitor=xxx&token=xxx&type=xxx 数据集名或id名
+#接口返回格式
+Json: 
+{
+"data":[[]],
+"result":"success",
+"maxpg":1,
+"pg":1
+}
+
+POST请求
+#接口请求格式:
+url: /echart/dataset_api/
+data: 
+{
+"visitor":"xxx",
+"token":"xxx",
+"type":"xxx",      #数据集名或id名
+"pagesize":"xxx",  #每页数据条数
+"pg":"xxx",        #返回第几页
+"param":'{"xxx":"xxxx"}'  #参数可选
+}
+#接口返回格式
+Json: 
+{
+"data":[[]],
+"result":"success",
+"maxpg":xxx,  #最大页数
+"pg":xx,  #当前页数
+"casheflag": xx,  #如果是999说明命中缓存
+"total":xx,   #总条数
+}
+
+注意:
+只有post是分页的, 第一页是带标题的, 后面页不带标题
+由于post方式会使用缓存, 小数据量建议你使用get方式请求
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/9.进阶开发PRO/模板开发/IDE开发模式/index.html b/docs/smartchart/docs/9.进阶开发PRO/模板开发/IDE开发模式/index.html new file mode 100644 index 0000000..fb40d19 --- /dev/null +++ b/docs/smartchart/docs/9.进阶开发PRO/模板开发/IDE开发模式/index.html @@ -0,0 +1,1737 @@ + + + + + + + + + + + + + + +ID E开发模式 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + ID E开发模式 + + +
+ + + + + + +
+ + + +

+ 应用场景 + # +

+
    +
  • 如果您是一个资深的前端开发者
  • +
  • 可能不需要使用smartchart组件,仅需使用到数据集
  • +
  • 你希望在IDE(如VS code)中开发然后打包发布
  • +
  • 非专用人士,请不要尝试这种方式
  • +
+

+ 开发方式 + # +

+

在模板中使用basesimple + + 输入图片说明 +此时smartchart不会引用任何echarts, vue组件, 完全由您自已控制引入 , 你可以直接采用以下代码替换模板中的代码

+
{% extends "echart/basesimple.html" %}{% block head %}
+
+<!--head区域的引用或代码-->
+
+{% endblock %}{% block body %}
+
+<!--在此区间粘入body相关代码-->
+
+{% endblock %}{% block javascript %}
+
+<!--粘入js相关引用或代码-->
+
+{% endblock %}{% block footer %}{% endblock %}
+

+ 如何使用数据集接口 + # +

+

按照自由开发模式中, 新增一个图形, 然后修改数据集为通用且懒加载数据集 + + 输入图片说明 +修改对应图形编辑器, 使数据赋值给一个全局变量或vue + + + +

+

+ 在IDE中开发 + # +

+

由于你在开发中仅需要用到filter_param及ds_refresh, 建意新建一个js文件, 文件内容:

+
//下面定义全局变量, 发布时需放入smartchart模板的script标签中
+var mypublicdata1 = xxxx;
+.....
+
+//以下为辅助方法, 发布时, 无需放入smartchart模板中
+var filter_param = {};
+function ds_refresh(num){
+  if(num === 0){你对应的图形中赋值代码,调试代码}
+  if(num === 1){....}
+  ......
+}
+

然后将这个js文件在你的项目中引用调试使用

+

+ 如何部署到smartchart + # +

+

打包完成后会有相应的css, js 和index.html文件, 将index.html中的代码复制贴粘到对应的模板区域中即可

+
    +
  • 上传css,js
  • +
  • 修改css, js 相关引用路径
  • +
  • 去除之前定义的js辅助开发文件引用, 如果有定义全局变量, 将全局变量定义复制到模板js区域
  • +
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/9.进阶开发PRO/模板开发/index.html b/docs/smartchart/docs/9.进阶开发PRO/模板开发/index.html new file mode 100644 index 0000000..142f0d0 --- /dev/null +++ b/docs/smartchart/docs/9.进阶开发PRO/模板开发/index.html @@ -0,0 +1,1626 @@ + + + + + + + + + + + + +模板开发 | Smartchart开发手册 + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 模板开发 + + +
+ + + + + + +
+ + + +
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/9.进阶开发PRO/模板开发/index.xml b/docs/smartchart/docs/9.进阶开发PRO/模板开发/index.xml new file mode 100644 index 0000000..13a6353 --- /dev/null +++ b/docs/smartchart/docs/9.进阶开发PRO/模板开发/index.xml @@ -0,0 +1,102 @@ + + + + Smartchart开发手册 + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/ + Recent content on Smartchart开发手册 + Hugo -- gohugo.io + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91%E7%95%8C%E9%9D%A2/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91%E7%95%8C%E9%9D%A2/ + 低代码化开发 # smartchart的标准模板为了标准化的原因,对于引用JS,编写CSS等有一定不方便性, 但有时候你可能需要放飞自由, 随意定制 你甚至可能想引用一些其它的UI组件, 所以smartchart给你一个原汗原味的开发空间 +开启方式 # 在高级中,设定template为diy 主菜单中会多出来一个 模板 的功能 进入模板编辑界面 + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E5%BF%AB%E6%8D%B7%E5%BC%80%E5%8F%91/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E5%BF%AB%E6%8D%B7%E5%BC%80%E5%8F%91/ + 应用场景 # 专业化开发, 可将仪表盘显示和模板开发分屏开发 当你熟悉smartchart的基础开发后, 你可能会喜欢上现在这种方式 把你的可视化页面移动的显示器上吧, 进入&quot;模板&quot; 开发页面(上节介绍如何进入) +方式一: 自动化DIV # 此方式当你新增数据集图形时会自动识别, 无需手动在模板在添加 采用此方式请不要采用点击模板上方菜单的图形新增 如需编辑图形或数据集可按如下方式: 方式二: 自由DIV # 你可以模板中按照常规的H5页面编辑, 只是在需要插入图形的地方插入即可(建意通过模板上方的图形新增) 开始畅快的开发 +点击图形即可新增一个图形,你甚至可以指定图表的位置, 完全和写html一样, 使用{{div_list.图表顺序号}} warning 注意请尽量避免删除DIV, 如果你中途有删除过div, 序号会不一样, 你可以在&quot;布局&quot;中重排序保持一致, 保持数据集编号从0开始 +如果使用自由布局, 请删除自动化DIV这一段代码 选中生成的图形代码段, 点击菜单栏的 数据集, 图形, 布局开发, 即可进入开发界面, 如果没有数据集, 会自动帮你新建 可以观看视屏, 视屏比较老和现在不太一样, 仅参考即可 自由开发模式视屏 + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E4%B8%8A%E4%BC%A0%E8%B5%84%E6%BA%90%E6%96%87%E4%BB%B6/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E4%B8%8A%E4%BC%A0%E8%B5%84%E6%BA%90%E6%96%87%E4%BB%B6/ + 点击 模板开发 中的菜单即可上传你的资源文件, 如css, js, 图片等 视屏介绍说明 常规上传 # 可直接上传单个文件或zip包上传, 注意zip包中不可以有中文文件名 上传后会提示引用路径为/static/custom/仪表盘ID/&hellip; +上传为共享资源 # 可把资源打包为zip文件, 上传名以usr_开头, 如usr_tp.zip 上传完后不会有路径提示, 引用路径为/static/custom/usr_tp/&hellip;. +上传自定义数据源或jar包 # 上传后不会有路径提示 + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E8%BE%B9%E6%A1%86%E4%B8%8E%E8%A3%85%E9%A5%B0/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E8%BE%B9%E6%A1%86%E4%B8%8E%E8%A3%85%E9%A5%B0/ + 观看视屏 # 边框与装饰说明1 边框与背景说明2 +边框/装饰/背景(购买专业版提供使用方法) # + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E6%A0%B7%E5%BC%8F%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E6%A0%B7%E5%BC%8F%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B/ + 样式操作: # 要想大屏做得好, 样式要写得好 可是我们不是前端的同学也能写样式么 当然可以, 相信你观看完以下视屏即可 +快速上手样式开发 +基础样式入门: # CSS介绍 # CSS(Cascading Style Sheet,层叠样式表)定义如何显示HTML元素。 当浏览器读到一个样式表,它就会按照这个样式表来对文档进行格式化(渲染)。 +CSS语法 # CSS实例 每个CSS样式由两个组成部分:选择器和声明。声明又包括属性和属性值。每个声明之后用分号结束。 CSS注释 +/*这是注释*/ 注释是代码之母, smartchart编辑中你可以使用CTRL+/快捷注释 +CSS的几种引入方式 行内样式 行内式是在标记的style属性中设定CSS样式。不推荐大规模使用。 +&lt;p style=&#34;color: red&#34;&gt;Hello world.&lt;/p&gt; 内部样式 嵌入式是将CSS样式集中写在网页的标签对的标签对中。格式如下: +&lt;head&gt; &lt;style&gt; p{ background-color: #2b99ff; } &lt;/style&gt; &lt;/head&gt; 外部样式 外部样式就是将css写在一个单独的文件中 +&lt;link href=&#34;mystyle.css&#34; rel=&#34;stylesheet&#34; type=&#34;text/css&#34;/&gt; CSS选择器 # 基本选择器 +元素选择器 p {color: &#34;red&#34;;} ID选择器 #i1 { background-color: red; } 类选择器 .c1 { font-size: 14px; } p .c1 { color: red; } 注意: 样式类名不要用数字开头(有的浏览器不认)。 标签中的class属性如果有多个,要用空格分隔。 + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/IDE%E5%BC%80%E5%8F%91%E6%A8%A1%E5%BC%8F/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/IDE%E5%BC%80%E5%8F%91%E6%A8%A1%E5%BC%8F/ + 应用场景 # 如果您是一个资深的前端开发者 可能不需要使用smartchart组件,仅需使用到数据集 你希望在IDE(如VS code)中开发然后打包发布 非专用人士,请不要尝试这种方式 开发方式 # 在模板中使用basesimple 此时smartchart不会引用任何echarts, vue组件, 完全由您自已控制引入 , 你可以直接采用以下代码替换模板中的代码 +{% extends &#34;echart/basesimple.html&#34; %}{% block head %} &lt;!--head区域的引用或代码--&gt; {% endblock %}{% block body %} &lt;!--在此区间粘入body相关代码--&gt; {% endblock %}{% block javascript %} &lt;!--粘入js相关引用或代码--&gt; {% endblock %}{% block footer %}{% endblock %} 如何使用数据集接口 # 按照自由开发模式中, 新增一个图形, 然后修改数据集为通用且懒加载数据集 修改对应图形编辑器, 使数据赋值给一个全局变量或vue 在IDE中开发 # 由于你在开发中仅需要用到filter_param及ds_refresh, 建意新建一个js文件, 文件内容: +//下面定义全局变量, 发布时需放入smartchart模板的script标签中 var mypublicdata1 = xxxx; ..... //以下为辅助方法, 发布时, 无需放入smartchart模板中 var filter_param = {}; function ds_refresh(num){ if(num === 0){你对应的图形中赋值代码,调试代码} if(num === 1){. + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E5%8A%A8%E7%94%BB%E6%95%88%E6%9E%9C/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E5%8A%A8%E7%94%BB%E6%95%88%E6%9E%9C/ + 自动旋转效果 # 在&quot;模板&quot;的style中加入以下样式 +@-webkit-keyframes spin { from {-webkit-transform: rotate(0deg);} to {-webkit-transform: rotate(360deg);} } @keyframes spin { from {transform: rotate(0deg);} to {transform: rotate(360deg);} } .Rotate { -webkit-animation: spin 3s linear 3s 5 alternate; animation: spin 3s linear infinite; } 如需任意组件自动旋转, 只需将Rotate这个类给到这个组件即可, 比如图形 +&lt;img class=&#34;Rotate&#34; src=&#34;https://www.smartchart.cn/media/editor/smc162_20220407150432307320.png&#34;&gt; 组件变形 # 常见变形沿着Y轴, 其它变形方式自已搜索, 比如需要0号,1号图形变形的样式写法 +#container_0{transform:skewY(10deg);} #container_1{transform:skewY(-10deg);} 效果如下: + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E7%BC%96%E8%BE%91%E5%99%A8%E5%BF%AB%E6%8D%B7%E9%94%AE/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E7%BC%96%E8%BE%91%E5%99%A8%E5%BF%AB%E6%8D%B7%E9%94%AE/ + 功能 WIN MAC 说明 显示菜单 CTRL-, Command-, 折叠其它 Alt-0 Command-Option-0 查找替换 Ctrl-F Command-F 重复选中 Ctrl-D Command-D 5.6以前的版本是删除所选 注释选中 Ctrl-/ Command-/ 取消修改 Ctrl-z Command-z 重新执行 Ctrl-y Command-y 选中大写 Ctrl-U Ctrl-U 选中小写 SHIFT-Ctrl-U SHIFT-Ctrl-U + + + + diff --git a/docs/smartchart/docs/9.进阶开发PRO/模板开发/上传资源文件/index.html b/docs/smartchart/docs/9.进阶开发PRO/模板开发/上传资源文件/index.html new file mode 100644 index 0000000..60ecc9c --- /dev/null +++ b/docs/smartchart/docs/9.进阶开发PRO/模板开发/上传资源文件/index.html @@ -0,0 +1,1685 @@ + + + + + + + + + + + + + + +上传资源文件 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 上传资源文件 + + +
+ + + + + + +
+ + + +

点击 模板开发 中的菜单即可上传你的资源文件, 如css, js, 图片等 + + 视屏介绍说明 + + 输入图片说明

+

+ 常规上传 + # +

+

可直接上传单个文件或zip包上传, 注意zip包中不可以有中文文件名 +上传后会提示引用路径为/static/custom/仪表盘ID/…

+

+ 上传为共享资源 + # +

+

可把资源打包为zip文件, 上传名以usr_开头, 如usr_tp.zip +上传完后不会有路径提示, 引用路径为/static/custom/usr_tp/….

+

+ 上传自定义数据源或jar包 + # +

+

上传后不会有路径提示

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/9.进阶开发PRO/模板开发/动画效果/index.html b/docs/smartchart/docs/9.进阶开发PRO/模板开发/动画效果/index.html new file mode 100644 index 0000000..b655de6 --- /dev/null +++ b/docs/smartchart/docs/9.进阶开发PRO/模板开发/动画效果/index.html @@ -0,0 +1,1693 @@ + + + + + + + + + + + + + + +动画效果 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 动画效果 + + +
+ + + + + + +
+ + + +

+ 自动旋转效果 + # +

+

在"模板"的style中加入以下样式

+
@-webkit-keyframes spin {
+    from {-webkit-transform: rotate(0deg);}
+    to {-webkit-transform: rotate(360deg);}
+}
+@keyframes spin {
+    from {transform: rotate(0deg);}
+    to {transform: rotate(360deg);}
+}
+
+.Rotate {
+    -webkit-animation: spin 3s linear 3s 5 alternate;
+    animation: spin 3s linear infinite;
+}
+

如需任意组件自动旋转, 只需将Rotate这个类给到这个组件即可, 比如图形

+
<img class="Rotate" src="https://www.smartchart.cn/media/editor/smc162_20220407150432307320.png">
+

+ 组件变形 + # +

+

常见变形沿着Y轴, 其它变形方式自已搜索, 比如需要0号,1号图形变形的样式写法

+
#container_0{transform:skewY(10deg);}
+#container_1{transform:skewY(-10deg);}
+

效果如下: + + 输入图片说明

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/9.进阶开发PRO/模板开发/快捷开发/index.html b/docs/smartchart/docs/9.进阶开发PRO/模板开发/快捷开发/index.html new file mode 100644 index 0000000..24ffd10 --- /dev/null +++ b/docs/smartchart/docs/9.进阶开发PRO/模板开发/快捷开发/index.html @@ -0,0 +1,1712 @@ + + + + + + + + + + + + + + +快捷开发 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 快捷开发 + + +
+ + + + + + +
+ + + +

+ 应用场景 + # +

+
    +
  • 专业化开发, 可将仪表盘显示和模板开发分屏开发
  • +
  • 当你熟悉smartchart的基础开发后, 你可能会喜欢上现在这种方式
  • +
+

把你的可视化页面移动的显示器上吧, 进入"模板" 开发页面(上节介绍如何进入)

+

+ 方式一: 自动化DIV + # +

+

此方式当你新增数据集图形时会自动识别, 无需手动在模板在添加 +采用此方式请不要采用点击模板上方菜单的图形新增 +如需编辑图形或数据集可按如下方式: + + 输入图片说明 + + 输入图片说明

+

+ 方式二: 自由DIV + # +

+

你可以模板中按照常规的H5页面编辑, 只是在需要插入图形的地方插入即可(建意通过模板上方的图形新增) +开始畅快的开发

+
    +
  • 点击图形即可新增一个图形,你甚至可以指定图表的位置, 完全和写html一样, 使用{{div_list.图表顺序号}} + + 输入图片说明
  • +
+
+

warning +注意请尽量避免删除DIV, 如果你中途有删除过div, 序号会不一样, +你可以在"布局"中重排序保持一致, 保持数据集编号从0开始

+
+
+

如果使用自由布局, 请删除自动化DIV这一段代码 + + 输入图片说明

+
+
    +
  • 选中生成的图形代码段, 点击菜单栏的 数据集, 图形, 布局开发, 即可进入开发界面, 如果没有数据集, 会自动帮你新建
  • +
+

可以观看视屏, 视屏比较老和现在不太一样, 仅参考即可 + + 自由开发模式视屏

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/9.进阶开发PRO/模板开发/样式快速上手/index.html b/docs/smartchart/docs/9.进阶开发PRO/模板开发/样式快速上手/index.html new file mode 100644 index 0000000..09d9f29 --- /dev/null +++ b/docs/smartchart/docs/9.进阶开发PRO/模板开发/样式快速上手/index.html @@ -0,0 +1,2067 @@ + + + + + + + + + + + + + + +样式快速上手 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 样式快速上手 + + +
+ + + + + + +
+ + + +

+ 样式操作: + # +

+

要想大屏做得好, 样式要写得好 +可是我们不是前端的同学也能写样式么 +当然可以, 相信你观看完以下视屏即可

+

+ 快速上手样式开发

+

+ 基础样式入门: + # +

+

+ CSS介绍 + # +

+

CSS(Cascading Style Sheet,层叠样式表)定义如何显示HTML元素。 +当浏览器读到一个样式表,它就会按照这个样式表来对文档进行格式化(渲染)。

+

+ CSS语法 + # +

+

CSS实例 +每个CSS样式由两个组成部分:选择器和声明。声明又包括属性和属性值。每个声明之后用分号结束。 + + 输入图片说明 +CSS注释

+
/*这是注释*/
+

注释是代码之母, smartchart编辑中你可以使用CTRL+/快捷注释

+

CSS的几种引入方式 +行内样式 +行内式是在标记的style属性中设定CSS样式。不推荐大规模使用。

+
<p style="color: red">Hello world.</p>
+

内部样式 +嵌入式是将CSS样式集中写在网页的标签对的标签对中。格式如下:

+
<head>
+ <style>
+ p{
+ background-color: #2b99ff;
+ }
+ </style>
+</head>
+

外部样式 +外部样式就是将css写在一个单独的文件中

+
<link href="mystyle.css" rel="stylesheet" type="text/css"/>
+

+ CSS选择器 + # +

+

基本选择器

+
元素选择器
+p {color: "red";}
+
+ID选择器
+#i1 {
+ background-color: red;
+}
+
+类选择器
+.c1 {
+ font-size: 14px;
+}
+p .c1 {
+ color: red;
+}
+

注意: +样式类名不要用数字开头(有的浏览器不认)。 +标签中的class属性如果有多个,要用空格分隔。

+

通用选择器

+
* {
+ color: white;
+}
+

组合选择器

+
后代选择器
+/*li内部的a标签设置字体颜色*/
+li a {
+ color: green;
+}
+儿子选择器
+/*选择所有父级是 <div> 元素的 <p> 元素*/
+div>p {
+ font-family: "Arial Black", arial-black, cursive;
+}
+毗邻选择器
+/*选择所有紧接着<div>元素之后的<p>元素*/
+div+p {
+ margin: 5px;
+}
+弟弟选择器
+/*i1后面所有的兄弟p标签*/
+#i1~p {
+ border: 2px solid royalblue;
+}
+属性选择器
+/*用于选取带有指定属性的元素。*/
+p[title] {
+ color: red;
+}
+/*用于选取带有指定属性和值的元素。*/
+p[title="213"] {
+ color: green;
+}
+/*找到所有title属性以hello开头的元素*/
+[title^="hello"] {
+ color: red;
+}
+/*找到所有title属性以hello结尾的元素*/
+[title$="hello"] {
+ color: yellow;
+}
+/*找到所有title属性中包含(字符串包含)hello的元素*/
+[title*="hello"] {
+ color: red;
+}
+/*找到所有title属性(有多个值或值以空格分割)中有一个值为hello的元素:*/
+[title~="hello"] {
+ color: green;
+}
+

分组和嵌套

+
分组
+当多个元素的样式相同的时候,我们没有必要重复地为每个元素都设置样式,我们可以通过在多个选择器之间使用逗号分隔的分组选择器来统一设置元素样式。
+例如:
+div, p {
+ color: red;
+}
+上面的代码为div标签和p标签统一设置字体为红色。
+
+嵌套
+多种选择器可以混合起来使用,比如:.c1类内部所有p标签设置字体颜色为红色。
+.c1 p {
+ color: red;
+}
+

伪类选择器

+
/* 未访问的链接 */
+a:link {
+ color: #FF0000
+}
+/* 鼠标移动到链接上 */
+a:hover {
+ color: #FF00FF
+} 
+/* 选定的链接 */ 
+a:active {
+ color: #0000FF
+}
+/* 已访问的链接 */
+a:visited {
+ color: #00FF00
+} 
+/*input输入框获取焦点时样式*/
+input:focus {
+ outline: none;
+ background-color: #eee;
+}
+

伪元素选择器

+
first-letter
+常用的给首字母设置特殊样式:
+
+p:first-letter {
+ font-size: 48px;
+ color: red;
+}
+before
+
+/*在每个<p>元素之前插入内容*/
+p:before {
+ content:"*";
+ color:red;
+}
+after
+
+/*在每个<p>元素之后插入内容*/
+p:after {
+ content:"[?]";
+ color:blue;
+} 
+before和after多用于清除浮动。
+

+ 选择器的优先级 + # +

+
CSS继承
+继承是CSS的一个主要特征,它是依赖于祖先-后代的关系的。继承是一种机制,它允许样式不仅可以应用于某个特定的元素,还可以应用于它的后代。例如一个body定义了的字体颜色值也会应用到段落的文本中。
+body {
+ color: red;
+}
+此时页面上所有标签都会继承body的字体颜色。然而CSS继承性的权重是非常低的,是比普通元素的权重还要低的0。
+我们只要给对应的标签设置字体颜色就可覆盖掉它继承的样式。
+p {
+ color: green;
+}
+

选择器的优先级 +我们上面学了很多的选择器,也就是说在一个HTML页面中有很多种方式找到一个元素并且为其设置样式,那浏览器根据什么来决定应该应用哪个样式呢? +其实是按照不同选择器的权重来决定的,具体的选择器权重计算方式如下图: + + +除此之外还可以通过添加 !important方式来强制让样式生效,但并不推荐使用。 +因为如果过多的使用!important会使样式文件混乱不易维护。 +万不得已可以使用!important

+

+ CSS属性相关 + # +

+

宽和高

+
width属性可以为元素设置宽度。
+height属性可以为元素设置高度。
+块级标签才能设置宽度,内联标签的宽度由内容来决定。
+

字体属性

+
文字字体
+font-family可以把多个字体名称作为一个“回退”系统来保存。如果浏览器不支持第一个字体,则会尝试下一个。浏览器会使用它可识别的第一个值。
+简单实例:
+body {
+ font-family: "Microsoft Yahei", "微软雅黑", "Arial", sans-serif
+}
+字体大小
+p {
+ font-size: 14px;
+}
+如果设置成inherit表示继承父元素的字体大小值。
+
+字重(粗细)
+font-weight用来设置字体的字重(粗细)。
+值描述normal默认值,标准粗细bold粗体bolder更粗lighter更细100~900设置具体粗细,400等同于normal,而700等同于boldinherit继承父元素字体的粗细值
+
+文本颜色
+color
+颜色是通过CSS最经常的指定:
+十六进制值 - 如: #FF0000
+一个RGB值 - 如: RGB(255,0,0)
+颜色的名称 - 如: red
+还有rgba(255,0,0,0.3),第四个值为alpha, 指定了色彩的透明度/不透明度,它的范围为0.0到1.0之间。
+

文字属性

+
文字对齐
+text-align 属性规定元素中的文本的水平对齐方式。
+值描述left左边对齐 默认值right右对齐center居中对齐justify两端对齐
+
+文字装饰
+text-decoration 属性用来给文字添加特殊效果。
+值描述none默认。定义标准的文本。underline定义文本下的一条线。overline定义文本上的一条线。line-through定义穿过文本下的一条线。inherit继承父元素的text-decoration属性的值。
+
+常用的为去掉a标签默认的自划线:
+a {
+ text-decoration: none;
+}
+首行缩进
+将段落的第一行缩进 32像素:
+p {
+ text-indent: 32px;
+}
+

背景属性

+
/*背景颜色*/
+background-color: red;
+/*背景图片*/
+background-image: url('1.jpg');
+/*
+ 背景重复
+ repeat(默认):背景图片平铺排满整个网页
+ repeat-x:背景图片只在水平方向上平铺
+ repeat-y:背景图片只在垂直方向上平铺
+ no-repeat:背景图片不平铺
+*/
+background-repeat: no-repeat; 
+/*背景位置*/
+background-position: left top;
+/*background-position: 200px 200px;*/
+支持简写:
+background:#336699 url('1.png') no-repeat left top;
+使用背景图片的一个常见案例就是很多网站会把很多小图标放在一张图片上,然后根据位置去显示图片。减少频繁的图片请求。
+

边框

+
边框属性
+border-width
+border-style
+border-color
+#i1 {
+ border-width: 2px;
+ border-style: solid;
+ border-color: red;
+}
+通常使用简写方式:
+#i1 {
+ border: 2px solid red;
+}
+边框样式
+值描述none无边框。dotted点状虚线边框。dashed矩形虚线边框。solid实线边框。
+
+除了可以统一设置边框外还可以单独为某一个边框设置样式,如下所示:
+#i1 {
+ border-top-style:dotted;
+ border-top-color: red;
+ border-right-style:solid;
+ border-bottom-style:dotted;
+ border-left-style:none;
+}
+border-radius
+用这个属性能实现圆角边框的效果。
+将border-radius设置为长或高的一半即可得到一个圆形。
+

display属性

+
用于控制HTML元素的显示效果。
+值意义display:"none"HTML文档中元素存在,但是在浏览器中不显示。一般用于配合JavaScript代码使用。display:"block"默认占满整个页面宽度,如果设置了指定宽度,则会用margin填充剩下的部分。display:"inline"按行内元素显示,此时再设置元素的width、height、margin-top、margin-bottom和float属性都不会有什么影响。display:"inline-block"使元素同时具有行内元素和块级元素的特点。
+display:"none"与visibility:hidden的区别:
+visibility:hidden: 可以隐藏某个元素,但隐藏的元素仍需占用与未隐藏之前一样的空间。也就是说,该元素虽然被隐藏了,但仍然会影响布局。
+display:none: 可以隐藏某个元素,且隐藏的元素不会占用任何空间。也就是说,该元素不但被隐藏了,而且该元素原本占用的空间也会从页面布局中消失。
+

CSS盒子模型

+
margin: 用于控制元素与元素之间的距离;margin的最基本用途就是控制元素周围空间的间隔,从视觉角度上达到相互隔开的目的。
+padding: 用于控制内容与边框之间的距离;
+Border(边框): 围绕在内边距和内容外的边框。
+Content(内容): 盒子的内容,显示文本和图像。
+

+ 输入图片说明

+
margin外边距
+.margin-test {
+ margin-top:5px;
+ margin-right:10px;
+ margin-bottom:15px;
+ margin-left:20px;
+}
+推荐使用简写:
+.margin-test {
+ margin: 5px 10px 15px 20px;
+}
+顺序:上右下左
+
+常见居中:
+.mycenter {
+ margin: 0 auto;
+}
+padding内填充
+.padding-test {
+ padding-top: 5px;
+ padding-right: 10px;
+ padding-bottom: 15px;
+ padding-left: 20px;
+}
+推荐使用简写:
+.padding-test {
+ padding: 5px 10px 15px 20px;
+}
+顺序:上右下左
+
+补充padding的常用简写方式:
+提供一个,用于四边;
+提供两个,第一个用于上-下,第二个用于左-右;
+如果提供三个,第一个用于上,第二个用于左-右,第三个用于下;
+提供四个参数值,将按上-右-下-左的顺序作用于四边;
+

float

+
在 CSS 中,任何元素都可以浮动。
+浮动元素会生成一个块级框,而不论它本身是何种元素。
+关于浮动的两个特点:
+浮动的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止。
+由于浮动框不在文档的普通流中,所以文档的普通流中的块框表现得就像浮动框不存在一样。
+三种取值
+left:向左浮动
+right:向右浮动
+none:默认值,不浮动
+

overflow溢出属性

+
值描述visible默认值。内容不会被修剪,会呈现在元素框之外。hidden内容会被修剪,并且其余内容是不可见的。scroll内容会被修剪,但是浏览器会显示滚动条以便查看其余的内容。auto如果内容被修剪,则浏览器会显示滚动条以便查看其余的内容。inherit规定应该从父元素继承 overflow 属性的值。
+overflow(水平和垂直均设置)
+overflow-x(设置水平方向)
+overflow-y(设置垂直方向)
+

定位(position)

+
static
+static 默认值,无定位,不能当作绝对定位的参照物,并且设置标签对象的left、top等值是不起作用的的。
+relative(相对定位)
+相对定位是相对于该元素在文档流中的原始位置,即以自己原始位置为参照物。有趣的是,即使设定了元素的相对定位以及偏移值,元素还占有着原来的位置,即占据文档流空间。对象遵循正常文档流,但将依据top,right,bottom,left等属性在正常文档流中偏移位置。而其层叠通过z-index属性定义。
+注意:position:relative的一个主要用法:方便绝对定位元素找到参照物。
+absolute(绝对定位)
+定义:设置为绝对定位的元素框从文档流完全删除,并相对于最近的已定位祖先元素定位,如果元素没有已定位的祖先元素,那么它的位置相对于最初的包含块(即body元素)。元素原先在正常文档流中所占的空间会关闭,就好像该元素原来不存在一样。元素定位后生成一个块级框,而不论原来它在正常流中生成何种类型的框。
+重点:如果父级设置了position属性,例如position:relative;,那么子元素就会以父级的左上角为原始点进行定位。这样能很好的解决自适应网站的标签偏离问题,即父级为自适应的,那我子元素就设置position:absolute;父元素设置position:relative;,然后Top、Right、Bottom、Left用百分比宽度表示。
+另外,对象脱离正常文档流,使用top,right,bottom,left等属性进行绝对定位。而其层叠通过z-index属性定义。
+fixed(固定)
+fixed:对象脱离正常文档流,使用top,right,bottom,left等属性以窗口为参考点进行定位,当出现滚动条时,对象不会随着滚动。而其层叠通过z-index属性 定义。 注意点: 一个元素若设置了 position:absolute | fixed; 则该元素就不能设置float。这 是一个常识性的知识点,因为这是两个不同的流,一个是浮动流,另一个是“定位流”。但是 relative 却可以。因为它原本所占的空间仍然占据文档流。
+在理论上,被设置为fixed的元素会被定位于浏览器窗口的一个指定坐标,不论窗口是否滚动,它都会固定在这个位置。
+

z-index

+
#i2 {
+ z-index: 999;
+}
+设置对象的层叠顺序。
+z-index 值表示谁压着谁,数值大的压盖住数值小的,
+只有定位了的元素,才能有z-index,也就是说,不管相对定位,绝对定位,固定定位,都可以使用z-index,而浮动元素不能使用z-index
+z-index值没有单位,就是一个正整数,默认的z-index值为0如果大家都没有z-index值,或者z-index值一样,那么谁写在HTML后面,谁在上面压着别人,定位了元素,永远压住没有定位的元素。
+从父现象:父亲怂了,儿子再牛逼也没用
+

opacity +用来定义透明效果。取值范围是0~1,0是完全透明,1是完全不透明。

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/9.进阶开发PRO/模板开发/模板开发界面/index.html b/docs/smartchart/docs/9.进阶开发PRO/模板开发/模板开发界面/index.html new file mode 100644 index 0000000..95117bf --- /dev/null +++ b/docs/smartchart/docs/9.进阶开发PRO/模板开发/模板开发界面/index.html @@ -0,0 +1,1678 @@ + + + + + + + + + + + + + + +模板开发界面 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 模板开发界面 + + +
+ + + + + + +
+ + + +

+ 低代码化开发 + # +

+

smartchart的标准模板为了标准化的原因,对于引用JS,编写CSS等有一定不方便性, 但有时候你可能需要放飞自由, 随意定制 +你甚至可能想引用一些其它的UI组件, 所以smartchart给你一个原汗原味的开发空间

+

+ 开启方式 + # +

+

在高级中,设定template为diy + + 输入图片说明 +主菜单中会多出来一个 模板 的功能 + + 输入图片说明 +进入模板编辑界面 + + 输入图片说明

+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/9.进阶开发PRO/模板开发/编辑器快捷键/index.html b/docs/smartchart/docs/9.进阶开发PRO/模板开发/编辑器快捷键/index.html new file mode 100644 index 0000000..27d436d --- /dev/null +++ b/docs/smartchart/docs/9.进阶开发PRO/模板开发/编辑器快捷键/index.html @@ -0,0 +1,1697 @@ + + + + + + + + + + + + + + +编辑器快捷键 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 编辑器快捷键 + + +
+ + + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
功能WINMAC说明
显示菜单CTRL-,Command-,
折叠其它Alt-0Command-Option-0
查找替换Ctrl-FCommand-F
重复选中Ctrl-DCommand-D5.6以前的版本是删除所选
注释选中Ctrl-/Command-/
取消修改Ctrl-zCommand-z
重新执行Ctrl-yCommand-y
选中大写Ctrl-UCtrl-U
选中小写SHIFT-Ctrl-USHIFT-Ctrl-U
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/9.进阶开发PRO/模板开发/边框与装饰/index.html b/docs/smartchart/docs/9.进阶开发PRO/模板开发/边框与装饰/index.html new file mode 100644 index 0000000..1afea45 --- /dev/null +++ b/docs/smartchart/docs/9.进阶开发PRO/模板开发/边框与装饰/index.html @@ -0,0 +1,1687 @@ + + + + + + + + + + + + + + +边框与装饰 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 边框与装饰 + + +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/index.html b/docs/smartchart/docs/index.html new file mode 100644 index 0000000..e24d184 --- /dev/null +++ b/docs/smartchart/docs/index.html @@ -0,0 +1,1619 @@ + + + + + + + + + + + + +Docs | Smartchart开发手册 + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Docs + + +
+ + + + + + +
+ + + +
+ + + +
+ +
+ + + + + +
+ + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/docs/index.xml b/docs/smartchart/docs/index.xml new file mode 100644 index 0000000..d4f1875 --- /dev/null +++ b/docs/smartchart/docs/index.xml @@ -0,0 +1,21 @@ + + + + Docs on Smartchart开发手册 + https://smartchart.gitee.io/docs/ + Recent content in Docs on Smartchart开发手册 + Hugo -- gohugo.io + + + https://smartchart.gitee.io/docs/%E5%85%B3%E4%BA%8E%E6%88%91%E4%BB%AC/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/%E5%85%B3%E4%BA%8E%E6%88%91%E4%BB%AC/ + 我们的目标 # 打造全生态的数据应用数据管理的平台,解决中小企业上中台难,上中台贵,见效慢的问题. 平台与时俱进,不断完善与优化中 可以通过视屏了解我们的架构设计 企业数字化与smartchart的一站式解决方案 +我们不提供数据存储与计算引擎, ETL工具, BI工具. 因为已有更优秀的产品,我们只为数据开发人员提供更敏捷的工具与平台,致力于数据服务中台建设,边缘可视化与数据管道产品, 站在巨人的肩上, 让数据更有个性,更灵活与可定制化,由于他的通用性,功能的扩展变得也是非常的Smart +产品定位: # 实现全生态的数据服务平台(数据收集, 数据加工, 数据分享,数据管理,数据应用) +产品模块: # 统一的数据处理调度平台、数据管道, 是基于Apache顶级项目Airflow上的二次开发产品,让数据处理的任务调度开发与管理微代码化,我们的设计理念是让开发者更方便的同时,不丧失灵活和高度可自定义,如果你使用过smartchat,你可以想象他会带来的便捷性, 产品名为smartpip, 为啥不叫smartpipe, 因为能省我们就要省&hellip; 统一的可视化管理平台, 为微信等第三方应用, 提供powerbi,tableau,finebi&hellip;的嵌入式及功能扩展服务,数据集即服务,一切为数据集 统一的数据上传平台, 实现线下数据的收集需求, 并提供专业的手工上传数据产品, 支持excel本地(安装与免安装版本), 支持WEB端 统一的数据分享平台与smartchart集成,可做为数据服务中台, 实现业务对数据下载的需要及为第三方提供获取数据的API接口 SmartChart可视化平台, 新一代的数据可视化产品, 解决传统BI各种痛点问题,真正面向开发人员的平台产品 元数据管理平台及数据治理,让数据的来源更清晰, 让数据应用更方便,具备自动化,可视化的数据血缘分析 新一代极速数据仓库技术, 极简架构即可实现在大数据应用的全场景需求 + + + + diff --git a/docs/smartchart/docs/关于我们/index.html b/docs/smartchart/docs/关于我们/index.html new file mode 100644 index 0000000..6414a7d --- /dev/null +++ b/docs/smartchart/docs/关于我们/index.html @@ -0,0 +1,1693 @@ + + + + + + + + + + + + + + +关于我们 | Smartchart开发手册 + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + 关于我们 + + +
+ + + + + + +
+ + + +

+ 我们的目标 + # +

+

打造全生态的数据应用数据管理的平台,解决中小企业上中台难,上中台贵,见效慢的问题. 平台与时俱进,不断完善与优化中 +可以通过视屏了解我们的架构设计 + 企业数字化与smartchart的一站式解决方案

+
+

我们不提供数据存储与计算引擎, ETL工具, BI工具. 因为已有更优秀的产品,我们只为数据开发人员提供更敏捷的工具与平台,致力于数据服务中台建设,边缘可视化与数据管道产品, 站在巨人的肩上, 让数据更有个性,更灵活与可定制化,由于他的通用性,功能的扩展变得也是非常的Smart

+

+ 产品定位: + # +

+

实现全生态的数据服务平台(数据收集, 数据加工, 数据分享,数据管理,数据应用)

+

+ 产品模块: + # +

+
    +
  • 统一的数据处理调度平台、数据管道, 是基于Apache顶级项目Airflow上的二次开发产品,让数据处理的任务调度开发与管理微代码化,我们的设计理念是让开发者更方便的同时,不丧失灵活和高度可自定义,如果你使用过smartchat,你可以想象他会带来的便捷性, 产品名为smartpip, 为啥不叫smartpipe, 因为能省我们就要省…
  • +
  • 统一的可视化管理平台, 为微信等第三方应用, 提供powerbi,tableau,finebi…的嵌入式及功能扩展服务,数据集即服务,一切为数据集
  • +
  • 统一的数据上传平台, 实现线下数据的收集需求, 并提供专业的手工上传数据产品, 支持excel本地(安装与免安装版本), 支持WEB端
  • +
  • 统一的数据分享平台与smartchart集成,可做为数据服务中台, 实现业务对数据下载的需要及为第三方提供获取数据的API接口
  • +
  • + SmartChart可视化平台, 新一代的数据可视化产品, 解决传统BI各种痛点问题,真正面向开发人员的平台产品
  • +
  • 元数据管理平台及数据治理,让数据的来源更清晰, 让数据应用更方便,具备自动化,可视化的数据血缘分析
  • +
  • 新一代极速数据仓库技术, 极简架构即可实现在大数据应用的全场景需求
  • +
+
+ + + +
+ +
+ + + + +
+ + Edit + Edit this page + +
+ + +
+ + + + + + + + +
+ + + +
+ +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/docs/smartchart/en.search-data.min.6325b92e2578ce162c49b50e5d0f669259962aac89a889a8a051ca34a48fe31d.json b/docs/smartchart/en.search-data.min.6325b92e2578ce162c49b50e5d0f669259962aac89a889a8a051ca34a48fe31d.json new file mode 100644 index 0000000..8d0a52a --- /dev/null +++ b/docs/smartchart/en.search-data.min.6325b92e2578ce162c49b50e5d0f669259962aac89a889a8a051ca34a48fe31d.json @@ -0,0 +1 @@ +[{"id":0,"href":"/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/VUE%E7%9B%B8%E5%85%B3/%E4%BD%BF%E7%94%A8VUE/","title":"使用 Vue","section":"Vue相关","content":" 使用场景 # 报表中涉及交互场景较多, 需要数据与页面绑定 开发者熟悉vue 常见绑定 # //显示变量message \u0026lt;p\u0026gt;{[ message ]}\u0026lt;/p\u0026gt; //循环产生li,变量sites \u0026lt;ol\u0026gt; \u0026lt;li v-for=\u0026#34;site in sites\u0026#34;\u0026gt; {[ site.name ]} \u0026lt;/li\u0026gt; \u0026lt;/ol\u0026gt; //绑定输入值变量use \u0026lt;input type=\u0026#34;checkbox\u0026#34; v-model=\u0026#34;use\u0026#34;\u0026gt; //显示控制 \u0026lt;p v-if=\u0026#34;seen\u0026#34;\u0026gt;现在你看到我了\u0026lt;/p\u0026gt; \u0026lt;p v-show=\u0026#34;seen\u0026#34;\u0026gt;现在你看到我了\u0026lt;/p\u0026gt; //绑定属性 \u0026lt;a :href=\u0026#34;url\u0026#34;\u0026gt;\u0026lt;/a\u0026gt; \u0026lt;div :style=\u0026#34;{ color: activeColor, fontSize: fontSize + \u0026#39;px\u0026#39; }\u0026#34;\u0026gt;\u0026lt;/div\u0026gt; \u0026lt;div :class=\u0026#34;[errorClass ,isActive ? activeClass : \u0026#39;\u0026#39;]\u0026#34;\u0026gt;\u0026lt;/div\u0026gt; //绑定点击方法 \u0026lt;a @click=\u0026#34;doSomething\u0026#34;\u0026gt;\u0026lt;/a\u0026gt; 开启VUE # 需要在高级中加入“dv”:2,即可开启vue模式 你可以在图形编辑器中给vue的变量赋值,我们内置了17个变量,从d0, d1\u0026hellip; d16 赋值方式 vapp.d0 = xxxx 你可以将d0赋值为字典, 如: vapp.d0 = { \u0026lsquo;index1\u0026rsquo;: 100, \u0026lsquo;index2\u0026rsquo;: 300}\n注意,我们修改了vue的默认引用方式, 你需要采用如下方法引用: {[d0.index1]}\n使用模板可以更方便使用VUE # 你也可以在 模板开发中 使用VUE 开启方法, 首先你需要在高级设定中 , 设定 \u0026ldquo;template\u0026rdquo;:\u0026ldquo;diy\u0026rdquo;, 然后你可以看到 模板 的菜单, 进入编辑器\n如果你需要更多自定义的方法, 例如加入方法, 你可以在模板的script中加入自定义代码\n\u0026lt;script\u0026gt; var vapp = new Vue({el: \u0026#39;#vue_app\u0026#39;, delimiters: [\u0026#39;{[\u0026#39;, \u0026#39;]}\u0026#39;], data: { tableData:\u0026#39;\u0026#39; }, methods: { formatter(row, column) { return row.address; } } }); \u0026lt;/script\u0026gt; "},{"id":1,"href":"/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E4%B8%8D%E5%A4%AA%E9%87%8D%E8%A6%81/%E4%B8%BB%E9%A2%98%E5%BA%94%E7%94%A8PRO/","title":"主题应用 Pro","section":"不太重要","content":"点击smartchart图标,切换到菜单固定模式, 你可看到主题的选择 "},{"id":2,"href":"/docs/11.%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97/Linux/%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B/","title":"快速开始","section":"Linux","content":" 涉及的基础环境和版本: # * Centos 7 * Python 3.9 /data/smartchart/ 项目主目录 /data/smartchart/tools 项目相关软件 下述内容中,凡是涉及到/data/smartchart路径的,都可以将其修改为你自己系统上的路径。 安装环境 # 安装Python # cd /data/smartchart/tools yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel libffi-devel 下载https://npm.taobao.org/mirrors/python/3.9.0/ 上传服务器,放入安装目录解压 或者 Wget https://npm.taobao.org/mirrors/python/3.9.0/Python-3.9.0.tgz tar -zxvf Python-3.9.0.tgz 进行源码目录 配置安装路径 ./Python-3.9.0/configure --prefix=/data/smartchart/tools/python3 编译安装 make \u0026amp;\u0026amp; make install 建立软链接 ln -s /data/smartchart/tools/python3/bin/python3.9 /usr/bin/python3 ln -s /data/smartchart/tools/python3/bin/pip3.9 /usr/bin/pip3 测试是否安装成功 python3 --version 建立python虚拟环境 # python3 -m venv myvenv cd myvenv source bin/activate 在虚拟环境中安装smartchart # pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple smartchart -U 启动smartchart(测试部署), 企业部署方式可有尝咨询 # smartchart runserver 0.0.0.0:8000 --insecure --noreload "},{"id":3,"href":"/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/EXCEL%E6%95%B0%E6%8D%AE/%E4%BB%8EEXCEL%E7%B2%98%E8%B4%B4%E6%95%B0%E6%8D%AE/","title":"从 Excel粘贴数据","section":"Excel数据","content":" 固定数据集 # 有一些场景, 比如已有一些固定的筛选器,或是需要测试用,或者Demo,或者其它图形需要用到一些共用的已确定好的数据 这样我们可以不需要通过查询数据库的方式, 而直接写入数据集, 支持数组和字典的格式 你只需要在数据集中起始写入 dataset= , 这样就是默认是固定数据\n如何快速的输入固定数据集, 你可以通过直接从EXCEL复制到数据集编辑器(以下图片非目前编辑器, 供参考),保存以后会自动生成: 固定数据集也支持之前提到传参数, 魔术方法, 缓存等所有数据集的功能 "},{"id":4,"href":"/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E6%95%B0%E6%8D%AE%E9%9B%86%E5%BC%80%E5%8F%91%E7%95%8C%E9%9D%A2/","title":"数据集开发界面","section":"2.数据集说明","content":"开发前建意先观看视屏, 了解基础说明, 视屏有点老和现在界面不一样, 目前很多功能已经做成可视化配置, 理解过程即可, 具体以文档为准\nSmartchart数据集与图形 从仪表盘界面中进入简易开发界面 # "},{"id":5,"href":"/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/API%E6%95%B0%E6%8D%AE%E9%9B%86/","title":"Api数据集","section":"特殊数据源","content":"对接外部API取数, 注意返回一定要是JSON格式 你只需要在数据集编辑框中如下输入\n-- GET 方法: dataset= { \u0026#34;url\u0026#34;:\u0026#34;https://www.smartchart.cn/smartdata/api/?i=loaddataset1\u0026amp;j=1\u0026#34; } -- POST 方法: dataset= { \u0026#34;url\u0026#34;:\u0026#34;https://www.smartchart.cn/smartdata/api\u0026#34;, \u0026#34;method\u0026#34;:\u0026#34;POST\u0026#34;, \u0026#34;data\u0026#34;:{\u0026#34;i\u0026#34;:\u0026#34;loaddataset1\u0026#34;, \u0026#34;j\u0026#34;:\u0026#34;1\u0026#34;} ... } 例如你可以传入参数做出联动效果\ndataset= { \u0026#34;url\u0026#34;:\u0026#34;https://www.smartchart.cn/smartdata/api\u0026#34;, \u0026#34;method\u0026#34;:\u0026#34;POST\u0026#34;, \u0026#34;data\u0026#34;:{\u0026#34;i\u0026#34;:\u0026#34;loaddataset1\u0026#34;, \u0026#34;j\u0026#34;:\u0026#34;/*$参数名*/\u0026#34;} ... } 你也可以增加header等认证方式\ndataset= { \u0026#34;url\u0026#34;:\u0026#34;https://www.smartchart.cn/smartdata/api\u0026#34;, \u0026#34;method\u0026#34;:\u0026#34;GET\u0026#34;, \u0026#34;headers\u0026#34;:{\u0026#34;Cookie\u0026#34;:\u0026#34;xxxxxxx\u0026#34;} ... } "},{"id":6,"href":"/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E5%87%BD%E6%95%B0%E6%96%B9%E6%B3%95/%E5%9B%BE%E5%BD%A2%E7%AB%AF%E6%95%B0%E6%8D%AE%E5%87%BD%E6%95%B0/","title":"图形端数据函数","section":"函数方法","content":" 应用场景 # 在图形开发中,我们可能需要使用js对传递过来的数据进行处理\n原始数据格式 # 假设dataset的格式是, SQL = Select 维度1,维度2,数据 from xxxx, 生成的数据集如下\ndataset = [[\u0026#39;category\u0026#39;,\u0026#39;C1\u0026#39;,\u0026#39;C2\u0026#39;], [\u0026#39;R1\u0026#39;, 12, 18], [\u0026#39;R2\u0026#39;, 10, 17] ] 转化函数 # 生成字典表示为key-\u0026gt;[], 常用于定制化高的图形 # result = ds_createMap(dataset) 结果 = {\u0026#34;category\u0026#34;:[\u0026#39;C1\u0026#39;,\u0026#39;C2\u0026#39;], \u0026#34;R1\u0026#34; : [12, 10], \u0026#34;R2\u0026#34; : [18, 17]} 生成非常多前端组件要求的格式 # result = ds_createMap_all(dataset) 结果 = [{\u0026#34;category\u0026#34;:\u0026#34;R1\u0026#34;, \u0026#34;C1\u0026#34;: 12, \u0026#34;C2\u0026#34;: 18}, {\u0026#34;category\u0026#34;:\u0026#34;R2\u0026#34;, \u0026#34;C1\u0026#34;: 10, \u0026#34;C2\u0026#34;: 17}] 获取列名list, 用于获取系列名 # result = ds_rowname(dataset) 结果 = [\u0026#39;R1\u0026#39;,\u0026#39;R2\u0026#39;] 将数据集行列转化, 一般用于坐标轴翻转 # result = ds_transform(dataset) 结果 = [[\u0026#39;category\u0026#39;,\u0026#39;R1\u0026#39;,\u0026#39;R2\u0026#39;], [\u0026#39;C1\u0026#39;, 12, 10], [\u0026#39;C2\u0026#39;, 18, 17]] 两个数据集左关联, 常用于将两段查询数据合并 # 假设需要关联的数据集格式: dataset2 = [[\u0026#39;category\u0026#39;,\u0026#39;C3\u0026#39;], [\u0026#39;R1\u0026#39;, 38], [\u0026#39;R6\u0026#39;, 13]] 处理后的结果: result = ds_leftjoin(dataset, dataset2) 结果 = [[\u0026#39;category\u0026#39;,\u0026#39;C1\u0026#39;,\u0026#39;C2\u0026#39;,\u0026#39;C3\u0026#39;], [\u0026#39;R1\u0026#39;, 12, 18, 38], [\u0026#39;R2\u0026#39;, 10, 17, 0] ] 数据集旋转,在excel中叫透视表 # 比如需要将dataset3的户型变成指标 dataset3 = [[\u0026#39;城市\u0026#39;,\u0026#39;户型\u0026#39;,\u0026#39;数量\u0026#39;], [\u0026#39;长沙\u0026#39;,\u0026#39;A\u0026#39;,35], [\u0026#39;上海\u0026#39;,\u0026#39;B\u0026#39;,19]] 处理后的结果: result = ds_pivot(dataset3) 结果 = [[\u0026#34;城市\u0026#34;,\u0026#34;A\u0026#34;,\u0026#34;B\u0026#34;], [\u0026#34;长沙\u0026#34;,35,0], [\u0026#34;上海\u0026#34;,0,19]] 移除数据集中的某几列 # 比如移除第1列(序号0) result=ds_remove_column(dataset,remove_list=[0]) 结果 = [[\u0026#39;R1\u0026#39;,\u0026#39;R2\u0026#39;], [12, 10], [18, 17] ] smartchart图形中可用的转化函数 # 函数名 函数说明 样列 ds_transform(dataset) 行列替换 ds_split(data,sep=\u0026rsquo;,\u0026rsquo;,head_add=[]) 将第一列拆分成多个字段,默认逗号分隔, 如果不传表头,取SQL中的字段名拆分 ds_createMap(data) data表示传入的二位数组,生成结果表示为key-\u0026gt;[], 常用于echarts指定数据 ds_createMap_all(data) data表示传入的二维数组,生成结果表示为[{A:A1,B:B1,C:C1},{A:A2,B:B2,C:C2}\u0026hellip;] ds_mapToList(data) 将createMap_all的格式还原成二维数组, 常用于将nosql(mongodb,es..)数据源数据处理 ds_fontSize(rem) 基于分辨率自动转字体大小, 参数rem ds_rowname(dataset,start_row=1,column=0) 获取指定列的数据, 默认取第一列从第二行(序号1)开始的数据,常用于获取维度 ds_remove_column(dataset,remove_list=[0]) 默认移除第一列, 也要移除指定的多个列 ds_toThousands(num) 转逗号分隔的千分位 ds_distinct(a, b=[]) 对单个或多个二维数组去重 ds_leftjoin(a,b,withhead=true,type=1) 两个数组join [[1,2,3,4],[2,3,4,5]] ,[[2,3,4]], 如果带头,合并头 ds_crossjoin(a,b,withhead=true) ds_fulljoin(a,b,withhead=true) ds_union(a,b,withhead=true) 合并两个数据集, 可选是否带头, 取第一个数据集的头, 去除第二个头 ds_pivot(arr) 传入一下二维数组(维度, 维度, 值), 进行透视 ds_sort(arr, index=0, asc=true) 指定二维数组列序号排序,默认升序,index参数也可以是函数,如(a,b)=\u0026gt;{return a.qty - b.qty} getUndefined(param,defaultValue) 获取value值,如果为空,null,undefined给默认值 ds_round(num,qty=2) 小数点处理, 默认保留两位小数 ds_param(name) 传入参数名,获取图形点击时传递来的参数值 ds_setParam(\u0026lsquo;参数名\u0026rsquo;, 参数值) 设定全局参数, 此方法将自动判断当参数值为空时, 删除参数回到初始未传参状态 ds_refresh(id, param=filter_param) 刷新图形, id为图形序号,默认采取全局参数刷新,也可指定param,参数为字典{\u0026ldquo;参数名\u0026rdquo;:\u0026ldquo;值\u0026rdquo;,\u0026hellip;} 多维度的数据透视 # 常规数据集中提到 A类数据源的情况, 格式都是: 维度A 维度B 数据 但还有情况比如你有一个数据格式是: 维度A 维度B 维度C 数据 你需要在表格中将 A,B维度做维度, 但C做透视为指标名进行展示 由于我们的数据透视只支持\u0026#34;字符, 字符, 数值\u0026#34;的SQL写法, 所以如果要多维, 我们需要做下转变, 可以写成: select concat_ws(\u0026#39;,\u0026#39;,维度A,维度B) AS 维度,维度C,SUM(数据) AS 度量 from tablename group by 维度, 维度C 得到的数据样式 dataset=[[\u0026#39;维度\u0026#39;,\u0026#39;C1\u0026#39;,\u0026#39;C2\u0026#39;....] ,[\u0026#39;A1,B1\u0026#39;,1,1...] ,[\u0026#39;A2,B2\u0026#39;,2,2...]] 最终在图形数据集处理中, 我们可以使用如下函数进行转化: dataset = ds_split(dataset,\u0026#39;,\u0026#39;,[\u0026#39;维度A\u0026#39;,\u0026#39;维度B\u0026#39;]) \u0026#39;,\u0026#39; : 参数为分隔符 [\u0026#39;维度A\u0026#39;,\u0026#39;维度B\u0026#39;] : 指第一个字段需要拆分的表头名称 最终得到的数据就是多维度透视 [[\u0026#39;维度A\u0026#39;,\u0026#39;维度B\u0026#39;,\u0026#39;C1\u0026#39;,\u0026#39;C2\u0026#39;....] ,[\u0026#39;A1\u0026#39;,\u0026#39;B1\u0026#39;,1,1...] ,[\u0026#39;A2\u0026#39;,\u0026#39;B2\u0026#39;,2,2...]] 常用JS原生函数 # //数组追加 dataset.push(item) //数组前方插入 dataset.unshit(item) //切片 dataset = dataset.slice(1) 从序号1个开始到最最后一个 dataset = dataset.slice(5, 10) 从第序号5开始截取到第10个 dataset = dataset.slice(-3) 截取最后三个元素 //循环遍历 for最快,但可读性比较差(smartchart推荐) forEach比较快,能够控制内容 for...in比较慢,不方便 for(let i=0; i\u0026lt;dataset.length; i++){ } "},{"id":7,"href":"/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E5%9F%BA%E7%A1%80%E5%9B%BE%E5%BD%A2/","title":"基础图形","section":"3.图形开发","content":" 快速应用基础图形组件 # 你可使用如下方式选择常规的图形一键进行应用(我们只放了基础图形,因为你可以通过简单修改配置转化为各种图形,如线性面积图, 柱形堆叠图..) 你也可以在图形商店中找到更多已转化好的Smartchart图形 配置项完全和Echarts原生一样\n注意: 对于一些特殊图形如地图js在图形编辑中需要进行动态加载, 如果你使用了非常规图形, 你可在图形编辑器使用ds_loadjs(\u0026lsquo;smt_china’)加载中国地图, 同理我们有 \u0026lsquo;smt_wordcloud\u0026rsquo;, \u0026lsquo;smt_world\u0026rsquo;, \u0026lsquo;smt_ecStat\u0026rsquo;, ‘smt_liquidfill’ 有些图形可能同时需要在模板中加载, 更多特殊图形加载说明参考 特殊图形模板加载\n"},{"id":8,"href":"/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E5%B8%83%E5%B1%80%E6%8C%87%E5%BC%95/","title":"布局指引","section":"4.布局说明","content":" 整理一份完整的SmartChart布局说明 # 推荐先观看视屏了解 smartchart布局方式\n容器说明 # 容器 说明 定位容器 用于图形定位, 有拖拽和栅格两种. 在界面上新增时会自带;在模板编辑中新增图形时需自行加入容器 图形容器 用于图形选择, 使用id选择器, 如序号为2的容器, 选择器为#container_2 图形 可视化的实际单位, 如选择图形中的table标签, 可使用#container_2 table 响应式布局 # 一般移动端报表推荐使用响应式布局, 一次布局可以同时满足电脑端/移动端的需求 当你新增一个数据集时, smartchart会给你一段默认的代码\n\u0026lt;div class=\u0026#34;el-col-xs-24 el-col-md-24\u0026#34; style=\u0026#34;padding:0.2rem;height:50%;\u0026#34; \u0026gt; \u0026lt;div style=\u0026#34;height:100%;\u0026#34; id=\u0026#34;container_{name}\u0026#34;\u0026gt;\u0026lt;/div\u0026gt; \u0026lt;/div\u0026gt; el-col-md-24 : 电脑端宽度设定 控制图形父容器的宽度, 整行分成24个栅格, 如果你想让图形占一半, 就可以改成el-col-md-12 el-col-xs-24 :移动端宽度设定 padding:0.5% 0.5%: 控制图形的上下, 左右内边距, padding: 上 右 下 左 比如你想要图形在容器中往下走一点, 你可写成 padding: 1% 0 0 0 height:50%; 盒子的高度, 相对于父容器的高度, 最外层即浏览器高度 大屏开发推荐使用拖拽布局(PRO) # 大家如果开发大屏, 只是用响应式布局可能对于复杂的布局不是很方便, 你也可以采用拖拽绝对定位的方法, 这样你可以随意指定图形的所在位置. 方法可参考视屏 拖拽说明 你可以配合使用 ”模板开发“ 来实现高度定制化的效果, 参考 模板开发指引\n混合布局(PRO) # 你可以考虑先用响应式布局把整体框架画出来, 如果要加一下装饰的情况, 可以用绝对定位(拖拽布局)来实现\n"},{"id":9,"href":"/docs/5.%E5%8F%82%E6%95%B0%E5%8F%8A%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/%E5%8F%82%E6%95%B0%E7%BC%96%E5%86%99%E6%96%B9%E6%B3%95/","title":"参数编写方法","section":"5.参数及联动钻取","content":" 使用场景 # 需要使用图表联动效果 数据服务接口开发 使用魔法方法(smartchart独创,拒绝抄袭) # 基础原理 # - $参数名, 当有传递参数时将替换相关的值 - /* ... $参数 ... */, 当参数写在这个区间时, 如果外部没有传入参数, 会自动忽略这一段代码 - -- 标识之后单行的代码会被忽略 常见组合应用 # 理解以下样列后, 可录活使用组合出各种可能的需求\n默认参数: 实现在不传参数时默认参数是当前月份 select xx from tablename where calmonth =/*\u0026#39;$calmonth\u0026#39; -- */ to_char(sysdate,\u0026#39;YYYYMM\u0026#39;) 多个参数: 注意使用1=1及and的位置 select xx from tablename where 1=1 /* and city = \u0026#39;$city\u0026#39; */ /* and calmonth =\u0026#39;$calmonth\u0026#39;*/ 维度变化: 将字段当成参数 select /*$calmonth,*/ city, count(1) as qty from tablename group by /*$calmonth,*/ city 维度变化: 当传入月份条件时, 按城市,月份的数据, 不传参数时只看按城市的总数 select /*月份, -- $Month */ 城市, sum(度量) from tablename where 1=1 /* and 月份 \u0026gt; \u0026#39;$Month\u0026#39; */ group by 城市 /*,月份 -- $Month*/ 高级开关应用 # 以上应用可以通过参数是否有传递来实现开关代码段的效果, 有些场景可能还希望通过参数值来进行代码段的开关 如下代码可以实现当传递参数type=1 或 type=2 时执行不同的代码段 使用 \u0026ldquo;$参数__值\u0026rdquo; 的方式做为开关\n/* select count(1) as qty from tablename1 $type__1*/ /* select count(1) as qty from tablename2 $type__2*/ 再比如 当参数D传值为\u0026quot;月份\u0026quot;时是统计2022年按月的统计, 传\u0026quot;日期\u0026quot;时统计的是2022年10月按天的统计\nselect $D, count(1) as qty from tablename where 1 = 1 /* and year=\u0026#39;2022\u0026#39; -- $D__日期 $D__月份 */ /* and month=\u0026#39;10\u0026#39; $D__日期 */ group by $D 加了\u0026quot;\u0026ndash;\u0026ldquo;是为了避免语法错误\n数据集开发调试参数方法 # 对于开发人员来说, 带参数的SQL调试不方便, 所以支持你在sql中写入默认参数 方法如下格式, 你可以在sql编辑器的最上方写上 /* {xxxxxx} */, 会默认在开发调试模式下取这些参数, 在用户模式下会忽略 /* {\u0026#34;月份\u0026#34;:\u0026#34;202009\u0026#34;,\u0026#34;城市\u0026#34;:\u0026#34;中山\u0026#34;} */ select xxx from table xxx 数据权限行级别控制 # 当你在sql查询中加上\u0026rsquo;$username\u0026rsquo;, 会自动替换成登录用户的用户名 如果你是嵌入到第三方系统, 你可以通过url传递参数id, 在后台会转化为参数_id, 在sql中配置$_id即可控制数据权限 可以采用此做数据权限关联后台权限mapping表进行数据权限控制实现不同人看不同的数据 参数的传递方式 # 你可以从url传入参数, 在url上加入 \u0026amp;param={\u0026ldquo;参数名\u0026rdquo;:\u0026ldquo;参数值\u0026rdquo;} 在图形联动的点击过程中会自动传递参数, 具体参考联动相关文档 TIPS 当设定参数后, 联动过程dataset的缓存功能失效, 所以不要让带参数的查询设计得太慢 参数如果存在一些非法字符可能会有问题, 比如参数中不可以有#号\n"},{"id":10,"href":"/docs/7.%E6%8A%A5%E8%A1%A8%E5%B5%8C%E5%85%A5/%E7%AE%80%E5%8D%95%E5%B5%8C%E5%85%A5/","title":"简单嵌入","section":"7.报表嵌入","content":"你可能需要把Smartchart生成的图形嵌入到其它系统 首先,所有smartchart设计出来的仪表盘都有一个访问url 你可以直接访问:\nhttp://localhost:8000/echart?type=仪表盘名称 如:http://localhost:8000/echart?type=demo 但是smartchart默认是有权限管理的,所以如果你需要嵌入你自已的系统又不考虑权限,你可以在“设定” \u0026ndash;\u0026gt; 公开 然后在你的网页就可以直接iframe了\n\u0026lt;iframe src=\u0026#34;http://localhost:8000/echart?type=demo\u0026#34; style=\u0026#34;width:100%;height:100%\u0026#34;\u0026gt;\u0026lt;/iframe\u0026gt; "},{"id":11,"href":"/docs/8.Django%E5%BA%94%E7%94%A8/%E5%B5%8C%E5%85%A5Django-Apps/","title":"嵌入 Django Apps","section":"8. Django应用","content":" 应用场景 # 你可以在你的django项目中直接使用smartchart做为插件的方式 你可以查看相关视屏\n使用方法 # 在你的setting.py的INSTALL_APPS中加入\u0026rsquo;smart_chart.echart' 如果你需要simpleui, 你可以在最上行加入我们适配好的\u0026rsquo;smart_chart.smartui\u0026rsquo; INSTALLED_APPS = [ \u0026#39;smart_chart.smartui\u0026#39;, .... .... \u0026#39;smart_chart.echart\u0026#39; ] MIDDLEWARE 中注释掉XFrameOptionsMiddleware\n检查确保在Templates的设定处有DIRS的相关设定\nTEMPLATES = [ { \u0026#39;BACKEND\u0026#39;: \u0026#39;django.template.backends.django.DjangoTemplates\u0026#39;, \u0026#39;DIRS\u0026#39;: [BASE_DIR / \u0026#39;templates\u0026#39;], #此处需要有 \u0026#39;APP_DIRS\u0026#39;: True, #也要有 ..... }, ] setting.py中设定为中国时区, 支持中文基础平台建设! LANGUAGE_CODE = \u0026#39;zh-hans\u0026#39; TIME_ZONE = \u0026#39;Asia/Shanghai\u0026#39; USE_I18N = True USE_L10N = True USE_TZ = False # 此处必须为False 在你的url.py中加入引用 from django.conf.urls import include from django.views.generic import RedirectView url.py的urlpatterns中加入路由 path(\u0026#39;echart/\u0026#39;, include(\u0026#39;smart_chart.echart.urls\u0026#39;)), path(\u0026#39;\u0026#39;, RedirectView.as_view(url=\u0026#39;echart/index/\u0026#39;)), #首页,可自定义路由 初始化DB, 命令行输入: python manage.py makemigrations python manage.py migrate 建立管理员帐号, 如果已有可忽略 python manage.py createsuperuser 启动服务 python manage.py runserver 10. 点击首页的组件升级进行初始化 :cupid: !!!! 重要!!! 注意 # 一般来说如果你使用django遇到的问题,都不是smartchart导致的, 作者也很难给你解答, 建议你可以进行有偿问答\n"},{"id":12,"href":"/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E5%AE%9E%E6%88%98%E5%A4%A7%E5%B1%8F%E6%A8%A1%E6%9D%BF%E8%BD%AC%E5%8C%96/","title":"实战大屏模板转化","section":"9.进阶开发 Pro","content":" 应用场景 # 已有开发好的非smartchart静态大屏模板(这种模板非常多, 不要上当) 对js, css及smartchart已有初始了解 业务需求展示有合适的模板, 变化不大 如何使用 # 请观看系列视屏, 相信人人都会 头条视屏: 大屏模板转化系列 B站视屏: 大屏模板转化系列\n"},{"id":13,"href":"/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91%E7%95%8C%E9%9D%A2/","title":"模板开发界面","section":"模板开发","content":" 低代码化开发 # smartchart的标准模板为了标准化的原因,对于引用JS,编写CSS等有一定不方便性, 但有时候你可能需要放飞自由, 随意定制 你甚至可能想引用一些其它的UI组件, 所以smartchart给你一个原汗原味的开发空间\n开启方式 # 在高级中,设定template为diy 主菜单中会多出来一个 模板 的功能 进入模板编辑界面 "},{"id":14,"href":"/docs/%E5%85%B3%E4%BA%8E%E6%88%91%E4%BB%AC/","title":"关于我们","section":"Docs","content":" 我们的目标 # 打造全生态的数据应用数据管理的平台,解决中小企业上中台难,上中台贵,见效慢的问题. 平台与时俱进,不断完善与优化中 可以通过视屏了解我们的架构设计 企业数字化与smartchart的一站式解决方案\n我们不提供数据存储与计算引擎, ETL工具, BI工具. 因为已有更优秀的产品,我们只为数据开发人员提供更敏捷的工具与平台,致力于数据服务中台建设,边缘可视化与数据管道产品, 站在巨人的肩上, 让数据更有个性,更灵活与可定制化,由于他的通用性,功能的扩展变得也是非常的Smart\n产品定位: # 实现全生态的数据服务平台(数据收集, 数据加工, 数据分享,数据管理,数据应用)\n产品模块: # 统一的数据处理调度平台、数据管道, 是基于Apache顶级项目Airflow上的二次开发产品,让数据处理的任务调度开发与管理微代码化,我们的设计理念是让开发者更方便的同时,不丧失灵活和高度可自定义,如果你使用过smartchat,你可以想象他会带来的便捷性, 产品名为smartpip, 为啥不叫smartpipe, 因为能省我们就要省\u0026hellip; 统一的可视化管理平台, 为微信等第三方应用, 提供powerbi,tableau,finebi\u0026hellip;的嵌入式及功能扩展服务,数据集即服务,一切为数据集 统一的数据上传平台, 实现线下数据的收集需求, 并提供专业的手工上传数据产品, 支持excel本地(安装与免安装版本), 支持WEB端 统一的数据分享平台与smartchart集成,可做为数据服务中台, 实现业务对数据下载的需要及为第三方提供获取数据的API接口 SmartChart可视化平台, 新一代的数据可视化产品, 解决传统BI各种痛点问题,真正面向开发人员的平台产品 元数据管理平台及数据治理,让数据的来源更清晰, 让数据应用更方便,具备自动化,可视化的数据血缘分析 新一代极速数据仓库技术, 极简架构即可实现在大数据应用的全场景需求 "},{"id":15,"href":"/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E4%B8%93%E4%B8%9A%E7%89%88%E8%AF%B4%E6%98%8E/","title":"专业版本说明","section":"1.基础操作","content":" 版权声明 # 为项目能持续维护,并保持稳定的模式,按照社区投票的意见, 开始区分免费版本和专业版本 目前免费版本无需激活, 你可以使用到常用的功能,我们也会保持持续的更新 为保持项目的健康发展,如需进行商用,您需提供使用方并知会作者进行授权\n免费版使用者必须保留SmartChart相关版权标识及LOGO,禁止对其进行修改和删除 如果违反,将保留对侵权者追究责任的权利\n激活方式 # 您在初次安装Smartchart后会自动免费激活20天的专业版本, 之后专业版本功能会限制使用 请务必仔细阅读免费版本与专业版本的区别, 避免带来的不便 后续如果您还需要继续体验专业版本, 点击查看激活试用方式, 如果您是企业用途,建意使用专业版,获取更快的开发效率,可视化效果, 可靠性的保障及极速的查询体验\n针对个人独立开发者,你可以采用廉价的专业版仪表盘激活方案, 可满足小项目的可视化要求 如果需要永久激活专业版,可关注公众号与客服联系,或扫码联系微信客服了解, 非诚勿扰\n微信客服不提供技术咨询, 如有使用方法的疑惑,建意加QQ群:476715246 进行沟通\n免费版本与专业版本对比: # 功能 免费版 专业版 中台版 栅格布局 V V V DATAV V V V 拖拽布局 V V 自由开发 V V 切换图表主题 V V 主题自由设计 V V 引入JS V V 引入CSS V V 上传静态资源 V V 使用VUE V V V 数据集开发 V V V 所有数据源 V V V 图形开发 V V V 图形商店 V V V 普通模板应用 V V V 专业模板应用 V V 复制仪表盘 V V V 钻取 V V V 联动 V V V 筛选 V V V 单点登录 V V V 嵌入认证 V V LDAP认证 V V Juypter V V V 快捷存档 V V 数据加速 V V 数据API服务 V V 后台API刷新 V V 仪表盘同步 V V 仪表盘版本管理 V V 数据填报 V V 报表Portal V V 多级项目菜单 V 商业授权 V V 优先咨询 V V 专业边框背景 V V 3D场景 V V 中国式报表 V V 生产部署文档 V V 个性化修改 V V 授权书 V V 低代码ETL V 调度平台 V 智慧BI V 数据资产 V 数据血缘 V 租户管理 V "},{"id":16,"href":"/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/VUE%E7%9B%B8%E5%85%B3/ElementUI/","title":"Element Ui","section":"Vue相关","content":" 应用场景 # 非大屏场景应用 有较多交互场景的报表, 如筛选,表格,分页,下载等 使用方法 # 如下图, base.html 改为 basevue.html 将自动开启加载vue和elementui 注意vue的变量引用在 模板编辑界面中, 写法变更为 {[ ]}\nElementUI组件说明 视屏参考\n参考样列 # 新增一个数据集(点击金色的新增按钮, 这样会新增一个可拖拽的数据集) 修改相应的数据集及图形 数据集端\nselect H1, H2, qty, rate from smartdemo2 limit 100 图形端\nlet dataset = __dataset__; let tableData = ds_createMap_all(dataset); vapp.d0={ tableData: tableData } 模板Body区端\n\u0026lt;div class=\u0026#34;smtdrag\u0026#34; id=\u0026#34;id_1639824145817\u0026#34;\u0026gt; \u0026lt;template\u0026gt; \u0026lt;el-table stripe border height=\u0026#34;100%\u0026#34; :data=\u0026#34;d0.tableData\u0026#34; style=\u0026#34;width: 100%\u0026#34;\u0026gt; \u0026lt;el-table-column label=\u0026#34;hero\u0026#34;\u0026gt; \u0026lt;el-table-column prop=\u0026#34;H1\u0026#34; label=\u0026#34;H1\u0026#34; fixed :default-sort = \u0026#34;{prop: \u0026#39;H2\u0026#39;, order: \u0026#39;descending\u0026#39;}\u0026#34; width=\u0026#34;180\u0026#34;\u0026gt; \u0026lt;/el-table-column\u0026gt; \u0026lt;el-table-column prop=\u0026#34;H2\u0026#34; label=\u0026#34;H2\u0026#34; sortable width=\u0026#34;180\u0026#34;\u0026gt; \u0026lt;/el-table-column\u0026gt; \u0026lt;/el-table-column\u0026gt; \u0026lt;el-table-column sortable prop=\u0026#34;qty\u0026#34; label=\u0026#34;qty\u0026#34;\u0026gt; \u0026lt;/el-table-column\u0026gt; \u0026lt;el-table-column prop=\u0026#34;rate\u0026#34; label=\u0026#34;rate\u0026#34;\u0026gt; \u0026lt;/el-table-column\u0026gt; \u0026lt;/el-table\u0026gt; \u0026lt;/template\u0026gt; \u0026lt;/div\u0026gt; "},{"id":17,"href":"/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E4%B8%8D%E5%A4%AA%E9%87%8D%E8%A6%81/%E5%A4%8D%E5%88%B6%E4%BB%AA%E8%A1%A8%E7%9B%98/","title":"复制仪表盘","section":"不太重要","content":" 复制仪表盘 # 好不容易开发好了一个仪表盘, 想再做一个类似的, 或者想要一个测试用, 还需要一个个数据集, 图形复制粘贴么, 不, 你仅仅只需要点击下, 将给你复制出一个全新的仪表盘 注意: 复制出来的仪表盘, 数据集是与原仪表盘公用的!!\n如果你想将数据集独立出来, 可以按下图操作, 进入数据集设定, 点击磁铁, 将为你自动创建一个全新的数据集 "},{"id":18,"href":"/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/EXCEL%E6%95%B0%E6%8D%AE/%E6%95%B0%E6%8D%AE%E4%B8%8A%E4%BC%A0/","title":"数据上传","section":"Excel数据","content":" 用户如何上传文件 # smartchart默认是不自带文件上传功能 但是smartchart是可以自已创造上传页面, 在模板商店中你可以找到相关模板进行购买 然后通过模板下载的方式下载后进行操作 这样每一个页面是可以单独使用权限控制的,就和控制报表权限一样,你还可能按需随意定制页面 关于上传文件的路径 # 默认的上传主目录是在项目的log的文件夹下面, 你可以在setting.py(自定义django) 或 config.ini中设定UPLOAD_PATH来修改你的上传目录 比如你上传页面的报表ID是23, 那么文件将会被上传到UPLOAD_PATH/23/你的文件名\n如何使用上传的文件 # 你需要使用 python连接器, 来操作你的上传的数据, 内置了变量ds_path为你的上传目录, 所以可以更方便的读取上传的文件,如上文件 df = pd.read_excel(ds_path+\u0026rsquo;/23/文件名')\n"},{"id":19,"href":"/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/SQL%E6%95%B0%E6%8D%AE%E9%9B%86/","title":"Sql数据集","section":"2.数据集说明","content":"SmartChart标准数据集你可以想象为一个EXCEL的二维表, 有行和列 你直接在数据集开发界面填写SQL即可\n标准图形的数据表类型 # A类数据源 # 比如你的原始数据库中表的格式如下, 表名tb_name: 城市 户型 数量 长沙 A 12 长沙 A 23 上海 B 19 查询的sql: select 城市,户型,sum(数量) AS 数量 from tb_name group by 城市,户型 正常的查询的结果为: [[\u0026#39;城市\u0026#39;,\u0026#39;户型\u0026#39;,\u0026#39;数量\u0026#39;], [\u0026#39;长沙\u0026#39;,\u0026#39;A\u0026#39;,35], [\u0026#39;上海\u0026#39;,\u0026#39;B \u0026#39;,19]] 由于生成的数据格式第二行是 [字符,字符,数值], 后台会自动进行转列动作, 生成图表更容易使用格式: [[\u0026#39;Categroy\u0026#39;,\u0026#39;A\u0026#39;,\u0026#39;B\u0026#39;], [\u0026#39;长沙\u0026#39;, 35, 0], [\u0026#39;上海\u0026#39;, 0, 19]] B类数据源 # 再比如我们有一个表的数据格式, 指标是展开的: 城市 A B 长沙 10 12 上海 11 19 长沙 9 10 我们可以写的sql是: select 城市, sum(A) as A, sum(B) as B from tb_name group by 城市 这样得到的结果是: [[\u0026#39;城市\u0026#39;,\u0026#39;A\u0026#39;,\u0026#39;B\u0026#39;], [\u0026#39;长沙\u0026#39;, 19, 22], [\u0026#39;上海\u0026#39;, 11, 19]] 和我们的标准格式也是一样的 SQL多段查询 # 有时你一个数据集可能只用一个SQL查询还不够,比如你需要一个清单数据,同时你需要一个汇总数据做为说明在图形中显示,这样你就需要使用多条SQL语句,在数据集中的写法你只需要用分号隔开,如:\nselect ... from xxx; select ..... from xxxxxxx 传递到图形中的格式为: {\u0026#34;df0\u0026#34;:[[...]]. \u0026#34;df1\u0026#34;:[[......]]} df0, df1分别对应的是第一段和第二段查询 多段查询使用视屏参考\n支持的数据源: # 数据库 驱动填写 需安装 使用说明 Mysql mysql 默认支持 Mysql连接池 mysqlpool Sqlite sqlite 默认支持 连接地址填写绝对路径 API 任意 默认支持 参考数据集说明文档 EXCEL 任意 默认支持 参考数据集说明文档 SQL Server mssql 需安装 pip install pymssql SQL Server连接池 mssqlpool ORACLE oracle pip install cx_Oracle ORACLE连接池 oraclepool PostgreSql gp pip install psycopg2 GP gp pip install psycopg2 Impala impala pip install impyla Hive hive pip install impyla DB2 db2 pip install ibm_db 达梦 dm pip install dmPython Python python pip install pandas, openpyxl 参考数据集-\u0026gt;特殊数据源 Redis redis pip install redis 参考数据集-\u0026gt;特殊数据源 Mongodb mongodb pip install pymongo 参考数据集-\u0026gt;特殊数据源 Clickhouse clickhouse pip install clickhouse_driver Elasticsearch es pip install elasticsearch==7.13.0 参考数据集-\u0026gt;特殊数据源 Sqlalchemy sqlalchemy pip install sqlalchemy 参考数据集-\u0026gt;特殊数据源 JDBC jdbc pip install JayDeBeApi 参考数据集-\u0026gt;特殊数据源 自定义 自定义 用户自由定义 参考数据集-\u0026gt;特殊数据源 "},{"id":20,"href":"/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/Python%E6%95%B0%E6%8D%AE%E9%9B%86/","title":"Python数据集","section":"特殊数据源","content":" 应用场景 # 当SQL查询无法满足你的需求, 你需要对查询后的结果进行处理, 或者你需要使用Excel的数据源, 甚至你需要对不同系统的数据进行查询, Python连接器可以帮到你 我们又称他为万能数据集, 你可以使用任何python语法, 需要把数据集的结果赋值给ds变量!!\n首先你需要新建python连接器, 由于安全控制只允许超级管理员建立 # 内置函数说明 ds_get(id) #输入目标数据集的id名, 可以获取目标数据集 ds_df(id) #输入目标数据集的id名, 转化成pandas的df对象 ds_sql(conn_name, sql_str) #输入连接池中的名称, SQL语句, 获取数据集 ds_list(df) #将pandas的df对象转化成数据集 使用方法样列说明 # # 读取Excel数据处理, 如需上传页面可参考\u0026#34;数据上传\u0026#34;说明 import pandas as pd df = pd.read_excel(\u0026#39;/Users/../smartdemo.xlsx\u0026#39;, \u0026#39;demo\u0026#39;) df = df.groupby(\u0026#39;c3\u0026#39;).agg({\u0026#39;qty\u0026#39;:\u0026#39;sum\u0026#39;}).reset_index() ds = ds_list(df) #从数据集获取数据 ds=ds_get(12) ds=ds[:15] #从数据集获取数据转化成pandas对象处理 df = ds_df(12) df = df.sort_values(by=\u0026#34;出场数\u0026#34;, ascending=False) ds = ds_list(df) #可以生成字典格式的数据集供多个图形使用 import pandas as pd df = pd.read_excel(\u0026#39;/Users/../smartdemo.xlsx\u0026#39;, \u0026#39;demo\u0026#39;) df1 = df.groupby(\u0026#39;c3\u0026#39;).agg({\u0026#39;qty\u0026#39;:\u0026#39;sum\u0026#39;}).reset_index() df2 = df.groupby([\u0026#39;province\u0026#39;,\u0026#39;c3\u0026#39;]).agg({\u0026#39;qty\u0026#39;:\u0026#39;sum\u0026#39;}).reset_index() ds = {\u0026#39;df1\u0026#39;: ds_list(df1), \u0026#39;df2\u0026#39;: ds_list(df2)} #可以直接执行SQL sql_str = \u0026#39;\u0026#39;\u0026#39;select H1 as heroname, sum(qty) as 出场数 from T /* where H2 = \u0026#39;$H2\u0026#39; */ group by H1 order by sum(qty) desc\u0026#39;\u0026#39;\u0026#39; ds = ds_sql(\u0026#39;XXX\u0026#39;, sql_str) ds = ds[:10] "},{"id":21,"href":"/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E5%87%BD%E6%95%B0%E6%96%B9%E6%B3%95/Jquery%E9%81%8D%E5%8E%86%E6%96%B9%E6%B3%95/","title":"Jquery遍历方法","section":"函数方法","content":"在做自定义html组件的时候你可能需要用得上:\n一、向上遍历\nparent() 获取元素的直接父元素 $(\u0026#34;span\u0026#34;).parent().css({ \u0026#34;color\u0026#34;:\u0026#34;red\u0026#34;, \u0026#34;border\u0026#34;:\u0026#34;1px solid red\u0026#34; }) parents() 获取元素的祖先元素,直到根元素html $(\u0026#34;span\u0026#34;).parents().css({ \u0026#34;color\u0026#34;:\u0026#34;red\u0026#34;, \u0026#34;border\u0026#34;:\u0026#34;1px solid red\u0026#34; }) parentsUntil() 向上查找直到遇见某个祖先元素为止 $(\u0026#34;span\u0026#34;).parentsUntil(\u0026#34;div\u0026#34;).css({\t//向上查找直到遇见div元素为止 \u0026#34;color\u0026#34;:\u0026#34;red\u0026#34;, \u0026#34;border\u0026#34;:\u0026#34;1px solid red\u0026#34; }) 二、向下遍历\n1. children() 查找子元素[按照从属关系] $(\u0026#34;ul\u0026#34;).children(\u0026#34;li:first-child\u0026#34;) 2. find() 按照指定的条件向下查找 $(\u0026#34;ul\u0026#34;).find(\u0026#34;span\u0026#34;) 三、水平遍历\n1. siblings() 获取元素的所有兄弟元素 $(\u0026#34;.start\u0026#34;).siblings().css({color:\u0026#34;red\u0026#34;,border:\u0026#34;2px solid red\u0026#34;}) 2. next() 获取元素的下一个兄弟元素 $(\u0026#34;.start\u0026#34;).next().css({color:\u0026#34;red\u0026#34;,border:\u0026#34;2px solid red\u0026#34;}) 3. nextAll() 获取其后的所有兄弟元素 $(\u0026#34;.start\u0026#34;).nextAll().css({color:\u0026#34;red\u0026#34;,border:\u0026#34;2px solid red\u0026#34;}) 4. nextUntil() 查找后面所有的兄弟元素,直到遇见某个元素为止 $(\u0026#34;.start\u0026#34;).nextUntil(\u0026#34;li:last-child\u0026#34;).css({color:\u0026#34;red\u0026#34;,border:\u0026#34;2px solid red\u0026#34;}) 5. prev() 查找上一个兄弟元素 $(\u0026#34;li.start\u0026#34;).prev().css({color:\u0026#34;red\u0026#34;,border:\u0026#34;2px solid red\u0026#34;}) 6. prevAll() 查找上面所有的兄弟元素 $(\u0026#34;li.start\u0026#34;).prevAll().css({color:\u0026#34;red\u0026#34;,border:\u0026#34;2px solid red\u0026#34;}) prevUntil() 查找上面所有的兄弟元素,直到遇见某个元素为止 $(\u0026#34;.start\u0026#34;).prevUntil(\u0026#34;li:first\u0026#34;).css({\u0026#34;color\u0026#34;:\u0026#34;red\u0026#34;,\u0026#34;border\u0026#34;:\u0026#34;2px solid red\u0026#34;}) 四、过滤\n1. first() 获取第一个元素 $(\u0026#34;li\u0026#34;).first().css(\u0026#34;color\u0026#34;,\u0026#34;red\u0026#34;); 2. last() 获取最后一个元素 $(\u0026#34;li\u0026#34;).last().css(\u0026#34;color\u0026#34;,\u0026#34;red\u0026#34;); 3. not() 获取不是…的元素 $(\u0026#34;li\u0026#34;).not(\u0026#34;:eq(2)\u0026#34;).css(\u0026#34;font-size\u0026#34;,\u0026#34;26px\u0026#34;); 4. eq(n) 获取索引为n的元素 $(\u0026#34;li\u0026#34;).eq(3).css(\u0026#34;background\u0026#34;,\u0026#34;green\u0026#34;); 5. has() 检测某个子元素是否存在 $(\u0026#34;li\u0026#34;).eq(1).has(\u0026#34;span\u0026#34;).length) 6. filter() 筛选出与符合条件的DOM元素 $(\u0026#34;div\u0026#34;)..filter(\u0026#34;.middle\u0026#34;) 7. is() 用来判断是否符合条件 $(\u0026#34;p\u0026#34;).parent().is(\u0026#34;div\u0026#34;)\t//判断p的父元素是不是div,是就返回true,不是就返回false 五、each遍历\n1. each() 方法为每个匹配元素规定要运行的函数。 $(selector).each(function(index,element){ ..... }) //index 表示当前遍历元素的索引 element 当前的元素(也可使用 \u0026#34;this\u0026#34; 选择器) 2. $.each(obj,function( index,value){}) "},{"id":22,"href":"/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%AE%A1%E7%90%86%E5%9B%BE%E5%BD%A2/","title":"管理图形","section":"3.图形开发","content":" 应用场景 # 如何快速复用已开发好的组件\n本地管理自定义组件 # 如下图,点击图形编辑器中的菜单,即可管理和查看自定义图形列表 点击\u0026quot;加入样列\u0026quot;即可把当前图形加入到样列清单, 点击\u0026quot;取消样列\u0026quot;即可将所选样列移除样列清单 云管理,在图形商店中保存你的图形 # 这样你就可以在图形商店看到你的图形进行重复利用 "},{"id":23,"href":"/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E6%8B%96%E6%8B%BD%E8%87%AA%E5%8A%A8%E5%AF%B9%E9%BD%90/","title":"拖拽自动对齐","section":"4.布局说明","content":"拖拽很方便, 但是精确对齐还是有些手抖, 所以smartchart增加了自动对齐的功能 你可以在\u0026quot;模板\u0026quot; \u0026ndash;\u0026gt; \u0026ldquo;转化\u0026rdquo; 中找到这个功能 首先我们随意拖拽了一些组件 然后选中拖拽代码段, 点\u0026quot;拖拽对齐\u0026quot; 后 点\u0026quot;保存\u0026quot; 就可以查看对齐后的效果了, 再进行下拖拽微调, 重复以上动作到满意 "},{"id":24,"href":"/docs/5.%E5%8F%82%E6%95%B0%E5%8F%8A%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/%E5%9B%BE%E5%BD%A2%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/","title":"图形联动钻取","section":"5.参数及联动钻取","content":" 数据集准备 # 首先在需要进行联动的数据集中SQL的写法如下, 比如对应2号图形:\n注意 /* ... */的写法, 当参数写在这个区间时, 如果外部没有传入参数, 会自动忽略这一段代码, 这样对于联动来说非常重要, 初始时全部显示, 点击其它图形时传入参数进行动态联动 select xxx,xxx,xxx from tablename /* where xxxx = \u0026#39;$参数名\u0026#39; */ .... 建意观看视屏比较容易理解: 数据联动说明\n常规方法 # 比如你需要点击0号图形, 指定其它图形联动 你只需要打开0号图形的数据集编辑页面, 点击标题的位置 然后输入相关的参数即可, 以下为sample 参数值设定的方法, 你可以先留空, 然后保存, F12打浏览器调试方法 点击0号图形你需要点击的动作, 你可以右调试窗口的console看到输入的log 比如我们需要传递的参数值是\u0026quot;廉颇\u0026quot;, 那么取数据的方法就是data.name, 你把这个填入即可 这样就实现按所选数据或所选系列钻取/联动了, 重新点击当前所选, 恢复原来的 如何在图形开发中获取参数值\n图形编辑器中, 你可以使用函数 ds_param(\u0026#39;参数名\u0026#39;) 来获取传入的参数值 高级定制方法 # 如果有更多个性化需求,可以在需要点击的图形的编辑器中加入以下代码,你仅仅需要修改的是序号和参数名\n//比如传入多个参数进行联动 myChart__name__.on(\u0026#39;click\u0026#39;, function(params){ let myparam = params.seriesName; //获取点击的值 filter_param[\u0026#39;参数名\u0026#39;] = myparam; //填写你的数据集的SQL设定中对应的参数名 filter_param[\u0026#39;参数名2\u0026#39;] = myparam2; //你可以赋值给多个参数 ds_refresh(3); //3 为你要刷新图形序号 }); 你也可以使用更方便的参数赋值方法(5.6以上)\n//使用方法 ds_setParam(\u0026#39;参数名\u0026#39;, 参数值) 此方法将自动判断当参数值为空时, 删除参数回到初始未传参状态 你还可以实现钻取到另外一个报表\nmyChart__name__.on(\u0026#39;click\u0026#39;, function (params) { let myparam = `\u0026amp;param={\u0026#34;参数名\u0026#34;: \u0026#34;${params.seriesName}\u0026#34;}`; //拼成url并传参,具体参考数据集说明中的数据联动url传参的方法 let myurl=\u0026#39;http://localhost:8000/echart/?type=目标报表名\u0026#39;+ myparam; window.open(myurl,\u0026#39;_blank\u0026#39;,\u0026#39;toolbar=no,scrollbar=no,top=100,left=100,width=800,height=500\u0026#39;); }); TIPS 如果你的参数中存在非法字符如\u0026amp;=, 你可以使用encodeURIComponent函数进行转义后赋值\n"},{"id":25,"href":"/docs/7.%E6%8A%A5%E8%A1%A8%E5%B5%8C%E5%85%A5/%E5%8D%95%E7%82%B9%E7%99%BB%E5%BD%95/","title":"单点登录","section":"7.报表嵌入","content":" 单点登录的方式与smartchart进行对接嵌入 # \u0026#39;/echart/smart_login?id=xxx\u0026amp;stamp=xxx\u0026amp;token=xxx\u0026amp;url=/\u0026#39; \u0026#39;\u0026#39;\u0026#39; 参数说明: id: 用户名(在smartchart平台中管理) stamp: 时间戳(1970年1月1日到生成时间的毫秒数) token: 采用sha1加密, token=SHA1(链接秘钥+stamp+id) 请在安装smartchart的这台机器上设定环境变量SMART_KEY = 链接秘钥 url: 登录成功后跳转链接 \u0026#39;\u0026#39;\u0026#39; Python后台样列: # import time import hashlib import os \u0026#34;\u0026#34;\u0026#34; 参数说明: id: 用户名(在smartchart平台中管理) stamp: 时间戳(1970年1月1日到生成时间的毫秒数) token: 采用sha1加密, token=SHA1(链接秘钥+stamp+id) url: 登录成功后跳转链接 \u0026#34;\u0026#34;\u0026#34; SMART_CHART_URL = \u0026#39;http://127.0.0.1:8000\u0026#39; LOGIN_URL = SMART_CHART_URL + \u0026#39;/echart/smart_login?id={id}\u0026amp;stamp={stamp}\u0026amp;token={token}\u0026amp;url={url}\u0026#39; SMART_KEY = 链接秘钥 def get_smarturl(username, url=\u0026#39;/\u0026#39;): stamp = int(time.time() * 1000) id = username res = SMART_KEY + str(stamp) + id token = hashlib.sha1(res.encode(\u0026#39;utf-8\u0026#39;)).hexdigest() LOGIN_DICT = { \u0026#34;id\u0026#34;: id, \u0026#34;stamp\u0026#34;: stamp, \u0026#34;token\u0026#34;: token, \u0026#34;url\u0026#34;: url } # 拼接好的url,直接访问 visit_url = LOGIN_URL.format(**LOGIN_DICT) return visit_url "},{"id":26,"href":"/docs/8.Django%E5%BA%94%E7%94%A8/FAQ/","title":"Faq","section":"8. Django应用","content":" FAQ # 如果你想对smartchart前端二次开发或关闭debug模式后找不到资源 在settings中加入\nSTATIC_ROOT = os.path.join(BASE_DIR, \u0026#34;static\u0026#34;) 执行以下命令将静态文件静态文件克隆到根目录\npython3 manage.py collectstatic "},{"id":27,"href":"/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%95%B0%E6%8D%AE%E6%9C%8D%E5%8A%A1API/","title":"数据服务 API","section":"9.进阶开发 Pro","content":" SmartChart的数据集功能, 可以非常方便的实现数据对外微服务 # 权限设定 # 如果你使用的是自已搭建的django项目, 你需要在项目的根目录下新建一个JSON文件, 如果是使用smartchart启动的, 配置文件在项目的安装目录下可以找到 名为apiconfig.json, 比如需要调用API的用户名为test 和 test2,用户名需要是在你的用户设定中存在的,内容如下: { \u0026#34;test\u0026#34;: { \u0026#34;token\u0026#34;: \u0026#34;smartchart\u0026#34; }, \u0026#34;test2\u0026#34;: { \u0026#34;token\u0026#34;: \u0026#34;smartchartxxx\u0026#34;, \u0026#34;host\u0026#34;: [\u0026#34;10.10.10.10\u0026#34;,\u0026#34;10.10.10.23\u0026#34;], \u0026#34;limit\u0026#39;: 60, \u0026#34;log\u0026#34;:1, \u0026#34;cors\u0026#34;: 1 } } 可选设定参考test2 host:API白名单配置,limit:一分钟内可调用次数, log:日志记录方式. cors:永许跨域访问\n然后你只需要将你的数据集中的权限设定给对应的用户即可 请求方式 # 加密接口请求方式(推荐) # GET 请求 # #接口请求格式: url: /echart/dataset_api/?visitor=xxx\u0026amp;token=xxx\u0026amp;type=xxx\u0026amp;stamp=xxxxx\u0026amp;param={\u0026#34;xx\u0026#34;:\u0026#34;xxx\u0026#34;,\u0026#34;xx\u0026#34;:\u0026#34;xxxx\u0026#34;} # 参数说明 visitor: 用户名 type: 接口数据集ID stamp: 时间戳(1970年1月1日到生成时间的毫秒数) token: 采用sha1加密, token=SHA1(秘钥 + stamp + Visitor + Type) param: 传入的参数值(可选),格式json字符串,如多个参数: \u0026#39;{\u0026#34;参数A\u0026#34;:\u0026#34;xxxx\u0026#34;, \u0026#34;参数B\u0026#34;:\u0026#34;xxxx\u0026#34;}\u0026#39; # 接口返回格式 Json: { \u0026#34;data\u0026#34;:[[]], \u0026#34;result\u0026#34;:\u0026#34;success\u0026#34;, \u0026#34;maxpg\u0026#34;:1, \u0026#34;pg\u0026#34;:1 } 返回值说明: data : 二维数组,第一行为表头, 样列数据 [[\u0026#34;heroname\u0026#34;, \u0026#34;qty\u0026#34;],[\u0026#34;镜\u0026#34;,658],[\u0026#34;猪八戒\u0026#34;,591]] result : success 或 error maxpg/pg : GET请求固定为1不分页 POST请求(适用于后台定时同步数据,查询请用GET请求方法) # #接口请求格式: url: /echart/dataset_api/ # 请求参数说明 data: { \u0026#34;visitor\u0026#34;:\u0026#34;xxx\u0026#34;, \u0026#34;token\u0026#34;:\u0026#34;xxx\u0026#34;, \u0026#34;stamp\u0026#34;:xxxxx, \u0026#34;type\u0026#34;:\u0026#34;xxx\u0026#34;, \u0026#34;pagesize\u0026#34;:\u0026#34;xxx\u0026#34;, \u0026#34;pg\u0026#34;:\u0026#34;xxx\u0026#34;, \u0026#34;param\u0026#34;:\u0026#39;{\u0026#34;xxx\u0026#34;:\u0026#34;xxxx\u0026#34;}\u0026#39; } # 参数说明 visitor: 用户名 type: 接口数据集ID stamp: 时间戳(1970年1月1日到生成时间的毫秒数) token: 采用sha1加密, token=SHA1(秘钥 + stamp + Visitor + Type) Pagesize: 采用分页,每页的数据量大小 pg: 返回第几页 param: 传入的参数值,格式json字符串,如多个参数 \u0026#39;{\u0026#34;参数A\u0026#34;:\u0026#34;xxxx\u0026#34;, \u0026#34;参数B\u0026#34;:\u0026#34;xxxx\u0026#34;}\u0026#39; #接口返回格式 Json: { \u0026#34;data\u0026#34;:[[]], \u0026#34;result\u0026#34;:\u0026#34;success\u0026#34;, \u0026#34;maxpg\u0026#34;:xxx, #最大页数 \u0026#34;pg\u0026#34;:xx, #当前页数 \u0026#34;casheflag\u0026#34;: xx, #如果是999说明命中缓存 \u0026#34;total\u0026#34;:xx, #总条数 } 注意: 只有post是分页的, 第一页是带标题的, 后面页不带标题 由于post方式会使用缓存进行分页,如命中缓存传参不会生效,小数据量请使用get方式请求 不要请求大数据量,大量数据请采用limit, offset传参方式进行分页\n不加密请求方式(简单但不安全) # GET 请求 #接口请求格式: url: /echart/dataset_api/?visitor=xxx\u0026amp;token=xxx\u0026amp;type=xxx 数据集名或id名 #接口返回格式 Json: { \u0026#34;data\u0026#34;:[[]], \u0026#34;result\u0026#34;:\u0026#34;success\u0026#34;, \u0026#34;maxpg\u0026#34;:1, \u0026#34;pg\u0026#34;:1 } POST请求 #接口请求格式: url: /echart/dataset_api/ data: { \u0026#34;visitor\u0026#34;:\u0026#34;xxx\u0026#34;, \u0026#34;token\u0026#34;:\u0026#34;xxx\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;xxx\u0026#34;, #数据集名或id名 \u0026#34;pagesize\u0026#34;:\u0026#34;xxx\u0026#34;, #每页数据条数 \u0026#34;pg\u0026#34;:\u0026#34;xxx\u0026#34;, #返回第几页 \u0026#34;param\u0026#34;:\u0026#39;{\u0026#34;xxx\u0026#34;:\u0026#34;xxxx\u0026#34;}\u0026#39; #参数可选 } #接口返回格式 Json: { \u0026#34;data\u0026#34;:[[]], \u0026#34;result\u0026#34;:\u0026#34;success\u0026#34;, \u0026#34;maxpg\u0026#34;:xxx, #最大页数 \u0026#34;pg\u0026#34;:xx, #当前页数 \u0026#34;casheflag\u0026#34;: xx, #如果是999说明命中缓存 \u0026#34;total\u0026#34;:xx, #总条数 } 注意: 只有post是分页的, 第一页是带标题的, 后面页不带标题 由于post方式会使用缓存, 小数据量建议你使用get方式请求 "},{"id":28,"href":"/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E5%BF%AB%E6%8D%B7%E5%BC%80%E5%8F%91/","title":"快捷开发","section":"模板开发","content":" 应用场景 # 专业化开发, 可将仪表盘显示和模板开发分屏开发 当你熟悉smartchart的基础开发后, 你可能会喜欢上现在这种方式 把你的可视化页面移动的显示器上吧, 进入\u0026quot;模板\u0026quot; 开发页面(上节介绍如何进入)\n方式一: 自动化DIV # 此方式当你新增数据集图形时会自动识别, 无需手动在模板在添加 采用此方式请不要采用点击模板上方菜单的图形新增 如需编辑图形或数据集可按如下方式: 方式二: 自由DIV # 你可以模板中按照常规的H5页面编辑, 只是在需要插入图形的地方插入即可(建意通过模板上方的图形新增) 开始畅快的开发\n点击图形即可新增一个图形,你甚至可以指定图表的位置, 完全和写html一样, 使用{{div_list.图表顺序号}} warning 注意请尽量避免删除DIV, 如果你中途有删除过div, 序号会不一样, 你可以在\u0026quot;布局\u0026quot;中重排序保持一致, 保持数据集编号从0开始\n如果使用自由布局, 请删除自动化DIV这一段代码 选中生成的图形代码段, 点击菜单栏的 数据集, 图形, 布局开发, 即可进入开发界面, 如果没有数据集, 会自动帮你新建 可以观看视屏, 视屏比较老和现在不太一样, 仅参考即可 自由开发模式视屏\n"},{"id":29,"href":"/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B/","title":"快速开始","section":"1.基础操作","content":"开发前你可以先观看操作方面的 :exclamation: 操作视屏教程 :exclamation: 5.0变更操作视屏教程 :exclamation: 开发系列合集,关注作者持续更新\n由于版本的变更, 一些图标可能会有一些变化, 但位置无太大的变化\n安装Python环境 # 环境准备: 官方 最新Python下载链接,可以到 淘宝镜象下载,也可以下载 WINDOWS64位安装版, MAC电脑安装版\nWindow平台安装视屏介绍,注意: Windows安装Python时需选中\u0026quot;Add to Path\u0026quot; Linux安装可参考文档下方的部署说明, Linux安装说明\n安装SmartChart # 在Shell或CMD命令行执行\npip3 install smartchart 如果安装过程慢,建意使用 pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple smartchart -U 升级方法: pip3 install smartchart -U (升级) 启动smartchart # 本地命令行启动: smartchart 如果你是服务器部署,远程访问,服务端启动方式: smartchart runserver 0.0.0.0:8000 --insecure --noreload 如果出现套接字,端口被占用, 可修改端口号启动, 如 smartchart runserver 0.0.0.0:8001 --insecure --noreload 一般本地启动后访问: http://127.0.0.1:8000 管理员帐号密码: admin/admin, 请及时更改密码\n如果忘记密码, 可以使用此命令重置 smartchart changepassword 用户名 鼠标滑动,点击如下图DEV图标, 切换为开发模式,这样才可以看到开发相关菜单,后打开demo页面 注意: 不切换是正常的用户报表浏览模式!! 仅管理员或开发人员能看到DEV菜单,用户只会有报表菜单页面\n尝试熟悉编辑菜单 尝试点开数据集查看SQL写法, 图形编辑器, 容器等 "},{"id":30,"href":"/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/VUE%E7%9B%B8%E5%85%B3/DataV%E5%BA%94%E7%94%A8/","title":"Data V应用","section":"Vue相关","content":"需要在高级中加入“dv”:1,即可开启datav模式\n参考视屏 1. DataV基础应用 2. DataV翻盘器\nDataV配置方法文档: 图表\n"},{"id":31,"href":"/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E5%85%B1%E4%BA%AB%E6%95%B0%E6%8D%AE%E9%9B%86/","title":"共享数据集","section":"2.数据集说明","content":" 应用场景 # 优化查询, 可一个数据集查询完所有数据进行分发 减少重复查询的浪费, 同一个数据只查询一次 使用方法 # 在数据开发界面点击按钮就可以切换成共享数据集/普通数据集 切换完成, 你会发现数据集消失,然后图标跑到菜单上面去了, 你可以在此修改你的查询 在”高级“ 中配置 这样1,2号图形都映射到了共享数据集的数据 你也可以在数据集中写多个SQL查询 在”高级“ 设定中进行数据映射 观察1,2 号图形的变化 "},{"id":32,"href":"/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E6%95%B0%E6%8D%AE%E9%9B%86%E6%95%B0%E6%8D%AE%E5%88%B7%E6%96%B0/","title":"数据集数据刷新","section":"2.数据集说明","content":" 数据刷新设定方法 # smartchart提供非常精细的数据刷新功能,及内存加速功能 你可以在数据集开发界面,点击连接的图标,进行设定 定时刷新 # 你可以设定前端页面数据集向后端请求刷新的时间间隔,单位秒\n如果你发现定时刷新,数据并没有变化,可能原因是您数据的缓存时间设定大于定时刷新的时间\n数据集缓存加速(PRO) # smartchart专业版提供内存加速技术,对数据库仅需请求一次,之后都是毫秒级响应\n间隔时间刷新,单位分钟,如设定 间隔时间为0.5, 则如果下一次访问时间超过30秒, 即触发数据刷新 固定时点刷新, 如设定 间隔时间 为-1, 则固定时点刷新, 即访问的时间超过固定的时点时(如下图每天09:25), 触发数据刷新 强制刷新, 访问url加上\u0026amp;refresh=Y, 则强制刷新数据, 此刷新不会影响间隔或固定刷新的时间, 不会更新下次同步时间 后台触发强制刷新 (PRO) # 请参考文档 后台主动触发刷新\n"},{"id":33,"href":"/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/%E8%87%AA%E5%AE%9A%E4%B9%89%E6%95%B0%E6%8D%AE%E6%BA%90/","title":"自定义数据源","section":"特殊数据源","content":"smartchart已实现大部分常用的数据源连接, 对于其它的, 您也可以使用python数据源进行处理 但是使用python数据源有一定的缺陷, 需要在dataset上写python代码, 不能复用 对于一些带连接信息的还需要重复写入 所以你还可以使用自定义数据源\n应用场景 # 未内置的数据源, 如需要使用sparkSQL, ES等 标准处理满足不了要求, 需要对数据进行预处理的情况 需要刷新时触发预警等自定义动作 需要自定义写入方法, 个性化查询需求, 甚至是实时爬取数据 使用方法 # 首先你需要新建一个python脚本文件, 如diy_conn.py 复制以下代码到这个文件, 然后编写你的自定义查询方法 def dataset(*args, **kwargs): \u0026#34;\u0026#34;\u0026#34; 返回查询数据集 :return: 二维数组或JSON字典 \u0026#34;\u0026#34;\u0026#34; sqlList = args[0] # 数据集编辑界面的输入已按分号拆分成数组 [sql1, sql2...] config = args[1] # 相关的配置字典{\u0026#39;host\u0026#39;,\u0026#39;port\u0026#39;,\u0026#39;user\u0026#39;,\u0026#39;password\u0026#39;,\u0026#39;db\u0026#39;} # 插入你的数据查询及处理代码, 生成result即可 result = [[]] return result def insert_dataset(*args, **kwargs): \u0026#34;\u0026#34;\u0026#34; 数据填表实现 \u0026#34;\u0026#34;\u0026#34; contents = args[0] # 传入的数据集二维数组格式 table = args[1] # 配置中的表名 config = args[3] # 相关的配置字典{\u0026#39;host\u0026#39;,\u0026#39;port\u0026#39;,\u0026#39;user\u0026#39;,\u0026#39;password\u0026#39;,\u0026#39;db\u0026#39;} # 插入你的写入数据逻辑代码 在任意的仪表盘开发界面中 \u0026ldquo;模板\u0026rdquo; \u0026ndash;\u0026gt; 点击上传图标, 将这个python文件上传即可 新建数据源, 驱动填写之前上传过的文件名, 比如我们这个是diy_conn, 其它参数按照你自定义的需求填写, 会自动传入你的自定义函数 之后你可以正常使用这个自定义数据源了\n如果你对python不熟悉, 也可按需定制, 你只需上传即可使用\n"},{"id":34,"href":"/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/Echarts%E7%BB%84%E4%BB%B6/","title":"Echarts组件","section":"3.图形开发","content":" 应用场景 # Smartchart提供了很多通用的图形,你可以在商店中直接使用 如果要个性化需要你进行自定义, 比如你可能需要在同一个图上展示柱形图和线性图\n开发前建意先观看视屏, 了解基础说明, 视屏有点老和现在界面不一样, 目前很多功能已经做成可视化配置, 理解过程即可, 具体以文档为准\nSmartchart数据库与图形的对话 Smartchart图形开发一 Smartchart图形开发二 获取原生echarts图形 # 首先我们在ECHART官网可能找一个你喜欢的图形, 如下简单柱形图链接: 打开我们可以看对应的option:\noption = { xAxis: { type: \u0026#39;category\u0026#39;, data: [\u0026#39;Mon\u0026#39;, \u0026#39;Tue\u0026#39;, \u0026#39;Wed\u0026#39;, \u0026#39;Thu\u0026#39;, \u0026#39;Fri\u0026#39;, \u0026#39;Sat\u0026#39;, \u0026#39;Sun\u0026#39;] }, yAxis: { type: \u0026#39;value\u0026#39; }, series: [{ data: [120, 200, 150, 80, 70, 110, 130], type: \u0026#39;bar\u0026#39; }] }; 转化为smartchart图形 # 复制到Smartchart图形编辑器, 点击\u0026quot;刀叉“ 图标(目前是魔法梆), 会自动进行初步转化 接下来我们就进行下改造, 请注意对比, 你只需照着复制即可\nlet dataset = __dataset__ //传入dataset let legend_label = ds_rowname(dataset) //可选, 自动获取legend let xlabel = dataset[0].splice(1) //x轴的标签列 dataset = ds_createMap(dataset) //转化成KV格式 //初始化series var series=[]; series.push({ data: dataset[legend_label[0]], //对应的第一个图列 type: \u0026#39;bar\u0026#39; }); series.push({ data: dataset[legend_label[1]], //对应的第二个图列 type: \u0026#39;line\u0026#39; }); option__name__ = { xAxis: { type: \u0026#39;category\u0026#39;, data: xlabel //X轴的标签 }, yAxis: { type: \u0026#39;value\u0026#39; }, series:series, }; charts.push(myChart__name__); 这样一个柱形+线性图就出来了 当然一个图形还有很多其它的元素, 比如标题, legend, 等等 更多option的配置项, 可以点击”!“号图标查看,你可以直接参考echarts的设定, 完全一样!!\n以下我们做了些简单的修改\noption__name__ = { title: { text: \u0026#39;自定义图示例\u0026#39;, left: \u0026#39;center\u0026#39; }, //定义标题的显示 tooltip: { trigger: \u0026#39;item\u0026#39;, formatter: \u0026#39;{a} \u0026lt;br/\u0026gt;{b} : {c}\u0026#39; //鼠标移动提示的格式 }, legend: { left: \u0026#39;left\u0026#39;, data: legend_label }, //定义图例的显示 xAxis: { type: \u0026#39;category\u0026#39;, data: xlabel }, //定义X轴的显示 yAxis: { type: \u0026#39;value\u0026#39; }, //图例定义 series:series, }; //关于自动化series, 可以参考以下代码 var series =[]; for (var i=1;i\u0026lt;dataset[0].length;i++){ series.push({type: \u0026#39;bar\u0026#39;}) } 是不是非常简单 Smartchart让你使用echarts没有门槛\nTIPS:\n如果你在图形编辑器中可以显示图形, 但是保存后在dashboard中无法, 首先检查下所有的mychart, option是否都有转化成带__name__, 如果都有,可能原因是你的代码中有mychart.setoption, 这样你可以在代码下方加上myChart__name__.setOption(option__name__);即可 如果你在开发界面的仪表盘能看到图形显示,但预览仪表盘时,不显示图形,一般都是因为你图形代码中js结束需加分号的地方没有添加导致的 "},{"id":35,"href":"/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E5%88%A0%E9%99%A4%E5%AE%B9%E5%99%A8/","title":"删除容器","section":"4.布局说明","content":"对于仪表盘中不再使用的数据集,你可能会考虑删除 首先smartchart推荐你不做删除,因为你可以保留他, 当你下次有新增数据集的需求时再拿出来 所以优先推荐使用隐藏的方法,你可以在数据集编辑界面找到他 如果你实在需要删除,可以在“报表”界面先中不需要容器后,选中删除,后保存\n"},{"id":36,"href":"/docs/5.%E5%8F%82%E6%95%B0%E5%8F%8A%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/%E7%AD%9B%E9%80%89%E5%99%A8%E6%8C%87%E5%8D%97/","title":"筛选器指南","section":"5.参数及联动钻取","content":" 通用实现方式 # SMARTCHART实现筛选最简单的方法只需要配一个控件即可:\n建立一个筛选清单数据集, 自动获取筛选的列表,那么可以这么写\nSelect xxxx as city from tablename..... 则会生成一个如下的数据集: [[\u0026#39;city\u0026#39;],[选项1],[选项2],..] 良好的习惯, 先保存在数据集 然后在筛选器数据集中的js编辑器(图形编辑器),填下如下代码:\n//如要要美化, 自已加样式, 只要保证id=\u0026#34;id_select__name__\u0026#34; let dataset=__dataset__; let table =\u0026#39;\u0026lt;span\u0026gt;标题\u0026lt;/span\u0026gt;\u0026lt;select id=\u0026#34;id_select__name__\u0026#34;\u0026gt;\u0026#39;; table = table + \u0026#39;\u0026lt;option value=\u0026#34;\u0026#34; selected\u0026gt;----\u0026lt;/option\u0026gt;\u0026#39;; for(let i=1;i\u0026lt;dataset.length;i++){ table = table + \u0026#39;\u0026lt;option\u0026gt;\u0026#39; + dataset[i][0] + \u0026#39;\u0026lt;/option\u0026gt;\u0026#39;; } table = table + \u0026#39;\u0026lt;/select\u0026gt;\u0026lt;/div\u0026gt;\u0026lt;/div\u0026gt;\u0026#39; dom__name__.innerHTML=table; 这个时候你已经可以看到筛选器了 现在我们来设定联动效果\n假设需要被筛选的数据集的SQL这样写,数据集的序号是0\n//那么在需要被联动的数据集中,如使用pcity做为参数写查询, 比如: select xx, xx, xx from tablename /* where xx = \u0026#39;$pcity\u0026#39; */ 现在回到我们筛选器数据集,点击标题的位置, 我们需要使0号图形被筛选器联动, 设置如下即可: 然后你就可以看到筛选效果了, 非常的简单方便, 需要多个图形被联动, 只需用逗号分隔即可 比如: 0, 2, 4\n"},{"id":37,"href":"/docs/7.%E6%8A%A5%E8%A1%A8%E5%B5%8C%E5%85%A5/%E5%8D%95%E9%A1%B5%E9%9D%A2%E5%B5%8C%E5%85%A5/","title":"单页面嵌入","section":"7.报表嵌入","content":" 嵌入报表 # 与单点登录类似, 单点登录用于直接登录到平台访问报表 但对于只嵌入报表, 用此方法更合适(需升级到5.3.11以上)\n嵌入的url: \u0026#39;/echart/?type={reportName}\u0026amp;visitor={visitor}\u0026amp;token={token}\u0026amp;stamp={stamp}\u0026#39; 参数说明: reportName: 报表名或报表ID visitor: 用户名(在smartchart平台中管理) stamp: 时间戳(1970年1月1日到生成时间的毫秒数) token: 采用sha1加密, token=SHA1(链接秘钥+stamp+visitor+reportName) 用户名和秘钥设定参考 数据服务API的config文件\n同时你需要将visitor加入到对应的报表权限查看访问\npython样列 # 以下为python版的url生成样列,你可以转化成你对应的开发语言\nimport time import hashlib import os SMART_CHART_URL = \u0026#39;http://127.0.0.1:8000\u0026#39; reportID = \u0026#39;报表ID\u0026#39; LOGIN_URL = SMART_CHART_URL + \u0026#39;/echart/?type={reportID}\u0026amp;visitor={visitor}\u0026amp;token={token}\u0026amp;stamp={stamp}\u0026#39; TOKEN = 链接秘钥 def get_smarturl(username, reportName): stamp = int(time.time() * 1000) visitor = username res = TOKEN + str(stamp) + visitor + reportID token = hashlib.sha1(res.encode(\u0026#39;utf-8\u0026#39;)).hexdigest() VISIT_DICT = { \u0026#34;visitor\u0026#34;: id, \u0026#34;stamp\u0026#34;: stamp, \u0026#34;token\u0026#34;: token, \u0026#34;reportID\u0026#34;: reportName } # 拼接好的url,直接访问 visit_url = LOGIN_URL.format(** VISIT_DICT) return visit_url 数据权限加密方法 # 如果你需要对用户进行一些数据权限控制, 可以避免用户越权访问 可以通过传入参数\u0026#34;id\u0026#34;, 如/echart/?type=xxx\u0026amp;visitor=xx\u0026amp;token=xx\u0026amp;stamp=xxxxx\u0026amp;id=xxx 后台会把这个id转化为参数名\u0026#34;_id\u0026#34;给对应的查询来进行数据权限控制 加密参数需把id加入, 例如id=john 那么 token=SHA1(链接秘钥+stamp+visitor+reportName+id) 全参数加密方法 # 如果需要将参数也加入认证中, 为保持兼容性, 我们把param这个参数改为params(具体参考参数文档中param的写法) \u0026#39;/echart/?type={reportName}\u0026amp;visitor={visitor}\u0026amp;token={token}\u0026amp;stamp={stamp}\u0026amp;params=xxxx\u0026#39; 加密参数把params加入, 例如params为 {\u0026#34;a\u0026#34;:\u0026#34;1\u0026#34;,\u0026#34;b\u0026#34;:2\u0026#34;} res = TOKEN + str(stamp) + visitor + reportName + \u0026#39;{\u0026#34;a\u0026#34;:\u0026#34;1\u0026#34;,\u0026#34;b\u0026#34;:2\u0026#34;}\u0026#39; "},{"id":38,"href":"/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E5%A4%87%E4%BB%BD%E6%81%A2%E5%A4%8D%E5%8F%8A%E7%89%88%E6%9C%AC/","title":"备份恢复及版本","section":"9.进阶开发 Pro","content":" 应用场景 # 本地仪表盘的备份恢复,版本管理 开发测试生产机之间的同步 具体使用方法请观看视屏 版本控制使用说明视屏\n使用方法 # 快速备份 # 可以在模板-\u0026gt;点击如下图标, 完成快速备份(注意会覆盖历史), 备份号统一为:SNAPSHOT 指定备份 # 你也可以在设定-\u0026gt;备份恢复 中进行按版本备份 查询备份 # 当不输入KEY值, 点击 本地备份时,可以查询此仪表盘已有的备份 备份恢复 # 备份可以在任意的仪表盘中进行恢复,如果是当前仪表盘, 仅输入KEY即可,比如:V01, 如果是跨仪表盘恢复, KEY需要带上仪表盘的编号如13_V01\n备份恢复参数说明 # 可以支持多种恢复模式, 只需要在KEY前面加上前缀即可, 如FORCEV01, FORCE13_V01.. FORCE: 删除自身所有数据集及高级设定,模板等,完全恢复备份 DATASET:只更新数据集及图形,模板,适用于测试上线正式 CHART: 只更新图形及模板,适用于前端变更上线\n跨服务器间同步 # 具体方法购买专业版本后提供\n使用以下流程, 可以使企业在使用最少资源做出最专业的可视化项目 # 前提条件: # 公司内部有技术人员(熟悉数据, 会写SQL) 服务器安装smartchart专业版 开发流程: # 由于公司内部人员是对业务最熟悉, 一般也都是后台数据管理相关的人员, 一般不太会有专职的前端开发和UI 所以数据开发人员可以使用smartchart开发仪表盘数据集, 并使用拖拽功能完成一个粗糙一点的框架和图形设计 一般情况下已经可以满足数据可视化的需求\n如果需要达到更专业的可视化效果, 可以外包前端/UI或在smartchart社区咨询, 由于需求变得非常简单 而前端开发又是一个通用技能, 可以使用非常廉价的费用获得最大的效果\n专业的事情专业来做, 才能达到效益最大化, 这是smartchart的设计理念 不管用什么工具, 在同等资源的投入下, 数据分析人员开发的可视化效果很难达到专业前端UI的效果 另外BI/数据开发人员的费用可是比前端高的, 也更稀缺\n前端开发只需本地安装smartchart, 而无需接触到公司数据库或数据接口, 开发完全解耦, 数据安全保障 smartchart可以将数据开发人员开发的仪表盘直接同步到前端开发的本地smartchart(仅会保留demo数据) 前端进行一些简单的美化工作即可, 无需对业务和数据进行理解, 花费的时间非常之少 前端开发完成后可以一键同步到smartchart服务端, 且可以只同步可视化部分 由于数据和展示是分离的, 所以数据开发和前端美化是可以同步进行 由于smartchart是一个平台化产品, 数据开发人员不熟悉前端也能在前端开发完成的基础上进行样式和图形的修改 "},{"id":39,"href":"/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E4%B8%8A%E4%BC%A0%E8%B5%84%E6%BA%90%E6%96%87%E4%BB%B6/","title":"上传资源文件","section":"模板开发","content":"点击 模板开发 中的菜单即可上传你的资源文件, 如css, js, 图片等 视屏介绍说明 常规上传 # 可直接上传单个文件或zip包上传, 注意zip包中不可以有中文文件名 上传后会提示引用路径为/static/custom/仪表盘ID/\u0026hellip;\n上传为共享资源 # 可把资源打包为zip文件, 上传名以usr_开头, 如usr_tp.zip 上传完后不会有路径提示, 引用路径为/static/custom/usr_tp/\u0026hellip;.\n上传自定义数据源或jar包 # 上传后不会有路径提示\n"},{"id":40,"href":"/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E7%AC%AC%E4%B8%80%E4%B8%AA%E4%BB%AA%E8%A1%A8%E7%9B%98/","title":"第一个仪表盘","section":"1.基础操作","content":"由于版本的变更, 一些图标可能会有一些变化, 但位置无太大的变化\n新建仪表盘 # 在开发模式下,滑动“开发管理” -\u0026gt;\u0026ldquo;仪表盘\u0026rdquo;-\u0026gt; \u0026ldquo;新增Dashboard\u0026rdquo; 填写相应信息后点击“保存” 点击进入仪表盘开发, 注意点击 \u0026ldquo;E\u0026rdquo; 字!! 点击新增(注意拖拽布局功能为PRO版本, 后续免费版本中将无法使用), 如果你坚持使用免费版本功能, 请使用左边的蓝色颜色的新增, 具体布局方式参考 数据集编辑 # 点开“数据集” 输入以下SQL后,点击“保存并刷新”, 关闭数据集编辑界面 select H1 as heroname, sum(qty) as 出场数 from smartdemo2 group by H1 order by sum(qty) desc 图形编辑 # 点开“图形编辑” 点击“云图标”,第一次使用可能要你进行登记,按提示操作即可, 在商店中找到合适的图形点击,会自动复制到剪贴板 贴粘到图形编辑器后,点击保存, 关闭图形编辑框 拖拽布局 # 重复以上步骤,再新增一个, 你可以使用拖拽的方式, 移动到不同的地方 "},{"id":41,"href":"/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E6%95%B0%E6%8D%AE%E9%9B%86%E6%87%92%E5%8A%A0%E8%BD%BD/","title":"数据集懒加载","section":"2.数据集说明","content":" 应用场景 # 类似于前后端开发, 后端会提供一些接口给前端, 但前端不一定需要在一打开页面就进行查询接口, 而是当有需要时再查询, 比如数据下载, 只有当用户有下载需求时再加载, 再比如有些与后台的数据联动, 我们只需要第一次加载时只显示第一层级, 点击时再加载其它层级\n开启数据集懒加载 # 你可以点击数据集的开发界面的\u0026quot;连接\u0026quot; 图标, 将\u0026quot;前端刷新(秒)\u0026quot; 修改为-1 这时当打开仪表盘时, 此数据集不会被加载\n应用 # 一般懒加载数据集主要是用来做数据查询的, 所以并不太需要显示图形, 所以我们主要是用于在图形中进行赋值操作 比如先在模板中定义一个全局变量: 然后修改图形编辑中的代码: 即刷新数据集时会进行变量赋值 如果您使用VUE, 那么会更方便, 你可以直接使用vapp.变量名 = dataset进行赋值\n查询数据 # 你可以随时手动触发数据集的刷新, 比如懒加载的数据集序号为0 你可以在你需要触发刷新的地方调用ds_refresh(0)即可刷新0号数据集并执行0号数据集中的JS代码\nTIPS 可以将懒加载的数据集同时转化为共享数据集(参考上文), 懒加载数据集将移到菜单栏显示\n"},{"id":42,"href":"/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/HTML%E7%BB%84%E4%BB%B6/","title":"Html组件","section":"3.图形开发","content":" 应用场景 # 输入控件,如输入框,筛选器,多选,按钮\u0026hellip; 显示组件, 文本, 图片, 视屏\u0026hellip; 表格组件 如果你还不熟悉html, 建意先花几分钟看下文档, 推荐 HTML基础 实际应用中有不熟悉的组件, 你都可以通过baidu搜索到, 如时间选择器 如何将html组件转化为smartchart组件 # 比如我们要实现一个有多选项和按钮的网页元素 从各大搜索平台上我们可以找到html的代码是:\n\u0026lt;label\u0026gt;\u0026lt;input type=\u0026#34;checkbox\u0026#34;\u0026gt;孙尚香\u0026lt;/label\u0026gt; ..... \u0026lt;button id=\u0026#39;id_select0\u0026#39;\u0026gt;提交\u0026lt;/button\u0026gt; 那么我们可以直接在图形编辑器写上\nlet dataset=__dataset__; let table = \u0026#39;\u0026#39;; table = `\u0026lt;label\u0026gt;\u0026lt;input type=\u0026#34;checkbox\u0026#34;\u0026gt;孙一香\u0026lt;/label\u0026gt; \u0026lt;label\u0026gt;\u0026lt;input type=\u0026#34;checkbox\u0026#34;\u0026gt;孙二香\u0026lt;/label\u0026gt; \u0026lt;label\u0026gt;\u0026lt;input type=\u0026#34;checkbox\u0026#34;\u0026gt;孙三香\u0026lt;/label\u0026gt;` table = table + \u0026#34;\u0026lt;button id=\u0026#39;id_select0\u0026#39;\u0026gt;提交\u0026lt;/button\u0026gt;\u0026#34; dom__name__.innerHTML=table; 但是由于我们是要通过传入的数据动态变化的,所以只需要做简单修改\nlet dataset=__dataset__; let table = \u0026#39;\u0026#39;; for (let i=1;i\u0026lt;dataset.length;i++){ table = `${table}\u0026lt;label\u0026gt;\u0026lt;input type=\u0026#34;checkbox\u0026#34;/\u0026gt;${dataset[i][0]}\u0026lt;/label\u0026gt; ` } table = table + \u0026#34;\u0026lt;button id=\u0026#39;id_select__name__\u0026#39;\u0026gt;提交\u0026lt;/button\u0026gt;\u0026#34; dom__name__.innerHTML=table; 所有html你都可以进行转化成smartchart组件, 你可以通过学习”万能表格系列视屏“ 来了解通用组件开发 第一波 第二波 第三波\n"},{"id":43,"href":"/docs/5.%E5%8F%82%E6%95%B0%E5%8F%8A%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/%E7%BB%84%E4%BB%B6%E8%87%AA%E5%AE%9A%E4%B9%89%E8%81%94%E5%8A%A8/","title":"组件自定义联动","section":"5.参数及联动钻取","content":" 应用场景 # Smartchart对于单项筛选有通用的组件, 可以直接配置即可,但对于个性化的筛选,需要你进行一些简单的定制化,以下就针对多项筛选联动的需求来介绍如何定制化你的筛选联动效果 通过此例,你可以了解如何自定义任意的联动效果 样列参考 # 以我们内置的仪表盘为例,\n第一步,新建一个数据集\n第二步,在新的数据集中编写查询\nselect distinct H1 as heroname from smartdemo2 limit 10 第三步,编辑此数据集的图形,可复制以下代码\n//select distinct xx from tablename let dataset=__dataset__; let table = \u0026#39;\u0026#39;; for (let i=1;i\u0026lt;dataset.length;i++){ table = `${table}\u0026lt;label\u0026gt;\u0026lt;input name=\u0026#34;select__name__\u0026#34; type=\u0026#34;checkbox\u0026#34; value=\u0026#34;${dataset[i][0]}\u0026#34; /\u0026gt;${dataset[i][0]}\u0026lt;/label\u0026gt; `; } table = table + \u0026#34;\u0026lt;button id=\u0026#39;id_select__name__\u0026#39;\u0026gt;提交\u0026lt;/button\u0026gt;\u0026#34;; dom__name__.innerHTML=table; $(\u0026#39;#id_select__name__\u0026#39;).click( function(){ let res = []; $(\u0026#34;input[name=\u0026#39;select__name__\u0026#39;]:checked\u0026#34;).each(function(i){ res.push(\u0026#34;\u0026#39;\u0026#34; + $(this).val() + \u0026#34;\u0026#39;\u0026#34;); }); filter_param[\u0026#39;H1\u0026#39;] = res.toString(); //参数赋值 ds_refresh(1); //刷新1号图形 } ) 第四步,在你要联动刷新数据集中增加代码\nselect H1 as heroname, sum(qty) as 出场数 from smartdemo2 where 1=1 /* and H1 in ($H1) */ --此处来新增 group by H1 order by sum(qty) desc 这样就完成了,任何其他需求,都可以采用类似方法自定义\nTIPS 如果你这个点击的图形又可能被其它图形来点击联动, 你需要加入如下unbind否则会触发多次刷新 $(\u0026rsquo;#id_select__name__\u0026rsquo;).unbind(\u0026lsquo;click\u0026rsquo;).click(\u0026hellip;..\n如果你想取消联动,恢复到初始效果, 你需要删除参数, 如: delete filter_param[\u0026lsquo;H1\u0026rsquo;]\n"},{"id":44,"href":"/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%95%B0%E6%8D%AE%E4%B8%8B%E8%BD%BD/","title":"数据下载","section":"9.进阶开发 Pro","content":" 应用场景: # 需要要下载数据集的数据到本地\n样例: # 可在\u0026quot;模板\u0026quot; 中新建一个下载按钮, 并指定一个ID,如id_down1, 拖拽到你需要的位置 在任意一个图形开发或js代码段中加入以下代码即可\n$(\u0026#39;#id_down1\u0026#39;).click(()=\u0026gt;{ ds_download(\u0026#39;报表数据.csv\u0026#39;, dataset); }); 这样就可以实现点击按钮下载数据了\n仅需要录活使用ds_download这个函数, 你可以开发出非常个性化的下载功能\nds_download(name, dataset) 参数说明: name: 文件名称 dataset: 可以是二维数组也可以是字符串 "},{"id":45,"href":"/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E8%BE%B9%E6%A1%86%E4%B8%8E%E8%A3%85%E9%A5%B0/","title":"边框与装饰","section":"模板开发","content":" 观看视屏 # 边框与装饰说明1 边框与背景说明2\n边框/装饰/背景(购买专业版提供使用方法) # "},{"id":46,"href":"/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E5%88%9B%E5%BB%BA%E8%BF%9E%E6%8E%A5%E6%B1%A0/","title":"创建连接池","section":"1.基础操作","content":" 如何新增数据源 # 在开发模式下,点击“开发管理”-\u0026gt;数据源-\u0026gt;新增 配置连接池参数,注意数据库填写是备注中有写的名称 你可以通过新建一个数据集来测试连接池的连通性\n点击“保存” 后,回到数据集列表 点击如下图标\u0026quot;E\u0026quot;,进入数据集开发界面 在开发界面调试 安全控制 # 你可以在“参数”中设定安全控制,可避免用户误操作导致前后端卡死 limit: 可限定最大返回数据数量(但实际数据库查询无limit,需通过mode控制) mode: 控制用户查询行为,默认为模式1\n模式 说明 0 严格模式,每次查询向数据库都会增加limit,MPP类型数据库可能会排序失效 1 开发模式,仅调试查询数据库都会增加limit,调试时MPP类型数据库可能会排序失效,但不影响实际 2 宽松模式,查询都不带limit, 仅控制返回limit,需开发者避免大查询 支持的数据源: # 数据库 驱动填写 需安装 使用说明 Mysql mysql 默认支持 Mysql连接池 mysqlpool Sqlite sqlite 默认支持 连接地址填写绝对路径 API 任意 默认支持 参考数据集说明文档 EXCEL 任意 默认支持 参考数据集说明文档 SQL Server mssql 需安装 pip install pymssql SQL Server连接池 mssqlpool ORACLE oracle pip install cx_Oracle ORACLE连接池 oraclepool PostgreSql gp pip install psycopg2 GP gp pip install psycopg2 Impala impala pip install impyla Hive hive pip install impyla DB2 db2 pip install ibm_db 达梦 dm pip install dmPython Python python pip install pandas, openpyxl 参考数据集-\u0026gt;特殊数据源 Redis redis pip install redis 参考数据集-\u0026gt;特殊数据源 Mongodb mongodb pip install pymongo 参考数据集-\u0026gt;特殊数据源 Clickhouse clickhouse pip install clickhouse_driver Elasticsearch es pip install elasticsearch==7.13.0 参考数据集-\u0026gt;特殊数据源 Sqlalchemy sqlalchemy pip install sqlalchemy 参考数据集-\u0026gt;特殊数据源 JDBC jdbc pip install JayDeBeApi 参考数据集-\u0026gt;特殊数据源 自定义 自定义 用户自由定义 参考数据集-\u0026gt;特殊数据源 "},{"id":47,"href":"/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E8%B0%83%E8%AF%95%E6%97%A5%E5%BF%97/","title":"调试日志","section":"3.图形开发","content":" 关于页面日志查看 # 大家可能比较熟悉使用F12来查看网页日志, 但有的同学会觉得这不够方便, 所以 在5.1.11后, smartchart加入了可以页面直接显示日志的功能\n在仪表盘中显示 # 你只需要点击如下菜单, 即可切换是否显示日志 当在刷新页面或执行时, 日志将直接显示在右上角中, 而且还能显示出对应出错的图表序号 在图形中显示 # smartchart基于python的使用习惯, 重定义的专用的日志打印函数print 你可以在图形编辑器中使用些函数即可打印日志 比如看看鼠标放在echarts图上params, 在编辑界面和console中都能看到日志, 方便你进行调试 不仅仅这些, 你可能会想写太多打印日志, 上线了不好 smartchart已为你想到这些, 如果你在仪表盘中没有开启日志显示, print函数是不会打印任何日志\n有了仪表盘日志显示, 我们还能做更多的事情, 比如实时显示你拖拽的坐标, 让你精确定位 "},{"id":48,"href":"/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%95%B0%E6%8D%AE%E5%A1%AB%E6%8A%A5/","title":"数据填报","section":"9.进阶开发 Pro","content":" 应用场景 # 收集用户端录入的数据 前端处理好的数据回写到任意系统 制做问卷系统 埋点应用 使用方法 # 新建数据集设定,格式如下: 只用指定表名 dataset={ \u0026#34;table\u0026#34;:\u0026#34;表名\u0026#34; } 你也可以指定字段, 比如 dataset={ \u0026#34;table\u0026#34;:\u0026#34;表名(字段1, 字段2)\u0026#34; } 在\u0026quot;容器\u0026quot;管理, 取消这个数据集激活, 并记录下来此数据集的ID, 比如132 在\u0026quot;模板\u0026quot;中编写录入组件代码, 具体可参考视屏\n\u0026lt;h1 class=\u0026#34;smtdrag\u0026#34; id=\u0026#34;id_1648895680659\u0026#34;\u0026gt;数据填报\u0026lt;/h1\u0026gt; \u0026lt;div class=\u0026#34;smtdrag\u0026#34; id=\u0026#34;id_1648895855760\u0026#34;\u0026gt; \u0026lt;label\u0026gt;用户\u0026lt;/label\u0026gt;\u0026lt;input id=\u0026#34;id_visitor\u0026#34;\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;div class=\u0026#34;smtdrag\u0026#34; id=\u0026#34;id_1648895859160\u0026#34;\u0026gt; \u0026lt;label\u0026gt;动作\u0026lt;/label\u0026gt;\u0026lt;input id=\u0026#34;id_action\u0026#34;\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;div class=\u0026#34;smtdrag\u0026#34; id=\u0026#34;id_1648895956207\u0026#34;\u0026gt; \u0026lt;button id=\u0026#34;idbtn01\u0026#34;\u0026gt;提交\u0026lt;/button\u0026gt; \u0026lt;/div\u0026gt; 在\u0026quot;模板\u0026quot; 中编写JS代码 $(\u0026#39;#idbtn01\u0026#39;).click(function(){ let visitor = $(\u0026#39;#id_visitor\u0026#39;).val(); let action = $(\u0026#39;#id_action\u0026#39;).val(); let dataset = [visitor, action]; print(ds_save(132, dataset)); //132数据集ID, dataset要写入的数据 }) 更多关于写入数据库的数据集格式说明 # 只写入一行数据, 样列如下: dataset = [\u0026#39;a\u0026#39;,\u0026#39;b\u0026#39;] 同时写入多行数据: dataset = [[], [\u0026#39;a1\u0026#39;,\u0026#39;b1\u0026#39;],[\u0026#39;a2\u0026#39;, \u0026#39;b2]] 如果需要自动记录写入者用户名: dataset = [\u0026#39;$username\u0026#39;, \u0026#39;b\u0026#39;] mongodb写入方式\nds_save(419, {\u0026#34;h1\u0026#34;:123, \u0026#34;h2\u0026#34;:\u0026#34;bb\u0026#34;}); ds_save(419, [[],{\u0026#34;h1\u0026#34;:123, \u0026#34;h2\u0026#34;:\u0026#34;aa\u0026#34;},{\u0026#34;h1\u0026#34;:1234, \u0026#34;h2\u0026#34;:\u0026#34;dd\u0026#34;}]); "},{"id":49,"href":"/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E6%A0%B7%E5%BC%8F%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B/","title":"样式快速上手","section":"模板开发","content":" 样式操作: # 要想大屏做得好, 样式要写得好 可是我们不是前端的同学也能写样式么 当然可以, 相信你观看完以下视屏即可\n快速上手样式开发\n基础样式入门: # CSS介绍 # CSS(Cascading Style Sheet,层叠样式表)定义如何显示HTML元素。 当浏览器读到一个样式表,它就会按照这个样式表来对文档进行格式化(渲染)。\nCSS语法 # CSS实例 每个CSS样式由两个组成部分:选择器和声明。声明又包括属性和属性值。每个声明之后用分号结束。 CSS注释\n/*这是注释*/ 注释是代码之母, smartchart编辑中你可以使用CTRL+/快捷注释\nCSS的几种引入方式 行内样式 行内式是在标记的style属性中设定CSS样式。不推荐大规模使用。\n\u0026lt;p style=\u0026#34;color: red\u0026#34;\u0026gt;Hello world.\u0026lt;/p\u0026gt; 内部样式 嵌入式是将CSS样式集中写在网页的标签对的标签对中。格式如下:\n\u0026lt;head\u0026gt; \u0026lt;style\u0026gt; p{ background-color: #2b99ff; } \u0026lt;/style\u0026gt; \u0026lt;/head\u0026gt; 外部样式 外部样式就是将css写在一个单独的文件中\n\u0026lt;link href=\u0026#34;mystyle.css\u0026#34; rel=\u0026#34;stylesheet\u0026#34; type=\u0026#34;text/css\u0026#34;/\u0026gt; CSS选择器 # 基本选择器\n元素选择器 p {color: \u0026#34;red\u0026#34;;} ID选择器 #i1 { background-color: red; } 类选择器 .c1 { font-size: 14px; } p .c1 { color: red; } 注意: 样式类名不要用数字开头(有的浏览器不认)。 标签中的class属性如果有多个,要用空格分隔。\n通用选择器\n* { color: white; } 组合选择器\n后代选择器 /*li内部的a标签设置字体颜色*/ li a { color: green; } 儿子选择器 /*选择所有父级是 \u0026lt;div\u0026gt; 元素的 \u0026lt;p\u0026gt; 元素*/ div\u0026gt;p { font-family: \u0026#34;Arial Black\u0026#34;, arial-black, cursive; } 毗邻选择器 /*选择所有紧接着\u0026lt;div\u0026gt;元素之后的\u0026lt;p\u0026gt;元素*/ div+p { margin: 5px; } 弟弟选择器 /*i1后面所有的兄弟p标签*/ #i1~p { border: 2px solid royalblue; } 属性选择器 /*用于选取带有指定属性的元素。*/ p[title] { color: red; } /*用于选取带有指定属性和值的元素。*/ p[title=\u0026#34;213\u0026#34;] { color: green; } /*找到所有title属性以hello开头的元素*/ [title^=\u0026#34;hello\u0026#34;] { color: red; } /*找到所有title属性以hello结尾的元素*/ [title$=\u0026#34;hello\u0026#34;] { color: yellow; } /*找到所有title属性中包含(字符串包含)hello的元素*/ [title*=\u0026#34;hello\u0026#34;] { color: red; } /*找到所有title属性(有多个值或值以空格分割)中有一个值为hello的元素:*/ [title~=\u0026#34;hello\u0026#34;] { color: green; } 分组和嵌套\n分组 当多个元素的样式相同的时候,我们没有必要重复地为每个元素都设置样式,我们可以通过在多个选择器之间使用逗号分隔的分组选择器来统一设置元素样式。 例如: div, p { color: red; } 上面的代码为div标签和p标签统一设置字体为红色。 嵌套 多种选择器可以混合起来使用,比如:.c1类内部所有p标签设置字体颜色为红色。 .c1 p { color: red; } 伪类选择器\n/* 未访问的链接 */ a:link { color: #FF0000 } /* 鼠标移动到链接上 */ a:hover { color: #FF00FF } /* 选定的链接 */ a:active { color: #0000FF } /* 已访问的链接 */ a:visited { color: #00FF00 } /*input输入框获取焦点时样式*/ input:focus { outline: none; background-color: #eee; } 伪元素选择器\nfirst-letter 常用的给首字母设置特殊样式: p:first-letter { font-size: 48px; color: red; } before /*在每个\u0026lt;p\u0026gt;元素之前插入内容*/ p:before { content:\u0026#34;*\u0026#34;; color:red; } after /*在每个\u0026lt;p\u0026gt;元素之后插入内容*/ p:after { content:\u0026#34;[?]\u0026#34;; color:blue; } before和after多用于清除浮动。 选择器的优先级 # CSS继承 继承是CSS的一个主要特征,它是依赖于祖先-后代的关系的。继承是一种机制,它允许样式不仅可以应用于某个特定的元素,还可以应用于它的后代。例如一个body定义了的字体颜色值也会应用到段落的文本中。 body { color: red; } 此时页面上所有标签都会继承body的字体颜色。然而CSS继承性的权重是非常低的,是比普通元素的权重还要低的0。 我们只要给对应的标签设置字体颜色就可覆盖掉它继承的样式。 p { color: green; } 选择器的优先级 我们上面学了很多的选择器,也就是说在一个HTML页面中有很多种方式找到一个元素并且为其设置样式,那浏览器根据什么来决定应该应用哪个样式呢? 其实是按照不同选择器的权重来决定的,具体的选择器权重计算方式如下图: 除此之外还可以通过添加 !important方式来强制让样式生效,但并不推荐使用。 因为如果过多的使用!important会使样式文件混乱不易维护。 万不得已可以使用!important\nCSS属性相关 # 宽和高\nwidth属性可以为元素设置宽度。 height属性可以为元素设置高度。 块级标签才能设置宽度,内联标签的宽度由内容来决定。 字体属性\n文字字体 font-family可以把多个字体名称作为一个“回退”系统来保存。如果浏览器不支持第一个字体,则会尝试下一个。浏览器会使用它可识别的第一个值。 简单实例: body { font-family: \u0026#34;Microsoft Yahei\u0026#34;, \u0026#34;微软雅黑\u0026#34;, \u0026#34;Arial\u0026#34;, sans-serif } 字体大小 p { font-size: 14px; } 如果设置成inherit表示继承父元素的字体大小值。 字重(粗细) font-weight用来设置字体的字重(粗细)。 值描述normal默认值,标准粗细bold粗体bolder更粗lighter更细100~900设置具体粗细,400等同于normal,而700等同于boldinherit继承父元素字体的粗细值 文本颜色 color 颜色是通过CSS最经常的指定: 十六进制值 - 如: #FF0000 一个RGB值 - 如: RGB(255,0,0) 颜色的名称 - 如: red 还有rgba(255,0,0,0.3),第四个值为alpha, 指定了色彩的透明度/不透明度,它的范围为0.0到1.0之间。 文字属性\n文字对齐 text-align 属性规定元素中的文本的水平对齐方式。 值描述left左边对齐 默认值right右对齐center居中对齐justify两端对齐 文字装饰 text-decoration 属性用来给文字添加特殊效果。 值描述none默认。定义标准的文本。underline定义文本下的一条线。overline定义文本上的一条线。line-through定义穿过文本下的一条线。inherit继承父元素的text-decoration属性的值。 常用的为去掉a标签默认的自划线: a { text-decoration: none; } 首行缩进 将段落的第一行缩进 32像素: p { text-indent: 32px; } 背景属性\n/*背景颜色*/ background-color: red; /*背景图片*/ background-image: url(\u0026#39;1.jpg\u0026#39;); /* 背景重复 repeat(默认):背景图片平铺排满整个网页 repeat-x:背景图片只在水平方向上平铺 repeat-y:背景图片只在垂直方向上平铺 no-repeat:背景图片不平铺 */ background-repeat: no-repeat; /*背景位置*/ background-position: left top; /*background-position: 200px 200px;*/ 支持简写: background:#336699 url(\u0026#39;1.png\u0026#39;) no-repeat left top; 使用背景图片的一个常见案例就是很多网站会把很多小图标放在一张图片上,然后根据位置去显示图片。减少频繁的图片请求。 边框\n边框属性 border-width border-style border-color #i1 { border-width: 2px; border-style: solid; border-color: red; } 通常使用简写方式: #i1 { border: 2px solid red; } 边框样式 值描述none无边框。dotted点状虚线边框。dashed矩形虚线边框。solid实线边框。 除了可以统一设置边框外还可以单独为某一个边框设置样式,如下所示: #i1 { border-top-style:dotted; border-top-color: red; border-right-style:solid; border-bottom-style:dotted; border-left-style:none; } border-radius 用这个属性能实现圆角边框的效果。 将border-radius设置为长或高的一半即可得到一个圆形。 display属性\n用于控制HTML元素的显示效果。 值意义display:\u0026#34;none\u0026#34;HTML文档中元素存在,但是在浏览器中不显示。一般用于配合JavaScript代码使用。display:\u0026#34;block\u0026#34;默认占满整个页面宽度,如果设置了指定宽度,则会用margin填充剩下的部分。display:\u0026#34;inline\u0026#34;按行内元素显示,此时再设置元素的width、height、margin-top、margin-bottom和float属性都不会有什么影响。display:\u0026#34;inline-block\u0026#34;使元素同时具有行内元素和块级元素的特点。 display:\u0026#34;none\u0026#34;与visibility:hidden的区别: visibility:hidden: 可以隐藏某个元素,但隐藏的元素仍需占用与未隐藏之前一样的空间。也就是说,该元素虽然被隐藏了,但仍然会影响布局。 display:none: 可以隐藏某个元素,且隐藏的元素不会占用任何空间。也就是说,该元素不但被隐藏了,而且该元素原本占用的空间也会从页面布局中消失。 CSS盒子模型\nmargin: 用于控制元素与元素之间的距离;margin的最基本用途就是控制元素周围空间的间隔,从视觉角度上达到相互隔开的目的。 padding: 用于控制内容与边框之间的距离; Border(边框): 围绕在内边距和内容外的边框。 Content(内容): 盒子的内容,显示文本和图像。 margin外边距 .margin-test { margin-top:5px; margin-right:10px; margin-bottom:15px; margin-left:20px; } 推荐使用简写: .margin-test { margin: 5px 10px 15px 20px; } 顺序:上右下左 常见居中: .mycenter { margin: 0 auto; } padding内填充 .padding-test { padding-top: 5px; padding-right: 10px; padding-bottom: 15px; padding-left: 20px; } 推荐使用简写: .padding-test { padding: 5px 10px 15px 20px; } 顺序:上右下左 补充padding的常用简写方式: 提供一个,用于四边; 提供两个,第一个用于上-下,第二个用于左-右; 如果提供三个,第一个用于上,第二个用于左-右,第三个用于下; 提供四个参数值,将按上-右-下-左的顺序作用于四边; float\n在 CSS 中,任何元素都可以浮动。 浮动元素会生成一个块级框,而不论它本身是何种元素。 关于浮动的两个特点: 浮动的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止。 由于浮动框不在文档的普通流中,所以文档的普通流中的块框表现得就像浮动框不存在一样。 三种取值 left:向左浮动 right:向右浮动 none:默认值,不浮动 overflow溢出属性\n值描述visible默认值。内容不会被修剪,会呈现在元素框之外。hidden内容会被修剪,并且其余内容是不可见的。scroll内容会被修剪,但是浏览器会显示滚动条以便查看其余的内容。auto如果内容被修剪,则浏览器会显示滚动条以便查看其余的内容。inherit规定应该从父元素继承 overflow 属性的值。 overflow(水平和垂直均设置) overflow-x(设置水平方向) overflow-y(设置垂直方向) 定位(position)\nstatic static 默认值,无定位,不能当作绝对定位的参照物,并且设置标签对象的left、top等值是不起作用的的。 relative(相对定位) 相对定位是相对于该元素在文档流中的原始位置,即以自己原始位置为参照物。有趣的是,即使设定了元素的相对定位以及偏移值,元素还占有着原来的位置,即占据文档流空间。对象遵循正常文档流,但将依据top,right,bottom,left等属性在正常文档流中偏移位置。而其层叠通过z-index属性定义。 注意:position:relative的一个主要用法:方便绝对定位元素找到参照物。 absolute(绝对定位) 定义:设置为绝对定位的元素框从文档流完全删除,并相对于最近的已定位祖先元素定位,如果元素没有已定位的祖先元素,那么它的位置相对于最初的包含块(即body元素)。元素原先在正常文档流中所占的空间会关闭,就好像该元素原来不存在一样。元素定位后生成一个块级框,而不论原来它在正常流中生成何种类型的框。 重点:如果父级设置了position属性,例如position:relative;,那么子元素就会以父级的左上角为原始点进行定位。这样能很好的解决自适应网站的标签偏离问题,即父级为自适应的,那我子元素就设置position:absolute;父元素设置position:relative;,然后Top、Right、Bottom、Left用百分比宽度表示。 另外,对象脱离正常文档流,使用top,right,bottom,left等属性进行绝对定位。而其层叠通过z-index属性定义。 fixed(固定) fixed:对象脱离正常文档流,使用top,right,bottom,left等属性以窗口为参考点进行定位,当出现滚动条时,对象不会随着滚动。而其层叠通过z-index属性 定义。 注意点: 一个元素若设置了 position:absolute | fixed; 则该元素就不能设置float。这 是一个常识性的知识点,因为这是两个不同的流,一个是浮动流,另一个是“定位流”。但是 relative 却可以。因为它原本所占的空间仍然占据文档流。 在理论上,被设置为fixed的元素会被定位于浏览器窗口的一个指定坐标,不论窗口是否滚动,它都会固定在这个位置。 z-index\n#i2 { z-index: 999; } 设置对象的层叠顺序。 z-index 值表示谁压着谁,数值大的压盖住数值小的, 只有定位了的元素,才能有z-index,也就是说,不管相对定位,绝对定位,固定定位,都可以使用z-index,而浮动元素不能使用z-index z-index值没有单位,就是一个正整数,默认的z-index值为0如果大家都没有z-index值,或者z-index值一样,那么谁写在HTML后面,谁在上面压着别人,定位了元素,永远压住没有定位的元素。 从父现象:父亲怂了,儿子再牛逼也没用 opacity 用来定义透明效果。取值范围是0~1,0是完全透明,1是完全不透明。\n"},{"id":50,"href":"/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E5%BA%94%E7%94%A8%E6%A8%A1%E6%9D%BF/","title":"应用模板","section":"1.基础操作","content":" 应用场景 # 你可以快速应用开发好的模板,极大的提高你的开发和学习效率\n应用本地模板 # 你可以快速应用本地备份的模板, 我们内置了一个 通用的数据查询和下载模板 , 你可以尝试\n新建一个全新的dashboard, 不要放任何报表, 点击保存且编辑后, 下方可以看到下载链接, 然后点击下载即可直接应用 输入\u0026quot;01_SMARTCHART\u0026quot;, 点击本地恢复即可 更多本地备份恢复参考\n应用商店模板 # 方法同上\u0026quot;应用本地模板\u0026quot;, 注意应用商店模板为收费增值服务\n你可以点击 模板查询, 查看相应的价格后在 TB购买即可获取下载密钥 如果是全新的仪表盘, 直接输入下载密钥, 点击\u0026quot; 商城下载 \u0026ldquo;即可 如果仪表盘中有数据集且不再需要, 可以在下载密钥前面加上FORCE即可自动清空已有数据集后自动下载 注意模板太廉价,购买后并没有咨询服务,请务必自行了解如何使用\n资源文件放置路径 有些资源会离线打包提供给你, 只需上传即可, 上传方法参考\n如果不清楚可以观看视屏说明 使用方法可参考视屏: 一键应用模板\n"},{"id":51,"href":"/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E5%90%8E%E5%8F%B0API%E5%88%B7%E6%96%B0/","title":"后台 Api刷新","section":"9.进阶开发 Pro","content":" 应用场景 # 有ETL流程,需要等待后台数据刷新完成后,再触发仪表盘的刷新,数据未完成刷新,仪表盘不刷新 针对有一些耗时的查询, 虽然smartchart有缓存加速, 但是在第一次刷新时可能不能达到极速 用户需要随时都能体验到极速的打开效果 使用后台API刷新,建意将仪表盘中数据集的缓存时间设置长一些,比如2天(2880分钟)\n后台数据主动刷新接口 # (购买专业版本后支持)\n你需要在setting.py中设定API_TOKEN API_TOKEN = \u0026#39;xxxxxxxx\u0026#39; 找到你要刷新的仪表盘编码, 你可以在打开的仪表盘url上面找到这个type id\n后台访问如下api url即可\nhttp://ip:端口/echart/refresh_ds/?type=你的报表ID\u0026amp;token=你设定的API_TOKEN 关于定时刷新 # 为保持产品的轻量化及坚持专业的产品做专业的事情, 归一化统一化的架构设计, 我们不会集成相关调度系统, 一般我们推荐使用您自有的调度工具或平台, 如airflow, 我们也有相关的配套产品\n如果您仅仅是简单应用, 也无需使用专用调度来增加运维复杂度, 可以使用linux自带的即可\n新建一个sh文件, 假设目录在/data/smartchart vim refresh_smartchart.sh 写入需要刷新的脚本 echo start refresh $(date \u0026#34;+%Y-%m-%d %H:%M:%S\u0026#34;) curl http://ip:端口/echart/?type=你的报表ID1\u0026amp;token=你设定的API_TOKEN curl http://ip:端口/echart/?type=你的报表ID2\u0026amp;token=你设定的API_TOKEN echo end refresh $(date \u0026#34;+%Y-%m-%d %H:%M:%S\u0026#34;) 如果你的网址是https, 可如下方法使用curl\ncurl -k --insecure \u0026#34;https://www.baidu.com” 修改为可执行文件 chmod 775 refresh_smartchart.sh 使用crontab来定时执行 # 编辑crontab crontab -e # 比如需要每天晚上5点10分执行 10 5 * * * /data/smartchart/refresh_smartchart.sh \u0026gt;\u0026gt;/data/smartchart/log.txt 2\u0026gt;\u0026amp;1 # 定时参数说明 * * * * * - - - - - | | | | | | | | | +----- 星期中星期几 (0 - 6) (星期天 为0) | | | +---------- 月份 (1 - 12) | | +--------------- 一个月中的第几天 (1 - 31) | +-------------------- 小时 (0 - 23) +------------------------- 分钟 (0 - 59) "},{"id":52,"href":"/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/IDE%E5%BC%80%E5%8F%91%E6%A8%A1%E5%BC%8F/","title":"ID E开发模式","section":"模板开发","content":" 应用场景 # 如果您是一个资深的前端开发者 可能不需要使用smartchart组件,仅需使用到数据集 你希望在IDE(如VS code)中开发然后打包发布 非专用人士,请不要尝试这种方式 开发方式 # 在模板中使用basesimple 此时smartchart不会引用任何echarts, vue组件, 完全由您自已控制引入 , 你可以直接采用以下代码替换模板中的代码\n{% extends \u0026#34;echart/basesimple.html\u0026#34; %}{% block head %} \u0026lt;!--head区域的引用或代码--\u0026gt; {% endblock %}{% block body %} \u0026lt;!--在此区间粘入body相关代码--\u0026gt; {% endblock %}{% block javascript %} \u0026lt;!--粘入js相关引用或代码--\u0026gt; {% endblock %}{% block footer %}{% endblock %} 如何使用数据集接口 # 按照自由开发模式中, 新增一个图形, 然后修改数据集为通用且懒加载数据集 修改对应图形编辑器, 使数据赋值给一个全局变量或vue 在IDE中开发 # 由于你在开发中仅需要用到filter_param及ds_refresh, 建意新建一个js文件, 文件内容:\n//下面定义全局变量, 发布时需放入smartchart模板的script标签中 var mypublicdata1 = xxxx; ..... //以下为辅助方法, 发布时, 无需放入smartchart模板中 var filter_param = {}; function ds_refresh(num){ if(num === 0){你对应的图形中赋值代码,调试代码} if(num === 1){....} ...... } 然后将这个js文件在你的项目中引用调试使用\n如何部署到smartchart # 打包完成后会有相应的css, js 和index.html文件, 将index.html中的代码复制贴粘到对应的模板区域中即可\n上传css,js 修改css, js 相关引用路径 去除之前定义的js辅助开发文件引用, 如果有定义全局变量, 将全局变量定义复制到模板js区域 "},{"id":53,"href":"/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E6%9D%83%E9%99%90%E7%AE%A1%E7%90%86/","title":"权限管理","section":"1.基础操作","content":"目前的权限管理,大概如下:\n开发者权限 # 你点击DEV后, 才会出进入后台的图标, 在后台中你可以控制用户的开发权限 新建用户默认是没有开发权限的, 在首页也看不到任何开发相关的菜单\n如果你需要给用户开发权限, 需要设定如下: Dashboard报表查看权限 # 你可以在 仪表盘设定 中进行权限管理 全局编辑或查看权限 由平台用户组或用户权限配置, 如果用户需要查看报表, 需先分配到有查看权限的组中, 默认加入集团组可以具备查看权限 在dashboard设定页面中可针对人员来分配 编辑权限, 有编辑权限同时也会满足查看权限 在dashboard设定页面中可针对组来分配 查看权限 未上线 的报表, 只会在编辑页面中出现, 可以预览 公开 的报表, 如没有分配编辑权限,在编辑页面中不出现, 但在查看页面所有人可见,你可以共享给所有人,访问url: http://xxxxx:8000/echart?type=你的仪表盘名称 手机端过滤, 你可以通过 \u0026ldquo;全端\u0026rdquo;,\u0026ldquo;电脑端\u0026rdquo; 选项实现, 当勾选 \u0026ldquo;全端\u0026rdquo; 时, 手机端电脑端都会显示, 当未勾选 全端, 也不勾选 电脑端时, 只会在 手机显示, 反之只在电脑端显示 总结 # 在编辑入口只会显示 有按人员分配编辑权限的报表清单, 在查看入口中会显示已启用且上线且(已分配查看权限或编辑权限或公开)的报表 所以你可以么这么搭配: 对于通用报表可以所有人访问的, 但你又不想让他在清单中显示, 你可以将他设为公开但不上线 对于开发中的报表, 你可以设为未上线\n"},{"id":54,"href":"/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/webSocket%E6%96%B9%E5%BC%8F/","title":"Web Socket方式","section":"9.进阶开发 Pro","content":" 应用场景 # 对于实时程度要求比较高的情况下, 如果你后端已有实现websocket的接口, smartchart也可以很方便的接入 参考以下步骤即可\n在\u0026quot;模板\u0026quot;中定义一个全局变量, 如ws_data 编写连接和接收代码段逻辑 在接收代码段加入ds_refresh, 如要刷新0号图形, 则加入ds_refresh(0) 在\u0026quot;高级\u0026quot;设定中加入共享数据集设定, 把ws_data映射到0号图形即可 代码段参考 # let ws_data = [[\u0026#39;初始化\u0026#39;,\u0026#39;V\u0026#39;],[\u0026#39;A\u0026#39;,\u0026#39;2\u0026#39;]]; let ws = null; if(\u0026#39;webSocket\u0026#39; in window){ print(\u0026#39;支持webSocket\u0026#39;); ws = new webSocket(\u0026#39;ws://127.0.0.1:2222/abc\u0026#39;); //连接成功 ws.onopen = function(){ print(\u0026#39;ws连接成功\u0026#39;); } //接收消息 ws.onmessage = function(evt){ ws_data = evt.data; ds_refresh(0); } } else{ print(\u0026#39;浏览器不支持ws\u0026#39;) } "},{"id":55,"href":"/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E5%8A%A8%E7%94%BB%E6%95%88%E6%9E%9C/","title":"动画效果","section":"模板开发","content":" 自动旋转效果 # 在\u0026quot;模板\u0026quot;的style中加入以下样式\n@-webkit-keyframes spin { from {-webkit-transform: rotate(0deg);} to {-webkit-transform: rotate(360deg);} } @keyframes spin { from {transform: rotate(0deg);} to {transform: rotate(360deg);} } .Rotate { -webkit-animation: spin 3s linear 3s 5 alternate; animation: spin 3s linear infinite; } 如需任意组件自动旋转, 只需将Rotate这个类给到这个组件即可, 比如图形\n\u0026lt;img class=\u0026#34;Rotate\u0026#34; src=\u0026#34;https://www.smartchart.cn/media/editor/smc162_20220407150432307320.png\u0026#34;\u0026gt; 组件变形 # 常见变形沿着Y轴, 其它变形方式自已搜索, 比如需要0号,1号图形变形的样式写法\n#container_0{transform:skewY(10deg);} #container_1{transform:skewY(-10deg);} 效果如下: "},{"id":56,"href":"/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E7%BC%96%E8%BE%91%E5%99%A8%E5%BF%AB%E6%8D%B7%E9%94%AE/","title":"编辑器快捷键","section":"模板开发","content":" 功能 WIN MAC 说明 显示菜单 CTRL-, Command-, 折叠其它 Alt-0 Command-Option-0 查找替换 Ctrl-F Command-F 重复选中 Ctrl-D Command-D 5.6以前的版本是删除所选 注释选中 Ctrl-/ Command-/ 取消修改 Ctrl-z Command-z 重新执行 Ctrl-y Command-y 选中大写 Ctrl-U Ctrl-U 选中小写 SHIFT-Ctrl-U SHIFT-Ctrl-U "},{"id":57,"href":"/docs/10.%E5%85%B6%E5%AE%83/FAQ/","title":"Faq","section":"10.其它","content":" FAQ # 启动显示 以一种访问权限不允许的方式做了一个访问套接字的尝试 出现这种情况在Windows中很常见,就是端口被占用,酷狗音乐会占用8000端口 使用netstat -ano|findstr 8000 找到进程号 使用taskkill /pid 进程号 /F\n输入命令找不到smartchart 检查你是否有安装多个python环境出现环境变量冲突,请卸载一个或取消一个环境变量\n如法安装pip 请确认在安装python时,有没有加入环境变量, 可自行加入, 或卸载重装\n关于mac版本安装后的各种问题 目前来看最大的可能是,/Library/Developer/CommandLineTools这个目录下有python3,应该是在某一个版本的Xcode command line tools安装时生成的 可以先把python3全部卸载,再重新按说明安装,命令行中输入python3 和 pip3, 找不到command时才说明完全卸载成功\nsudo rm -rf /Library/Developer/CommandLineTools sudo rm -f /usr/bin/python3 如果密码忘记了怎么办 命令行输入smartchart changepassword 你的用户名\n"},{"id":58,"href":"/docs/10.%E5%85%B6%E5%AE%83/%E8%AF%95%E7%94%A8%E6%BF%80%E6%B4%BB%E8%AF%B4%E6%98%8E/","title":"试用激活说明","section":"10.其它","content":"试用专业版激活码需要每3天激活一次,激活方式: 由于开发很忙, 文档可能会写得有不尽之处, 多多包涵\n"},{"id":59,"href":"/docs/11.%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97/Linux/SQLite3%E7%89%88%E6%9C%AC%E9%94%99%E8%AF%AF/","title":"Sqlite3版本错误","section":"Linux","content":"SQLite3版本错误 在部分操作系统下(比如CentOS 7)使用SQLite3数据库运行会出现如下的错误提示:\ndjango.core.exceptions.ImproperlyConfigured: SQLite 3.8.3 or later is required (found 3.7.17). 这表明操作系统自带的sqlite3版本过低,需要将系统的sqlite3进行升级。\n以下是一种方法,来自于 StackOverlow:\n1、下载新版本的SQLite3\nwget https://www.sqlite.org/2019/sqlite-autoconf-3290000.tar.gz 2、解压文件\ntar zxvf sqlite-autoconf-3290000.tar.gz 3、进行解压后的目录\ncd sqlite-autoconf-3290000 4、配置安装目录\n./configure --prefix=$HOME/opt/sqlite 5、编译安装\nmake \u0026amp;\u0026amp; make install 6、指定环境变量\nexport PATH=$HOME/opt/sqlite/bin:$PATH export LD_LIBRARY_PATH=$HOME/opt/sqlite/lib export LD_RUN_PATH=$HOME/opt/sqlite/lib 完成之后可以运行sqlite3 \u0026ndash;version 命令来查看当前的SQLite3版本。\n"},{"id":60,"href":"/docs/11.%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97/Linux/%E7%94%9F%E4%BA%A7%E9%83%A8%E7%BD%B2/","title":"生产部署","section":"Linux","content":"购买专业版本,提供企业生产部署及无网离线部署方案\n"},{"id":61,"href":"/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/Elasticsearch%E6%95%B0%E6%8D%AE%E6%BA%90/","title":"Elasticsearch数据源","section":"特殊数据源","content":" 数据源配置方法 # 查询方法 # 更多查询方法参考 # 模糊查询 body = { \u0026#39;query\u0026#39;: { # 查询命令 \u0026#39;match\u0026#39;: { # 查询方法:模糊查询(会被分词)。比如此代码,会查到只包含:“我爱你”, “中国”的内容 \u0026#39;name\u0026#39;: \u0026#39;刘\u0026#39; } }, \u0026#39;size\u0026#39;: 20 # 不指定默认是10,最大值不超过10000(可以修改,但是同时会增加数据库压力) } term,精准单值查询 # 注:此方法只能查询一个字段,且只能指定一个值。类似于mysql中的where ziduan=\u0026#39;a\u0026#39; body ={ \u0026#39;query\u0026#39;:{ \u0026#39;term\u0026#39;:{ \u0026#39;ziduan1.keyword\u0026#39;: \u0026#39;刘婵\u0026#39; # 查询内容等于“我爱你中国的”的数据。查询中文,在字段后面需要加上.keyword # \u0026#39;ziduan2\u0026#39;: \u0026#39;liuchan\u0026#39; } } } erms,精准多值查询 #此方法只能查询一个字段,但可以同时指定多个值。类似于mysql中的where ziduan in (a, b,c...) body ={ \u0026#34;query\u0026#34;:{ \u0026#34;terms\u0026#34;:{ \u0026#34;ziduan1.keyword\u0026#34;: [\u0026#34;刘婵\u0026#34;, \u0026#34;赵云\u0026#34;] # 查询ziduan1=\u0026#34;刘婵\u0026#34;或=赵云...的数据 } } } multi_match,多字段查询 # 查询多个字段中都包含指定内容的数据 body = { \u0026#34;query\u0026#34;:{ \u0026#34;multi_match\u0026#34;:{ \u0026#34;query\u0026#34;:\u0026#34;我爱你中国\u0026#34;, # 指定查询内容,注意:会被分词 \u0026#34;fields\u0026#34;:[\u0026#34;ziduan1\u0026#34;, \u0026#34;ziduan2\u0026#34;] # 指定字段 } } } prefix,前缀查询 body = { \u0026#39;query\u0026#39;: { \u0026#39;prefix\u0026#39;: { \u0026#39;ziduan.keyword\u0026#39;: \u0026#39;我爱你\u0026#39; # 查询前缀是指定字符串的数据 } } } # 注:英文不需要加keyword wildcard,通配符查询 body = { \u0026#39;query\u0026#39;: { \u0026#39;wildcard\u0026#39;: { \u0026#39;ziduan1.keyword\u0026#39;: \u0026#39;?刘婵*\u0026#39; # ?代表一个字符,*代表0个或多个字符 } } } # 注:此方法只能查询单一格式的(都是英文字符串,或者都是汉语字符串)。两者混合不能查询出来。 regexp,正则匹配 body = { \u0026#39;query\u0026#39;: { \u0026#39;regexp\u0026#39;: { \u0026#39;ziduan1\u0026#39;: \u0026#39;W[0-9].+\u0026#39; # 使用正则表达式查询 } } } bool,多条件查询 # must:[] 各条件之间是and的关系 body = { \u0026#34;query\u0026#34;:{ \u0026#34;bool\u0026#34;:{ \u0026#39;must\u0026#39;: [{\u0026#34;term\u0026#34;:{\u0026#39;ziduan1.keyword\u0026#39;: \u0026#39;我爱你中国\u0026#39;}}, {\u0026#39;terms\u0026#39;: {\u0026#39;ziduan2\u0026#39;: [\u0026#39;I love\u0026#39;, \u0026#39;China\u0026#39;]}}] } } } # should: [] 各条件之间是or的关系 body = { \u0026#34;query\u0026#34;:{ \u0026#34;bool\u0026#34;:{ \u0026#39;should\u0026#39;: [{\u0026#34;term\u0026#34;:{\u0026#39;ziduan1.keyword\u0026#39;: \u0026#39;我爱你中国\u0026#39;}}, {\u0026#39;terms\u0026#39;: {\u0026#39;ziduan2\u0026#39;: [\u0026#39;I love\u0026#39;, \u0026#39;China\u0026#39;]}}] } } } # must_not:[]各条件都不满足 body = { \u0026#34;query\u0026#34;:{ \u0026#34;bool\u0026#34;:{ \u0026#39;must_not\u0026#39;: [{\u0026#34;term\u0026#34;:{\u0026#39;ziduan1.keyword\u0026#39;: \u0026#39;我爱你中国\u0026#39;}}, {\u0026#39;terms\u0026#39;: {\u0026#39;ziduan2\u0026#39;: [\u0026#39;I love\u0026#39;, \u0026#39;China\u0026#39;]}}] } } } # bool嵌套bool # ziduan1、ziduan2条件必须满足的前提下,ziduan3、ziduan4满足一个即可 body = { \u0026#34;query\u0026#34;:{ \u0026#34;bool\u0026#34;:{ \u0026#34;must\u0026#34;:[{\u0026#34;term\u0026#34;:{\u0026#34;ziduan1\u0026#34;:\u0026#34;China\u0026#34;}}, # 多个条件并列 ,注意:must后面是[{}, {}],[]里面的每个条件外面有个{} {\u0026#34;term\u0026#34;:{\u0026#34;ziduan2.keyword\u0026#34;: \u0026#39;我爱你中国\u0026#39;}}, {\u0026#39;bool\u0026#39;: { \u0026#39;should\u0026#39;: [ {\u0026#39;term\u0026#39;: {\u0026#39;ziduan3\u0026#39;: \u0026#39;Love\u0026#39;}}, {\u0026#39;term\u0026#39;: {\u0026#39;ziduan4\u0026#39;: \u0026#39;Like\u0026#39;}} ] }} ] } } } "},{"id":62,"href":"/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/JDBC%E6%95%B0%E6%8D%AE%E6%BA%90/","title":"Jdbc数据源","section":"特殊数据源","content":" 应用场景 # 当无法在python中找到连接库时, 你还可以采用jdbc的连接方式\n使用方法 # 首先您需要安装jdbc的包 pip install JayDeBeApi 在任意的一个仪表盘的 \u0026ldquo;模板\u0026rdquo; 编辑器中, 点击上传资源的图标上传相应的jdbc JAR包即可 新建连接的方式, 以下使用impala为例 "},{"id":63,"href":"/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/kafka%E6%95%B0%E6%8D%AE%E6%BA%90/","title":"Kafka数据源","section":"特殊数据源","content":"用于获取kafka指定分区的最后一条记录, 用于实时场景 使用方法参考\u0026quot;自定义数据源\u0026quot; 以下为参考代码:\ndef dataset(*args, **kwargs): \u0026#34;\u0026#34;\u0026#34; 返回查询数据集 :return: 二维数组或JSON字典 \u0026#34;\u0026#34;\u0026#34; from kafka import KafkaConsumer, TopicPartition import json sqlList = args[0] # 数据集编辑界面的输入已按分号拆分成数组 [sql1, sql2...] config = args[1] # 相关的配置字典{\u0026#39;host\u0026#39;,\u0026#39;port\u0026#39;,\u0026#39;user\u0026#39;,\u0026#39;password\u0026#39;,\u0026#39;db\u0026#39;} # 插入你的数据查询及处理代码, 生成result即可 result = {} consumer = KafkaConsumer(sasl_mechanism=\u0026#39;PLAIN\u0026#39;, security_protocol=\u0026#39;SASL_PLAINTEXT\u0026#39;, sasl_plain_username=config[\u0026#39;user\u0026#39;], sasl_plain_password=config[\u0026#39;password\u0026#39;], bootstrap_servers=config[\u0026#39;host\u0026#39;], auto_offset_reset=\u0026#39;earliest\u0026#39;, api_version=(1, 0, 0), consumer_timeout_ms=50, value_deserializer=lambda v: json.loads(v.decode(\u0026#39;utf-8\u0026#39;)), ) topic = sqlList[0] partition = int(config[\u0026#39;db\u0026#39;]) tp = TopicPartition(topic=topic, partition=partition) consumer.assign([tp]) end_offsets = consumer.end_offsets([tp]).get(tp) # 获取当前消费者最大偏移量 consumer.seek(tp, offset=end_offsets-1) for message in consumer: result = message.value break return result def insert_dataset(*args, **kwargs): \u0026#34;\u0026#34;\u0026#34; 数据填报实现 \u0026#34;\u0026#34;\u0026#34; from kafka import KafkaProducer import json contents = args[0] # 传入的数据集二维数组格式 table = args[1] # 配置中的表名 config = args[3] # 相关的配置字典{\u0026#39;host\u0026#39;,\u0026#39;port\u0026#39;,\u0026#39;user\u0026#39;,\u0026#39;password\u0026#39;,\u0026#39;db\u0026#39;} # 插入你的写入数据逻辑代码 producer = KafkaProducer(sasl_mechanism=\u0026#39;PLAIN\u0026#39;, security_protocol=\u0026#39;SASL_PLAINTEXT\u0026#39;, sasl_plain_username=config[\u0026#39;user\u0026#39;], sasl_plain_password=config[\u0026#39;password\u0026#39;], bootstrap_servers=config[\u0026#39;host\u0026#39;], value_serializer=lambda v: json.dumps(v).encode(\u0026#39;utf-8\u0026#39;) ) producer.send(table, value=contents, partition=int(config[\u0026#39;db\u0026#39;])) "},{"id":64,"href":"/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/mongodb%E6%95%B0%E6%8D%AE%E6%BA%90/","title":"Mongodb数据源","section":"特殊数据源","content":" 使用方法 # 连接池正常配置即可 数据集开发中,填写查询需求: {\u0026#34;db\u0026#34;: \u0026#34;db1\u0026#34;, \u0026#34;table\u0026#34;: \u0026#34;tb1\u0026#34;, \u0026#34;filter\u0026#34;: {\u0026#34;name\u0026#34;: \u0026#34;Zarten\u0026#34;}, \u0026#34;projection\u0026#34;: {\u0026#34;_id\u0026#34;: 0}, \u0026#34;sort\u0026#34;: [[\u0026#34;_id\u0026#34;, 1]], \u0026#34;limit\u0026#34;: 10} 由于返回的字典格式, 如需转化成二维数组, 可使图形中的转化函数ds_mapToList\nlet dataset=ds_mapToList(__dataset__); 参数说明: # 除table,其它都为可选参数\n参数 说明 样列 db 数库名,默认连接设定中db名 table 表名[必填] filter 筛选项,具体用法参考下文 {\u0026ldquo;name\u0026rdquo;: \u0026ldquo;Zarten\u0026rdquo;,\u0026ldquo;date\u0026rdquo;:\u0026ldquo;2020-10-01\u0026rdquo;} projection 显示列 {\u0026ldquo;name\u0026rdquo;: 1,\u0026ldquo;date\u0026rdquo;:1} sort 排序,-1为降序 [[\u0026ldquo;date\u0026rdquo;, -1]] limit 限定返回数量 filter条件说明 # 且条件\n{\u0026#34;age\u0026#34;:{\u0026#34;$gt\u0026#34;:22}, \u0026#34;name\u0026#34;:{\u0026#34;$regex\u0026#34;:\u0026#34;user\u0026#34;}} 或条件\n{ \u0026#34;$or\u0026#34;: [ {\u0026#34;age\u0026#34;: {\u0026#34;$gt\u0026#34;: 22}}, {\u0026#34;name\u0026#34;: {\u0026#34;$regex\u0026#34;: \u0026#34;user\u0026#34;}} ] } 比较查询 $lt和\u0026lt;,$lte和\u0026lt;=,$gt和\u0026gt;,gte和\u0026gt;=,ne和!=是一一对应的 {\u0026#34;field_name\u0026#34;: {\u0026#34;$lt\u0026#34;: value, \u0026#34;$gt\u0026#34;: value}} 关联查询$in和$nin {\u0026#34;field_name\u0026#34;: {\u0026#34;$in\u0026#34;: [1,5,8]}} $regex为模糊查询的字符串提供正则表达式功能 {\u0026#34;$or\u0026#34;: [{\u0026#34;field_name\u0026#34;: {\u0026#39;$regex\u0026#39;: value}},{\u0026#34;field_name2\u0026#34;: {\u0026#34;$regex\u0026#34;: value}}]} "},{"id":65,"href":"/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/Redis%E6%95%B0%E6%8D%AE%E6%BA%90/","title":"Redis数据源","section":"特殊数据源","content":" 应用场景 # 你可能会有这样的一些需求, 展示数据是要通过外部的程序计算好,如一些实时的计算场景,用spark计算好的数据 或爬虫爬取的数据, 然后写入redis或nosql的数据库,最后由前端图形直接展示或数据下载,SmartChart支持这一块的应用\n使用方法 # 你可以创建一个redis的连接池, 然后按照通用的方法建立数据集 不同的是, 数据集的SQL区不再是写sql代码, 而只需要写redis中的keyname\n如redis中存储的数据是keyname 为 \u0026ldquo;指标A\u0026rdquo;, 数据 \u0026lsquo;{\u0026ldquo;长沙\u0026rdquo;:1,\u0026ldquo;上海\u0026rdquo;:2}\u0026rsquo; 这样我们只需要在数据集中写上\n指标A 即可, 最后你会得到{\u0026ldquo;长沙\u0026rdquo;:1,\u0026ldquo;上海\u0026rdquo;:2}的返回结果\n如果你需要的是表格格式, 那么你只需要往redis中存入一个二维数组, 比如: [[\u0026ldquo;省份\u0026rdquo;,\u0026ldquo;数量\u0026rdquo;],[\u0026ldquo;长沙\u0026rdquo;,1],[\u0026ldquo;上海\u0026rdquo;,2]]\n注意数据存入redis为字符串格式,你可使用python的json.dumps来生成字符串格式存入\n当然我们也支持同一个数据中获取多个keyname # 比如还有一个\u0026quot;指标B\u0026quot;, 数据是'12345' 我们可以同时写上两个指标,用分号隔开:\n指标A;指标B 最后你会得到的结果是: { \u0026ldquo;指标A\u0026rdquo;:{\u0026ldquo;长沙\u0026rdquo;:1,\u0026ldquo;上海\u0026rdquo;:2}, \u0026ldquo;指标B\u0026rdquo;:12345 }\n"},{"id":66,"href":"/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/sqlalchemy%E8%BF%9E%E6%8E%A5/","title":"Sqlalchemy连接","section":"特殊数据源","content":"常规的连接池的设定, 大家应该都很清楚了, Smartchart也支持sqlalchemy连接, 对于一些smartchart不支持的数据源可以使用此方法 配置方法: 只用填以上内容, 其它可留空 连接地址的写法参考sqlalchemy说明:\n可选参数。一个标准的链接URL是这样的: dialect+driver://username:password@host:port/database dialect,是数据库类型,大概包括:sqlite, mysql, postgresql, oracle, or mssql. driver,是使用的数据库API,驱动,连接包,随便叫什么吧。 username,用户名 password,密码 host,网络地址,可以用ip,域名,计算机名,当然是你能访问到的。 port,数据库端口。 databas,数据库名。 其实这些也就dialect和dirver需要解释。 二:连接sqlite3 1,驱动 sqlite3是个文件数据库,不需要什么驱动,或者说python内置了驱动。 2,标准连接参数 # sqlite://\u0026lt;nohostname\u0026gt;/\u0026lt;path\u0026gt; 没有hostname 3,各种链接参数 # 相对路径,就是这个python文件同目录下foo.db engine = create_engine(\u0026#39;sqlite:///foo.db\u0026#39;) #绝对路径 #Unix/Mac下用四条////表示 engine = create_engine(\u0026#39;sqlite:////absolute/path/to/foo.db\u0026#39;) #Windows下用三条///加盘符路径用两条\\\\ engine = create_engine(\u0026#39;sqlite:///C:\\\\path\\\\to\\\\foo.db\u0026#39;) #Windows 也可以这么用三条///加盘符路径用一条\\ engine = create_engine(r\u0026#39;sqlite:///C:\\path\\to\\foo.db\u0026#39;) #数据库建在内存里。URI保持为空即可 engine = create_engine(\u0026#39;sqlite://\u0026#39;) 三:连接mysql(mariadb) sqlalchemy默认使用mysql-python作为链接驱动,既default模式 选哪种驱动,就装哪个包。 1,default默认链接方式 engine = create_engine(\u0026#39;mysql://scott:tiger@localhost/foo\u0026#39;) 2,# mysql-python,声明使用mysql-python驱动 engine = create_engine(\u0026#39;mysql+mysqldb://scott:tiger@localhost/foo\u0026#39;) 3,MySQL-connector-python 声明使用MySQL-connector-python驱动(推荐使用) engine = create_engine(\u0026#39;mysql+mysqlconnector://scott:tiger@localhost/foo\u0026#39;) 4,OurSQL 声明使用OurSQL驱动 engine = create_engine(\u0026#39;mysql+oursql://scott:tiger@localhost/foo\u0026#39;) 四:连接Microsoft SQL Server sqlalchemy默认使用 pyodbc作为链接驱动。 1,pyodbc engine = create_engine(\u0026#39;mssql+pyodbc://scott:tiger@mydsn\u0026#39;) 2,pymssql engine = create_engine(\u0026#39;mssql+pymssql://scott:tiger@hostname:port/dbname\u0026#39;) 五:连接PostgreSQL PostgreSQL默认使用 psycopg2作为链接驱动,既default模式 1, default engine = create_engine(\u0026#39;postgresql://scott:tiger@localhost/mydatabase\u0026#39;) 2,psycopg2 engine = create_engine(\u0026#39;postgresql+psycopg2://scott:tiger@localhost/mydatabase\u0026#39;) 3, pg8000 engine = create_engine(\u0026#39;postgresql+pg8000://scott:tiger@localhost/mydatabase\u0026#39;) 六:连接Oracle Oracle可能只有 cx_oracle一个驱动包,既default模式和声明模式一样。 1,default engine = create_engine(\u0026#39;oracle://scott:tiger@127.0.0.1:1521/sidname\u0026#39;) 2,cx_oracle engine = create_engine(\u0026#39;oracle+cx_oracle://scott:tiger@tnsname\u0026#39;) "},{"id":67,"href":"/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/ElementUI%E7%BB%84%E4%BB%B6/%E5%B8%A6%E5%88%86%E9%A1%B5%E7%9A%84%E8%A1%A8%E6%A0%BC/","title":"带分页的表格","section":"Element Ui组件","content":" 模式开启 # 需要开启模板开发模式, 并开启basevue模板 在Body加入组件 # \u0026lt;!--表格--\u0026gt; \u0026lt;div class=\u0026#34;smtdrag\u0026#34; id=\u0026#34;id_1654907858638\u0026#34;\u0026gt; \u0026lt;el-table :data=\u0026#34;tableData.slice((currentPage-1)*pageSize, currentPage*pageSize)\u0026#34; height=\u0026#34;100%\u0026#34; size=\u0026#34;mini\u0026#34; header-cell-class-name=\u0026#34;tablehead\u0026#34; border style=\u0026#34;width: 100%\u0026#34;\u0026gt; \u0026lt;el-table-column v-for=\u0026#34;item in tableHead\u0026#34; :label=\u0026#34;item.label\u0026#34; :property=\u0026#34;item.prop\u0026#34; sortable\u0026gt; \u0026lt;/el-table-column\u0026gt; \u0026lt;/el-table\u0026gt; \u0026lt;!--表格结束--\u0026gt; \u0026lt;!--分页控件--\u0026gt; \u0026lt;el-pagination align=\u0026#39;center\u0026#39; @size-change=\u0026#34;handlerSizeChange\u0026#34; @current-change=\u0026#34;handlerCurrentChange\u0026#34; :current-page=\u0026#34;currentPage\u0026#34; :page-size=\u0026#34;pageSize\u0026#34; layout=\u0026#34;total,sizes,prev,pager,next,jumper\u0026#34; :total=\u0026#34;tableData.length\u0026#34; \u0026gt;\u0026lt;/el-pagination\u0026gt; \u0026lt;!--分页控件结束--\u0026gt; \u0026lt;/div\u0026gt; 在JS区域加入 # var vapp = new Vue({el: \u0026#39;#vue_app\u0026#39;, delimiters: [\u0026#39;{[\u0026#39;, \u0026#39;]}\u0026#39;], data: { tableData:[], //表数据 tableHead:[], //表头 currentPage:1, total:20, pageSize:10 }, methods: { //处理分页数量 handlerSizeChange(val){ this.currentPage = 1; this.pageSize=val; }, //处理页选择 handlerCurrentChange(val){ this.currentPage = val; } } }); 新增一个数据集 # select * from smartdemo2 limit /* $limit -- */ 100 图形开发中修改 # let df0 = __dataset__; //处理表头 let columnsDict = {\u0026#39;c1\u0026#39;:\u0026#39;渠道\u0026#39;,\u0026#39;qty\u0026#39;:\u0026#39;数量\u0026#39;}; let tableHead = []; let tableHeadLabel; for (let i=0;i\u0026lt;df0[0].length;i++){ if(columnsDict.hasOwnProperty(df0[0][i])){ df0[0][i] = columnsDict[df0[0][i]] } tableHeadLabel=df0[0][i]; tableHead.push({label: tableHeadLabel, prop:df0[0][i]}); } //VUE赋值 vapp.tableHead = tableHead; vapp.tableData=ds_createMap_all(df0); smartchart内置了这个查询模板, 你可以通过 本地模板恢复快速应用\n"},{"id":68,"href":"/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2/LineUp%E5%9B%BE%E5%BD%A2/","title":"Line Up图形","section":"特殊图形","content":"Smartchart内置了LineUp图形 LineUp is an interactive technique designed to create, visualize and explore rankings of items based on a set of heterogeneous attributes. LineUp图形参考\nds_loadcss(\u0026#39;smt_LineUp\u0026#39;); ds_loadjs(\u0026#39;smt_LineUp\u0026#39;); let dataset = __dataset__; dataset = ds_createMap_all(dataset); try{Ljs__name__.destroy()}catch{} Ljs__name__ = LineUpJS.asTaggle(dom__name__, dataset); // 点击选中行响应动作 Ljs__name__.on(LineUpJS.LineUp.EVENT_SELECTION_CHANGED, (selection) =\u0026gt; { console.log(Ljs__name__.data._data[selection]); //通过以上log可以查看到数据格式, 以下就是标准的联动写法 filter_param[\u0026#39;LineupParam\u0026#39;] = Ljs__name__.data._data[selection].xx ds_refresh(2); }); //更多响应动作 Ljs__name__.on(LineUpJS.LineUp.EVENT_HIGHLIGHT_CHANGED, (highlight) =\u0026gt; { }); // document.querySelector(\u0026#39;button#select\u0026#39;).addEventListener(\u0026#39;click\u0026#39;, () =\u0026gt; { // Ljs__name__.setSelection([1, 2, 3]); // }); // document.querySelector(\u0026#39;button#highlight\u0026#39;).addEventListener(\u0026#39;click\u0026#39;, () =\u0026gt; { // Ljs__name__.setHighlight(50); // }); // 获取筛选后的数据并下载(来源与\u0026#34;路阳\u0026#34; 赞助开发) outputStr=Ljs__name__.data.exportTable(Ljs__name__.data.getRankings()[0], {}); outputStr = outputStr.replace(/\\t/g, \u0026#39;,\u0026#39;); ds_download(\u0026#39;abc.csv\u0026#39;, outputStr); "},{"id":69,"href":"/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2/%E4%BD%BF%E7%94%A8%E5%9B%BE%E6%A0%87/","title":"使用图标","section":"特殊图形","content":"在\u0026quot;模板\u0026quot;中加载图标资源 使用方法, 可参考 font-awesome菜鸟教程 V5图标名称参考, 也可以 图标样列查询 "},{"id":70,"href":"/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2/%E6%97%A0%E7%BC%9D%E6%BB%9A%E5%8A%A8/","title":"无缝滚动","section":"特殊图形","content":" 通用滚动 # 例如你的html如下\n\u0026lt;div id=\u0026#34;smtid\u0026#34; style=\u0026#34;height:100%\u0026#34;\u0026gt; \u0026lt;ul\u0026gt; \u0026lt;li\u0026gt;smartchart\u0026lt;/li\u0026gt; \u0026lt;li\u0026gt;bigdata\u0026lt;/li\u0026gt; \u0026lt;li\u0026gt;echarts\u0026lt;/li\u0026gt; \u0026lt;li\u0026gt;make it great\u0026lt;/li\u0026gt; \u0026lt;/ul\u0026gt; \u0026lt;/div\u0026gt; 你只需要使用以下函数, 即可实现在无缝滚动 由于smtid是ID, 则使用 ds_liMarquee(\u0026rsquo;#smtid\u0026rsquo;) 即可开启自动滚动 如果 class=\u0026ldquo;smtclass\u0026rdquo;, 那么也可以使用类选择器 ds_liMarquee(\u0026rsquo;.smtclass')\n我们也可以使用更多的配置方法\nmarconfig={ playtime: 3000, //滚动3秒 pausetime: 3000, //停3秒 config:{ direction: \u0026#39;up\u0026#39;,//向上滚动 runshort: false,//内容不足时不滚动 scrollamount: 20//速度 } } 可以使用 ds_liMarquee(\u0026rsquo;#smtid\u0026rsquo;, marconfig) 传入配置\n更多config说明:\n名称 类型 默认值 说明 direction 字符串 left 滚动方向,可选 left / right / up / down loop 整数 -1 循环次数,-1 为无限循环 scrolldelay 整数 0 每次重复之前的延迟 scrollamount 整数 50 滚动速度,越大越快 circular 布尔值 true 无缝滚动,如果为 false,则和 marquee 效果一样 drag 布尔值 true 鼠标可拖动 runshort 布尔值 true 内容不足是否滚动 hoverstop 布尔值 true 鼠标悬停暂停 xml 布尔值 false 加载xml 文件 inverthover 布尔值 false 反向,即默认不滚动,鼠标悬停滚动 内置滚动表格 # smartchart内置了滚动表格, 可以一键生成 如果你需要修改表格的样式, 如字体,颜色等, 你可以在模板中重定义样式 具体样式的写法, 参考 样式快速入门\n如下例修改表头高度为5rem, 内容单元格高度3rem 及背景字体等 /*表头样式*/ .smtlisthead{ background: #fff2cc; color: red; height: 5rem; } .smtlisthead span{ height: 5rem; } /*表格本体样式*/ .smtlistnav{ height: calc(100% - 5rem); color: red; overflow: auto; } .smtlistnav li span{ height: 3rem; } /*修改奇数行背景*/ .smtlistnav ul li:nth-child(odd){ background: rgba(100,100,100,.1);} 偶数行将odd改为even /*指定某单独格宽度对齐*/ \u0026lt;span\u0026gt; \u0026lt;span style=\u0026#34;width:32rem;height:100%;flex-shrink:0;justify-content:left\u0026#34;\u0026gt;\u0026lt;span\u0026gt; \u0026lt;/span\u0026gt; /*单元格点击响应*/ let lastClickDom; let lastDomColor; $(\u0026#39;#smtlist__name__, li\u0026#39;).click(function(params){ try{lastClickDom.css(\u0026#39;background\u0026#39;, lastDomColor)}catch{} lastDomColor = $(this).css(\u0026#39;background\u0026#39;); $(this).css(\u0026#39;background\u0026#39;, \u0026#39;yellow\u0026#39;); lastClickDom = $(this); let myparam = $(this).children(\u0026#39;span\u0026#39;).eq(0).text(); //获取点击的参数 //以下加入你的action }); "},{"id":71,"href":"/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2%E5%8A%A0%E8%BD%BD/","title":"特殊图形加载","section":"特殊图形","content":"smartchart默认只会引echarts的基础图形 如果你需要使用到更多图形, 你可以自行引用,可以写在模板的javascript标签中\n中国地图 \u0026lt;script src=\u0026#34;/static/smartchart/opt/smt_china.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; 世界地图 \u0026lt;script src=\u0026#34;/static/smartchart/opt/smt_world.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; 统计图 \u0026lt;script src=\u0026#34;/static/smartchart/opt/smt_ecStat.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; 水球图 \u0026lt;script src=\u0026#34;/static/smartchart/opt/smt_liquidfill.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; 词云 \u0026lt;script src=\u0026#34;/static/smartchart/opt/smt_wordcloud.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; 百度地图 \u0026lt;script type=\u0026#34;text/javascript\u0026#34; src=\u0026#34;https://fastly.jsdelivr.net/npm/echarts@5/dist/extension/bmap.min.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; "},{"id":72,"href":"/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E4%B8%8D%E5%B8%B8%E7%94%A8/%E4%BB%A3%E7%A0%81%E8%BD%AC%E5%8C%96%E5%B8%83%E5%B1%80/","title":"代码转化布局","section":"不常用","content":"由于我们移除了boostrap的布局方式, 此布局不再做推荐! 初次学习的同学, 可能会需要一个拖拉拽的布局方式(3.9.9.13以上才支持), 所以下面介绍的是smartchart的辅助布局方法\n你可以在\u0026quot;布局\u0026quot; 中找到入口 进入编辑器后, 你可以拖拉拽的方式进行布局, 注意我们建意你一个column(C)容器只放一个smartchart的图形便于标准化 点击\u0026quot;生成\u0026quot;, 复制相关代码 回到仪表盘\u0026quot;布局\u0026quot;, 粘贴到编辑器, 点击 \u0026ldquo;闪电\u0026rdquo; 图标, 进行转化, 可能会提示你数据集不够,这样你需要新增足够数量的数据集后再点转化 注: 代码转化布局你可以不用可视化辅助, 可以用其它任意每三方布局工具生成代码后粘过来生成, 需要注意的格式是: 在你需要数据集的地方使用以下代码即可:\n\u0026lt;div style=\u0026#34;height:100%\u0026#34; id=\u0026#34;container_{name}\u0026#34;\u0026gt;\u0026lt;/div\u0026gt; 转化完成后, 点击保存即可应用布局 "},{"id":73,"href":"/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E4%B8%8D%E5%B8%B8%E7%94%A8/%E5%AE%B9%E5%99%A8%E7%AE%A1%E7%90%86%E7%95%8C%E9%9D%A2/","title":"容器管理界面","section":"不常用","content":" 容器管理 # 你可以单独对一个容器进行编辑,或者在全局进行编辑 全局编辑器 移动图形\n你有两种方法移动数据集 可以在“报表” 中直接暴力修改序号 也可以在数据集编辑器中移动, 可选择插入(带着容器一起动),替换(容器不动,就是整体布局不变化, 只移动数据和图形) "},{"id":74,"href":"/docs/6.Jupyter%E5%BA%94%E7%94%A8/Jupyter%E4%B8%AD%E4%BD%BF%E7%94%A8%E6%8C%87%E5%BC%95/","title":"Jupyter中使用指引","section":"6. Jupyter应用","content":" 应用场景 # 你需要在jupyter中通过smartchart分享的数据集获取数据进行分析 你有很多线下数据需要进行个性化分析, 然后制做仪表盘 在Jupyter的数据分析过程中, 你需要快速生成图形 大屏或报表有部分数据集是需要能过复杂的分析生成的\nSmartchart支持像pyecharts, Matplotlib 等python绘图工具一样在Jupyter中使用, 但她更加方便, 更加炫酷 和 通用化, 不仅仅是一个绘图工具, 而且是一个平台\n我们有什么特色:\n使用上手非常简单, 仅仅只有两个命令, get and set, 配置项采用原生的Echarts配置, 无重复学习成本, 使用顺滑 支持Echarts所有功能, 可定制化程度高, 显示效果好, 可嵌入也可以弹出窗口显示, 也可以dashboard中显示 数据可以固化存储, 采用smartchart Portal可以直接拼接炫酷大屏\nSmartchart与Pandas Smartchart与Jupyter SmartChart大屏新思路\n安装使用方法 # 你需要在jupyter相同的python环境中安装smartchart客户端 pip install smartchart 或pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple smartchart 如果你只是需要连接已部署好的smartchart服务端, 本地无需启动smartchart 快速开始 # 初始化认证: 第一次使用时, 打开jupyter后, 需要设定默认用户和smartchart服务端url 同一个环境, 只需初始化一次, 后面无需再设定\nfrom smart_chart import Smart Smart().set_auth(\u0026#39;用户名\u0026#39;, \u0026#39;密码\u0026#39;,url = \u0026#39;http://xxxxx\u0026#39;) 如果smartchart服务端在本地, 可以省略url\nSmart().set_auth(\u0026#39;用户名\u0026#39;, \u0026#39;密码\u0026#39;) 使用方法:\nfrom smart_chart import Smart mysmart = Smart() dataset = [[\u0026#39;A\u0026#39;,\u0026#39;B\u0026#39;,\u0026#39;C\u0026#39;],[12,34,23],[22,33,37]] #把数据写入临时数据集并显示图形 mysmart.set(1,dataset) #随意命名临时数据集, 不一定需要smartchart中数据集已有的 mysmart.set(\u0026#39;DD\u0026#39;, dataset) #从已有的数据集中获取数据(格式参考smartchart数据集) ds1 = mysmart.get(1) ds2 = mysmart.get(\u0026#39;DD\u0026#39;) 修改图形显示 # 方法一: 你可以在图形菜单中选择内置图形或主题 方法二: set默认是表格显示,你也可通过名称加前缀 bar, line, pie进行修改\nmysmart.set(\u0026#39;barxxx\u0026#39;, dataset) #显示柱形图, 另外还有linexxx, piexxx 方法三: 简单图形,可能无法满足你的个性化要求, 你可以采用实例化数据集的方式后做出炫酷的自定义图形\nmysmart.set(\u0026#39;myds_1\u0026#39;, dataset, push=1) #参数push=1, 将实例化数据集 实例化的数据集, 在图形编辑区点击, 可以进入定制化图形开发, 可使用原生的Echarts配置和实时调试,或直接使用社区图形(第一次使用,有一个登记的过程, 按提示进行) 方法四: 如何在非实例化的数据集中使用自定义图形进行临时显示 假如你已经实例化并自定义了图形, 比如 \u0026lsquo;myds_1\u0026rsquo;, 你可以直接用它的名称来set\n#不加push, 将使用新的数据采用myds_1的图形临时显示, 而不会改变原myds_1的数据 mysmart.set(\u0026#39;myds_1\u0026#39;, dataset) 显示设定参数 # 你可以通过参数来设定图形的高宽, 是否嵌入等个性化要求\n# width, height指定图形嵌入显示的宽高 # embed 默认不嵌入, embed=1 嵌入, embed=0 不嵌入 # editor 是否显示图形菜单, 1显示, 0不显示 # push 是否持久化数据集 push=1, 无则新建有则保存数据 # url 报表访问的url,默认是localhost #可以全局初始化设定 mysmart = Smart(width=xx, height=xx, embed=1, editor=\u0026#39;\u0026#39;) #也可以全局单独进行设定 mysmart.url = \u0026#39;http://ip:8000\u0026#39; mysmart.embed = 1 #也可以针对单独的一个图形设定 mysmart.set(1,dataset,embed=1,height=200,editor=0) SmartChart与Pandas # Smartchart的set支持直接set Pandas的dataframe对象\nfrom smart_chart import Smart import pandas as pd mysmart = Smart() df = pd.read_excel(\u0026#39;manual_smartdemo.xlsx\u0026#39;, \u0026#39;sheet1\u0026#39;) mysmart.set(\u0026#39;excelsample\u0026#39;, df.sample(10)) df1 = df.groupby(\u0026#39;province\u0026#39;).agg({\u0026#39;qty\u0026#39;:\u0026#39;sum\u0026#39;}).reset_index() mysmart.set(\u0026#39;ec_df1\u0026#39;, df1, push=1) df2 = df.groupby(\u0026#39;c1\u0026#39;).agg({\u0026#39;qty\u0026#39;:\u0026#39;sum\u0026#39;}).reset_index() mysmart.set(\u0026#39;ec_df2\u0026#39;, df2, push=1) df4 = df.groupby(\u0026#39;province\u0026#39;).agg({\u0026#39;qty\u0026#39;:\u0026#39;count\u0026#39;}).reset_index() mysmart.set(\u0026#39;ec_df4\u0026#39;, df1, push=1) df3 = df.groupby(\u0026#39;c3\u0026#39;).agg({\u0026#39;qty\u0026#39;:\u0026#39;sum\u0026#39;}).reset_index() print(df3) df3.loc[1, \u0026#39;qty\u0026#39;] = df3.loc[1, \u0026#39;qty\u0026#39;] * 100 print(df3) mysmart.set(\u0026#39;ec_df3\u0026#39;, df3, push=1) #mysmart.set(\u0026#39;pie0\u0026#39;, df1) #df2 = df.groupby([\u0026#39;province\u0026#39;,\u0026#39;c3\u0026#39;]).agg({\u0026#39;qty\u0026#39;:\u0026#39;sum\u0026#39;}).reset_index() #print(df2) #mysmart.set(\u0026#39;ssss\u0026#39;, df2) #print(mysmart.get(15)) "}] \ No newline at end of file diff --git a/docs/smartchart/en.search.min.9676739f7d6fb9d37e12fd58a755b4f44ec0d94abaddeb103ece302f676fbdef.js b/docs/smartchart/en.search.min.9676739f7d6fb9d37e12fd58a755b4f44ec0d94abaddeb103ece302f676fbdef.js new file mode 100644 index 0000000..31f65a1 --- /dev/null +++ b/docs/smartchart/en.search.min.9676739f7d6fb9d37e12fd58a755b4f44ec0d94abaddeb103ece302f676fbdef.js @@ -0,0 +1 @@ +"use strict";(function(){const o="/en.search-data.min.6325b92e2578ce162c49b50e5d0f669259962aac89a889a8a051ca34a48fe31d.json",i=Object.assign({cache:!0},{doc:{id:"id",field:["title","content"],store:["title","href","section"]}}),e=document.querySelector("#book-search-input"),t=document.querySelector("#book-search-results");if(!e)return;e.addEventListener("focus",n),e.addEventListener("keyup",s),document.addEventListener("keypress",a);function a(t){if(t.target.value!==void 0)return;if(e===document.activeElement)return;const n=String.fromCharCode(t.charCode);if(!r(n))return;e.focus(),t.preventDefault()}function r(t){const n=e.getAttribute("data-hotkeys")||"";return n.indexOf(t)>=0}function n(){e.removeEventListener("focus",n),e.required=!0,fetch(o).then(e=>e.json()).then(e=>{window.bookSearchIndex=FlexSearch.create("balance",i),window.bookSearchIndex.add(e)}).then(()=>e.required=!1).then(s)}function s(){for(;t.firstChild;)t.removeChild(t.firstChild);if(!e.value)return;const n=window.bookSearchIndex.search(e.value,10);n.forEach(function(e){const n=c("
  • "),s=n.querySelector("a"),o=n.querySelector("small");s.href=e.href,s.textContent=e.title,o.textContent=e.section,t.appendChild(n)})}function c(e){const t=document.createElement("div");return t.innerHTML=e,t.firstChild}})() \ No newline at end of file diff --git a/docs/smartchart/favicon.png b/docs/smartchart/favicon.png new file mode 100644 index 0000000..59c7c2a Binary files /dev/null and b/docs/smartchart/favicon.png differ diff --git a/docs/smartchart/favicon.svg b/docs/smartchart/favicon.svg new file mode 100644 index 0000000..a3c696d --- /dev/null +++ b/docs/smartchart/favicon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/smartchart/flexsearch.min.js b/docs/smartchart/flexsearch.min.js new file mode 100644 index 0000000..984d8c6 --- /dev/null +++ b/docs/smartchart/flexsearch.min.js @@ -0,0 +1,42 @@ +/* + FlexSearch v0.6.30 + Copyright 2019 Nextapps GmbH + Author: Thomas Wilkerling + Released under the Apache 2.0 Licence + https://github.com/nextapps-de/flexsearch +*/ +'use strict';(function(K,R,w){let L;(L=w.define)&&L.amd?L([],function(){return R}):(L=w.modules)?L[K.toLowerCase()]=R:"object"===typeof exports?module.exports=R:w[K]=R})("FlexSearch",function ma(K){function w(a,c){const b=c?c.id:a&&a.id;this.id=b||0===b?b:na++;this.init(a,c);fa(this,"index",function(){return this.a?Object.keys(this.a.index[this.a.keys[0]].c):Object.keys(this.c)});fa(this,"length",function(){return this.index.length})}function L(a,c,b,d){this.u!==this.g&&(this.o=this.o.concat(b),this.u++, +d&&this.o.length>=d&&(this.u=this.g),this.u===this.g&&(this.cache&&this.j.set(c,this.o),this.F&&this.F(this.o)));return this}function S(a){const c=B();for(const b in a)if(a.hasOwnProperty(b)){const d=a[b];F(d)?c[b]=d.slice(0):G(d)?c[b]=S(d):c[b]=d}return c}function W(a,c){const b=a.length,d=O(c),e=[];for(let f=0,h=0;f=h&&(a=a[g-(e+.5>>0)],a=a[b]||(a[b]=[]), +a[a.length]=d);return e}function ba(a,c){if(a){const b=Object.keys(a);for(let d=0,e=b.length;da?1:a?-1:0}function pa(a,c){a=a[M];c=c[M];return ac?1:0}function oa(a,c){const b=M.length;for(let d=0;dc?1:0}function T(a,c,b){return a?{page:a,next:c?""+c:null,result:b}:b}function ha(a,c,b,d,e,f,h){let g,k=[];if(!0===b){b="0";var l=""}else l=b&&b.split(":");const p=a.length;if(1h&&(l=0),l=l||0,g=l+c,g=this.m.length&&(this.C=0),this.m[this.C].postMessage({add:!0,id:a, +content:c}),this.c[f]=""+this.C,b&&b(),this;if(!e){if(this.async&&"function"!==typeof importScripts){let t=this;f=new Promise(function(v){setTimeout(function(){t.add(a,c,null,d,!0);t=null;v()})});if(b)f.then(b);else return f;return this}if(b)return this.add(a,c,null,d,!0),b(),this}c=this.encode(c);if(!c.length)return this;b=this.f;e=O(b)?b(c):c.split(this.split);this.filter&&(e=W(e,this.filter));const n=B();n._ctx=B();const m=e.length,u=this.threshold,q=this.depth,A=this.b,z=this.i,y=this.D;for(let t= +0;tp;x--)l=h.substring(p,x),V(z,n,l,a,v,k,u,A-1)}break;default:if(g=V(z,n,h,a,1,k,u,A-1),q&&1=u)for(g=n._ctx[h]||(n._ctx[h]=B()),h=this.h[h]||(this.h[h]=ia(A-(u||0))),k=t-q,l=t+q+1,0>k&&(k=0),l> +m&&(l=m);kh;d--)e=g[d-1],g[d]=e,f[e]=d;g[h]=c;f[c]=h}}}return b};return a}();return w}(function(){const K={},R="undefined"!==typeof Blob&& +"undefined"!==typeof URL&&URL.createObjectURL;return function(w,L,S,W,P){S=R?URL.createObjectURL(new Blob(["("+S.toString()+")()"],{type:"text/javascript"})):w+".min.js";w+="-"+L;K[w]||(K[w]=[]);K[w][P]=new Worker(S);K[w][P].onmessage=W;return K[w][P]}}()),this); diff --git a/docs/smartchart/fonts/roboto-mono-v13-latin-regular.woff b/docs/smartchart/fonts/roboto-mono-v13-latin-regular.woff new file mode 100644 index 0000000..f319fbf Binary files /dev/null and b/docs/smartchart/fonts/roboto-mono-v13-latin-regular.woff differ diff --git a/docs/smartchart/fonts/roboto-mono-v13-latin-regular.woff2 b/docs/smartchart/fonts/roboto-mono-v13-latin-regular.woff2 new file mode 100644 index 0000000..ed384d2 Binary files /dev/null and b/docs/smartchart/fonts/roboto-mono-v13-latin-regular.woff2 differ diff --git a/docs/smartchart/fonts/roboto-v27-latin-700.woff b/docs/smartchart/fonts/roboto-v27-latin-700.woff new file mode 100644 index 0000000..a5d98fc Binary files /dev/null and b/docs/smartchart/fonts/roboto-v27-latin-700.woff differ diff --git a/docs/smartchart/fonts/roboto-v27-latin-700.woff2 b/docs/smartchart/fonts/roboto-v27-latin-700.woff2 new file mode 100644 index 0000000..01d05fa Binary files /dev/null and b/docs/smartchart/fonts/roboto-v27-latin-700.woff2 differ diff --git a/docs/smartchart/fonts/roboto-v27-latin-regular.woff b/docs/smartchart/fonts/roboto-v27-latin-regular.woff new file mode 100644 index 0000000..86b3863 Binary files /dev/null and b/docs/smartchart/fonts/roboto-v27-latin-regular.woff differ diff --git a/docs/smartchart/fonts/roboto-v27-latin-regular.woff2 b/docs/smartchart/fonts/roboto-v27-latin-regular.woff2 new file mode 100644 index 0000000..ebe1795 Binary files /dev/null and b/docs/smartchart/fonts/roboto-v27-latin-regular.woff2 differ diff --git a/docs/smartchart/index.html b/docs/smartchart/index.html new file mode 100644 index 0000000..4b5eafe --- /dev/null +++ b/docs/smartchart/index.html @@ -0,0 +1,1680 @@ + + + + + + + + + + + + + +介绍 | Smartchart开发手册 + + + + + + + + + + + + + + +
    + + +
    +
    + +
    + + + 介绍 + + +
    + + + + + + +
    + + + +

    Smartchart6.0 预计2022年底发布, 带来全新的功能与体验, 请关注

    +

    + 设计哲学: + # +

    +
      +
    • 她是基于真实应用场景的敏捷数据中台而设计的产品,已成熟在多个大型企业应用多年,不仅是一个可视化低代码开发平台, 也是数据接口低代码, 甚至是业务系统低代码开发平台
    • +
    • 支持多种混合布局, 对于普通报表可以使用响应式布局同时满足大屏, 电脑, 平板, 手机端的页面, 对于大屏也可使用拖拽辅助布局来配合自由开发模式(专业版)
    • +
    • 她是面向开发者, 如果需要设计出来非常漂亮有个性的数据展现形式, 我们发现如果要达到这个目的, 不管用什么开发工具, 最终还是需要用户了解一些基础的html, css, echarts的配置, 如果去学习某个平台中要在那些地方点点点的界面上进行配置, 那么为什么不去学习使用原生的呢, 这样反而更简单, 用户可以找到的参考资源更全面, 甚至可以从社区的代码中直接复制过来, 所以我们设计理念是不自定义开发语言, 而是帮大家建立数据与图形的高速公路, 定义交通规则 和提供服务区
    • +
    • smartchart有很多隐藏功能, 所以初入smartchart的同学会一脸迷惑, 无从下手, 因为我们讲究 精减设计可扩展性 , 如果有些功能只用一次, 就不会让他在界面显示, 我们不推荐不看文档和视屏就直接上手开发的模式, 给你门槛是为了将来使用得不会太累
    • +
    • 她重在数据处理的便捷, 联动/刷新机制设计一气喝成, 无缝的原生图形开发工具, 没有脱泥带水的让用户去找设定开关, 你甚至可以使用你喜欢的IDE进行开发, 给开发者充分发挥的自由
    • +
    • smartchart是一个企业级解决方案, 不是一个玩具, 她不喜欢浮躁, 需要你沉下心, 慢慢体验, 属于慢热型, 就好比是做菜, smartchart是给你提供了已经切好的菜和菜谱说明, 你可以按自已喜欢加火放调料就行, 你甚至可以增加新的调料(如css, js引用) 或更换调料. 相比有些产品就是给你准备的是已做好的菜品, 如果你觉得它盐放得太多, 你得清洗下, 再重新回锅, 对于我们开发人员来说, 这是不可忍受的
    • +
    • 类似于养成类游戏, 你可以在开发过程中积累图形, 模板等等, 在后面的项目中可以直接用复制粘贴的方式进行复用, 而不需要再界面上重新进行配置调整. 你也可以和其它开发者(厨师)交流, 互通有无, 快速提升自已的等级, 比如购买模板就是最快的方法
    • +
    +

    + 与传统BI的区别 + # +

    +
      +
    • 传统BI面向非技术人员, 更注重于开发的过程无代码化,所以最终实现的可视化效果较差, 可定制化程度低, 访问速度慢,对硬件要求高, 应用场景局限性比较大
    • +
    • smartchart是面向技术人员的可视化产品, 更注重于最终效果, 采用的是低代码技术, 对技术人员更友好, 可定制化高, 可视化效果更好, 访问速度快, 更灵活,对硬件要求低, 应用范围广
    • +
    +
    + + + +
    + +
    + + + + + + + +
    + + + + + + + + +
    + + + +
    + +
    + + + + +
    + + + + +
    + + + + + + + + + + + + + + + + diff --git a/docs/smartchart/index.xml b/docs/smartchart/index.xml new file mode 100644 index 0000000..32e0663 --- /dev/null +++ b/docs/smartchart/index.xml @@ -0,0 +1,861 @@ + + + + 介绍 on Smartchart开发手册 + https://smartchart.gitee.io/ + Recent content in 介绍 on Smartchart开发手册 + Hugo -- gohugo.io + + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/VUE%E7%9B%B8%E5%85%B3/%E4%BD%BF%E7%94%A8VUE/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/VUE%E7%9B%B8%E5%85%B3/%E4%BD%BF%E7%94%A8VUE/ + 使用场景 # 报表中涉及交互场景较多, 需要数据与页面绑定 开发者熟悉vue 常见绑定 # //显示变量message &lt;p&gt;{[ message ]}&lt;/p&gt; //循环产生li,变量sites &lt;ol&gt; &lt;li v-for=&#34;site in sites&#34;&gt; {[ site.name ]} &lt;/li&gt; &lt;/ol&gt; //绑定输入值变量use &lt;input type=&#34;checkbox&#34; v-model=&#34;use&#34;&gt; //显示控制 &lt;p v-if=&#34;seen&#34;&gt;现在你看到我了&lt;/p&gt; &lt;p v-show=&#34;seen&#34;&gt;现在你看到我了&lt;/p&gt; //绑定属性 &lt;a :href=&#34;url&#34;&gt;&lt;/a&gt; &lt;div :style=&#34;{ color: activeColor, fontSize: fontSize + &#39;px&#39; }&#34;&gt;&lt;/div&gt; &lt;div :class=&#34;[errorClass ,isActive ? activeClass : &#39;&#39;]&#34;&gt;&lt;/div&gt; //绑定点击方法 &lt;a @click=&#34;doSomething&#34;&gt;&lt;/a&gt; 开启VUE # 需要在高级中加入“dv”:2,即可开启vue模式 你可以在图形编辑器中给vue的变量赋值,我们内置了17个变量,从d0, d1&hellip; d16 赋值方式 vapp.d0 = xxxx 你可以将d0赋值为字典, 如: vapp.d0 = { &lsquo;index1&rsquo;: 100, &lsquo;index2&rsquo;: 300} + + + + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E4%B8%8D%E5%A4%AA%E9%87%8D%E8%A6%81/%E4%B8%BB%E9%A2%98%E5%BA%94%E7%94%A8PRO/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E4%B8%8D%E5%A4%AA%E9%87%8D%E8%A6%81/%E4%B8%BB%E9%A2%98%E5%BA%94%E7%94%A8PRO/ + 点击smartchart图标,切换到菜单固定模式, 你可看到主题的选择 + + + + + https://smartchart.gitee.io/docs/11.%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97/Linux/%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/11.%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97/Linux/%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B/ + 涉及的基础环境和版本: # * Centos 7 * Python 3.9 /data/smartchart/ 项目主目录 /data/smartchart/tools 项目相关软件 下述内容中,凡是涉及到/data/smartchart路径的,都可以将其修改为你自己系统上的路径。 安装环境 # 安装Python # cd /data/smartchart/tools yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel libffi-devel 下载https://npm.taobao.org/mirrors/python/3.9.0/ 上传服务器,放入安装目录解压 或者 Wget https://npm.taobao.org/mirrors/python/3.9.0/Python-3.9.0.tgz tar -zxvf Python-3.9.0.tgz 进行源码目录 配置安装路径 ./Python-3.9.0/configure --prefix=/data/smartchart/tools/python3 编译安装 make &amp;&amp; make install 建立软链接 ln -s /data/smartchart/tools/python3/bin/python3.9 /usr/bin/python3 ln -s /data/smartchart/tools/python3/bin/pip3.9 /usr/bin/pip3 测试是否安装成功 python3 --version 建立python虚拟环境 # python3 -m venv myvenv cd myvenv source bin/activate 在虚拟环境中安装smartchart # pip3 install -i https://pypi. + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/EXCEL%E6%95%B0%E6%8D%AE/%E4%BB%8EEXCEL%E7%B2%98%E8%B4%B4%E6%95%B0%E6%8D%AE/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/EXCEL%E6%95%B0%E6%8D%AE/%E4%BB%8EEXCEL%E7%B2%98%E8%B4%B4%E6%95%B0%E6%8D%AE/ + 固定数据集 # 有一些场景, 比如已有一些固定的筛选器,或是需要测试用,或者Demo,或者其它图形需要用到一些共用的已确定好的数据 这样我们可以不需要通过查询数据库的方式, 而直接写入数据集, 支持数组和字典的格式 你只需要在数据集中起始写入 dataset= , 这样就是默认是固定数据 +如何快速的输入固定数据集, 你可以通过直接从EXCEL复制到数据集编辑器(以下图片非目前编辑器, 供参考),保存以后会自动生成: 固定数据集也支持之前提到传参数, 魔术方法, 缓存等所有数据集的功能 + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E6%95%B0%E6%8D%AE%E9%9B%86%E5%BC%80%E5%8F%91%E7%95%8C%E9%9D%A2/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E6%95%B0%E6%8D%AE%E9%9B%86%E5%BC%80%E5%8F%91%E7%95%8C%E9%9D%A2/ + 开发前建意先观看视屏, 了解基础说明, 视屏有点老和现在界面不一样, 目前很多功能已经做成可视化配置, 理解过程即可, 具体以文档为准 +Smartchart数据集与图形 从仪表盘界面中进入简易开发界面 # + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/API%E6%95%B0%E6%8D%AE%E9%9B%86/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/API%E6%95%B0%E6%8D%AE%E9%9B%86/ + 对接外部API取数, 注意返回一定要是JSON格式 你只需要在数据集编辑框中如下输入 +-- GET 方法: dataset= { &#34;url&#34;:&#34;https://www.smartchart.cn/smartdata/api/?i=loaddataset1&amp;j=1&#34; } -- POST 方法: dataset= { &#34;url&#34;:&#34;https://www.smartchart.cn/smartdata/api&#34;, &#34;method&#34;:&#34;POST&#34;, &#34;data&#34;:{&#34;i&#34;:&#34;loaddataset1&#34;, &#34;j&#34;:&#34;1&#34;} ... } 例如你可以传入参数做出联动效果 +dataset= { &#34;url&#34;:&#34;https://www.smartchart.cn/smartdata/api&#34;, &#34;method&#34;:&#34;POST&#34;, &#34;data&#34;:{&#34;i&#34;:&#34;loaddataset1&#34;, &#34;j&#34;:&#34;/*$参数名*/&#34;} ... } 你也可以增加header等认证方式 +dataset= { &#34;url&#34;:&#34;https://www.smartchart.cn/smartdata/api&#34;, &#34;method&#34;:&#34;GET&#34;, &#34;headers&#34;:{&#34;Cookie&#34;:&#34;xxxxxxx&#34;} ... } + + + + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E5%87%BD%E6%95%B0%E6%96%B9%E6%B3%95/%E5%9B%BE%E5%BD%A2%E7%AB%AF%E6%95%B0%E6%8D%AE%E5%87%BD%E6%95%B0/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E5%87%BD%E6%95%B0%E6%96%B9%E6%B3%95/%E5%9B%BE%E5%BD%A2%E7%AB%AF%E6%95%B0%E6%8D%AE%E5%87%BD%E6%95%B0/ + 应用场景 # 在图形开发中,我们可能需要使用js对传递过来的数据进行处理 +原始数据格式 # 假设dataset的格式是, SQL = Select 维度1,维度2,数据 from xxxx, 生成的数据集如下 +dataset = [[&#39;category&#39;,&#39;C1&#39;,&#39;C2&#39;], [&#39;R1&#39;, 12, 18], [&#39;R2&#39;, 10, 17] ] 转化函数 # 生成字典表示为key-&gt;[], 常用于定制化高的图形 # result = ds_createMap(dataset) 结果 = {&#34;category&#34;:[&#39;C1&#39;,&#39;C2&#39;], &#34;R1&#34; : [12, 10], &#34;R2&#34; : [18, 17]} 生成非常多前端组件要求的格式 # result = ds_createMap_all(dataset) 结果 = [{&#34;category&#34;:&#34;R1&#34;, &#34;C1&#34;: 12, &#34;C2&#34;: 18}, {&#34;category&#34;:&#34;R2&#34;, &#34;C1&#34;: 10, &#34;C2&#34;: 17}] 获取列名list, 用于获取系列名 # result = ds_rowname(dataset) 结果 = [&#39;R1&#39;,&#39;R2&#39;] 将数据集行列转化, 一般用于坐标轴翻转 # result = ds_transform(dataset) 结果 = [[&#39;category&#39;,&#39;R1&#39;,&#39;R2&#39;], [&#39;C1&#39;, 12, 10], [&#39;C2&#39;, 18, 17]] 两个数据集左关联, 常用于将两段查询数据合并 # 假设需要关联的数据集格式: dataset2 = [[&#39;category&#39;,&#39;C3&#39;], [&#39;R1&#39;, 38], [&#39;R6&#39;, 13]] 处理后的结果: result = ds_leftjoin(dataset, dataset2) 结果 = [[&#39;category&#39;,&#39;C1&#39;,&#39;C2&#39;,&#39;C3&#39;], [&#39;R1&#39;, 12, 18, 38], [&#39;R2&#39;, 10, 17, 0] ] 数据集旋转,在excel中叫透视表 # 比如需要将dataset3的户型变成指标 dataset3 = [[&#39;城市&#39;,&#39;户型&#39;,&#39;数量&#39;], [&#39;长沙&#39;,&#39;A&#39;,35], [&#39;上海&#39;,&#39;B&#39;,19]] 处理后的结果: result = ds_pivot(dataset3) 结果 = [[&#34;城市&#34;,&#34;A&#34;,&#34;B&#34;], [&#34;长沙&#34;,35,0], [&#34;上海&#34;,0,19]] 移除数据集中的某几列 # 比如移除第1列(序号0) result=ds_remove_column(dataset,remove_list=[0]) 结果 = [[&#39;R1&#39;,&#39;R2&#39;], [12, 10], [18, 17] ] smartchart图形中可用的转化函数 # 函数名 函数说明 样列 ds_transform(dataset) 行列替换 ds_split(data,sep=&rsquo;,&rsquo;,head_add=[]) 将第一列拆分成多个字段,默认逗号分隔, 如果不传表头,取SQL中的字段名拆分 ds_createMap(data) data表示传入的二位数组,生成结果表示为key-&gt;[], 常用于echarts指定数据 ds_createMap_all(data) data表示传入的二维数组,生成结果表示为[{A:A1,B:B1,C:C1},{A:A2,B:B2,C:C2}&hellip;] ds_mapToList(data) 将createMap_all的格式还原成二维数组, 常用于将nosql(mongodb,es. + + + + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E5%9F%BA%E7%A1%80%E5%9B%BE%E5%BD%A2/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E5%9F%BA%E7%A1%80%E5%9B%BE%E5%BD%A2/ + 快速应用基础图形组件 # 你可使用如下方式选择常规的图形一键进行应用(我们只放了基础图形,因为你可以通过简单修改配置转化为各种图形,如线性面积图, 柱形堆叠图..) 你也可以在图形商店中找到更多已转化好的Smartchart图形 配置项完全和Echarts原生一样 +注意: 对于一些特殊图形如地图js在图形编辑中需要进行动态加载, 如果你使用了非常规图形, 你可在图形编辑器使用ds_loadjs(&lsquo;smt_china’)加载中国地图, 同理我们有 &lsquo;smt_wordcloud&rsquo;, &lsquo;smt_world&rsquo;, &lsquo;smt_ecStat&rsquo;, ‘smt_liquidfill’ 有些图形可能同时需要在模板中加载, 更多特殊图形加载说明参考 特殊图形模板加载 + + + + + https://smartchart.gitee.io/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E5%B8%83%E5%B1%80%E6%8C%87%E5%BC%95/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E5%B8%83%E5%B1%80%E6%8C%87%E5%BC%95/ + 整理一份完整的SmartChart布局说明 # 推荐先观看视屏了解 smartchart布局方式 +容器说明 # 容器 说明 定位容器 用于图形定位, 有拖拽和栅格两种. 在界面上新增时会自带;在模板编辑中新增图形时需自行加入容器 图形容器 用于图形选择, 使用id选择器, 如序号为2的容器, 选择器为#container_2 图形 可视化的实际单位, 如选择图形中的table标签, 可使用#container_2 table 响应式布局 # 一般移动端报表推荐使用响应式布局, 一次布局可以同时满足电脑端/移动端的需求 当你新增一个数据集时, smartchart会给你一段默认的代码 +&lt;div class=&#34;el-col-xs-24 el-col-md-24&#34; style=&#34;padding:0.2rem;height:50%;&#34; &gt; &lt;div style=&#34;height:100%;&#34; id=&#34;container_{name}&#34;&gt;&lt;/div&gt; &lt;/div&gt; el-col-md-24 : 电脑端宽度设定 控制图形父容器的宽度, 整行分成24个栅格, 如果你想让图形占一半, 就可以改成el-col-md-12 el-col-xs-24 :移动端宽度设定 padding:0.5% 0.5%: 控制图形的上下, 左右内边距, padding: 上 右 下 左 比如你想要图形在容器中往下走一点, 你可写成 padding: 1% 0 0 0 height:50%; 盒子的高度, 相对于父容器的高度, 最外层即浏览器高度 大屏开发推荐使用拖拽布局(PRO) # 大家如果开发大屏, 只是用响应式布局可能对于复杂的布局不是很方便, 你也可以采用拖拽绝对定位的方法, 这样你可以随意指定图形的所在位置. + + + + + https://smartchart.gitee.io/docs/5.%E5%8F%82%E6%95%B0%E5%8F%8A%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/%E5%8F%82%E6%95%B0%E7%BC%96%E5%86%99%E6%96%B9%E6%B3%95/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/5.%E5%8F%82%E6%95%B0%E5%8F%8A%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/%E5%8F%82%E6%95%B0%E7%BC%96%E5%86%99%E6%96%B9%E6%B3%95/ + 使用场景 # 需要使用图表联动效果 数据服务接口开发 使用魔法方法(smartchart独创,拒绝抄袭) # 基础原理 # - $参数名, 当有传递参数时将替换相关的值 - /* ... $参数 ... */, 当参数写在这个区间时, 如果外部没有传入参数, 会自动忽略这一段代码 - -- 标识之后单行的代码会被忽略 常见组合应用 # 理解以下样列后, 可录活使用组合出各种可能的需求 +默认参数: 实现在不传参数时默认参数是当前月份 select xx from tablename where calmonth =/*&#39;$calmonth&#39; -- */ to_char(sysdate,&#39;YYYYMM&#39;) 多个参数: 注意使用1=1及and的位置 select xx from tablename where 1=1 /* and city = &#39;$city&#39; */ /* and calmonth =&#39;$calmonth&#39;*/ 维度变化: 将字段当成参数 select /*$calmonth,*/ city, count(1) as qty from tablename group by /*$calmonth,*/ city 维度变化: 当传入月份条件时, 按城市,月份的数据, 不传参数时只看按城市的总数 select /*月份, -- $Month */ 城市, sum(度量) from tablename where 1=1 /* and 月份 &gt; &#39;$Month&#39; */ group by 城市 /*,月份 -- $Month*/ 高级开关应用 # 以上应用可以通过参数是否有传递来实现开关代码段的效果, 有些场景可能还希望通过参数值来进行代码段的开关 如下代码可以实现当传递参数type=1 或 type=2 时执行不同的代码段 使用 &ldquo;$参数__值&rdquo; 的方式做为开关 + + + + + https://smartchart.gitee.io/docs/7.%E6%8A%A5%E8%A1%A8%E5%B5%8C%E5%85%A5/%E7%AE%80%E5%8D%95%E5%B5%8C%E5%85%A5/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/7.%E6%8A%A5%E8%A1%A8%E5%B5%8C%E5%85%A5/%E7%AE%80%E5%8D%95%E5%B5%8C%E5%85%A5/ + 你可能需要把Smartchart生成的图形嵌入到其它系统 首先,所有smartchart设计出来的仪表盘都有一个访问url 你可以直接访问: +http://localhost:8000/echart?type=仪表盘名称 如:http://localhost:8000/echart?type=demo 但是smartchart默认是有权限管理的,所以如果你需要嵌入你自已的系统又不考虑权限,你可以在“设定” &ndash;&gt; 公开 然后在你的网页就可以直接iframe了 +&lt;iframe src=&#34;http://localhost:8000/echart?type=demo&#34; style=&#34;width:100%;height:100%&#34;&gt;&lt;/iframe&gt; + + + + + https://smartchart.gitee.io/docs/8.Django%E5%BA%94%E7%94%A8/%E5%B5%8C%E5%85%A5Django-Apps/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/8.Django%E5%BA%94%E7%94%A8/%E5%B5%8C%E5%85%A5Django-Apps/ + 应用场景 # 你可以在你的django项目中直接使用smartchart做为插件的方式 你可以查看相关视屏 +使用方法 # 在你的setting.py的INSTALL_APPS中加入&rsquo;smart_chart.echart' 如果你需要simpleui, 你可以在最上行加入我们适配好的&rsquo;smart_chart.smartui&rsquo; INSTALLED_APPS = [ &#39;smart_chart.smartui&#39;, .... .... &#39;smart_chart.echart&#39; ] MIDDLEWARE 中注释掉XFrameOptionsMiddleware +检查确保在Templates的设定处有DIRS的相关设定 +TEMPLATES = [ { &#39;BACKEND&#39;: &#39;django.template.backends.django.DjangoTemplates&#39;, &#39;DIRS&#39;: [BASE_DIR / &#39;templates&#39;], #此处需要有 &#39;APP_DIRS&#39;: True, #也要有 ..... }, ] setting.py中设定为中国时区, 支持中文基础平台建设! LANGUAGE_CODE = &#39;zh-hans&#39; TIME_ZONE = &#39;Asia/Shanghai&#39; USE_I18N = True USE_L10N = True USE_TZ = False # 此处必须为False 在你的url.py中加入引用 from django.conf.urls import include from django.views.generic import RedirectView url.py的urlpatterns中加入路由 path(&#39;echart/&#39;, include(&#39;smart_chart.echart.urls&#39;)), path(&#39;&#39;, RedirectView. + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E5%AE%9E%E6%88%98%E5%A4%A7%E5%B1%8F%E6%A8%A1%E6%9D%BF%E8%BD%AC%E5%8C%96/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E5%AE%9E%E6%88%98%E5%A4%A7%E5%B1%8F%E6%A8%A1%E6%9D%BF%E8%BD%AC%E5%8C%96/ + 应用场景 # 已有开发好的非smartchart静态大屏模板(这种模板非常多, 不要上当) 对js, css及smartchart已有初始了解 业务需求展示有合适的模板, 变化不大 如何使用 # 请观看系列视屏, 相信人人都会 头条视屏: 大屏模板转化系列 B站视屏: 大屏模板转化系列 + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91%E7%95%8C%E9%9D%A2/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91%E7%95%8C%E9%9D%A2/ + 低代码化开发 # smartchart的标准模板为了标准化的原因,对于引用JS,编写CSS等有一定不方便性, 但有时候你可能需要放飞自由, 随意定制 你甚至可能想引用一些其它的UI组件, 所以smartchart给你一个原汗原味的开发空间 +开启方式 # 在高级中,设定template为diy 主菜单中会多出来一个 模板 的功能 进入模板编辑界面 + + + + + https://smartchart.gitee.io/docs/%E5%85%B3%E4%BA%8E%E6%88%91%E4%BB%AC/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/%E5%85%B3%E4%BA%8E%E6%88%91%E4%BB%AC/ + 我们的目标 # 打造全生态的数据应用数据管理的平台,解决中小企业上中台难,上中台贵,见效慢的问题. 平台与时俱进,不断完善与优化中 可以通过视屏了解我们的架构设计 企业数字化与smartchart的一站式解决方案 +我们不提供数据存储与计算引擎, ETL工具, BI工具. 因为已有更优秀的产品,我们只为数据开发人员提供更敏捷的工具与平台,致力于数据服务中台建设,边缘可视化与数据管道产品, 站在巨人的肩上, 让数据更有个性,更灵活与可定制化,由于他的通用性,功能的扩展变得也是非常的Smart +产品定位: # 实现全生态的数据服务平台(数据收集, 数据加工, 数据分享,数据管理,数据应用) +产品模块: # 统一的数据处理调度平台、数据管道, 是基于Apache顶级项目Airflow上的二次开发产品,让数据处理的任务调度开发与管理微代码化,我们的设计理念是让开发者更方便的同时,不丧失灵活和高度可自定义,如果你使用过smartchat,你可以想象他会带来的便捷性, 产品名为smartpip, 为啥不叫smartpipe, 因为能省我们就要省&hellip; 统一的可视化管理平台, 为微信等第三方应用, 提供powerbi,tableau,finebi&hellip;的嵌入式及功能扩展服务,数据集即服务,一切为数据集 统一的数据上传平台, 实现线下数据的收集需求, 并提供专业的手工上传数据产品, 支持excel本地(安装与免安装版本), 支持WEB端 统一的数据分享平台与smartchart集成,可做为数据服务中台, 实现业务对数据下载的需要及为第三方提供获取数据的API接口 SmartChart可视化平台, 新一代的数据可视化产品, 解决传统BI各种痛点问题,真正面向开发人员的平台产品 元数据管理平台及数据治理,让数据的来源更清晰, 让数据应用更方便,具备自动化,可视化的数据血缘分析 新一代极速数据仓库技术, 极简架构即可实现在大数据应用的全场景需求 + + + + 专业版本说明 + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E4%B8%93%E4%B8%9A%E7%89%88%E8%AF%B4%E6%98%8E/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E4%B8%93%E4%B8%9A%E7%89%88%E8%AF%B4%E6%98%8E/ + 版权声明 # 为项目能持续维护,并保持稳定的模式,按照社区投票的意见, 开始区分免费版本和专业版本 目前免费版本无需激活, 你可以使用到常用的功能,我们也会保持持续的更新 为保持项目的健康发展,如需进行商用,您需提供使用方并知会作者进行授权 +免费版使用者必须保留SmartChart相关版权标识及LOGO,禁止对其进行修改和删除 如果违反,将保留对侵权者追究责任的权利 +激活方式 # 您在初次安装Smartchart后会自动免费激活20天的专业版本, 之后专业版本功能会限制使用 请务必仔细阅读免费版本与专业版本的区别, 避免带来的不便 后续如果您还需要继续体验专业版本, 点击查看激活试用方式, 如果您是企业用途,建意使用专业版,获取更快的开发效率,可视化效果, 可靠性的保障及极速的查询体验 +针对个人独立开发者,你可以采用廉价的专业版仪表盘激活方案, 可满足小项目的可视化要求 如果需要永久激活专业版,可关注公众号与客服联系,或扫码联系微信客服了解, 非诚勿扰 +微信客服不提供技术咨询, 如有使用方法的疑惑,建意加QQ群:476715246 进行沟通 +免费版本与专业版本对比: # 功能 免费版 专业版 中台版 栅格布局 V V V DATAV V V V 拖拽布局 V V 自由开发 V V 切换图表主题 V V 主题自由设计 V V 引入JS V V 引入CSS V V 上传静态资源 V V 使用VUE V V V 数据集开发 V V V 所有数据源 V V V 图形开发 V V V 图形商店 V V V 普通模板应用 V V V 专业模板应用 V V 复制仪表盘 V V V 钻取 V V V 联动 V V V 筛选 V V V 单点登录 V V V 嵌入认证 V V LDAP认证 V V Juypter V V V 快捷存档 V V 数据加速 V V 数据API服务 V V 后台API刷新 V V 仪表盘同步 V V 仪表盘版本管理 V V 数据填报 V V 报表Portal V V 多级项目菜单 V 商业授权 V V 优先咨询 V V 专业边框背景 V V 3D场景 V V 中国式报表 V V 生产部署文档 V V 个性化修改 V V 授权书 V V 低代码ETL V 调度平台 V 智慧BI V 数据资产 V 数据血缘 V 租户管理 V + + + + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/VUE%E7%9B%B8%E5%85%B3/ElementUI/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/VUE%E7%9B%B8%E5%85%B3/ElementUI/ + 应用场景 # 非大屏场景应用 有较多交互场景的报表, 如筛选,表格,分页,下载等 使用方法 # 如下图, base.html 改为 basevue.html 将自动开启加载vue和elementui 注意vue的变量引用在 模板编辑界面中, 写法变更为 {[ ]} +ElementUI组件说明 视屏参考 +参考样列 # 新增一个数据集(点击金色的新增按钮, 这样会新增一个可拖拽的数据集) 修改相应的数据集及图形 数据集端 +select H1, H2, qty, rate from smartdemo2 limit 100 图形端 +let dataset = __dataset__; let tableData = ds_createMap_all(dataset); vapp.d0={ tableData: tableData } 模板Body区端 +&lt;div class=&#34;smtdrag&#34; id=&#34;id_1639824145817&#34;&gt; &lt;template&gt; &lt;el-table stripe border height=&#34;100%&#34; :data=&#34;d0.tableData&#34; style=&#34;width: 100%&#34;&gt; &lt;el-table-column label=&#34;hero&#34;&gt; &lt;el-table-column prop=&#34;H1&#34; label=&#34;H1&#34; fixed :default-sort = &#34;{prop: &#39;H2&#39;, order: &#39;descending&#39;}&#34; width=&#34;180&#34;&gt; &lt;/el-table-column&gt; &lt;el-table-column prop=&#34;H2&#34; label=&#34;H2&#34; sortable width=&#34;180&#34;&gt; &lt;/el-table-column&gt; &lt;/el-table-column&gt; &lt;el-table-column sortable prop=&#34;qty&#34; label=&#34;qty&#34;&gt; &lt;/el-table-column&gt; &lt;el-table-column prop=&#34;rate&#34; label=&#34;rate&#34;&gt; &lt;/el-table-column&gt; &lt;/el-table&gt; &lt;/template&gt; &lt;/div&gt; + + + + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E4%B8%8D%E5%A4%AA%E9%87%8D%E8%A6%81/%E5%A4%8D%E5%88%B6%E4%BB%AA%E8%A1%A8%E7%9B%98/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E4%B8%8D%E5%A4%AA%E9%87%8D%E8%A6%81/%E5%A4%8D%E5%88%B6%E4%BB%AA%E8%A1%A8%E7%9B%98/ + 复制仪表盘 # 好不容易开发好了一个仪表盘, 想再做一个类似的, 或者想要一个测试用, 还需要一个个数据集, 图形复制粘贴么, 不, 你仅仅只需要点击下, 将给你复制出一个全新的仪表盘 注意: 复制出来的仪表盘, 数据集是与原仪表盘公用的!! +如果你想将数据集独立出来, 可以按下图操作, 进入数据集设定, 点击磁铁, 将为你自动创建一个全新的数据集 + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/EXCEL%E6%95%B0%E6%8D%AE/%E6%95%B0%E6%8D%AE%E4%B8%8A%E4%BC%A0/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/EXCEL%E6%95%B0%E6%8D%AE/%E6%95%B0%E6%8D%AE%E4%B8%8A%E4%BC%A0/ + 用户如何上传文件 # smartchart默认是不自带文件上传功能 但是smartchart是可以自已创造上传页面, 在模板商店中你可以找到相关模板进行购买 然后通过模板下载的方式下载后进行操作 这样每一个页面是可以单独使用权限控制的,就和控制报表权限一样,你还可能按需随意定制页面 关于上传文件的路径 # 默认的上传主目录是在项目的log的文件夹下面, 你可以在setting.py(自定义django) 或 config.ini中设定UPLOAD_PATH来修改你的上传目录 比如你上传页面的报表ID是23, 那么文件将会被上传到UPLOAD_PATH/23/你的文件名 +如何使用上传的文件 # 你需要使用 python连接器, 来操作你的上传的数据, 内置了变量ds_path为你的上传目录, 所以可以更方便的读取上传的文件,如上文件 df = pd.read_excel(ds_path+&rsquo;/23/文件名') + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/SQL%E6%95%B0%E6%8D%AE%E9%9B%86/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/SQL%E6%95%B0%E6%8D%AE%E9%9B%86/ + SmartChart标准数据集你可以想象为一个EXCEL的二维表, 有行和列 你直接在数据集开发界面填写SQL即可 +标准图形的数据表类型 # A类数据源 # 比如你的原始数据库中表的格式如下, 表名tb_name: 城市 户型 数量 长沙 A 12 长沙 A 23 上海 B 19 查询的sql: select 城市,户型,sum(数量) AS 数量 from tb_name group by 城市,户型 正常的查询的结果为: [[&#39;城市&#39;,&#39;户型&#39;,&#39;数量&#39;], [&#39;长沙&#39;,&#39;A&#39;,35], [&#39;上海&#39;,&#39;B &#39;,19]] 由于生成的数据格式第二行是 [字符,字符,数值], 后台会自动进行转列动作, 生成图表更容易使用格式: [[&#39;Categroy&#39;,&#39;A&#39;,&#39;B&#39;], [&#39;长沙&#39;, 35, 0], [&#39;上海&#39;, 0, 19]] B类数据源 # 再比如我们有一个表的数据格式, 指标是展开的: 城市 A B 长沙 10 12 上海 11 19 长沙 9 10 我们可以写的sql是: select 城市, sum(A) as A, sum(B) as B from tb_name group by 城市 这样得到的结果是: [[&#39;城市&#39;,&#39;A&#39;,&#39;B&#39;], [&#39;长沙&#39;, 19, 22], [&#39;上海&#39;, 11, 19]] 和我们的标准格式也是一样的 SQL多段查询 # 有时你一个数据集可能只用一个SQL查询还不够,比如你需要一个清单数据,同时你需要一个汇总数据做为说明在图形中显示,这样你就需要使用多条SQL语句,在数据集中的写法你只需要用分号隔开,如: + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/Python%E6%95%B0%E6%8D%AE%E9%9B%86/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/Python%E6%95%B0%E6%8D%AE%E9%9B%86/ + 应用场景 # 当SQL查询无法满足你的需求, 你需要对查询后的结果进行处理, 或者你需要使用Excel的数据源, 甚至你需要对不同系统的数据进行查询, Python连接器可以帮到你 我们又称他为万能数据集, 你可以使用任何python语法, 需要把数据集的结果赋值给ds变量!! +首先你需要新建python连接器, 由于安全控制只允许超级管理员建立 # 内置函数说明 ds_get(id) #输入目标数据集的id名, 可以获取目标数据集 ds_df(id) #输入目标数据集的id名, 转化成pandas的df对象 ds_sql(conn_name, sql_str) #输入连接池中的名称, SQL语句, 获取数据集 ds_list(df) #将pandas的df对象转化成数据集 使用方法样列说明 # # 读取Excel数据处理, 如需上传页面可参考&#34;数据上传&#34;说明 import pandas as pd df = pd.read_excel(&#39;/Users/../smartdemo.xlsx&#39;, &#39;demo&#39;) df = df.groupby(&#39;c3&#39;).agg({&#39;qty&#39;:&#39;sum&#39;}).reset_index() ds = ds_list(df) #从数据集获取数据 ds=ds_get(12) ds=ds[:15] #从数据集获取数据转化成pandas对象处理 df = ds_df(12) df = df.sort_values(by=&#34;出场数&#34;, ascending=False) ds = ds_list(df) #可以生成字典格式的数据集供多个图形使用 import pandas as pd df = pd.read_excel(&#39;/Users/../smartdemo.xlsx&#39;, &#39;demo&#39;) df1 = df. + + + + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E5%87%BD%E6%95%B0%E6%96%B9%E6%B3%95/Jquery%E9%81%8D%E5%8E%86%E6%96%B9%E6%B3%95/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E5%87%BD%E6%95%B0%E6%96%B9%E6%B3%95/Jquery%E9%81%8D%E5%8E%86%E6%96%B9%E6%B3%95/ + 在做自定义html组件的时候你可能需要用得上: +一、向上遍历 +parent() 获取元素的直接父元素 $(&#34;span&#34;).parent().css({ &#34;color&#34;:&#34;red&#34;, &#34;border&#34;:&#34;1px solid red&#34; }) parents() 获取元素的祖先元素,直到根元素html $(&#34;span&#34;).parents().css({ &#34;color&#34;:&#34;red&#34;, &#34;border&#34;:&#34;1px solid red&#34; }) parentsUntil() 向上查找直到遇见某个祖先元素为止 $(&#34;span&#34;).parentsUntil(&#34;div&#34;).css({ //向上查找直到遇见div元素为止 &#34;color&#34;:&#34;red&#34;, &#34;border&#34;:&#34;1px solid red&#34; }) 二、向下遍历 +1. children() 查找子元素[按照从属关系] $(&#34;ul&#34;).children(&#34;li:first-child&#34;) 2. find() 按照指定的条件向下查找 $(&#34;ul&#34;).find(&#34;span&#34;) 三、水平遍历 +1. siblings() 获取元素的所有兄弟元素 $(&#34;.start&#34;).siblings().css({color:&#34;red&#34;,border:&#34;2px solid red&#34;}) 2. next() 获取元素的下一个兄弟元素 $(&#34;.start&#34;).next().css({color:&#34;red&#34;,border:&#34;2px solid red&#34;}) 3. nextAll() 获取其后的所有兄弟元素 $(&#34;.start&#34;).nextAll().css({color:&#34;red&#34;,border:&#34;2px solid red&#34;}) 4. nextUntil() 查找后面所有的兄弟元素,直到遇见某个元素为止 $(&#34;.start&#34;).nextUntil(&#34;li:last-child&#34;).css({color:&#34;red&#34;,border:&#34;2px solid red&#34;}) 5. prev() 查找上一个兄弟元素 $(&#34;li.start&#34;).prev().css({color:&#34;red&#34;,border:&#34;2px solid red&#34;}) 6. prevAll() 查找上面所有的兄弟元素 $(&#34;li. + + + + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%AE%A1%E7%90%86%E5%9B%BE%E5%BD%A2/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%AE%A1%E7%90%86%E5%9B%BE%E5%BD%A2/ + 应用场景 # 如何快速复用已开发好的组件 +本地管理自定义组件 # 如下图,点击图形编辑器中的菜单,即可管理和查看自定义图形列表 点击&quot;加入样列&quot;即可把当前图形加入到样列清单, 点击&quot;取消样列&quot;即可将所选样列移除样列清单 云管理,在图形商店中保存你的图形 # 这样你就可以在图形商店看到你的图形进行重复利用 + + + + + https://smartchart.gitee.io/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E6%8B%96%E6%8B%BD%E8%87%AA%E5%8A%A8%E5%AF%B9%E9%BD%90/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E6%8B%96%E6%8B%BD%E8%87%AA%E5%8A%A8%E5%AF%B9%E9%BD%90/ + 拖拽很方便, 但是精确对齐还是有些手抖, 所以smartchart增加了自动对齐的功能 你可以在&quot;模板&quot; &ndash;&gt; &ldquo;转化&rdquo; 中找到这个功能 首先我们随意拖拽了一些组件 然后选中拖拽代码段, 点&quot;拖拽对齐&quot; 后 点&quot;保存&quot; 就可以查看对齐后的效果了, 再进行下拖拽微调, 重复以上动作到满意 + + + + + https://smartchart.gitee.io/docs/5.%E5%8F%82%E6%95%B0%E5%8F%8A%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/%E5%9B%BE%E5%BD%A2%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/5.%E5%8F%82%E6%95%B0%E5%8F%8A%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/%E5%9B%BE%E5%BD%A2%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/ + 数据集准备 # 首先在需要进行联动的数据集中SQL的写法如下, 比如对应2号图形: +注意 /* ... */的写法, 当参数写在这个区间时, 如果外部没有传入参数, 会自动忽略这一段代码, 这样对于联动来说非常重要, 初始时全部显示, 点击其它图形时传入参数进行动态联动 select xxx,xxx,xxx from tablename /* where xxxx = &#39;$参数名&#39; */ .... 建意观看视屏比较容易理解: 数据联动说明 +常规方法 # 比如你需要点击0号图形, 指定其它图形联动 你只需要打开0号图形的数据集编辑页面, 点击标题的位置 然后输入相关的参数即可, 以下为sample 参数值设定的方法, 你可以先留空, 然后保存, F12打浏览器调试方法 点击0号图形你需要点击的动作, 你可以右调试窗口的console看到输入的log 比如我们需要传递的参数值是&quot;廉颇&quot;, 那么取数据的方法就是data.name, 你把这个填入即可 这样就实现按所选数据或所选系列钻取/联动了, 重新点击当前所选, 恢复原来的 如何在图形开发中获取参数值 +图形编辑器中, 你可以使用函数 ds_param(&#39;参数名&#39;) 来获取传入的参数值 高级定制方法 # 如果有更多个性化需求,可以在需要点击的图形的编辑器中加入以下代码,你仅仅需要修改的是序号和参数名 +//比如传入多个参数进行联动 myChart__name__.on(&#39;click&#39;, function(params){ let myparam = params.seriesName; //获取点击的值 filter_param[&#39;参数名&#39;] = myparam; //填写你的数据集的SQL设定中对应的参数名 filter_param[&#39;参数名2&#39;] = myparam2; //你可以赋值给多个参数 ds_refresh(3); //3 为你要刷新图形序号 }); 你也可以使用更方便的参数赋值方法(5. + + + + + https://smartchart.gitee.io/docs/7.%E6%8A%A5%E8%A1%A8%E5%B5%8C%E5%85%A5/%E5%8D%95%E7%82%B9%E7%99%BB%E5%BD%95/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/7.%E6%8A%A5%E8%A1%A8%E5%B5%8C%E5%85%A5/%E5%8D%95%E7%82%B9%E7%99%BB%E5%BD%95/ + 单点登录的方式与smartchart进行对接嵌入 # &#39;/echart/smart_login?id=xxx&amp;stamp=xxx&amp;token=xxx&amp;url=https://smartchart.gitee.io/&#39; &#39;&#39;&#39; 参数说明: id: 用户名(在smartchart平台中管理) stamp: 时间戳(1970年1月1日到生成时间的毫秒数) token: 采用sha1加密, token=SHA1(链接秘钥+stamp+id) 请在安装smartchart的这台机器上设定环境变量SMART_KEY = 链接秘钥 url: 登录成功后跳转链接 &#39;&#39;&#39; Python后台样列: # import time import hashlib import os &#34;&#34;&#34; 参数说明: id: 用户名(在smartchart平台中管理) stamp: 时间戳(1970年1月1日到生成时间的毫秒数) token: 采用sha1加密, token=SHA1(链接秘钥+stamp+id) url: 登录成功后跳转链接 &#34;&#34;&#34; SMART_CHART_URL = &#39;http://127.0.0.1:8000&#39; LOGIN_URL = SMART_CHART_URL + &#39;/echart/smart_login?id={id}&amp;stamp={stamp}&amp;token={token}&amp;url={url}&#39; SMART_KEY = 链接秘钥 def get_smarturl(username, url=&#39;/&#39;): stamp = int(time.time() * 1000) id = username res = SMART_KEY + str(stamp) + id token = hashlib. + + + + + https://smartchart.gitee.io/docs/8.Django%E5%BA%94%E7%94%A8/FAQ/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/8.Django%E5%BA%94%E7%94%A8/FAQ/ + FAQ # 如果你想对smartchart前端二次开发或关闭debug模式后找不到资源 在settings中加入 +STATIC_ROOT = os.path.join(BASE_DIR, &#34;static&#34;) 执行以下命令将静态文件静态文件克隆到根目录 +python3 manage.py collectstatic + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%95%B0%E6%8D%AE%E6%9C%8D%E5%8A%A1API/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%95%B0%E6%8D%AE%E6%9C%8D%E5%8A%A1API/ + SmartChart的数据集功能, 可以非常方便的实现数据对外微服务 # 权限设定 # 如果你使用的是自已搭建的django项目, 你需要在项目的根目录下新建一个JSON文件, 如果是使用smartchart启动的, 配置文件在项目的安装目录下可以找到 名为apiconfig.json, 比如需要调用API的用户名为test 和 test2,用户名需要是在你的用户设定中存在的,内容如下: { &#34;test&#34;: { &#34;token&#34;: &#34;smartchart&#34; }, &#34;test2&#34;: { &#34;token&#34;: &#34;smartchartxxx&#34;, &#34;host&#34;: [&#34;10.10.10.10&#34;,&#34;10.10.10.23&#34;], &#34;limit&#39;: 60, &#34;log&#34;:1, &#34;cors&#34;: 1 } } 可选设定参考test2 host:API白名单配置,limit:一分钟内可调用次数, log:日志记录方式. cors:永许跨域访问 +然后你只需要将你的数据集中的权限设定给对应的用户即可 请求方式 # 加密接口请求方式(推荐) # GET 请求 # #接口请求格式: url: /echart/dataset_api/?visitor=xxx&amp;token=xxx&amp;type=xxx&amp;stamp=xxxxx&amp;param={&#34;xx&#34;:&#34;xxx&#34;,&#34;xx&#34;:&#34;xxxx&#34;} # 参数说明 visitor: 用户名 type: 接口数据集ID stamp: 时间戳(1970年1月1日到生成时间的毫秒数) token: 采用sha1加密, token=SHA1(秘钥 + stamp + Visitor + Type) param: 传入的参数值(可选),格式json字符串,如多个参数: &#39;{&#34;参数A&#34;:&#34;xxxx&#34;, &#34;参数B&#34;:&#34;xxxx&#34;}&#39; # 接口返回格式 Json: { &#34;data&#34;:[[]], &#34;result&#34;:&#34;success&#34;, &#34;maxpg&#34;:1, &#34;pg&#34;:1 } 返回值说明: data : 二维数组,第一行为表头, 样列数据 [[&#34;heroname&#34;, &#34;qty&#34;],[&#34;镜&#34;,658],[&#34;猪八戒&#34;,591]] result : success 或 error maxpg/pg : GET请求固定为1不分页 POST请求(适用于后台定时同步数据,查询请用GET请求方法) # #接口请求格式: url: /echart/dataset_api/ # 请求参数说明 data: { &#34;visitor&#34;:&#34;xxx&#34;, &#34;token&#34;:&#34;xxx&#34;, &#34;stamp&#34;:xxxxx, &#34;type&#34;:&#34;xxx&#34;, &#34;pagesize&#34;:&#34;xxx&#34;, &#34;pg&#34;:&#34;xxx&#34;, &#34;param&#34;:&#39;{&#34;xxx&#34;:&#34;xxxx&#34;}&#39; } # 参数说明 visitor: 用户名 type: 接口数据集ID stamp: 时间戳(1970年1月1日到生成时间的毫秒数) token: 采用sha1加密, token=SHA1(秘钥 + stamp + Visitor + Type) Pagesize: 采用分页,每页的数据量大小 pg: 返回第几页 param: 传入的参数值,格式json字符串,如多个参数 &#39;{&#34;参数A&#34;:&#34;xxxx&#34;, &#34;参数B&#34;:&#34;xxxx&#34;}&#39; #接口返回格式 Json: { &#34;data&#34;:[[]], &#34;result&#34;:&#34;success&#34;, &#34;maxpg&#34;:xxx, #最大页数 &#34;pg&#34;:xx, #当前页数 &#34;casheflag&#34;: xx, #如果是999说明命中缓存 &#34;total&#34;:xx, #总条数 } 注意: 只有post是分页的, 第一页是带标题的, 后面页不带标题 由于post方式会使用缓存进行分页,如命中缓存传参不会生效,小数据量请使用get方式请求 不要请求大数据量,大量数据请采用limit, offset传参方式进行分页 + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E5%BF%AB%E6%8D%B7%E5%BC%80%E5%8F%91/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E5%BF%AB%E6%8D%B7%E5%BC%80%E5%8F%91/ + 应用场景 # 专业化开发, 可将仪表盘显示和模板开发分屏开发 当你熟悉smartchart的基础开发后, 你可能会喜欢上现在这种方式 把你的可视化页面移动的显示器上吧, 进入&quot;模板&quot; 开发页面(上节介绍如何进入) +方式一: 自动化DIV # 此方式当你新增数据集图形时会自动识别, 无需手动在模板在添加 采用此方式请不要采用点击模板上方菜单的图形新增 如需编辑图形或数据集可按如下方式: 方式二: 自由DIV # 你可以模板中按照常规的H5页面编辑, 只是在需要插入图形的地方插入即可(建意通过模板上方的图形新增) 开始畅快的开发 +点击图形即可新增一个图形,你甚至可以指定图表的位置, 完全和写html一样, 使用{{div_list.图表顺序号}} warning 注意请尽量避免删除DIV, 如果你中途有删除过div, 序号会不一样, 你可以在&quot;布局&quot;中重排序保持一致, 保持数据集编号从0开始 +如果使用自由布局, 请删除自动化DIV这一段代码 选中生成的图形代码段, 点击菜单栏的 数据集, 图形, 布局开发, 即可进入开发界面, 如果没有数据集, 会自动帮你新建 可以观看视屏, 视屏比较老和现在不太一样, 仅参考即可 自由开发模式视屏 + + + + 快速开始 + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B/ + 开发前你可以先观看操作方面的 :exclamation: 操作视屏教程 :exclamation: 5.0变更操作视屏教程 :exclamation: 开发系列合集,关注作者持续更新 +由于版本的变更, 一些图标可能会有一些变化, 但位置无太大的变化 +安装Python环境 # 环境准备: 官方 最新Python下载链接,可以到 淘宝镜象下载,也可以下载 WINDOWS64位安装版, MAC电脑安装版 +Window平台安装视屏介绍,注意: Windows安装Python时需选中&quot;Add to Path&quot; Linux安装可参考文档下方的部署说明, Linux安装说明 +安装SmartChart # 在Shell或CMD命令行执行 +pip3 install smartchart 如果安装过程慢,建意使用 pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple smartchart -U 升级方法: pip3 install smartchart -U (升级) 启动smartchart # 本地命令行启动: smartchart 如果你是服务器部署,远程访问,服务端启动方式: smartchart runserver 0.0.0.0:8000 --insecure --noreload 如果出现套接字,端口被占用, 可修改端口号启动, 如 smartchart runserver 0.0.0.0:8001 --insecure --noreload 一般本地启动后访问: http://127.0.0.1:8000 管理员帐号密码: admin/admin, 请及时更改密码 +如果忘记密码, 可以使用此命令重置 smartchart changepassword 用户名 鼠标滑动,点击如下图DEV图标, 切换为开发模式,这样才可以看到开发相关菜单,后打开demo页面 注意: 不切换是正常的用户报表浏览模式! + + + + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/VUE%E7%9B%B8%E5%85%B3/DataV%E5%BA%94%E7%94%A8/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/VUE%E7%9B%B8%E5%85%B3/DataV%E5%BA%94%E7%94%A8/ + 需要在高级中加入“dv”:1,即可开启datav模式 +参考视屏 1. DataV基础应用 2. DataV翻盘器 +DataV配置方法文档: 图表 + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E5%85%B1%E4%BA%AB%E6%95%B0%E6%8D%AE%E9%9B%86/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E5%85%B1%E4%BA%AB%E6%95%B0%E6%8D%AE%E9%9B%86/ + 应用场景 # 优化查询, 可一个数据集查询完所有数据进行分发 减少重复查询的浪费, 同一个数据只查询一次 使用方法 # 在数据开发界面点击按钮就可以切换成共享数据集/普通数据集 切换完成, 你会发现数据集消失,然后图标跑到菜单上面去了, 你可以在此修改你的查询 在”高级“ 中配置 这样1,2号图形都映射到了共享数据集的数据 你也可以在数据集中写多个SQL查询 在”高级“ 设定中进行数据映射 观察1,2 号图形的变化 + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E6%95%B0%E6%8D%AE%E9%9B%86%E6%95%B0%E6%8D%AE%E5%88%B7%E6%96%B0/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E6%95%B0%E6%8D%AE%E9%9B%86%E6%95%B0%E6%8D%AE%E5%88%B7%E6%96%B0/ + 数据刷新设定方法 # smartchart提供非常精细的数据刷新功能,及内存加速功能 你可以在数据集开发界面,点击连接的图标,进行设定 定时刷新 # 你可以设定前端页面数据集向后端请求刷新的时间间隔,单位秒 +如果你发现定时刷新,数据并没有变化,可能原因是您数据的缓存时间设定大于定时刷新的时间 +数据集缓存加速(PRO) # smartchart专业版提供内存加速技术,对数据库仅需请求一次,之后都是毫秒级响应 +间隔时间刷新,单位分钟,如设定 间隔时间为0.5, 则如果下一次访问时间超过30秒, 即触发数据刷新 固定时点刷新, 如设定 间隔时间 为-1, 则固定时点刷新, 即访问的时间超过固定的时点时(如下图每天09:25), 触发数据刷新 强制刷新, 访问url加上&amp;refresh=Y, 则强制刷新数据, 此刷新不会影响间隔或固定刷新的时间, 不会更新下次同步时间 后台触发强制刷新 (PRO) # 请参考文档 后台主动触发刷新 + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/%E8%87%AA%E5%AE%9A%E4%B9%89%E6%95%B0%E6%8D%AE%E6%BA%90/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/%E8%87%AA%E5%AE%9A%E4%B9%89%E6%95%B0%E6%8D%AE%E6%BA%90/ + smartchart已实现大部分常用的数据源连接, 对于其它的, 您也可以使用python数据源进行处理 但是使用python数据源有一定的缺陷, 需要在dataset上写python代码, 不能复用 对于一些带连接信息的还需要重复写入 所以你还可以使用自定义数据源 +应用场景 # 未内置的数据源, 如需要使用sparkSQL, ES等 标准处理满足不了要求, 需要对数据进行预处理的情况 需要刷新时触发预警等自定义动作 需要自定义写入方法, 个性化查询需求, 甚至是实时爬取数据 使用方法 # 首先你需要新建一个python脚本文件, 如diy_conn.py 复制以下代码到这个文件, 然后编写你的自定义查询方法 def dataset(*args, **kwargs): &#34;&#34;&#34; 返回查询数据集 :return: 二维数组或JSON字典 &#34;&#34;&#34; sqlList = args[0] # 数据集编辑界面的输入已按分号拆分成数组 [sql1, sql2...] config = args[1] # 相关的配置字典{&#39;host&#39;,&#39;port&#39;,&#39;user&#39;,&#39;password&#39;,&#39;db&#39;} # 插入你的数据查询及处理代码, 生成result即可 result = [[]] return result def insert_dataset(*args, **kwargs): &#34;&#34;&#34; 数据填表实现 &#34;&#34;&#34; contents = args[0] # 传入的数据集二维数组格式 table = args[1] # 配置中的表名 config = args[3] # 相关的配置字典{&#39;host&#39;,&#39;port&#39;,&#39;user&#39;,&#39;password&#39;,&#39;db&#39;} # 插入你的写入数据逻辑代码 在任意的仪表盘开发界面中 &ldquo;模板&rdquo; &ndash;&gt; 点击上传图标, 将这个python文件上传即可 新建数据源, 驱动填写之前上传过的文件名, 比如我们这个是diy_conn, 其它参数按照你自定义的需求填写, 会自动传入你的自定义函数 之后你可以正常使用这个自定义数据源了 + + + + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/Echarts%E7%BB%84%E4%BB%B6/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/Echarts%E7%BB%84%E4%BB%B6/ + 应用场景 # Smartchart提供了很多通用的图形,你可以在商店中直接使用 如果要个性化需要你进行自定义, 比如你可能需要在同一个图上展示柱形图和线性图 +开发前建意先观看视屏, 了解基础说明, 视屏有点老和现在界面不一样, 目前很多功能已经做成可视化配置, 理解过程即可, 具体以文档为准 +Smartchart数据库与图形的对话 Smartchart图形开发一 Smartchart图形开发二 获取原生echarts图形 # 首先我们在ECHART官网可能找一个你喜欢的图形, 如下简单柱形图链接: 打开我们可以看对应的option: +option = { xAxis: { type: &#39;category&#39;, data: [&#39;Mon&#39;, &#39;Tue&#39;, &#39;Wed&#39;, &#39;Thu&#39;, &#39;Fri&#39;, &#39;Sat&#39;, &#39;Sun&#39;] }, yAxis: { type: &#39;value&#39; }, series: [{ data: [120, 200, 150, 80, 70, 110, 130], type: &#39;bar&#39; }] }; 转化为smartchart图形 # 复制到Smartchart图形编辑器, 点击&quot;刀叉“ 图标(目前是魔法梆), 会自动进行初步转化 接下来我们就进行下改造, 请注意对比, 你只需照着复制即可 +let dataset = __dataset__ //传入dataset let legend_label = ds_rowname(dataset) //可选, 自动获取legend let xlabel = dataset[0]. + + + + + https://smartchart.gitee.io/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E5%88%A0%E9%99%A4%E5%AE%B9%E5%99%A8/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E5%88%A0%E9%99%A4%E5%AE%B9%E5%99%A8/ + 对于仪表盘中不再使用的数据集,你可能会考虑删除 首先smartchart推荐你不做删除,因为你可以保留他, 当你下次有新增数据集的需求时再拿出来 所以优先推荐使用隐藏的方法,你可以在数据集编辑界面找到他 如果你实在需要删除,可以在“报表”界面先中不需要容器后,选中删除,后保存 + + + + + https://smartchart.gitee.io/docs/5.%E5%8F%82%E6%95%B0%E5%8F%8A%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/%E7%AD%9B%E9%80%89%E5%99%A8%E6%8C%87%E5%8D%97/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/5.%E5%8F%82%E6%95%B0%E5%8F%8A%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/%E7%AD%9B%E9%80%89%E5%99%A8%E6%8C%87%E5%8D%97/ + 通用实现方式 # SMARTCHART实现筛选最简单的方法只需要配一个控件即可: +建立一个筛选清单数据集, 自动获取筛选的列表,那么可以这么写 +Select xxxx as city from tablename..... 则会生成一个如下的数据集: [[&#39;city&#39;],[选项1],[选项2],..] 良好的习惯, 先保存在数据集 然后在筛选器数据集中的js编辑器(图形编辑器),填下如下代码: +//如要要美化, 自已加样式, 只要保证id=&#34;id_select__name__&#34; let dataset=__dataset__; let table =&#39;&lt;span&gt;标题&lt;/span&gt;&lt;select id=&#34;id_select__name__&#34;&gt;&#39;; table = table + &#39;&lt;option value=&#34;&#34; selected&gt;----&lt;/option&gt;&#39;; for(let i=1;i&lt;dataset.length;i++){ table = table + &#39;&lt;option&gt;&#39; + dataset[i][0] + &#39;&lt;/option&gt;&#39;; } table = table + &#39;&lt;/select&gt;&lt;/div&gt;&lt;/div&gt;&#39; dom__name__.innerHTML=table; 这个时候你已经可以看到筛选器了 现在我们来设定联动效果 +假设需要被筛选的数据集的SQL这样写,数据集的序号是0 +//那么在需要被联动的数据集中,如使用pcity做为参数写查询, 比如: select xx, xx, xx from tablename /* where xx = &#39;$pcity&#39; */ 现在回到我们筛选器数据集,点击标题的位置, 我们需要使0号图形被筛选器联动, 设置如下即可: 然后你就可以看到筛选效果了, 非常的简单方便, 需要多个图形被联动, 只需用逗号分隔即可 比如: 0, 2, 4 + + + + + https://smartchart.gitee.io/docs/7.%E6%8A%A5%E8%A1%A8%E5%B5%8C%E5%85%A5/%E5%8D%95%E9%A1%B5%E9%9D%A2%E5%B5%8C%E5%85%A5/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/7.%E6%8A%A5%E8%A1%A8%E5%B5%8C%E5%85%A5/%E5%8D%95%E9%A1%B5%E9%9D%A2%E5%B5%8C%E5%85%A5/ + 嵌入报表 # 与单点登录类似, 单点登录用于直接登录到平台访问报表 但对于只嵌入报表, 用此方法更合适(需升级到5.3.11以上) +嵌入的url: &#39;/echart/?type={reportName}&amp;visitor={visitor}&amp;token={token}&amp;stamp={stamp}&#39; 参数说明: reportName: 报表名或报表ID visitor: 用户名(在smartchart平台中管理) stamp: 时间戳(1970年1月1日到生成时间的毫秒数) token: 采用sha1加密, token=SHA1(链接秘钥+stamp+visitor+reportName) 用户名和秘钥设定参考 数据服务API的config文件 +同时你需要将visitor加入到对应的报表权限查看访问 +python样列 # 以下为python版的url生成样列,你可以转化成你对应的开发语言 +import time import hashlib import os SMART_CHART_URL = &#39;http://127.0.0.1:8000&#39; reportID = &#39;报表ID&#39; LOGIN_URL = SMART_CHART_URL + &#39;/echart/?type={reportID}&amp;visitor={visitor}&amp;token={token}&amp;stamp={stamp}&#39; TOKEN = 链接秘钥 def get_smarturl(username, reportName): stamp = int(time.time() * 1000) visitor = username res = TOKEN + str(stamp) + visitor + reportID token = hashlib.sha1(res.encode(&#39;utf-8&#39;)).hexdigest() VISIT_DICT = { &#34;visitor&#34;: id, &#34;stamp&#34;: stamp, &#34;token&#34;: token, &#34;reportID&#34;: reportName } # 拼接好的url,直接访问 visit_url = LOGIN_URL. + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E5%A4%87%E4%BB%BD%E6%81%A2%E5%A4%8D%E5%8F%8A%E7%89%88%E6%9C%AC/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E5%A4%87%E4%BB%BD%E6%81%A2%E5%A4%8D%E5%8F%8A%E7%89%88%E6%9C%AC/ + 应用场景 # 本地仪表盘的备份恢复,版本管理 开发测试生产机之间的同步 具体使用方法请观看视屏 版本控制使用说明视屏 +使用方法 # 快速备份 # 可以在模板-&gt;点击如下图标, 完成快速备份(注意会覆盖历史), 备份号统一为:SNAPSHOT 指定备份 # 你也可以在设定-&gt;备份恢复 中进行按版本备份 查询备份 # 当不输入KEY值, 点击 本地备份时,可以查询此仪表盘已有的备份 备份恢复 # 备份可以在任意的仪表盘中进行恢复,如果是当前仪表盘, 仅输入KEY即可,比如:V01, 如果是跨仪表盘恢复, KEY需要带上仪表盘的编号如13_V01 +备份恢复参数说明 # 可以支持多种恢复模式, 只需要在KEY前面加上前缀即可, 如FORCEV01, FORCE13_V01.. FORCE: 删除自身所有数据集及高级设定,模板等,完全恢复备份 DATASET:只更新数据集及图形,模板,适用于测试上线正式 CHART: 只更新图形及模板,适用于前端变更上线 +跨服务器间同步 # 具体方法购买专业版本后提供 +使用以下流程, 可以使企业在使用最少资源做出最专业的可视化项目 # 前提条件: # 公司内部有技术人员(熟悉数据, 会写SQL) 服务器安装smartchart专业版 开发流程: # 由于公司内部人员是对业务最熟悉, 一般也都是后台数据管理相关的人员, 一般不太会有专职的前端开发和UI 所以数据开发人员可以使用smartchart开发仪表盘数据集, 并使用拖拽功能完成一个粗糙一点的框架和图形设计 一般情况下已经可以满足数据可视化的需求 +如果需要达到更专业的可视化效果, 可以外包前端/UI或在smartchart社区咨询, 由于需求变得非常简单 而前端开发又是一个通用技能, 可以使用非常廉价的费用获得最大的效果 +专业的事情专业来做, 才能达到效益最大化, 这是smartchart的设计理念 不管用什么工具, 在同等资源的投入下, 数据分析人员开发的可视化效果很难达到专业前端UI的效果 另外BI/数据开发人员的费用可是比前端高的, 也更稀缺 + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E4%B8%8A%E4%BC%A0%E8%B5%84%E6%BA%90%E6%96%87%E4%BB%B6/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E4%B8%8A%E4%BC%A0%E8%B5%84%E6%BA%90%E6%96%87%E4%BB%B6/ + 点击 模板开发 中的菜单即可上传你的资源文件, 如css, js, 图片等 视屏介绍说明 常规上传 # 可直接上传单个文件或zip包上传, 注意zip包中不可以有中文文件名 上传后会提示引用路径为/static/custom/仪表盘ID/&hellip; +上传为共享资源 # 可把资源打包为zip文件, 上传名以usr_开头, 如usr_tp.zip 上传完后不会有路径提示, 引用路径为/static/custom/usr_tp/&hellip;. +上传自定义数据源或jar包 # 上传后不会有路径提示 + + + + 第一个仪表盘 + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E7%AC%AC%E4%B8%80%E4%B8%AA%E4%BB%AA%E8%A1%A8%E7%9B%98/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E7%AC%AC%E4%B8%80%E4%B8%AA%E4%BB%AA%E8%A1%A8%E7%9B%98/ + 由于版本的变更, 一些图标可能会有一些变化, 但位置无太大的变化 +新建仪表盘 # 在开发模式下,滑动“开发管理” -&gt;&ldquo;仪表盘&rdquo;-&gt; &ldquo;新增Dashboard&rdquo; 填写相应信息后点击“保存” 点击进入仪表盘开发, 注意点击 &ldquo;E&rdquo; 字!! 点击新增(注意拖拽布局功能为PRO版本, 后续免费版本中将无法使用), 如果你坚持使用免费版本功能, 请使用左边的蓝色颜色的新增, 具体布局方式参考 数据集编辑 # 点开“数据集” 输入以下SQL后,点击“保存并刷新”, 关闭数据集编辑界面 select H1 as heroname, sum(qty) as 出场数 from smartdemo2 group by H1 order by sum(qty) desc 图形编辑 # 点开“图形编辑” 点击“云图标”,第一次使用可能要你进行登记,按提示操作即可, 在商店中找到合适的图形点击,会自动复制到剪贴板 贴粘到图形编辑器后,点击保存, 关闭图形编辑框 拖拽布局 # 重复以上步骤,再新增一个, 你可以使用拖拽的方式, 移动到不同的地方 + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E6%95%B0%E6%8D%AE%E9%9B%86%E6%87%92%E5%8A%A0%E8%BD%BD/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E6%95%B0%E6%8D%AE%E9%9B%86%E6%87%92%E5%8A%A0%E8%BD%BD/ + 应用场景 # 类似于前后端开发, 后端会提供一些接口给前端, 但前端不一定需要在一打开页面就进行查询接口, 而是当有需要时再查询, 比如数据下载, 只有当用户有下载需求时再加载, 再比如有些与后台的数据联动, 我们只需要第一次加载时只显示第一层级, 点击时再加载其它层级 +开启数据集懒加载 # 你可以点击数据集的开发界面的&quot;连接&quot; 图标, 将&quot;前端刷新(秒)&quot; 修改为-1 这时当打开仪表盘时, 此数据集不会被加载 +应用 # 一般懒加载数据集主要是用来做数据查询的, 所以并不太需要显示图形, 所以我们主要是用于在图形中进行赋值操作 比如先在模板中定义一个全局变量: 然后修改图形编辑中的代码: 即刷新数据集时会进行变量赋值 如果您使用VUE, 那么会更方便, 你可以直接使用vapp.变量名 = dataset进行赋值 +查询数据 # 你可以随时手动触发数据集的刷新, 比如懒加载的数据集序号为0 你可以在你需要触发刷新的地方调用ds_refresh(0)即可刷新0号数据集并执行0号数据集中的JS代码 +TIPS 可以将懒加载的数据集同时转化为共享数据集(参考上文), 懒加载数据集将移到菜单栏显示 + + + + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/HTML%E7%BB%84%E4%BB%B6/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/HTML%E7%BB%84%E4%BB%B6/ + 应用场景 # 输入控件,如输入框,筛选器,多选,按钮&hellip; 显示组件, 文本, 图片, 视屏&hellip; 表格组件 如果你还不熟悉html, 建意先花几分钟看下文档, 推荐 HTML基础 实际应用中有不熟悉的组件, 你都可以通过baidu搜索到, 如时间选择器 如何将html组件转化为smartchart组件 # 比如我们要实现一个有多选项和按钮的网页元素 从各大搜索平台上我们可以找到html的代码是: +&lt;label&gt;&lt;input type=&#34;checkbox&#34;&gt;孙尚香&lt;/label&gt; ..... &lt;button id=&#39;id_select0&#39;&gt;提交&lt;/button&gt; 那么我们可以直接在图形编辑器写上 +let dataset=__dataset__; let table = &#39;&#39;; table = `&lt;label&gt;&lt;input type=&#34;checkbox&#34;&gt;孙一香&lt;/label&gt; &lt;label&gt;&lt;input type=&#34;checkbox&#34;&gt;孙二香&lt;/label&gt; &lt;label&gt;&lt;input type=&#34;checkbox&#34;&gt;孙三香&lt;/label&gt;` table = table + &#34;&lt;button id=&#39;id_select0&#39;&gt;提交&lt;/button&gt;&#34; dom__name__.innerHTML=table; 但是由于我们是要通过传入的数据动态变化的,所以只需要做简单修改 +let dataset=__dataset__; let table = &#39;&#39;; for (let i=1;i&lt;dataset.length;i++){ table = `${table}&lt;label&gt;&lt;input type=&#34;checkbox&#34;/&gt;${dataset[i][0]}&lt;/label&gt; ` } table = table + &#34;&lt;button id=&#39;id_select__name__&#39;&gt;提交&lt;/button&gt;&#34; dom__name__.innerHTML=table; 所有html你都可以进行转化成smartchart组件, 你可以通过学习”万能表格系列视屏“ 来了解通用组件开发 第一波 第二波 第三波 + + + + + https://smartchart.gitee.io/docs/5.%E5%8F%82%E6%95%B0%E5%8F%8A%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/%E7%BB%84%E4%BB%B6%E8%87%AA%E5%AE%9A%E4%B9%89%E8%81%94%E5%8A%A8/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/5.%E5%8F%82%E6%95%B0%E5%8F%8A%E8%81%94%E5%8A%A8%E9%92%BB%E5%8F%96/%E7%BB%84%E4%BB%B6%E8%87%AA%E5%AE%9A%E4%B9%89%E8%81%94%E5%8A%A8/ + 应用场景 # Smartchart对于单项筛选有通用的组件, 可以直接配置即可,但对于个性化的筛选,需要你进行一些简单的定制化,以下就针对多项筛选联动的需求来介绍如何定制化你的筛选联动效果 通过此例,你可以了解如何自定义任意的联动效果 样列参考 # 以我们内置的仪表盘为例, +第一步,新建一个数据集 +第二步,在新的数据集中编写查询 +select distinct H1 as heroname from smartdemo2 limit 10 第三步,编辑此数据集的图形,可复制以下代码 +//select distinct xx from tablename let dataset=__dataset__; let table = &#39;&#39;; for (let i=1;i&lt;dataset.length;i++){ table = `${table}&lt;label&gt;&lt;input name=&#34;select__name__&#34; type=&#34;checkbox&#34; value=&#34;${dataset[i][0]}&#34; /&gt;${dataset[i][0]}&lt;/label&gt; `; } table = table + &#34;&lt;button id=&#39;id_select__name__&#39;&gt;提交&lt;/button&gt;&#34;; dom__name__.innerHTML=table; $(&#39;#id_select__name__&#39;).click( function(){ let res = []; $(&#34;input[name=&#39;select__name__&#39;]:checked&#34;).each(function(i){ res.push(&#34;&#39;&#34; + $(this).val() + &#34;&#39;&#34;); }); filter_param[&#39;H1&#39;] = res.toString(); //参数赋值 ds_refresh(1); //刷新1号图形 } ) 第四步,在你要联动刷新数据集中增加代码 + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%95%B0%E6%8D%AE%E4%B8%8B%E8%BD%BD/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%95%B0%E6%8D%AE%E4%B8%8B%E8%BD%BD/ + 应用场景: # 需要要下载数据集的数据到本地 +样例: # 可在&quot;模板&quot; 中新建一个下载按钮, 并指定一个ID,如id_down1, 拖拽到你需要的位置 在任意一个图形开发或js代码段中加入以下代码即可 +$(&#39;#id_down1&#39;).click(()=&gt;{ ds_download(&#39;报表数据.csv&#39;, dataset); }); 这样就可以实现点击按钮下载数据了 +仅需要录活使用ds_download这个函数, 你可以开发出非常个性化的下载功能 +ds_download(name, dataset) 参数说明: name: 文件名称 dataset: 可以是二维数组也可以是字符串 + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E8%BE%B9%E6%A1%86%E4%B8%8E%E8%A3%85%E9%A5%B0/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E8%BE%B9%E6%A1%86%E4%B8%8E%E8%A3%85%E9%A5%B0/ + 观看视屏 # 边框与装饰说明1 边框与背景说明2 +边框/装饰/背景(购买专业版提供使用方法) # + + + + 创建连接池 + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E5%88%9B%E5%BB%BA%E8%BF%9E%E6%8E%A5%E6%B1%A0/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E5%88%9B%E5%BB%BA%E8%BF%9E%E6%8E%A5%E6%B1%A0/ + 如何新增数据源 # 在开发模式下,点击“开发管理”-&gt;数据源-&gt;新增 配置连接池参数,注意数据库填写是备注中有写的名称 你可以通过新建一个数据集来测试连接池的连通性 +点击“保存” 后,回到数据集列表 点击如下图标&quot;E&quot;,进入数据集开发界面 在开发界面调试 安全控制 # 你可以在“参数”中设定安全控制,可避免用户误操作导致前后端卡死 limit: 可限定最大返回数据数量(但实际数据库查询无limit,需通过mode控制) mode: 控制用户查询行为,默认为模式1 +模式 说明 0 严格模式,每次查询向数据库都会增加limit,MPP类型数据库可能会排序失效 1 开发模式,仅调试查询数据库都会增加limit,调试时MPP类型数据库可能会排序失效,但不影响实际 2 宽松模式,查询都不带limit, 仅控制返回limit,需开发者避免大查询 支持的数据源: # 数据库 驱动填写 需安装 使用说明 Mysql mysql 默认支持 Mysql连接池 mysqlpool Sqlite sqlite 默认支持 连接地址填写绝对路径 API 任意 默认支持 参考数据集说明文档 EXCEL 任意 默认支持 参考数据集说明文档 SQL Server mssql 需安装 pip install pymssql SQL Server连接池 mssqlpool ORACLE oracle pip install cx_Oracle ORACLE连接池 oraclepool PostgreSql gp pip install psycopg2 GP gp pip install psycopg2 Impala impala pip install impyla Hive hive pip install impyla DB2 db2 pip install ibm_db 达梦 dm pip install dmPython Python python pip install pandas, openpyxl 参考数据集-&gt;特殊数据源 Redis redis pip install redis 参考数据集-&gt;特殊数据源 Mongodb mongodb pip install pymongo 参考数据集-&gt;特殊数据源 Clickhouse clickhouse pip install clickhouse_driver Elasticsearch es pip install elasticsearch==7. + + + + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E8%B0%83%E8%AF%95%E6%97%A5%E5%BF%97/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E8%B0%83%E8%AF%95%E6%97%A5%E5%BF%97/ + 关于页面日志查看 # 大家可能比较熟悉使用F12来查看网页日志, 但有的同学会觉得这不够方便, 所以 在5.1.11后, smartchart加入了可以页面直接显示日志的功能 +在仪表盘中显示 # 你只需要点击如下菜单, 即可切换是否显示日志 当在刷新页面或执行时, 日志将直接显示在右上角中, 而且还能显示出对应出错的图表序号 在图形中显示 # smartchart基于python的使用习惯, 重定义的专用的日志打印函数print 你可以在图形编辑器中使用些函数即可打印日志 比如看看鼠标放在echarts图上params, 在编辑界面和console中都能看到日志, 方便你进行调试 不仅仅这些, 你可能会想写太多打印日志, 上线了不好 smartchart已为你想到这些, 如果你在仪表盘中没有开启日志显示, print函数是不会打印任何日志 +有了仪表盘日志显示, 我们还能做更多的事情, 比如实时显示你拖拽的坐标, 让你精确定位 + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%95%B0%E6%8D%AE%E5%A1%AB%E6%8A%A5/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%95%B0%E6%8D%AE%E5%A1%AB%E6%8A%A5/ + 应用场景 # 收集用户端录入的数据 前端处理好的数据回写到任意系统 制做问卷系统 埋点应用 使用方法 # 新建数据集设定,格式如下: 只用指定表名 dataset={ &#34;table&#34;:&#34;表名&#34; } 你也可以指定字段, 比如 dataset={ &#34;table&#34;:&#34;表名(字段1, 字段2)&#34; } 在&quot;容器&quot;管理, 取消这个数据集激活, 并记录下来此数据集的ID, 比如132 在&quot;模板&quot;中编写录入组件代码, 具体可参考视屏 +&lt;h1 class=&#34;smtdrag&#34; id=&#34;id_1648895680659&#34;&gt;数据填报&lt;/h1&gt; &lt;div class=&#34;smtdrag&#34; id=&#34;id_1648895855760&#34;&gt; &lt;label&gt;用户&lt;/label&gt;&lt;input id=&#34;id_visitor&#34;&gt; &lt;/div&gt; &lt;div class=&#34;smtdrag&#34; id=&#34;id_1648895859160&#34;&gt; &lt;label&gt;动作&lt;/label&gt;&lt;input id=&#34;id_action&#34;&gt; &lt;/div&gt; &lt;div class=&#34;smtdrag&#34; id=&#34;id_1648895956207&#34;&gt; &lt;button id=&#34;idbtn01&#34;&gt;提交&lt;/button&gt; &lt;/div&gt; 在&quot;模板&quot; 中编写JS代码 $(&#39;#idbtn01&#39;).click(function(){ let visitor = $(&#39;#id_visitor&#39;).val(); let action = $(&#39;#id_action&#39;).val(); let dataset = [visitor, action]; print(ds_save(132, dataset)); //132数据集ID, dataset要写入的数据 }) 更多关于写入数据库的数据集格式说明 # 只写入一行数据, 样列如下: dataset = [&#39;a&#39;,&#39;b&#39;] 同时写入多行数据: dataset = [[], [&#39;a1&#39;,&#39;b1&#39;],[&#39;a2&#39;, &#39;b2]] 如果需要自动记录写入者用户名: dataset = [&#39;$username&#39;, &#39;b&#39;] mongodb写入方式 + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E6%A0%B7%E5%BC%8F%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E6%A0%B7%E5%BC%8F%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B/ + 样式操作: # 要想大屏做得好, 样式要写得好 可是我们不是前端的同学也能写样式么 当然可以, 相信你观看完以下视屏即可 +快速上手样式开发 +基础样式入门: # CSS介绍 # CSS(Cascading Style Sheet,层叠样式表)定义如何显示HTML元素。 当浏览器读到一个样式表,它就会按照这个样式表来对文档进行格式化(渲染)。 +CSS语法 # CSS实例 每个CSS样式由两个组成部分:选择器和声明。声明又包括属性和属性值。每个声明之后用分号结束。 CSS注释 +/*这是注释*/ 注释是代码之母, smartchart编辑中你可以使用CTRL+/快捷注释 +CSS的几种引入方式 行内样式 行内式是在标记的style属性中设定CSS样式。不推荐大规模使用。 +&lt;p style=&#34;color: red&#34;&gt;Hello world.&lt;/p&gt; 内部样式 嵌入式是将CSS样式集中写在网页的标签对的标签对中。格式如下: +&lt;head&gt; &lt;style&gt; p{ background-color: #2b99ff; } &lt;/style&gt; &lt;/head&gt; 外部样式 外部样式就是将css写在一个单独的文件中 +&lt;link href=&#34;mystyle.css&#34; rel=&#34;stylesheet&#34; type=&#34;text/css&#34;/&gt; CSS选择器 # 基本选择器 +元素选择器 p {color: &#34;red&#34;;} ID选择器 #i1 { background-color: red; } 类选择器 .c1 { font-size: 14px; } p .c1 { color: red; } 注意: 样式类名不要用数字开头(有的浏览器不认)。 标签中的class属性如果有多个,要用空格分隔。 + + + + 应用模板 + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E5%BA%94%E7%94%A8%E6%A8%A1%E6%9D%BF/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E5%BA%94%E7%94%A8%E6%A8%A1%E6%9D%BF/ + 应用场景 # 你可以快速应用开发好的模板,极大的提高你的开发和学习效率 +应用本地模板 # 你可以快速应用本地备份的模板, 我们内置了一个 通用的数据查询和下载模板 , 你可以尝试 +新建一个全新的dashboard, 不要放任何报表, 点击保存且编辑后, 下方可以看到下载链接, 然后点击下载即可直接应用 输入&quot;01_SMARTCHART&quot;, 点击本地恢复即可 更多本地备份恢复参考 +应用商店模板 # 方法同上&quot;应用本地模板&quot;, 注意应用商店模板为收费增值服务 +你可以点击 模板查询, 查看相应的价格后在 TB购买即可获取下载密钥 如果是全新的仪表盘, 直接输入下载密钥, 点击&quot; 商城下载 &ldquo;即可 如果仪表盘中有数据集且不再需要, 可以在下载密钥前面加上FORCE即可自动清空已有数据集后自动下载 注意模板太廉价,购买后并没有咨询服务,请务必自行了解如何使用 +资源文件放置路径 有些资源会离线打包提供给你, 只需上传即可, 上传方法参考 +如果不清楚可以观看视屏说明 使用方法可参考视屏: 一键应用模板 + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E5%90%8E%E5%8F%B0API%E5%88%B7%E6%96%B0/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E5%90%8E%E5%8F%B0API%E5%88%B7%E6%96%B0/ + 应用场景 # 有ETL流程,需要等待后台数据刷新完成后,再触发仪表盘的刷新,数据未完成刷新,仪表盘不刷新 针对有一些耗时的查询, 虽然smartchart有缓存加速, 但是在第一次刷新时可能不能达到极速 用户需要随时都能体验到极速的打开效果 使用后台API刷新,建意将仪表盘中数据集的缓存时间设置长一些,比如2天(2880分钟) +后台数据主动刷新接口 # (购买专业版本后支持) +你需要在setting.py中设定API_TOKEN API_TOKEN = &#39;xxxxxxxx&#39; 找到你要刷新的仪表盘编码, 你可以在打开的仪表盘url上面找到这个type id +后台访问如下api url即可 +http://ip:端口/echart/refresh_ds/?type=你的报表ID&amp;token=你设定的API_TOKEN 关于定时刷新 # 为保持产品的轻量化及坚持专业的产品做专业的事情, 归一化统一化的架构设计, 我们不会集成相关调度系统, 一般我们推荐使用您自有的调度工具或平台, 如airflow, 我们也有相关的配套产品 +如果您仅仅是简单应用, 也无需使用专用调度来增加运维复杂度, 可以使用linux自带的即可 +新建一个sh文件, 假设目录在/data/smartchart vim refresh_smartchart.sh 写入需要刷新的脚本 echo start refresh $(date &#34;+%Y-%m-%d %H:%M:%S&#34;) curl http://ip:端口/echart/?type=你的报表ID1&amp;token=你设定的API_TOKEN curl http://ip:端口/echart/?type=你的报表ID2&amp;token=你设定的API_TOKEN echo end refresh $(date &#34;+%Y-%m-%d %H:%M:%S&#34;) 如果你的网址是https, 可如下方法使用curl +curl -k --insecure &#34;https://www.baidu.com” 修改为可执行文件 chmod 775 refresh_smartchart.sh 使用crontab来定时执行 # 编辑crontab crontab -e # 比如需要每天晚上5点10分执行 10 5 * * * /data/smartchart/refresh_smartchart. + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/IDE%E5%BC%80%E5%8F%91%E6%A8%A1%E5%BC%8F/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/IDE%E5%BC%80%E5%8F%91%E6%A8%A1%E5%BC%8F/ + 应用场景 # 如果您是一个资深的前端开发者 可能不需要使用smartchart组件,仅需使用到数据集 你希望在IDE(如VS code)中开发然后打包发布 非专用人士,请不要尝试这种方式 开发方式 # 在模板中使用basesimple 此时smartchart不会引用任何echarts, vue组件, 完全由您自已控制引入 , 你可以直接采用以下代码替换模板中的代码 +{% extends &#34;echart/basesimple.html&#34; %}{% block head %} &lt;!--head区域的引用或代码--&gt; {% endblock %}{% block body %} &lt;!--在此区间粘入body相关代码--&gt; {% endblock %}{% block javascript %} &lt;!--粘入js相关引用或代码--&gt; {% endblock %}{% block footer %}{% endblock %} 如何使用数据集接口 # 按照自由开发模式中, 新增一个图形, 然后修改数据集为通用且懒加载数据集 修改对应图形编辑器, 使数据赋值给一个全局变量或vue 在IDE中开发 # 由于你在开发中仅需要用到filter_param及ds_refresh, 建意新建一个js文件, 文件内容: +//下面定义全局变量, 发布时需放入smartchart模板的script标签中 var mypublicdata1 = xxxx; ..... //以下为辅助方法, 发布时, 无需放入smartchart模板中 var filter_param = {}; function ds_refresh(num){ if(num === 0){你对应的图形中赋值代码,调试代码} if(num === 1){. + + + + 权限管理 + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E6%9D%83%E9%99%90%E7%AE%A1%E7%90%86/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/1.%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/%E6%9D%83%E9%99%90%E7%AE%A1%E7%90%86/ + 目前的权限管理,大概如下: +开发者权限 # 你点击DEV后, 才会出进入后台的图标, 在后台中你可以控制用户的开发权限 新建用户默认是没有开发权限的, 在首页也看不到任何开发相关的菜单 +如果你需要给用户开发权限, 需要设定如下: Dashboard报表查看权限 # 你可以在 仪表盘设定 中进行权限管理 全局编辑或查看权限 由平台用户组或用户权限配置, 如果用户需要查看报表, 需先分配到有查看权限的组中, 默认加入集团组可以具备查看权限 在dashboard设定页面中可针对人员来分配 编辑权限, 有编辑权限同时也会满足查看权限 在dashboard设定页面中可针对组来分配 查看权限 未上线 的报表, 只会在编辑页面中出现, 可以预览 公开 的报表, 如没有分配编辑权限,在编辑页面中不出现, 但在查看页面所有人可见,你可以共享给所有人,访问url: http://xxxxx:8000/echart?type=你的仪表盘名称 手机端过滤, 你可以通过 &ldquo;全端&rdquo;,&ldquo;电脑端&rdquo; 选项实现, 当勾选 &ldquo;全端&rdquo; 时, 手机端电脑端都会显示, 当未勾选 全端, 也不勾选 电脑端时, 只会在 手机显示, 反之只在电脑端显示 总结 # 在编辑入口只会显示 有按人员分配编辑权限的报表清单, 在查看入口中会显示已启用且上线且(已分配查看权限或编辑权限或公开)的报表 所以你可以么这么搭配: 对于通用报表可以所有人访问的, 但你又不想让他在清单中显示, 你可以将他设为公开但不上线 对于开发中的报表, 你可以设为未上线 + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/webSocket%E6%96%B9%E5%BC%8F/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/webSocket%E6%96%B9%E5%BC%8F/ + 应用场景 # 对于实时程度要求比较高的情况下, 如果你后端已有实现websocket的接口, smartchart也可以很方便的接入 参考以下步骤即可 +在&quot;模板&quot;中定义一个全局变量, 如ws_data 编写连接和接收代码段逻辑 在接收代码段加入ds_refresh, 如要刷新0号图形, 则加入ds_refresh(0) 在&quot;高级&quot;设定中加入共享数据集设定, 把ws_data映射到0号图形即可 代码段参考 # let ws_data = [[&#39;初始化&#39;,&#39;V&#39;],[&#39;A&#39;,&#39;2&#39;]]; let ws = null; if(&#39;webSocket&#39; in window){ print(&#39;支持webSocket&#39;); ws = new webSocket(&#39;ws://127.0.0.1:2222/abc&#39;); //连接成功 ws.onopen = function(){ print(&#39;ws连接成功&#39;); } //接收消息 ws.onmessage = function(evt){ ws_data = evt.data; ds_refresh(0); } } else{ print(&#39;浏览器不支持ws&#39;) } + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E5%8A%A8%E7%94%BB%E6%95%88%E6%9E%9C/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E5%8A%A8%E7%94%BB%E6%95%88%E6%9E%9C/ + 自动旋转效果 # 在&quot;模板&quot;的style中加入以下样式 +@-webkit-keyframes spin { from {-webkit-transform: rotate(0deg);} to {-webkit-transform: rotate(360deg);} } @keyframes spin { from {transform: rotate(0deg);} to {transform: rotate(360deg);} } .Rotate { -webkit-animation: spin 3s linear 3s 5 alternate; animation: spin 3s linear infinite; } 如需任意组件自动旋转, 只需将Rotate这个类给到这个组件即可, 比如图形 +&lt;img class=&#34;Rotate&#34; src=&#34;https://www.smartchart.cn/media/editor/smc162_20220407150432307320.png&#34;&gt; 组件变形 # 常见变形沿着Y轴, 其它变形方式自已搜索, 比如需要0号,1号图形变形的样式写法 +#container_0{transform:skewY(10deg);} #container_1{transform:skewY(-10deg);} 效果如下: + + + + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E7%BC%96%E8%BE%91%E5%99%A8%E5%BF%AB%E6%8D%B7%E9%94%AE/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/9.%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91PRO/%E6%A8%A1%E6%9D%BF%E5%BC%80%E5%8F%91/%E7%BC%96%E8%BE%91%E5%99%A8%E5%BF%AB%E6%8D%B7%E9%94%AE/ + 功能 WIN MAC 说明 显示菜单 CTRL-, Command-, 折叠其它 Alt-0 Command-Option-0 查找替换 Ctrl-F Command-F 重复选中 Ctrl-D Command-D 5.6以前的版本是删除所选 注释选中 Ctrl-/ Command-/ 取消修改 Ctrl-z Command-z 重新执行 Ctrl-y Command-y 选中大写 Ctrl-U Ctrl-U 选中小写 SHIFT-Ctrl-U SHIFT-Ctrl-U + + + + + https://smartchart.gitee.io/docs/10.%E5%85%B6%E5%AE%83/FAQ/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/10.%E5%85%B6%E5%AE%83/FAQ/ + FAQ # 启动显示 以一种访问权限不允许的方式做了一个访问套接字的尝试 出现这种情况在Windows中很常见,就是端口被占用,酷狗音乐会占用8000端口 使用netstat -ano|findstr 8000 找到进程号 使用taskkill /pid 进程号 /F +输入命令找不到smartchart 检查你是否有安装多个python环境出现环境变量冲突,请卸载一个或取消一个环境变量 +如法安装pip 请确认在安装python时,有没有加入环境变量, 可自行加入, 或卸载重装 +关于mac版本安装后的各种问题 目前来看最大的可能是,/Library/Developer/CommandLineTools这个目录下有python3,应该是在某一个版本的Xcode command line tools安装时生成的 可以先把python3全部卸载,再重新按说明安装,命令行中输入python3 和 pip3, 找不到command时才说明完全卸载成功 +sudo rm -rf /Library/Developer/CommandLineTools sudo rm -f /usr/bin/python3 如果密码忘记了怎么办 命令行输入smartchart changepassword 你的用户名 + + + + + https://smartchart.gitee.io/docs/10.%E5%85%B6%E5%AE%83/%E8%AF%95%E7%94%A8%E6%BF%80%E6%B4%BB%E8%AF%B4%E6%98%8E/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/10.%E5%85%B6%E5%AE%83/%E8%AF%95%E7%94%A8%E6%BF%80%E6%B4%BB%E8%AF%B4%E6%98%8E/ + 试用专业版激活码需要每3天激活一次,激活方式: 由于开发很忙, 文档可能会写得有不尽之处, 多多包涵 + + + + + https://smartchart.gitee.io/docs/11.%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97/Linux/SQLite3%E7%89%88%E6%9C%AC%E9%94%99%E8%AF%AF/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/11.%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97/Linux/SQLite3%E7%89%88%E6%9C%AC%E9%94%99%E8%AF%AF/ + SQLite3版本错误 在部分操作系统下(比如CentOS 7)使用SQLite3数据库运行会出现如下的错误提示: +django.core.exceptions.ImproperlyConfigured: SQLite 3.8.3 or later is required (found 3.7.17). 这表明操作系统自带的sqlite3版本过低,需要将系统的sqlite3进行升级。 +以下是一种方法,来自于 StackOverlow: +1、下载新版本的SQLite3 +wget https://www.sqlite.org/2019/sqlite-autoconf-3290000.tar.gz 2、解压文件 +tar zxvf sqlite-autoconf-3290000.tar.gz 3、进行解压后的目录 +cd sqlite-autoconf-3290000 4、配置安装目录 +./configure --prefix=$HOME/opt/sqlite 5、编译安装 +make &amp;&amp; make install 6、指定环境变量 +export PATH=$HOME/opt/sqlite/bin:$PATH export LD_LIBRARY_PATH=$HOME/opt/sqlite/lib export LD_RUN_PATH=$HOME/opt/sqlite/lib 完成之后可以运行sqlite3 &ndash;version 命令来查看当前的SQLite3版本。 + + + + + https://smartchart.gitee.io/docs/11.%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97/Linux/%E7%94%9F%E4%BA%A7%E9%83%A8%E7%BD%B2/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/11.%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97/Linux/%E7%94%9F%E4%BA%A7%E9%83%A8%E7%BD%B2/ + 购买专业版本,提供企业生产部署及无网离线部署方案 + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/Elasticsearch%E6%95%B0%E6%8D%AE%E6%BA%90/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/Elasticsearch%E6%95%B0%E6%8D%AE%E6%BA%90/ + 数据源配置方法 # 查询方法 # 更多查询方法参考 # 模糊查询 body = { &#39;query&#39;: { # 查询命令 &#39;match&#39;: { # 查询方法:模糊查询(会被分词)。比如此代码,会查到只包含:“我爱你”, “中国”的内容 &#39;name&#39;: &#39;刘&#39; } }, &#39;size&#39;: 20 # 不指定默认是10,最大值不超过10000(可以修改,但是同时会增加数据库压力) } term,精准单值查询 # 注:此方法只能查询一个字段,且只能指定一个值。类似于mysql中的where ziduan=&#39;a&#39; body ={ &#39;query&#39;:{ &#39;term&#39;:{ &#39;ziduan1.keyword&#39;: &#39;刘婵&#39; # 查询内容等于“我爱你中国的”的数据。查询中文,在字段后面需要加上.keyword # &#39;ziduan2&#39;: &#39;liuchan&#39; } } } erms,精准多值查询 #此方法只能查询一个字段,但可以同时指定多个值。类似于mysql中的where ziduan in (a, b,c...) body ={ &#34;query&#34;:{ &#34;terms&#34;:{ &#34;ziduan1.keyword&#34;: [&#34;刘婵&#34;, &#34;赵云&#34;] # 查询ziduan1=&#34;刘婵&#34;或=赵云...的数据 } } } multi_match,多字段查询 # 查询多个字段中都包含指定内容的数据 body = { &#34;query&#34;:{ &#34;multi_match&#34;:{ &#34;query&#34;:&#34;我爱你中国&#34;, # 指定查询内容,注意:会被分词 &#34;fields&#34;:[&#34;ziduan1&#34;, &#34;ziduan2&#34;] # 指定字段 } } } prefix,前缀查询 body = { &#39;query&#39;: { &#39;prefix&#39;: { &#39;ziduan. + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/JDBC%E6%95%B0%E6%8D%AE%E6%BA%90/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/JDBC%E6%95%B0%E6%8D%AE%E6%BA%90/ + 应用场景 # 当无法在python中找到连接库时, 你还可以采用jdbc的连接方式 +使用方法 # 首先您需要安装jdbc的包 pip install JayDeBeApi 在任意的一个仪表盘的 &ldquo;模板&rdquo; 编辑器中, 点击上传资源的图标上传相应的jdbc JAR包即可 新建连接的方式, 以下使用impala为例 + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/kafka%E6%95%B0%E6%8D%AE%E6%BA%90/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/kafka%E6%95%B0%E6%8D%AE%E6%BA%90/ + 用于获取kafka指定分区的最后一条记录, 用于实时场景 使用方法参考&quot;自定义数据源&quot; 以下为参考代码: +def dataset(*args, **kwargs): &#34;&#34;&#34; 返回查询数据集 :return: 二维数组或JSON字典 &#34;&#34;&#34; from kafka import KafkaConsumer, TopicPartition import json sqlList = args[0] # 数据集编辑界面的输入已按分号拆分成数组 [sql1, sql2...] config = args[1] # 相关的配置字典{&#39;host&#39;,&#39;port&#39;,&#39;user&#39;,&#39;password&#39;,&#39;db&#39;} # 插入你的数据查询及处理代码, 生成result即可 result = {} consumer = KafkaConsumer(sasl_mechanism=&#39;PLAIN&#39;, security_protocol=&#39;SASL_PLAINTEXT&#39;, sasl_plain_username=config[&#39;user&#39;], sasl_plain_password=config[&#39;password&#39;], bootstrap_servers=config[&#39;host&#39;], auto_offset_reset=&#39;earliest&#39;, api_version=(1, 0, 0), consumer_timeout_ms=50, value_deserializer=lambda v: json.loads(v.decode(&#39;utf-8&#39;)), ) topic = sqlList[0] partition = int(config[&#39;db&#39;]) tp = TopicPartition(topic=topic, partition=partition) consumer.assign([tp]) end_offsets = consumer.end_offsets([tp]).get(tp) # 获取当前消费者最大偏移量 consumer.seek(tp, offset=end_offsets-1) for message in consumer: result = message. + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/mongodb%E6%95%B0%E6%8D%AE%E6%BA%90/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/mongodb%E6%95%B0%E6%8D%AE%E6%BA%90/ + 使用方法 # 连接池正常配置即可 数据集开发中,填写查询需求: {&#34;db&#34;: &#34;db1&#34;, &#34;table&#34;: &#34;tb1&#34;, &#34;filter&#34;: {&#34;name&#34;: &#34;Zarten&#34;}, &#34;projection&#34;: {&#34;_id&#34;: 0}, &#34;sort&#34;: [[&#34;_id&#34;, 1]], &#34;limit&#34;: 10} 由于返回的字典格式, 如需转化成二维数组, 可使图形中的转化函数ds_mapToList +let dataset=ds_mapToList(__dataset__); 参数说明: # 除table,其它都为可选参数 +参数 说明 样列 db 数库名,默认连接设定中db名 table 表名[必填] filter 筛选项,具体用法参考下文 {&ldquo;name&rdquo;: &ldquo;Zarten&rdquo;,&ldquo;date&rdquo;:&ldquo;2020-10-01&rdquo;} projection 显示列 {&ldquo;name&rdquo;: 1,&ldquo;date&rdquo;:1} sort 排序,-1为降序 [[&ldquo;date&rdquo;, -1]] limit 限定返回数量 filter条件说明 # 且条件 +{&#34;age&#34;:{&#34;$gt&#34;:22}, &#34;name&#34;:{&#34;$regex&#34;:&#34;user&#34;}} 或条件 +{ &#34;$or&#34;: [ {&#34;age&#34;: {&#34;$gt&#34;: 22}}, {&#34;name&#34;: {&#34;$regex&#34;: &#34;user&#34;}} ] } 比较查询 $lt和&lt;,$lte和&lt;=,$gt和&gt;,gte和&gt;=,ne和!=是一一对应的 {&#34;field_name&#34;: {&#34;$lt&#34;: value, &#34;$gt&#34;: value}} 关联查询$in和$nin {&#34;field_name&#34;: {&#34;$in&#34;: [1,5,8]}} $regex为模糊查询的字符串提供正则表达式功能 {&#34;$or&#34;: [{&#34;field_name&#34;: {&#39;$regex&#39;: value}},{&#34;field_name2&#34;: {&#34;$regex&#34;: value}}]} + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/Redis%E6%95%B0%E6%8D%AE%E6%BA%90/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/Redis%E6%95%B0%E6%8D%AE%E6%BA%90/ + 应用场景 # 你可能会有这样的一些需求, 展示数据是要通过外部的程序计算好,如一些实时的计算场景,用spark计算好的数据 或爬虫爬取的数据, 然后写入redis或nosql的数据库,最后由前端图形直接展示或数据下载,SmartChart支持这一块的应用 +使用方法 # 你可以创建一个redis的连接池, 然后按照通用的方法建立数据集 不同的是, 数据集的SQL区不再是写sql代码, 而只需要写redis中的keyname +如redis中存储的数据是keyname 为 &ldquo;指标A&rdquo;, 数据 &lsquo;{&ldquo;长沙&rdquo;:1,&ldquo;上海&rdquo;:2}&rsquo; 这样我们只需要在数据集中写上 +指标A 即可, 最后你会得到{&ldquo;长沙&rdquo;:1,&ldquo;上海&rdquo;:2}的返回结果 +如果你需要的是表格格式, 那么你只需要往redis中存入一个二维数组, 比如: [[&ldquo;省份&rdquo;,&ldquo;数量&rdquo;],[&ldquo;长沙&rdquo;,1],[&ldquo;上海&rdquo;,2]] +注意数据存入redis为字符串格式,你可使用python的json.dumps来生成字符串格式存入 +当然我们也支持同一个数据中获取多个keyname # 比如还有一个&quot;指标B&quot;, 数据是'12345' 我们可以同时写上两个指标,用分号隔开: +指标A;指标B 最后你会得到的结果是: { &ldquo;指标A&rdquo;:{&ldquo;长沙&rdquo;:1,&ldquo;上海&rdquo;:2}, &ldquo;指标B&rdquo;:12345 } + + + + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/sqlalchemy%E8%BF%9E%E6%8E%A5/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/2.%E6%95%B0%E6%8D%AE%E9%9B%86%E8%AF%B4%E6%98%8E/%E7%89%B9%E6%AE%8A%E6%95%B0%E6%8D%AE%E6%BA%90/sqlalchemy%E8%BF%9E%E6%8E%A5/ + 常规的连接池的设定, 大家应该都很清楚了, Smartchart也支持sqlalchemy连接, 对于一些smartchart不支持的数据源可以使用此方法 配置方法: 只用填以上内容, 其它可留空 连接地址的写法参考sqlalchemy说明: +可选参数。一个标准的链接URL是这样的: dialect+driver://username:password@host:port/database dialect,是数据库类型,大概包括:sqlite, mysql, postgresql, oracle, or mssql. driver,是使用的数据库API,驱动,连接包,随便叫什么吧。 username,用户名 password,密码 host,网络地址,可以用ip,域名,计算机名,当然是你能访问到的。 port,数据库端口。 databas,数据库名。 其实这些也就dialect和dirver需要解释。 二:连接sqlite3 1,驱动 sqlite3是个文件数据库,不需要什么驱动,或者说python内置了驱动。 2,标准连接参数 # sqlite://&lt;nohostname&gt;/&lt;path&gt; 没有hostname 3,各种链接参数 # 相对路径,就是这个python文件同目录下foo.db engine = create_engine(&#39;sqlite:///foo.db&#39;) #绝对路径 #Unix/Mac下用四条////表示 engine = create_engine(&#39;sqlite:////absolute/path/to/foo.db&#39;) #Windows下用三条///加盘符路径用两条\\ engine = create_engine(&#39;sqlite:///C:\\path\\to\\foo.db&#39;) #Windows 也可以这么用三条///加盘符路径用一条\ engine = create_engine(r&#39;sqlite:///C:\path\to\foo.db&#39;) #数据库建在内存里。URI保持为空即可 engine = create_engine(&#39;sqlite://&#39;) 三:连接mysql(mariadb) sqlalchemy默认使用mysql-python作为链接驱动,既default模式 选哪种驱动,就装哪个包。 1,default默认链接方式 engine = create_engine(&#39;mysql://scott:tiger@localhost/foo&#39;) 2,# mysql-python,声明使用mysql-python驱动 engine = create_engine(&#39;mysql+mysqldb://scott:tiger@localhost/foo&#39;) 3,MySQL-connector-python 声明使用MySQL-connector-python驱动(推荐使用) engine = create_engine(&#39;mysql+mysqlconnector://scott:tiger@localhost/foo&#39;) 4,OurSQL 声明使用OurSQL驱动 engine = create_engine(&#39;mysql+oursql://scott:tiger@localhost/foo&#39;) 四:连接Microsoft SQL Server sqlalchemy默认使用 pyodbc作为链接驱动。 1,pyodbc engine = create_engine(&#39;mssql+pyodbc://scott:tiger@mydsn&#39;) 2,pymssql engine = create_engine(&#39;mssql+pymssql://scott:tiger@hostname:port/dbname&#39;) 五:连接PostgreSQL PostgreSQL默认使用 psycopg2作为链接驱动,既default模式 1, default engine = create_engine(&#39;postgresql://scott:tiger@localhost/mydatabase&#39;) 2,psycopg2 engine = create_engine(&#39;postgresql+psycopg2://scott:tiger@localhost/mydatabase&#39;) 3, pg8000 engine = create_engine(&#39;postgresql+pg8000://scott:tiger@localhost/mydatabase&#39;) 六:连接Oracle Oracle可能只有 cx_oracle一个驱动包,既default模式和声明模式一样。 1,default engine = create_engine(&#39;oracle://scott:tiger@127. + + + + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/ElementUI%E7%BB%84%E4%BB%B6/%E5%B8%A6%E5%88%86%E9%A1%B5%E7%9A%84%E8%A1%A8%E6%A0%BC/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/ElementUI%E7%BB%84%E4%BB%B6/%E5%B8%A6%E5%88%86%E9%A1%B5%E7%9A%84%E8%A1%A8%E6%A0%BC/ + 模式开启 # 需要开启模板开发模式, 并开启basevue模板 在Body加入组件 # &lt;!--表格--&gt; &lt;div class=&#34;smtdrag&#34; id=&#34;id_1654907858638&#34;&gt; &lt;el-table :data=&#34;tableData.slice((currentPage-1)*pageSize, currentPage*pageSize)&#34; height=&#34;100%&#34; size=&#34;mini&#34; header-cell-class-name=&#34;tablehead&#34; border style=&#34;width: 100%&#34;&gt; &lt;el-table-column v-for=&#34;item in tableHead&#34; :label=&#34;item.label&#34; :property=&#34;item.prop&#34; sortable&gt; &lt;/el-table-column&gt; &lt;/el-table&gt; &lt;!--表格结束--&gt; &lt;!--分页控件--&gt; &lt;el-pagination align=&#39;center&#39; @size-change=&#34;handlerSizeChange&#34; @current-change=&#34;handlerCurrentChange&#34; :current-page=&#34;currentPage&#34; :page-size=&#34;pageSize&#34; layout=&#34;total,sizes,prev,pager,next,jumper&#34; :total=&#34;tableData.length&#34; &gt;&lt;/el-pagination&gt; &lt;!--分页控件结束--&gt; &lt;/div&gt; 在JS区域加入 # var vapp = new Vue({el: &#39;#vue_app&#39;, delimiters: [&#39;{[&#39;, &#39;]}&#39;], data: { tableData:[], //表数据 tableHead:[], //表头 currentPage:1, total:20, pageSize:10 }, methods: { //处理分页数量 handlerSizeChange(val){ this.currentPage = 1; this. + + + + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2/LineUp%E5%9B%BE%E5%BD%A2/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2/LineUp%E5%9B%BE%E5%BD%A2/ + Smartchart内置了LineUp图形 LineUp is an interactive technique designed to create, visualize and explore rankings of items based on a set of heterogeneous attributes. LineUp图形参考 +ds_loadcss(&#39;smt_LineUp&#39;); ds_loadjs(&#39;smt_LineUp&#39;); let dataset = __dataset__; dataset = ds_createMap_all(dataset); try{Ljs__name__.destroy()}catch{} Ljs__name__ = LineUpJS.asTaggle(dom__name__, dataset); // 点击选中行响应动作 Ljs__name__.on(LineUpJS.LineUp.EVENT_SELECTION_CHANGED, (selection) =&gt; { console.log(Ljs__name__.data._data[selection]); //通过以上log可以查看到数据格式, 以下就是标准的联动写法 filter_param[&#39;LineupParam&#39;] = Ljs__name__.data._data[selection].xx ds_refresh(2); }); //更多响应动作 Ljs__name__.on(LineUpJS.LineUp.EVENT_HIGHLIGHT_CHANGED, (highlight) =&gt; { }); // document.querySelector(&#39;button#select&#39;).addEventListener(&#39;click&#39;, () =&gt; { // Ljs__name__.setSelection([1, 2, 3]); // }); // document.querySelector(&#39;button#highlight&#39;).addEventListener(&#39;click&#39;, () =&gt; { // Ljs__name__. + + + + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2/%E4%BD%BF%E7%94%A8%E5%9B%BE%E6%A0%87/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2/%E4%BD%BF%E7%94%A8%E5%9B%BE%E6%A0%87/ + 在&quot;模板&quot;中加载图标资源 使用方法, 可参考 font-awesome菜鸟教程 V5图标名称参考, 也可以 图标样列查询 + + + + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2/%E6%97%A0%E7%BC%9D%E6%BB%9A%E5%8A%A8/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2/%E6%97%A0%E7%BC%9D%E6%BB%9A%E5%8A%A8/ + 通用滚动 # 例如你的html如下 +&lt;div id=&#34;smtid&#34; style=&#34;height:100%&#34;&gt; &lt;ul&gt; &lt;li&gt;smartchart&lt;/li&gt; &lt;li&gt;bigdata&lt;/li&gt; &lt;li&gt;echarts&lt;/li&gt; &lt;li&gt;make it great&lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; 你只需要使用以下函数, 即可实现在无缝滚动 由于smtid是ID, 则使用 ds_liMarquee(&rsquo;#smtid&rsquo;) 即可开启自动滚动 如果 class=&ldquo;smtclass&rdquo;, 那么也可以使用类选择器 ds_liMarquee(&rsquo;.smtclass') +我们也可以使用更多的配置方法 +marconfig={ playtime: 3000, //滚动3秒 pausetime: 3000, //停3秒 config:{ direction: &#39;up&#39;,//向上滚动 runshort: false,//内容不足时不滚动 scrollamount: 20//速度 } } 可以使用 ds_liMarquee(&rsquo;#smtid&rsquo;, marconfig) 传入配置 +更多config说明: +名称 类型 默认值 说明 direction 字符串 left 滚动方向,可选 left / right / up / down loop 整数 -1 循环次数,-1 为无限循环 scrolldelay 整数 0 每次重复之前的延迟 scrollamount 整数 50 滚动速度,越大越快 circular 布尔值 true 无缝滚动,如果为 false,则和 marquee 效果一样 drag 布尔值 true 鼠标可拖动 runshort 布尔值 true 内容不足是否滚动 hoverstop 布尔值 true 鼠标悬停暂停 xml 布尔值 false 加载xml 文件 inverthover 布尔值 false 反向,即默认不滚动,鼠标悬停滚动 内置滚动表格 # smartchart内置了滚动表格, 可以一键生成 如果你需要修改表格的样式, 如字体,颜色等, 你可以在模板中重定义样式 具体样式的写法, 参考 样式快速入门 + + + + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2%E5%8A%A0%E8%BD%BD/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/3.%E5%9B%BE%E5%BD%A2%E5%BC%80%E5%8F%91/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2/%E7%89%B9%E6%AE%8A%E5%9B%BE%E5%BD%A2%E5%8A%A0%E8%BD%BD/ + smartchart默认只会引echarts的基础图形 如果你需要使用到更多图形, 你可以自行引用,可以写在模板的javascript标签中 +中国地图 &lt;script src=&#34;/static/smartchart/opt/smt_china.js&#34;&gt;&lt;/script&gt; 世界地图 &lt;script src=&#34;/static/smartchart/opt/smt_world.js&#34;&gt;&lt;/script&gt; 统计图 &lt;script src=&#34;/static/smartchart/opt/smt_ecStat.js&#34;&gt;&lt;/script&gt; 水球图 &lt;script src=&#34;/static/smartchart/opt/smt_liquidfill.js&#34;&gt;&lt;/script&gt; 词云 &lt;script src=&#34;/static/smartchart/opt/smt_wordcloud.js&#34;&gt;&lt;/script&gt; 百度地图 &lt;script type=&#34;text/javascript&#34; src=&#34;https://fastly.jsdelivr.net/npm/echarts@5/dist/extension/bmap.min.js&#34;&gt;&lt;/script&gt; + + + + + https://smartchart.gitee.io/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E4%B8%8D%E5%B8%B8%E7%94%A8/%E4%BB%A3%E7%A0%81%E8%BD%AC%E5%8C%96%E5%B8%83%E5%B1%80/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E4%B8%8D%E5%B8%B8%E7%94%A8/%E4%BB%A3%E7%A0%81%E8%BD%AC%E5%8C%96%E5%B8%83%E5%B1%80/ + 由于我们移除了boostrap的布局方式, 此布局不再做推荐! 初次学习的同学, 可能会需要一个拖拉拽的布局方式(3.9.9.13以上才支持), 所以下面介绍的是smartchart的辅助布局方法 +你可以在&quot;布局&quot; 中找到入口 进入编辑器后, 你可以拖拉拽的方式进行布局, 注意我们建意你一个column(C)容器只放一个smartchart的图形便于标准化 点击&quot;生成&quot;, 复制相关代码 回到仪表盘&quot;布局&quot;, 粘贴到编辑器, 点击 &ldquo;闪电&rdquo; 图标, 进行转化, 可能会提示你数据集不够,这样你需要新增足够数量的数据集后再点转化 注: 代码转化布局你可以不用可视化辅助, 可以用其它任意每三方布局工具生成代码后粘过来生成, 需要注意的格式是: 在你需要数据集的地方使用以下代码即可: +&lt;div style=&#34;height:100%&#34; id=&#34;container_{name}&#34;&gt;&lt;/div&gt; 转化完成后, 点击保存即可应用布局 + + + + + https://smartchart.gitee.io/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E4%B8%8D%E5%B8%B8%E7%94%A8/%E5%AE%B9%E5%99%A8%E7%AE%A1%E7%90%86%E7%95%8C%E9%9D%A2/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/4.%E5%B8%83%E5%B1%80%E8%AF%B4%E6%98%8E/%E4%B8%8D%E5%B8%B8%E7%94%A8/%E5%AE%B9%E5%99%A8%E7%AE%A1%E7%90%86%E7%95%8C%E9%9D%A2/ + 容器管理 # 你可以单独对一个容器进行编辑,或者在全局进行编辑 全局编辑器 移动图形 +你有两种方法移动数据集 可以在“报表” 中直接暴力修改序号 也可以在数据集编辑器中移动, 可选择插入(带着容器一起动),替换(容器不动,就是整体布局不变化, 只移动数据和图形) + + + + + https://smartchart.gitee.io/docs/6.Jupyter%E5%BA%94%E7%94%A8/Jupyter%E4%B8%AD%E4%BD%BF%E7%94%A8%E6%8C%87%E5%BC%95/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://smartchart.gitee.io/docs/6.Jupyter%E5%BA%94%E7%94%A8/Jupyter%E4%B8%AD%E4%BD%BF%E7%94%A8%E6%8C%87%E5%BC%95/ + 应用场景 # 你需要在jupyter中通过smartchart分享的数据集获取数据进行分析 你有很多线下数据需要进行个性化分析, 然后制做仪表盘 在Jupyter的数据分析过程中, 你需要快速生成图形 大屏或报表有部分数据集是需要能过复杂的分析生成的 +Smartchart支持像pyecharts, Matplotlib 等python绘图工具一样在Jupyter中使用, 但她更加方便, 更加炫酷 和 通用化, 不仅仅是一个绘图工具, 而且是一个平台 +我们有什么特色: +使用上手非常简单, 仅仅只有两个命令, get and set, 配置项采用原生的Echarts配置, 无重复学习成本, 使用顺滑 支持Echarts所有功能, 可定制化程度高, 显示效果好, 可嵌入也可以弹出窗口显示, 也可以dashboard中显示 数据可以固化存储, 采用smartchart Portal可以直接拼接炫酷大屏 +Smartchart与Pandas Smartchart与Jupyter SmartChart大屏新思路 +安装使用方法 # 你需要在jupyter相同的python环境中安装smartchart客户端 pip install smartchart 或pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple smartchart 如果你只是需要连接已部署好的smartchart服务端, 本地无需启动smartchart 快速开始 # 初始化认证: 第一次使用时, 打开jupyter后, 需要设定默认用户和smartchart服务端url 同一个环境, 只需初始化一次, 后面无需再设定 +from smart_chart import Smart Smart().set_auth(&#39;用户名&#39;, &#39;密码&#39;,url = &#39;http://xxxxx&#39;) 如果smartchart服务端在本地, 可以省略url + + + + diff --git a/docs/smartchart/katex/auto-render.min.js b/docs/smartchart/katex/auto-render.min.js new file mode 100644 index 0000000..3a6d663 --- /dev/null +++ b/docs/smartchart/katex/auto-render.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("katex")):"function"==typeof define&&define.amd?define(["katex"],t):"object"==typeof exports?exports.renderMathInElement=t(require("katex")):e.renderMathInElement=t(e.katex)}("undefined"!=typeof self?self:this,function(e){return function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=1)}([function(t,r){t.exports=e},function(e,t,r){"use strict";r.r(t);var n=r(0),o=r.n(n),a=function(e,t,r){for(var n=r,o=0,a=e.length;n.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathdefault{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-weight:700;font-style:italic}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;vertical-align:bottom;position:relative}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;vertical-align:bottom;font-size:1px;width:2px;min-width:2px}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{display:inline-block;width:100%;border-bottom-style:solid}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .clap,.katex .llap,.katex .rlap{width:0;position:relative}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{display:inline-block;border:0 solid;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{display:inline-block;width:100%;border-bottom-style:solid}.katex .hdashline{display:inline-block;width:100%;border-bottom-style:dashed}.katex .sqrt>.root{margin-left:.27777778em;margin-right:-.55555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.83333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.16666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.66666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.45666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.14666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.71428571em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.85714286em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.14285714em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.28571429em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.42857143em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.71428571em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.05714286em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.46857143em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.96285714em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.55428571em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.55555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.66666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.77777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.88888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.11111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.30444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.76444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.41666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.58333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.66666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.83333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.72833333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.07333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.34722222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.41666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.48611111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.55555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.69444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.83333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.44027778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.72777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.28935185em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.34722222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.40509259em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.46296296em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.52083333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.69444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.83333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.20023148em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.43981481em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.24108004em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.28929605em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.33751205em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.38572806em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.43394407em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.48216008em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.57859209em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.69431051em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.83317261em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.19961427em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.20096463em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.24115756em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.28135048em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.32154341em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.36173633em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.40192926em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.48231511em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.57877814em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.69453376em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.83360129em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .op-limits>.vlist-t{text-align:center}.katex .accent>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{display:block;position:absolute;width:100%;height:inherit;fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1}.katex svg path{stroke:none}.katex img{border-style:none;min-width:0;min-height:0;max-width:none;max-height:none}.katex .stretchy{width:100%;display:block;position:relative;overflow:hidden}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{width:100%;position:relative;overflow:hidden}.katex .halfarrow-left{position:absolute;left:0;width:50.2%;overflow:hidden}.katex .halfarrow-right{position:absolute;right:0;width:50.2%;overflow:hidden}.katex .brace-left{position:absolute;left:0;width:25.1%;overflow:hidden}.katex .brace-center{position:absolute;left:25%;width:50%;overflow:hidden}.katex .brace-right{position:absolute;right:0;width:25.1%;overflow:hidden}.katex .x-arrow-pad{padding:0 .5em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{box-sizing:border-box;border:.04em solid}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{text-align:left} diff --git a/docs/smartchart/katex/katex.min.js b/docs/smartchart/katex/katex.min.js new file mode 100644 index 0000000..906ce12 --- /dev/null +++ b/docs/smartchart/katex/katex.min.js @@ -0,0 +1 @@ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.katex=e():t.katex=e()}("undefined"!=typeof self?self:this,function(){return function(t){var e={};function r(a){if(e[a])return e[a].exports;var n=e[a]={i:a,l:!1,exports:{}};return t[a].call(n.exports,n,n.exports,r),n.l=!0,n.exports}return r.m=t,r.c=e,r.d=function(t,e,a){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:a})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var a=Object.create(null);if(r.r(a),Object.defineProperty(a,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var n in t)r.d(a,n,function(e){return t[e]}.bind(null,n));return a},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=1)}([function(t,e,r){},function(t,e,r){"use strict";r.r(e);r(0);var a=function(){function t(t,e,r){this.lexer=void 0,this.start=void 0,this.end=void 0,this.lexer=t,this.start=e,this.end=r}return t.range=function(e,r){return r?e&&e.loc&&r.loc&&e.loc.lexer===r.loc.lexer?new t(e.loc.lexer,e.loc.start,r.loc.end):null:e&&e.loc},t}(),n=function(){function t(t,e){this.text=void 0,this.loc=void 0,this.text=t,this.loc=e}return t.prototype.range=function(e,r){return new t(r,a.range(this,e))},t}(),i=function t(e,r){this.position=void 0;var a,n="KaTeX parse error: "+e,i=r&&r.loc;if(i&&i.start<=i.end){var o=i.lexer.input;a=i.start;var s=i.end;a===o.length?n+=" at end of input: ":n+=" at position "+(a+1)+": ";var h=o.slice(a,s).replace(/[^]/g,"$&\u0332");n+=(a>15?"\u2026"+o.slice(a-15,a):o.slice(0,a))+h+(s+15":">","<":"<",'"':""","'":"'"},l=/[&><"']/g;var m=function t(e){return"ordgroup"===e.type?1===e.body.length?t(e.body[0]):e:"color"===e.type?1===e.body.length?t(e.body[0]):e:"font"===e.type?t(e.body):e},c={contains:function(t,e){return-1!==t.indexOf(e)},deflt:function(t,e){return void 0===t?e:t},escape:function(t){return String(t).replace(l,function(t){return h[t]})},hyphenate:function(t){return t.replace(s,"-$1").toLowerCase()},getBaseElem:m,isCharacterBox:function(t){var e=m(t);return"mathord"===e.type||"textord"===e.type||"atom"===e.type},protocolFromUrl:function(t){var e=/^\s*([^\\\/#]*?)(?::|�*58|�*3a)/i.exec(t);return null!=e?e[1]:"_relative"}},u=function(){function t(t){this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextColor=void 0,this.strict=void 0,this.trust=void 0,this.maxSize=void 0,this.maxExpand=void 0,t=t||{},this.displayMode=c.deflt(t.displayMode,!1),this.output=c.deflt(t.output,"htmlAndMathml"),this.leqno=c.deflt(t.leqno,!1),this.fleqn=c.deflt(t.fleqn,!1),this.throwOnError=c.deflt(t.throwOnError,!0),this.errorColor=c.deflt(t.errorColor,"#cc0000"),this.macros=t.macros||{},this.minRuleThickness=Math.max(0,c.deflt(t.minRuleThickness,0)),this.colorIsTextColor=c.deflt(t.colorIsTextColor,!1),this.strict=c.deflt(t.strict,"warn"),this.trust=c.deflt(t.trust,!1),this.maxSize=Math.max(0,c.deflt(t.maxSize,1/0)),this.maxExpand=Math.max(0,c.deflt(t.maxExpand,1e3))}var e=t.prototype;return e.reportNonstrict=function(t,e,r){var a=this.strict;if("function"==typeof a&&(a=a(t,e,r)),a&&"ignore"!==a){if(!0===a||"error"===a)throw new o("LaTeX-incompatible input and strict mode is set to 'error': "+e+" ["+t+"]",r);"warn"===a?"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+e+" ["+t+"]"):"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+a+"': "+e+" ["+t+"]")}},e.useStrictBehavior=function(t,e,r){var a=this.strict;if("function"==typeof a)try{a=a(t,e,r)}catch(t){a="error"}return!(!a||"ignore"===a)&&(!0===a||"error"===a||("warn"===a?("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+e+" ["+t+"]"),!1):("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+a+"': "+e+" ["+t+"]"),!1)))},e.isTrusted=function(t){t.url&&!t.protocol&&(t.protocol=c.protocolFromUrl(t.url));var e="function"==typeof this.trust?this.trust(t):this.trust;return Boolean(e)},t}(),p=function(){function t(t,e,r){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=t,this.size=e,this.cramped=r}var e=t.prototype;return e.sup=function(){return d[f[this.id]]},e.sub=function(){return d[g[this.id]]},e.fracNum=function(){return d[x[this.id]]},e.fracDen=function(){return d[v[this.id]]},e.cramp=function(){return d[b[this.id]]},e.text=function(){return d[y[this.id]]},e.isTight=function(){return this.size>=2},t}(),d=[new p(0,0,!1),new p(1,0,!0),new p(2,1,!1),new p(3,1,!0),new p(4,2,!1),new p(5,2,!0),new p(6,3,!1),new p(7,3,!0)],f=[4,5,4,5,6,7,6,7],g=[5,5,5,5,7,7,7,7],x=[2,3,4,5,6,7,6,7],v=[3,3,5,5,7,7,7,7],b=[1,1,3,3,5,5,7,7],y=[0,1,2,3,2,3,2,3],w={DISPLAY:d[0],TEXT:d[2],SCRIPT:d[4],SCRIPTSCRIPT:d[6]},k=[{name:"latin",blocks:[[256,591],[768,879]]},{name:"cyrillic",blocks:[[1024,1279]]},{name:"brahmic",blocks:[[2304,4255]]},{name:"georgian",blocks:[[4256,4351]]},{name:"cjk",blocks:[[12288,12543],[19968,40879],[65280,65376]]},{name:"hangul",blocks:[[44032,55215]]}];var S=[];function M(t){for(var e=0;e=S[e]&&t<=S[e+1])return!0;return!1}k.forEach(function(t){return t.blocks.forEach(function(t){return S.push.apply(S,t)})});var z={doubleleftarrow:"M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5\nc2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5\n 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87\n-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7\n-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z\nm8 0v40h399730v-40zm0 194v40h399730v-40z",doublerightarrow:"M399738 392l\n-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5\n 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88\n-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68\n-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18\n-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782\nc-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3\n-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z",leftarrow:"M400000 241H110l3-3c68.7-52.7 113.7-120\n 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8\n-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247\nc-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208\n 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3\n 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202\n l-3-3h399890zM100 241v40h399900v-40z",leftbrace:"M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117\n-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7\n 5-6 9-10 13-.7 1-7.3 1-20 1H6z",leftbraceunder:"M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13\n 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688\n 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7\n-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z",leftgroup:"M400000 80\nH435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0\n 435 0h399565z",leftgroupunder:"M400000 262\nH435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219\n 435 219h399565z",leftharpoon:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3\n-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5\n-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7\n-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z",leftharpoonplus:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5\n 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3\n-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7\n-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z\nm0 0v40h400000v-40z",leftharpoondown:"M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333\n 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5\n 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667\n-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z",leftharpoondownplus:"M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z",lefthook:"M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21\n 71.5 23h399859zM103 281v-40h399897v40z",leftlinesegment:"M40 281 V428 H0 V94 H40 V241 H400000 v40z\nM40 281 V428 H0 V94 H40 V241 H400000 v40z",leftmapsto:"M40 281 V448H0V74H40V241H400000v40z\nM40 281 V448H0V74H40V241H400000v40z",leftToFrom:"M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z",longequal:"M0 50 h400000 v40H0z m0 194h40000v40H0z\nM0 50 h400000 v40H0z m0 194h40000v40H0z",midbrace:"M200428 334\nc-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z",midbraceunder:"M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z",oiintSize1:"M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z",oiintSize2:"M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8\n-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z\nm502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2\nc0 110 84 276 504 276s502.4-166 502.4-276z",oiiintSize1:"M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6\n-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z\nm525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0\n85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z",oiiintSize2:"M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8\n-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z\nm770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1\nc0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z",rightarrow:"M0 241v40h399891c-47.3 35.3-84 78-110 128\n-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20\n 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7\n 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85\n-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n 151.7 139 205zm0 0v40h399900v-40z",rightbrace:"M400000 542l\n-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5\ns-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1\nc124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z",rightbraceunder:"M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3\n 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237\n-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z",rightgroup:"M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0\n 3-1 3-3v-38c-76-158-257-219-435-219H0z",rightgroupunder:"M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18\n 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z",rightharpoon:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3\n-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2\n-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58\n 69.2 92 94.5zm0 0v40h399900v-40z",rightharpoonplus:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11\n-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7\n 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z\nm0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z",rightharpoondown:"M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z",rightharpoondownplus:"M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z",righthook:"M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z",rightlinesegment:"M399960 241 V94 h40 V428 h-40 V281 H0 v-40z\nM399960 241 V94 h40 V428 h-40 V281 H0 v-40z",rightToFrom:"M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z",twoheadleftarrow:"M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z",twoheadrightarrow:"M400000 167\nc-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3\n 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42\n 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333\n-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70\n 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z",tilde1:"M200 55.538c-77 0-168 73.953-177 73.953-3 0-7\n-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0\n 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0\n 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128\n-68.267.847-113-73.952-191-73.952z",tilde2:"M344 55.266c-142 0-300.638 81.316-311.5 86.418\n-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9\n 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114\nc1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751\n 181.476 676 181.476c-149 0-189-126.21-332-126.21z",tilde3:"M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457\n-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0\n 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697\n 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696\n -338 0-409-156.573-744-156.573z",tilde4:"M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345\n-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409\n 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9\n 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409\n -175.236-744-175.236z",vec:"M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z",widehat1:"M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22\nc-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z",widehat2:"M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat3:"M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat4:"M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widecheck1:"M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,\n-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z",widecheck2:"M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck3:"M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck4:"M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",baraboveleftarrow:"M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202\nc4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5\nc-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130\ns-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47\n121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6\ns2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11\nc0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z\nM100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z",rightarrowabovebar:"M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32\n-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0\n13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39\n-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5\n-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z",baraboveshortleftharpoon:"M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17\nc2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21\nc-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40\nc-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z\nM0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z",rightharpoonaboveshortbar:"M0,241 l0,40c399126,0,399993,0,399993,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z",shortbaraboveleftharpoon:"M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,\n1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,\n-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z\nM93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z",shortrightharpoonabovebar:"M53,241l0,40c398570,0,399437,0,399437,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z"},A=function(){function t(t){this.children=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.children=t,this.classes=[],this.height=0,this.depth=0,this.maxFontSize=0,this.style={}}var e=t.prototype;return e.hasClass=function(t){return c.contains(this.classes,t)},e.toNode=function(){for(var t=document.createDocumentFragment(),e=0;e"},N=function(){function t(t,e,r,a){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.width=void 0,this.maxFontSize=void 0,this.style=void 0,B.call(this,t,r,a),this.children=e||[]}var e=t.prototype;return e.setAttribute=function(t,e){this.attributes[t]=e},e.hasClass=function(t){return c.contains(this.classes,t)},e.toNode=function(){return C.call(this,"span")},e.toMarkup=function(){return q.call(this,"span")},t}(),I=function(){function t(t,e,r,a){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,B.call(this,e,a),this.children=r||[],this.setAttribute("href",t)}var e=t.prototype;return e.setAttribute=function(t,e){this.attributes[t]=e},e.hasClass=function(t){return c.contains(this.classes,t)},e.toNode=function(){return C.call(this,"a")},e.toMarkup=function(){return q.call(this,"a")},t}(),R=function(){function t(t,e,r){this.src=void 0,this.alt=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.alt=e,this.src=t,this.classes=["mord"],this.style=r}var e=t.prototype;return e.hasClass=function(t){return c.contains(this.classes,t)},e.toNode=function(){var t=document.createElement("img");for(var e in t.src=this.src,t.alt=this.alt,t.className="mord",this.style)this.style.hasOwnProperty(e)&&(t.style[e]=this.style[e]);return t},e.toMarkup=function(){var t=""+this.alt+"=n[0]&&t<=n[1])return r.name}return null}(this.text.charCodeAt(0));h&&this.classes.push(h+"_fallback"),/[\xee\xef\xed\xec]/.test(this.text)&&(this.text=O[this.text])}var e=t.prototype;return e.hasClass=function(t){return c.contains(this.classes,t)},e.toNode=function(){var t=document.createTextNode(this.text),e=null;for(var r in this.italic>0&&((e=document.createElement("span")).style.marginRight=this.italic+"em"),this.classes.length>0&&((e=e||document.createElement("span")).className=T(this.classes)),this.style)this.style.hasOwnProperty(r)&&((e=e||document.createElement("span")).style[r]=this.style[r]);return e?(e.appendChild(t),e):t},e.toMarkup=function(){var t=!1,e="0&&(r+="margin-right:"+this.italic+"em;"),this.style)this.style.hasOwnProperty(a)&&(r+=c.hyphenate(a)+":"+this.style[a]+";");r&&(t=!0,e+=' style="'+c.escape(r)+'"');var n=c.escape(this.text);return t?(e+=">",e+=n,e+=""):n},t}(),L=function(){function t(t,e){this.children=void 0,this.attributes=void 0,this.children=t||[],this.attributes=e||{}}var e=t.prototype;return e.toNode=function(){var t=document.createElementNS("http://www.w3.org/2000/svg","svg");for(var e in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,e)&&t.setAttribute(e,this.attributes[e]);for(var r=0;r":""},t}(),P=function(){function t(t){this.attributes=void 0,this.attributes=t||{}}var e=t.prototype;return e.toNode=function(){var t=document.createElementNS("http://www.w3.org/2000/svg","line");for(var e in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,e)&&t.setAttribute(e,this.attributes[e]);return t},e.toMarkup=function(){var t="",">"),$("math",Z,et,":",":"),$("math",Z,et,"\u2248","\\approx",!0),$("math",Z,et,"\u2245","\\cong",!0),$("math",Z,et,"\u2265","\\ge"),$("math",Z,et,"\u2265","\\geq",!0),$("math",Z,et,"\u2190","\\gets"),$("math",Z,et,">","\\gt"),$("math",Z,et,"\u2208","\\in",!0),$("math",Z,et,"\ue020","\\@not"),$("math",Z,et,"\u2282","\\subset",!0),$("math",Z,et,"\u2283","\\supset",!0),$("math",Z,et,"\u2286","\\subseteq",!0),$("math",Z,et,"\u2287","\\supseteq",!0),$("math",K,et,"\u2288","\\nsubseteq",!0),$("math",K,et,"\u2289","\\nsupseteq",!0),$("math",Z,et,"\u22a8","\\models"),$("math",Z,et,"\u2190","\\leftarrow",!0),$("math",Z,et,"\u2264","\\le"),$("math",Z,et,"\u2264","\\leq",!0),$("math",Z,et,"<","\\lt"),$("math",Z,et,"\u2192","\\rightarrow",!0),$("math",Z,et,"\u2192","\\to"),$("math",K,et,"\u2271","\\ngeq",!0),$("math",K,et,"\u2270","\\nleq",!0),$("math",Z,"spacing","\xa0","\\ "),$("math",Z,"spacing","\xa0","~"),$("math",Z,"spacing","\xa0","\\space"),$("math",Z,"spacing","\xa0","\\nobreakspace"),$("text",Z,"spacing","\xa0","\\ "),$("text",Z,"spacing","\xa0","~"),$("text",Z,"spacing","\xa0","\\space"),$("text",Z,"spacing","\xa0","\\nobreakspace"),$("math",Z,"spacing",null,"\\nobreak"),$("math",Z,"spacing",null,"\\allowbreak"),$("math",Z,"punct",",",","),$("math",Z,"punct",";",";"),$("math",K,J,"\u22bc","\\barwedge",!0),$("math",K,J,"\u22bb","\\veebar",!0),$("math",Z,J,"\u2299","\\odot",!0),$("math",Z,J,"\u2295","\\oplus",!0),$("math",Z,J,"\u2297","\\otimes",!0),$("math",Z,"textord","\u2202","\\partial",!0),$("math",Z,J,"\u2298","\\oslash",!0),$("math",K,J,"\u229a","\\circledcirc",!0),$("math",K,J,"\u22a1","\\boxdot",!0),$("math",Z,J,"\u25b3","\\bigtriangleup"),$("math",Z,J,"\u25bd","\\bigtriangledown"),$("math",Z,J,"\u2020","\\dagger"),$("math",Z,J,"\u22c4","\\diamond"),$("math",Z,J,"\u22c6","\\star"),$("math",Z,J,"\u25c3","\\triangleleft"),$("math",Z,J,"\u25b9","\\triangleright"),$("math",Z,"open","{","\\{"),$("text",Z,"textord","{","\\{"),$("text",Z,"textord","{","\\textbraceleft"),$("math",Z,"close","}","\\}"),$("text",Z,"textord","}","\\}"),$("text",Z,"textord","}","\\textbraceright"),$("math",Z,"open","{","\\lbrace"),$("math",Z,"close","}","\\rbrace"),$("math",Z,"open","[","\\lbrack"),$("text",Z,"textord","[","\\lbrack"),$("math",Z,"close","]","\\rbrack"),$("text",Z,"textord","]","\\rbrack"),$("math",Z,"open","(","\\lparen"),$("math",Z,"close",")","\\rparen"),$("text",Z,"textord","<","\\textless"),$("text",Z,"textord",">","\\textgreater"),$("math",Z,"open","\u230a","\\lfloor",!0),$("math",Z,"close","\u230b","\\rfloor",!0),$("math",Z,"open","\u2308","\\lceil",!0),$("math",Z,"close","\u2309","\\rceil",!0),$("math",Z,"textord","\\","\\backslash"),$("math",Z,"textord","\u2223","|"),$("math",Z,"textord","\u2223","\\vert"),$("text",Z,"textord","|","\\textbar"),$("math",Z,"textord","\u2225","\\|"),$("math",Z,"textord","\u2225","\\Vert"),$("text",Z,"textord","\u2225","\\textbardbl"),$("text",Z,"textord","~","\\textasciitilde"),$("text",Z,"textord","\\","\\textbackslash"),$("text",Z,"textord","^","\\textasciicircum"),$("math",Z,et,"\u2191","\\uparrow",!0),$("math",Z,et,"\u21d1","\\Uparrow",!0),$("math",Z,et,"\u2193","\\downarrow",!0),$("math",Z,et,"\u21d3","\\Downarrow",!0),$("math",Z,et,"\u2195","\\updownarrow",!0),$("math",Z,et,"\u21d5","\\Updownarrow",!0),$("math",Z,tt,"\u2210","\\coprod"),$("math",Z,tt,"\u22c1","\\bigvee"),$("math",Z,tt,"\u22c0","\\bigwedge"),$("math",Z,tt,"\u2a04","\\biguplus"),$("math",Z,tt,"\u22c2","\\bigcap"),$("math",Z,tt,"\u22c3","\\bigcup"),$("math",Z,tt,"\u222b","\\int"),$("math",Z,tt,"\u222b","\\intop"),$("math",Z,tt,"\u222c","\\iint"),$("math",Z,tt,"\u222d","\\iiint"),$("math",Z,tt,"\u220f","\\prod"),$("math",Z,tt,"\u2211","\\sum"),$("math",Z,tt,"\u2a02","\\bigotimes"),$("math",Z,tt,"\u2a01","\\bigoplus"),$("math",Z,tt,"\u2a00","\\bigodot"),$("math",Z,tt,"\u222e","\\oint"),$("math",Z,tt,"\u222f","\\oiint"),$("math",Z,tt,"\u2230","\\oiiint"),$("math",Z,tt,"\u2a06","\\bigsqcup"),$("math",Z,tt,"\u222b","\\smallint"),$("text",Z,"inner","\u2026","\\textellipsis"),$("math",Z,"inner","\u2026","\\mathellipsis"),$("text",Z,"inner","\u2026","\\ldots",!0),$("math",Z,"inner","\u2026","\\ldots",!0),$("math",Z,"inner","\u22ef","\\@cdots",!0),$("math",Z,"inner","\u22f1","\\ddots",!0),$("math",Z,"textord","\u22ee","\\varvdots"),$("math",Z,"accent-token","\u02ca","\\acute"),$("math",Z,"accent-token","\u02cb","\\grave"),$("math",Z,"accent-token","\xa8","\\ddot"),$("math",Z,"accent-token","~","\\tilde"),$("math",Z,"accent-token","\u02c9","\\bar"),$("math",Z,"accent-token","\u02d8","\\breve"),$("math",Z,"accent-token","\u02c7","\\check"),$("math",Z,"accent-token","^","\\hat"),$("math",Z,"accent-token","\u20d7","\\vec"),$("math",Z,"accent-token","\u02d9","\\dot"),$("math",Z,"accent-token","\u02da","\\mathring"),$("math",Z,Q,"\u0131","\\imath",!0),$("math",Z,Q,"\u0237","\\jmath",!0),$("text",Z,"textord","\u0131","\\i",!0),$("text",Z,"textord","\u0237","\\j",!0),$("text",Z,"textord","\xdf","\\ss",!0),$("text",Z,"textord","\xe6","\\ae",!0),$("text",Z,"textord","\xe6","\\ae",!0),$("text",Z,"textord","\u0153","\\oe",!0),$("text",Z,"textord","\xf8","\\o",!0),$("text",Z,"textord","\xc6","\\AE",!0),$("text",Z,"textord","\u0152","\\OE",!0),$("text",Z,"textord","\xd8","\\O",!0),$("text",Z,"accent-token","\u02ca","\\'"),$("text",Z,"accent-token","\u02cb","\\`"),$("text",Z,"accent-token","\u02c6","\\^"),$("text",Z,"accent-token","\u02dc","\\~"),$("text",Z,"accent-token","\u02c9","\\="),$("text",Z,"accent-token","\u02d8","\\u"),$("text",Z,"accent-token","\u02d9","\\."),$("text",Z,"accent-token","\u02da","\\r"),$("text",Z,"accent-token","\u02c7","\\v"),$("text",Z,"accent-token","\xa8",'\\"'),$("text",Z,"accent-token","\u02dd","\\H"),$("text",Z,"accent-token","\u25ef","\\textcircled");var rt={"--":!0,"---":!0,"``":!0,"''":!0};$("text",Z,"textord","\u2013","--"),$("text",Z,"textord","\u2013","\\textendash"),$("text",Z,"textord","\u2014","---"),$("text",Z,"textord","\u2014","\\textemdash"),$("text",Z,"textord","\u2018","`"),$("text",Z,"textord","\u2018","\\textquoteleft"),$("text",Z,"textord","\u2019","'"),$("text",Z,"textord","\u2019","\\textquoteright"),$("text",Z,"textord","\u201c","``"),$("text",Z,"textord","\u201c","\\textquotedblleft"),$("text",Z,"textord","\u201d","''"),$("text",Z,"textord","\u201d","\\textquotedblright"),$("math",Z,"textord","\xb0","\\degree",!0),$("text",Z,"textord","\xb0","\\degree"),$("text",Z,"textord","\xb0","\\textdegree",!0),$("math",Z,Q,"\xa3","\\pounds"),$("math",Z,Q,"\xa3","\\mathsterling",!0),$("text",Z,Q,"\xa3","\\pounds"),$("text",Z,Q,"\xa3","\\textsterling",!0),$("math",K,"textord","\u2720","\\maltese"),$("text",K,"textord","\u2720","\\maltese"),$("text",Z,"spacing","\xa0","\\ "),$("text",Z,"spacing","\xa0"," "),$("text",Z,"spacing","\xa0","~");for(var at=0;at<'0123456789/@."'.length;at++){var nt='0123456789/@."'.charAt(at);$("math",Z,"textord",nt,nt)}for(var it=0;it<'0123456789!@*()-=+[]<>|";:?/.,'.length;it++){var ot='0123456789!@*()-=+[]<>|";:?/.,'.charAt(it);$("text",Z,"textord",ot,ot)}for(var st="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",ht=0;ht=5?0:t>=3?1:2]){var r=Y[e]={cssEmPerMu:V.quad[e]/18};for(var a in V)V.hasOwnProperty(a)&&(r[a]=V[a][e])}return Y[e]}(this.size)),this._fontMetrics},e.getColor=function(){return this.phantom?"transparent":this.color},t}();kt.BASESIZE=6;var St=kt,Mt={pt:1,mm:7227/2540,cm:7227/254,in:72.27,bp:1.00375,pc:12,dd:1238/1157,cc:14856/1157,nd:685/642,nc:1370/107,sp:1/65536,px:1.00375},zt={ex:!0,em:!0,mu:!0},At=function(t){return"string"!=typeof t&&(t=t.unit),t in Mt||t in zt||"ex"===t},Tt=function(t,e){var r;if(t.unit in Mt)r=Mt[t.unit]/e.fontMetrics().ptPerEm/e.sizeMultiplier;else if("mu"===t.unit)r=e.fontMetrics().cssEmPerMu;else{var a;if(a=e.style.isTight()?e.havingStyle(e.style.text()):e,"ex"===t.unit)r=a.fontMetrics().xHeight;else{if("em"!==t.unit)throw new o("Invalid unit: '"+t.unit+"'");r=a.fontMetrics().quad}a!==e&&(r*=a.sizeMultiplier/e.sizeMultiplier)}return Math.min(t.number*r,e.maxSize)},Bt=["\\imath","\u0131","\\jmath","\u0237","\\pounds","\\mathsterling","\\textsterling","\xa3"],Ct=function(t,e,r){return j[r][t]&&j[r][t].replace&&(t=j[r][t].replace),{value:t,metrics:G(t,e,r)}},qt=function(t,e,r,a,n){var i,o=Ct(t,e,r),s=o.metrics;if(t=o.value,s){var h=s.italic;("text"===r||a&&"mathit"===a.font)&&(h=0),i=new E(t,s.height,s.depth,h,s.skew,s.width,n)}else"undefined"!=typeof console&&console.warn("No character metrics for '"+t+"' in style '"+e+"' and mode '"+r+"'"),i=new E(t,0,0,0,0,0,n);if(a){i.maxFontSize=a.sizeMultiplier,a.style.isTight()&&i.classes.push("mtight");var l=a.getColor();l&&(i.style.color=l)}return i},Nt=function(t,e){if(T(t.classes)!==T(e.classes)||t.skew!==e.skew||t.maxFontSize!==e.maxFontSize)return!1;for(var r in t.style)if(t.style.hasOwnProperty(r)&&t.style[r]!==e.style[r])return!1;for(var a in e.style)if(e.style.hasOwnProperty(a)&&t.style[a]!==e.style[a])return!1;return!0},It=function(t){for(var e=0,r=0,a=0,n=0;ne&&(e=i.height),i.depth>r&&(r=i.depth),i.maxFontSize>a&&(a=i.maxFontSize)}t.height=e,t.depth=r,t.maxFontSize=a},Rt=function(t,e,r,a){var n=new N(t,e,r,a);return It(n),n},Ot=function(t,e,r,a){return new N(t,e,r,a)},Et=function(t){var e=new A(t);return It(e),e},Lt=function(t,e,r){var a="";switch(t){case"amsrm":a="AMS";break;case"textrm":a="Main";break;case"textsf":a="SansSerif";break;case"texttt":a="Typewriter";break;default:a=t}return a+"-"+("textbf"===e&&"textit"===r?"BoldItalic":"textbf"===e?"Bold":"textit"===e?"Italic":"Regular")},Ht={mathbf:{variant:"bold",fontName:"Main-Bold"},mathrm:{variant:"normal",fontName:"Main-Regular"},textit:{variant:"italic",fontName:"Main-Italic"},mathit:{variant:"italic",fontName:"Main-Italic"},mathbb:{variant:"double-struck",fontName:"AMS-Regular"},mathcal:{variant:"script",fontName:"Caligraphic-Regular"},mathfrak:{variant:"fraktur",fontName:"Fraktur-Regular"},mathscr:{variant:"script",fontName:"Script-Regular"},mathsf:{variant:"sans-serif",fontName:"SansSerif-Regular"},mathtt:{variant:"monospace",fontName:"Typewriter-Regular"}},Pt={vec:["vec",.471,.714],oiintSize1:["oiintSize1",.957,.499],oiintSize2:["oiintSize2",1.472,.659],oiiintSize1:["oiiintSize1",1.304,.499],oiiintSize2:["oiiintSize2",1.98,.659]},Dt={fontMap:Ht,makeSymbol:qt,mathsym:function(t,e,r,a){return void 0===a&&(a=[]),"boldsymbol"===r.font&&Ct(t,"Main-Bold",e).metrics?qt(t,"Main-Bold",e,r,a.concat(["mathbf"])):"\\"===t||"main"===j[e][t].font?qt(t,"Main-Regular",e,r,a):qt(t,"AMS-Regular",e,r,a.concat(["amsrm"]))},makeSpan:Rt,makeSvgSpan:Ot,makeLineSpan:function(t,e,r){var a=Rt([t],[],e);return a.height=Math.max(r||e.fontMetrics().defaultRuleThickness,e.minRuleThickness),a.style.borderBottomWidth=a.height+"em",a.maxFontSize=1,a},makeAnchor:function(t,e,r,a){var n=new I(t,e,r,a);return It(n),n},makeFragment:Et,wrapFragment:function(t,e){return t instanceof A?Rt([],[t],e):t},makeVList:function(t,e){for(var r=function(t){if("individualShift"===t.positionType){for(var e=t.children,r=[e[0]],a=-e[0].shift-e[0].elem.depth,n=a,i=1;i0&&(i.push(pe(o,e)),o=[]),i.push(n[s]));o.length>0&&i.push(pe(o,e)),r&&((a=pe(se(r,e,!0))).classes=["tag"],i.push(a));var l=re(["katex-html"],i);if(l.setAttribute("aria-hidden","true"),a){var m=a.children[0];m.style.height=l.height+l.depth+"em",m.style.verticalAlign=-l.depth+"em"}return l}function fe(t){return new A(t)}var ge=function(){function t(t,e){this.type=void 0,this.attributes=void 0,this.children=void 0,this.type=t,this.attributes={},this.children=e||[]}var e=t.prototype;return e.setAttribute=function(t,e){this.attributes[t]=e},e.getAttribute=function(t){return this.attributes[t]},e.toNode=function(){var t=document.createElementNS("http://www.w3.org/1998/Math/MathML",this.type);for(var e in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,e)&&t.setAttribute(e,this.attributes[e]);for(var r=0;r"},e.toText=function(){return this.children.map(function(t){return t.toText()}).join("")},t}(),xe=function(){function t(t){this.text=void 0,this.text=t}var e=t.prototype;return e.toNode=function(){return document.createTextNode(this.text)},e.toMarkup=function(){return c.escape(this.toText())},e.toText=function(){return this.text},t}(),ve={MathNode:ge,TextNode:xe,SpaceNode:function(){function t(t){this.width=void 0,this.character=void 0,this.width=t,this.character=t>=.05555&&t<=.05556?"\u200a":t>=.1666&&t<=.1667?"\u2009":t>=.2222&&t<=.2223?"\u2005":t>=.2777&&t<=.2778?"\u2005\u200a":t>=-.05556&&t<=-.05555?"\u200a\u2063":t>=-.1667&&t<=-.1666?"\u2009\u2063":t>=-.2223&&t<=-.2222?"\u205f\u2063":t>=-.2778&&t<=-.2777?"\u2005\u2063":null}var e=t.prototype;return e.toNode=function(){if(this.character)return document.createTextNode(this.character);var t=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace");return t.setAttribute("width",this.width+"em"),t},e.toMarkup=function(){return this.character?""+this.character+"":''},e.toText=function(){return this.character?this.character:" "},t}(),newDocumentFragment:fe},be=function(t,e,r){return!j[e][t]||!j[e][t].replace||55349===t.charCodeAt(0)||rt.hasOwnProperty(t)&&r&&(r.fontFamily&&"tt"===r.fontFamily.substr(4,2)||r.font&&"tt"===r.font.substr(4,2))||(t=j[e][t].replace),new ve.TextNode(t)},ye=function(t){return 1===t.length?t[0]:new ve.MathNode("mrow",t)},we=function(t,e){if("texttt"===e.fontFamily)return"monospace";if("textsf"===e.fontFamily)return"textit"===e.fontShape&&"textbf"===e.fontWeight?"sans-serif-bold-italic":"textit"===e.fontShape?"sans-serif-italic":"textbf"===e.fontWeight?"bold-sans-serif":"sans-serif";if("textit"===e.fontShape&&"textbf"===e.fontWeight)return"bold-italic";if("textit"===e.fontShape)return"italic";if("textbf"===e.fontWeight)return"bold";var r=e.font;if(!r||"mathnormal"===r)return null;var a=t.mode;if("mathit"===r)return"italic";if("boldsymbol"===r)return"bold-italic";if("mathbf"===r)return"bold";if("mathbb"===r)return"double-struck";if("mathfrak"===r)return"fraktur";if("mathscr"===r||"mathcal"===r)return"script";if("mathsf"===r)return"sans-serif";if("mathtt"===r)return"monospace";var n=t.text;return c.contains(["\\imath","\\jmath"],n)?null:(j[a][n]&&j[a][n].replace&&(n=j[a][n].replace),G(n,Dt.fontMap[r].fontName,a)?Dt.fontMap[r].variant:null)},ke=function(t,e,r){if(1===t.length){var a=Me(t[0],e);return r&&a instanceof ge&&"mo"===a.type&&(a.setAttribute("lspace","0em"),a.setAttribute("rspace","0em")),[a]}for(var n,i=[],o=0;o0&&(p.text=p.text.slice(0,1)+"\u0338"+p.text.slice(1),i.pop())}}}i.push(s),n=s}return i},Se=function(t,e,r){return ye(ke(t,e,r))},Me=function(t,e){if(!t)return new ve.MathNode("mrow");if(Jt[t.type])return Jt[t.type](t,e);throw new o("Got group of unknown type: '"+t.type+"'")};function ze(t,e,r,a){var n,i=ke(t,r);n=1===i.length&&i[0]instanceof ge&&c.contains(["mrow","mtable"],i[0].type)?i[0]:new ve.MathNode("mrow",i);var o=new ve.MathNode("annotation",[new ve.TextNode(e)]);o.setAttribute("encoding","application/x-tex");var s=new ve.MathNode("semantics",[n,o]),h=new ve.MathNode("math",[s]);h.setAttribute("xmlns","http://www.w3.org/1998/Math/MathML");var l=a?"katex":"katex-mathml";return Dt.makeSpan([l],[h])}var Ae=function(t){return new St({style:t.displayMode?w.DISPLAY:w.TEXT,maxSize:t.maxSize,minRuleThickness:t.minRuleThickness})},Te=function(t,e){if(e.displayMode){var r=["katex-display"];e.leqno&&r.push("leqno"),e.fleqn&&r.push("fleqn"),t=Dt.makeSpan(r,[t])}return t},Be=function(t,e,r){var a,n=Ae(r);if("mathml"===r.output)return ze(t,e,n,!0);if("html"===r.output){var i=de(t,n);a=Dt.makeSpan(["katex"],[i])}else{var o=ze(t,e,n,!1),s=de(t,n);a=Dt.makeSpan(["katex"],[o,s])}return Te(a,r)},Ce={widehat:"^",widecheck:"\u02c7",widetilde:"~",utilde:"~",overleftarrow:"\u2190",underleftarrow:"\u2190",xleftarrow:"\u2190",overrightarrow:"\u2192",underrightarrow:"\u2192",xrightarrow:"\u2192",underbrace:"\u23df",overbrace:"\u23de",overgroup:"\u23e0",undergroup:"\u23e1",overleftrightarrow:"\u2194",underleftrightarrow:"\u2194",xleftrightarrow:"\u2194",Overrightarrow:"\u21d2",xRightarrow:"\u21d2",overleftharpoon:"\u21bc",xleftharpoonup:"\u21bc",overrightharpoon:"\u21c0",xrightharpoonup:"\u21c0",xLeftarrow:"\u21d0",xLeftrightarrow:"\u21d4",xhookleftarrow:"\u21a9",xhookrightarrow:"\u21aa",xmapsto:"\u21a6",xrightharpoondown:"\u21c1",xleftharpoondown:"\u21bd",xrightleftharpoons:"\u21cc",xleftrightharpoons:"\u21cb",xtwoheadleftarrow:"\u219e",xtwoheadrightarrow:"\u21a0",xlongequal:"=",xtofrom:"\u21c4",xrightleftarrows:"\u21c4",xrightequilibrium:"\u21cc",xleftequilibrium:"\u21cb"},qe={overrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],overleftarrow:[["leftarrow"],.888,522,"xMinYMin"],underrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],underleftarrow:[["leftarrow"],.888,522,"xMinYMin"],xrightarrow:[["rightarrow"],1.469,522,"xMaxYMin"],xleftarrow:[["leftarrow"],1.469,522,"xMinYMin"],Overrightarrow:[["doublerightarrow"],.888,560,"xMaxYMin"],xRightarrow:[["doublerightarrow"],1.526,560,"xMaxYMin"],xLeftarrow:[["doubleleftarrow"],1.526,560,"xMinYMin"],overleftharpoon:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoonup:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoondown:[["leftharpoondown"],.888,522,"xMinYMin"],overrightharpoon:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoonup:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoondown:[["rightharpoondown"],.888,522,"xMaxYMin"],xlongequal:[["longequal"],.888,334,"xMinYMin"],xtwoheadleftarrow:[["twoheadleftarrow"],.888,334,"xMinYMin"],xtwoheadrightarrow:[["twoheadrightarrow"],.888,334,"xMaxYMin"],overleftrightarrow:[["leftarrow","rightarrow"],.888,522],overbrace:[["leftbrace","midbrace","rightbrace"],1.6,548],underbrace:[["leftbraceunder","midbraceunder","rightbraceunder"],1.6,548],underleftrightarrow:[["leftarrow","rightarrow"],.888,522],xleftrightarrow:[["leftarrow","rightarrow"],1.75,522],xLeftrightarrow:[["doubleleftarrow","doublerightarrow"],1.75,560],xrightleftharpoons:[["leftharpoondownplus","rightharpoonplus"],1.75,716],xleftrightharpoons:[["leftharpoonplus","rightharpoondownplus"],1.75,716],xhookleftarrow:[["leftarrow","righthook"],1.08,522],xhookrightarrow:[["lefthook","rightarrow"],1.08,522],overlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],underlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],overgroup:[["leftgroup","rightgroup"],.888,342],undergroup:[["leftgroupunder","rightgroupunder"],.888,342],xmapsto:[["leftmapsto","rightarrow"],1.5,522],xtofrom:[["leftToFrom","rightToFrom"],1.75,528],xrightleftarrows:[["baraboveleftarrow","rightarrowabovebar"],1.75,901],xrightequilibrium:[["baraboveshortleftharpoon","rightharpoonaboveshortbar"],1.75,716],xleftequilibrium:[["shortbaraboveleftharpoon","shortrightharpoonabovebar"],1.75,716]},Ne=function(t){return"ordgroup"===t.type?t.body.length:1},Ie=function(t,e,r,a){var n,i=t.height+t.depth+2*r;if(/fbox|color/.test(e)){if(n=Dt.makeSpan(["stretchy",e],[],a),"fbox"===e){var o=a.color&&a.getColor();o&&(n.style.borderColor=o)}}else{var s=[];/^[bx]cancel$/.test(e)&&s.push(new P({x1:"0",y1:"0",x2:"100%",y2:"100%","stroke-width":"0.046em"})),/^x?cancel$/.test(e)&&s.push(new P({x1:"0",y1:"100%",x2:"100%",y2:"0","stroke-width":"0.046em"}));var h=new L(s,{width:"100%",height:i+"em"});n=Dt.makeSvgSpan([],[h],a)}return n.height=i,n.style.height=i+"em",n},Re=function(t){var e=new ve.MathNode("mo",[new ve.TextNode(Ce[t.substr(1)])]);return e.setAttribute("stretchy","true"),e},Oe=function(t,e){var r=function(){var r=4e5,a=t.label.substr(1);if(c.contains(["widehat","widecheck","widetilde","utilde"],a)){var n,i,o,s=Ne(t.base);if(s>5)"widehat"===a||"widecheck"===a?(n=420,r=2364,o=.42,i=a+"4"):(n=312,r=2340,o=.34,i="tilde4");else{var h=[1,1,2,2,3,3][s];"widehat"===a||"widecheck"===a?(r=[0,1062,2364,2364,2364][h],n=[0,239,300,360,420][h],o=[0,.24,.3,.3,.36,.42][h],i=a+h):(r=[0,600,1033,2339,2340][h],n=[0,260,286,306,312][h],o=[0,.26,.286,.3,.306,.34][h],i="tilde"+h)}var l=new H(i),m=new L([l],{width:"100%",height:o+"em",viewBox:"0 0 "+r+" "+n,preserveAspectRatio:"none"});return{span:Dt.makeSvgSpan([],[m],e),minWidth:0,height:o}}var u,p,d=[],f=qe[a],g=f[0],x=f[1],v=f[2],b=v/1e3,y=g.length;if(1===y)u=["hide-tail"],p=[f[3]];else if(2===y)u=["halfarrow-left","halfarrow-right"],p=["xMinYMin","xMaxYMin"];else{if(3!==y)throw new Error("Correct katexImagesData or update code here to support\n "+y+" children.");u=["brace-left","brace-center","brace-right"],p=["xMinYMin","xMidYMin","xMaxYMin"]}for(var w=0;w0&&(a.style.minWidth=n+"em"),a},Ee=function(t,e){var r,a,n,i=Vt(t,"supsub");i?(r=(a=Ft(i.base,"accent")).base,i.base=r,n=function(t){if(t instanceof N)return t;throw new Error("Expected span but got "+String(t)+".")}(ue(i,e)),i.base=a):r=(a=Ft(t,"accent")).base;var o=ue(r,e.havingCrampedStyle()),s=0;if(a.isShifty&&c.isCharacterBox(r)){var h=c.getBaseElem(r);s=D(ue(h,e.havingCrampedStyle())).skew}var l,m=Math.min(o.height,e.fontMetrics().xHeight);if(a.isStretchy)l=Oe(a,e),l=Dt.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:o},{type:"elem",elem:l,wrapperClasses:["svg-align"],wrapperStyle:s>0?{width:"calc(100% - "+2*s+"em)",marginLeft:2*s+"em"}:void 0}]},e);else{var u,p;"\\vec"===a.label?(u=Dt.staticSvg("vec",e),p=Dt.svgData.vec[1]):((u=D(u=Dt.makeOrd({mode:a.mode,text:a.label},e,"textord"))).italic=0,p=u.width),l=Dt.makeSpan(["accent-body"],[u]);var d="\\textcircled"===a.label;d&&(l.classes.push("accent-full"),m=o.height);var f=s;d||(f-=p/2),l.style.left=f+"em","\\textcircled"===a.label&&(l.style.top=".2em"),l=Dt.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:o},{type:"kern",size:-m},{type:"elem",elem:l}]},e)}var g=Dt.makeSpan(["mord","accent"],[l],e);return n?(n.children[0]=g,n.height=Math.max(g.height,n.height),n.classes[0]="mord",n):g},Le=function(t,e){var r=t.isStretchy?Re(t.label):new ve.MathNode("mo",[be(t.label,t.mode)]),a=new ve.MathNode("mover",[Me(t.base,e),r]);return a.setAttribute("accent","true"),a},He=new RegExp(["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring"].map(function(t){return"\\"+t}).join("|"));Qt({type:"accent",names:["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring","\\widecheck","\\widehat","\\widetilde","\\overrightarrow","\\overleftarrow","\\Overrightarrow","\\overleftrightarrow","\\overgroup","\\overlinesegment","\\overleftharpoon","\\overrightharpoon"],props:{numArgs:1},handler:function(t,e){var r=e[0],a=!He.test(t.funcName),n=!a||"\\widehat"===t.funcName||"\\widetilde"===t.funcName||"\\widecheck"===t.funcName;return{type:"accent",mode:t.parser.mode,label:t.funcName,isStretchy:a,isShifty:n,base:r}},htmlBuilder:Ee,mathmlBuilder:Le}),Qt({type:"accent",names:["\\'","\\`","\\^","\\~","\\=","\\u","\\.",'\\"',"\\r","\\H","\\v","\\textcircled"],props:{numArgs:1,allowedInText:!0,allowedInMath:!1},handler:function(t,e){var r=e[0];return{type:"accent",mode:t.parser.mode,label:t.funcName,isStretchy:!1,isShifty:!0,base:r}},htmlBuilder:Ee,mathmlBuilder:Le}),Qt({type:"accentUnder",names:["\\underleftarrow","\\underrightarrow","\\underleftrightarrow","\\undergroup","\\underlinesegment","\\utilde"],props:{numArgs:1},handler:function(t,e){var r=t.parser,a=t.funcName,n=e[0];return{type:"accentUnder",mode:r.mode,label:a,base:n}},htmlBuilder:function(t,e){var r=ue(t.base,e),a=Oe(t,e),n="\\utilde"===t.label?.12:0,i=Dt.makeVList({positionType:"bottom",positionData:a.height+n,children:[{type:"elem",elem:a,wrapperClasses:["svg-align"]},{type:"kern",size:n},{type:"elem",elem:r}]},e);return Dt.makeSpan(["mord","accentunder"],[i],e)},mathmlBuilder:function(t,e){var r=Re(t.label),a=new ve.MathNode("munder",[Me(t.base,e),r]);return a.setAttribute("accentunder","true"),a}});var Pe=function(t){var e=new ve.MathNode("mpadded",t?[t]:[]);return e.setAttribute("width","+0.6em"),e.setAttribute("lspace","0.3em"),e};Qt({type:"xArrow",names:["\\xleftarrow","\\xrightarrow","\\xLeftarrow","\\xRightarrow","\\xleftrightarrow","\\xLeftrightarrow","\\xhookleftarrow","\\xhookrightarrow","\\xmapsto","\\xrightharpoondown","\\xrightharpoonup","\\xleftharpoondown","\\xleftharpoonup","\\xrightleftharpoons","\\xleftrightharpoons","\\xlongequal","\\xtwoheadrightarrow","\\xtwoheadleftarrow","\\xtofrom","\\xrightleftarrows","\\xrightequilibrium","\\xleftequilibrium"],props:{numArgs:1,numOptionalArgs:1},handler:function(t,e,r){var a=t.parser,n=t.funcName;return{type:"xArrow",mode:a.mode,label:n,body:e[0],below:r[0]}},htmlBuilder:function(t,e){var r,a=e.style,n=e.havingStyle(a.sup()),i=Dt.wrapFragment(ue(t.body,n,e),e);i.classes.push("x-arrow-pad"),t.below&&(n=e.havingStyle(a.sub()),(r=Dt.wrapFragment(ue(t.below,n,e),e)).classes.push("x-arrow-pad"));var o,s=Oe(t,e),h=-e.fontMetrics().axisHeight+.5*s.height,l=-e.fontMetrics().axisHeight-.5*s.height-.111;if((i.depth>.25||"\\xleftequilibrium"===t.label)&&(l-=i.depth),r){var m=-e.fontMetrics().axisHeight+r.height+.5*s.height+.111;o=Dt.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:l},{type:"elem",elem:s,shift:h},{type:"elem",elem:r,shift:m}]},e)}else o=Dt.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:l},{type:"elem",elem:s,shift:h}]},e);return o.children[0].children[0].children[1].classes.push("svg-align"),Dt.makeSpan(["mrel","x-arrow"],[o],e)},mathmlBuilder:function(t,e){var r,a=Re(t.label);if(t.body){var n=Pe(Me(t.body,e));if(t.below){var i=Pe(Me(t.below,e));r=new ve.MathNode("munderover",[a,i,n])}else r=new ve.MathNode("mover",[a,n])}else if(t.below){var o=Pe(Me(t.below,e));r=new ve.MathNode("munder",[a,o])}else r=Pe(),r=new ve.MathNode("mover",[a,r]);return r}}),Qt({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler:function(t,e){for(var r=t.parser,a=Ft(e[0],"ordgroup").body,n="",i=0;i","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],Je=[0,1.2,1.8,2.4,3],Qe=[{type:"small",style:w.SCRIPTSCRIPT},{type:"small",style:w.SCRIPT},{type:"small",style:w.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],tr=[{type:"small",style:w.SCRIPTSCRIPT},{type:"small",style:w.SCRIPT},{type:"small",style:w.TEXT},{type:"stack"}],er=[{type:"small",style:w.SCRIPTSCRIPT},{type:"small",style:w.SCRIPT},{type:"small",style:w.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],rr=function(t){if("small"===t.type)return"Main-Regular";if("large"===t.type)return"Size"+t.size+"-Regular";if("stack"===t.type)return"Size4-Regular";throw new Error("Add support for delim type '"+t.type+"' here.")},ar=function(t,e,r,a){for(var n=Math.min(2,3-a.style.size);ne)return r[n]}return r[r.length-1]},nr=function(t,e,r,a,n,i){var o;"<"===t||"\\lt"===t||"\u27e8"===t?t="\\langle":">"!==t&&"\\gt"!==t&&"\u27e9"!==t||(t="\\rangle"),o=c.contains(Ke,t)?Qe:c.contains($e,t)?er:tr;var s=ar(t,e,o,a);return"small"===s.type?function(t,e,r,a,n,i){var o=Dt.makeSymbol(t,"Main-Regular",n,a),s=Ue(o,e,a,i);return r&&Ge(s,a,e),s}(t,s.style,r,a,n,i):"large"===s.type?Ye(t,s.size,r,a,n,i):_e(t,e,r,a,n,i)},ir=function(t,e){var r,a,n=e.havingBaseSizing(),i=ar("\\surd",t*n.sizeMultiplier,er,n),o=n.sizeMultiplier,s=Math.max(0,e.minRuleThickness-e.fontMetrics().sqrtRuleThickness),h=0,l=0,m=0;return"small"===i.type?(t<1?o=1:t<1.4&&(o=.7),l=(1+s)/o,(r=je("sqrtMain",h=(1+s+.08)/o,m=1e3+1e3*s+80,s,e)).style.minWidth="0.853em",a=.833/o):"large"===i.type?(m=1080*Je[i.size],l=(Je[i.size]+s)/o,h=(Je[i.size]+s+.08)/o,(r=je("sqrtSize"+i.size,h,m,s,e)).style.minWidth="1.02em",a=1/o):(h=t+s+.08,l=t+s,m=Math.floor(1e3*t+s)+80,(r=je("sqrtTall",h,m,s,e)).style.minWidth="0.742em",a=1.056),r.height=l,r.style.height=h+"em",{span:r,advanceWidth:a,ruleWidth:(e.fontMetrics().sqrtRuleThickness+s)*o}},or=function(t,e,r,a,n){if("<"===t||"\\lt"===t||"\u27e8"===t?t="\\langle":">"!==t&&"\\gt"!==t&&"\u27e9"!==t||(t="\\rangle"),c.contains($e,t)||c.contains(Ke,t))return Ye(t,e,!1,r,a,n);if(c.contains(Ze,t))return _e(t,Je[e],!1,r,a,n);throw new o("Illegal delimiter: '"+t+"'")},sr=nr,hr=function(t,e,r,a,n,i){var o=a.fontMetrics().axisHeight*a.sizeMultiplier,s=5/a.fontMetrics().ptPerEm,h=Math.max(e-o,r+o),l=Math.max(h/500*901,2*h-s);return nr(t,l,!0,a,n,i)},lr={"\\bigl":{mclass:"mopen",size:1},"\\Bigl":{mclass:"mopen",size:2},"\\biggl":{mclass:"mopen",size:3},"\\Biggl":{mclass:"mopen",size:4},"\\bigr":{mclass:"mclose",size:1},"\\Bigr":{mclass:"mclose",size:2},"\\biggr":{mclass:"mclose",size:3},"\\Biggr":{mclass:"mclose",size:4},"\\bigm":{mclass:"mrel",size:1},"\\Bigm":{mclass:"mrel",size:2},"\\biggm":{mclass:"mrel",size:3},"\\Biggm":{mclass:"mrel",size:4},"\\big":{mclass:"mord",size:1},"\\Big":{mclass:"mord",size:2},"\\bigg":{mclass:"mord",size:3},"\\Bigg":{mclass:"mord",size:4}},mr=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","<",">","\\langle","\u27e8","\\rangle","\u27e9","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];function cr(t,e){var r=Yt(t);if(r&&c.contains(mr,r.text))return r;throw new o("Invalid delimiter: '"+(r?r.text:JSON.stringify(t))+"' after '"+e.funcName+"'",t)}function ur(t){if(!t.body)throw new Error("Bug: The leftright ParseNode wasn't fully parsed.")}Qt({type:"delimsizing",names:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg"],props:{numArgs:1},handler:function(t,e){var r=cr(e[0],t);return{type:"delimsizing",mode:t.parser.mode,size:lr[t.funcName].size,mclass:lr[t.funcName].mclass,delim:r.text}},htmlBuilder:function(t,e){return"."===t.delim?Dt.makeSpan([t.mclass]):or(t.delim,t.size,e,t.mode,[t.mclass])},mathmlBuilder:function(t){var e=[];"."!==t.delim&&e.push(be(t.delim,t.mode));var r=new ve.MathNode("mo",e);return"mopen"===t.mclass||"mclose"===t.mclass?r.setAttribute("fence","true"):r.setAttribute("fence","false"),r}}),Qt({type:"leftright-right",names:["\\right"],props:{numArgs:1},handler:function(t,e){var r=t.parser.gullet.macros.get("\\current@color");if(r&&"string"!=typeof r)throw new o("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:t.parser.mode,delim:cr(e[0],t).text,color:r}}}),Qt({type:"leftright",names:["\\left"],props:{numArgs:1},handler:function(t,e){var r=cr(e[0],t),a=t.parser;++a.leftrightDepth;var n=a.parseExpression(!1);--a.leftrightDepth,a.expect("\\right",!1);var i=Ft(a.parseFunction(),"leftright-right");return{type:"leftright",mode:a.mode,body:n,left:r.text,right:i.delim,rightColor:i.color}},htmlBuilder:function(t,e){ur(t);for(var r,a,n=se(t.body,e,!0,["mopen","mclose"]),i=0,o=0,s=!1,h=0;h-1?"mpadded":"menclose",[Me(t.body,e)]);switch(t.label){case"\\cancel":a.setAttribute("notation","updiagonalstrike");break;case"\\bcancel":a.setAttribute("notation","downdiagonalstrike");break;case"\\sout":a.setAttribute("notation","horizontalstrike");break;case"\\fbox":a.setAttribute("notation","box");break;case"\\fcolorbox":case"\\colorbox":if(r=e.fontMetrics().fboxsep*e.fontMetrics().ptPerEm,a.setAttribute("width","+"+2*r+"pt"),a.setAttribute("height","+"+2*r+"pt"),a.setAttribute("lspace",r+"pt"),a.setAttribute("voffset",r+"pt"),"\\fcolorbox"===t.label){var n=Math.max(e.fontMetrics().fboxrule,e.minRuleThickness);a.setAttribute("style","border: "+n+"em solid "+String(t.borderColor))}break;case"\\xcancel":a.setAttribute("notation","updiagonalstrike downdiagonalstrike")}return t.backgroundColor&&a.setAttribute("mathbackground",t.backgroundColor),a};Qt({type:"enclose",names:["\\colorbox"],props:{numArgs:2,allowedInText:!0,greediness:3,argTypes:["color","text"]},handler:function(t,e,r){var a=t.parser,n=t.funcName,i=Ft(e[0],"color-token").color,o=e[1];return{type:"enclose",mode:a.mode,label:n,backgroundColor:i,body:o}},htmlBuilder:pr,mathmlBuilder:dr}),Qt({type:"enclose",names:["\\fcolorbox"],props:{numArgs:3,allowedInText:!0,greediness:3,argTypes:["color","color","text"]},handler:function(t,e,r){var a=t.parser,n=t.funcName,i=Ft(e[0],"color-token").color,o=Ft(e[1],"color-token").color,s=e[2];return{type:"enclose",mode:a.mode,label:n,backgroundColor:o,borderColor:i,body:s}},htmlBuilder:pr,mathmlBuilder:dr}),Qt({type:"enclose",names:["\\fbox"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!0},handler:function(t,e){return{type:"enclose",mode:t.parser.mode,label:"\\fbox",body:e[0]}}}),Qt({type:"enclose",names:["\\cancel","\\bcancel","\\xcancel","\\sout"],props:{numArgs:1},handler:function(t,e,r){var a=t.parser,n=t.funcName,i=e[0];return{type:"enclose",mode:a.mode,label:n,body:i}},htmlBuilder:pr,mathmlBuilder:dr});var fr={};function gr(t){for(var e=t.type,r=t.names,a=t.props,n=t.handler,i=t.htmlBuilder,o=t.mathmlBuilder,s={type:e,numArgs:a.numArgs||0,greediness:1,allowedInText:!1,numOptionalArgs:0,handler:n},h=0;h0&&(b+=.25),l.push({pos:b,isDashed:t[e]})}for(y(i[0]),r=0;r0&&(M<(B+=v)&&(M=B),B=0),t.addJot&&(M+=f),z.height=S,z.depth=M,b+=S,z.pos=b,b+=M+B,h[r]=z,y(i[r+1])}var C,q,N=b/2+e.fontMetrics().axisHeight,I=t.cols||[],R=[];for(a=0,q=0;a=s)){var P=void 0;(a>0||t.hskipBeforeAndAfter)&&0!==(P=c.deflt(O.pregap,p))&&((C=Dt.makeSpan(["arraycolsep"],[])).style.width=P+"em",R.push(C));var D=[];for(r=0;r0){for(var G=Dt.makeLineSpan("hline",e,m),Y=Dt.makeLineSpan("hdashline",e,m),W=[{type:"elem",elem:h,shift:0}];l.length>0;){var X=l.pop(),_=X.pos-N;X.isDashed?W.push({type:"elem",elem:Y,shift:_}):W.push({type:"elem",elem:G,shift:_})}h=Dt.makeVList({positionType:"individualShift",children:W},e)}return Dt.makeSpan(["mord"],[h],e)},wr={c:"center ",l:"left ",r:"right "},kr=function(t,e){var r=new ve.MathNode("mtable",t.body.map(function(t){return new ve.MathNode("mtr",t.map(function(t){return new ve.MathNode("mtd",[Me(t,e)])}))})),a=.5===t.arraystretch?.1:.16+t.arraystretch-1+(t.addJot?.09:0);r.setAttribute("rowspacing",a+"em");var n="",i="";if(t.cols){var o=t.cols,s="",h=!1,l=0,m=o.length;"separator"===o[0].type&&(n+="top ",l=1),"separator"===o[o.length-1].type&&(n+="bottom ",m-=1);for(var c=l;c0?"left ":"",n+=g[g.length-1].length>0?"right ":"";for(var x=1;x0&&c&&(d=1),a[u]={type:"align",align:p,pregap:d,postgap:0}}return n.colSeparationType=c?"align":"alignat",n};gr({type:"array",names:["array","darray"],props:{numArgs:1},handler:function(t,e){var r={cols:(Yt(e[0])?[e[0]]:Ft(e[0],"ordgroup").body).map(function(t){var e=Gt(t).text;if(-1!=="lcr".indexOf(e))return{type:"align",align:e};if("|"===e)return{type:"separator",separator:"|"};if(":"===e)return{type:"separator",separator:":"};throw new o("Unknown column alignment: "+e,t)}),hskipBeforeAndAfter:!0};return vr(t.parser,r,br(t.envName))},htmlBuilder:yr,mathmlBuilder:kr}),gr({type:"array",names:["matrix","pmatrix","bmatrix","Bmatrix","vmatrix","Vmatrix"],props:{numArgs:0},handler:function(t){var e={matrix:null,pmatrix:["(",")"],bmatrix:["[","]"],Bmatrix:["\\{","\\}"],vmatrix:["|","|"],Vmatrix:["\\Vert","\\Vert"]}[t.envName],r=vr(t.parser,{hskipBeforeAndAfter:!1},br(t.envName));return e?{type:"leftright",mode:t.mode,body:[r],left:e[0],right:e[1],rightColor:void 0}:r},htmlBuilder:yr,mathmlBuilder:kr}),gr({type:"array",names:["smallmatrix"],props:{numArgs:0},handler:function(t){var e=vr(t.parser,{arraystretch:.5},"script");return e.colSeparationType="small",e},htmlBuilder:yr,mathmlBuilder:kr}),gr({type:"array",names:["subarray"],props:{numArgs:1},handler:function(t,e){var r=(Yt(e[0])?[e[0]]:Ft(e[0],"ordgroup").body).map(function(t){var e=Gt(t).text;if(-1!=="lc".indexOf(e))return{type:"align",align:e};throw new o("Unknown column alignment: "+e,t)});if(r.length>1)throw new o("{subarray} can contain only one column");var a={cols:r,hskipBeforeAndAfter:!1,arraystretch:.5};if((a=vr(t.parser,a,"script")).body[0].length>1)throw new o("{subarray} can contain only one column");return a},htmlBuilder:yr,mathmlBuilder:kr}),gr({type:"array",names:["cases","dcases"],props:{numArgs:0},handler:function(t){var e=vr(t.parser,{arraystretch:1.2,cols:[{type:"align",align:"l",pregap:0,postgap:1},{type:"align",align:"l",pregap:0,postgap:0}]},br(t.envName));return{type:"leftright",mode:t.mode,body:[e],left:"\\{",right:".",rightColor:void 0}},htmlBuilder:yr,mathmlBuilder:kr}),gr({type:"array",names:["aligned"],props:{numArgs:0},handler:Sr,htmlBuilder:yr,mathmlBuilder:kr}),gr({type:"array",names:["gathered"],props:{numArgs:0},handler:function(t){return vr(t.parser,{cols:[{type:"align",align:"c"}],addJot:!0},"display")},htmlBuilder:yr,mathmlBuilder:kr}),gr({type:"array",names:["alignedat"],props:{numArgs:1},handler:Sr,htmlBuilder:yr,mathmlBuilder:kr}),Qt({type:"text",names:["\\hline","\\hdashline"],props:{numArgs:0,allowedInText:!0,allowedInMath:!0},handler:function(t,e){throw new o(t.funcName+" valid only within array environment")}});var Mr=fr;Qt({type:"environment",names:["\\begin","\\end"],props:{numArgs:1,argTypes:["text"]},handler:function(t,e){var r=t.parser,a=t.funcName,n=e[0];if("ordgroup"!==n.type)throw new o("Invalid environment name",n);for(var i="",s=0;s=w.SCRIPT.id?r.text():w.DISPLAY:"text"===t&&r.size===w.DISPLAY.size?r=w.TEXT:"script"===t?r=w.SCRIPT:"scriptscript"===t&&(r=w.SCRIPTSCRIPT),r},Rr=function(t,e){var r,a=Ir(t.size,e.style),n=a.fracNum(),i=a.fracDen();r=e.havingStyle(n);var o=ue(t.numer,r,e);if(t.continued){var s=8.5/e.fontMetrics().ptPerEm,h=3.5/e.fontMetrics().ptPerEm;o.height=o.height0?3*c:7*c,d=e.fontMetrics().denom1):(m>0?(u=e.fontMetrics().num2,p=c):(u=e.fontMetrics().num3,p=3*c),d=e.fontMetrics().denom2),l){var y=e.fontMetrics().axisHeight;u-o.depth-(y+.5*m)0&&(e="."===(e=t)?null:e),e};Qt({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,greediness:6,argTypes:["math","math","size","text","math","math"]},handler:function(t,e){var r=t.parser,a=e[4],n=e[5],i=Vt(e[0],"atom");i&&(i=Ut(e[0],"open"));var o=i?Lr(i.text):null,s=Vt(e[1],"atom");s&&(s=Ut(e[1],"close"));var h,l=s?Lr(s.text):null,m=Ft(e[2],"size"),c=null;h=!!m.isBlank||(c=m.value).number>0;var u="auto",p=Vt(e[3],"ordgroup");if(p){if(p.body.length>0){var d=Ft(p.body[0],"textord");u=Er[Number(d.text)]}}else p=Ft(e[3],"textord"),u=Er[Number(p.text)];return{type:"genfrac",mode:r.mode,numer:a,denom:n,continued:!1,hasBarLine:h,barSize:c,leftDelim:o,rightDelim:l,size:u}},htmlBuilder:Rr,mathmlBuilder:Or}),Qt({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler:function(t,e){var r=t.parser,a=(t.funcName,t.token);return{type:"infix",mode:r.mode,replaceWith:"\\\\abovefrac",size:Ft(e[0],"size").value,token:a}}}),Qt({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:function(t,e){var r=t.parser,a=(t.funcName,e[0]),n=function(t){if(!t)throw new Error("Expected non-null, but got "+String(t));return t}(Ft(e[1],"infix").size),i=e[2],o=n.number>0;return{type:"genfrac",mode:r.mode,numer:a,denom:i,continued:!1,hasBarLine:o,barSize:n,leftDelim:null,rightDelim:null,size:"auto"}},htmlBuilder:Rr,mathmlBuilder:Or});var Hr=function(t,e){var r,a,n=e.style,i=Vt(t,"supsub");i?(r=i.sup?ue(i.sup,e.havingStyle(n.sup()),e):ue(i.sub,e.havingStyle(n.sub()),e),a=Ft(i.base,"horizBrace")):a=Ft(t,"horizBrace");var o,s=ue(a.base,e.havingBaseStyle(w.DISPLAY)),h=Oe(a,e);if(a.isOver?(o=Dt.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:s},{type:"kern",size:.1},{type:"elem",elem:h}]},e)).children[0].children[0].children[1].classes.push("svg-align"):(o=Dt.makeVList({positionType:"bottom",positionData:s.depth+.1+h.height,children:[{type:"elem",elem:h},{type:"kern",size:.1},{type:"elem",elem:s}]},e)).children[0].children[0].children[0].classes.push("svg-align"),r){var l=Dt.makeSpan(["mord",a.isOver?"mover":"munder"],[o],e);o=a.isOver?Dt.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:l},{type:"kern",size:.2},{type:"elem",elem:r}]},e):Dt.makeVList({positionType:"bottom",positionData:l.depth+.2+r.height+r.depth,children:[{type:"elem",elem:r},{type:"kern",size:.2},{type:"elem",elem:l}]},e)}return Dt.makeSpan(["mord",a.isOver?"mover":"munder"],[o],e)};Qt({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler:function(t,e){var r=t.parser,a=t.funcName;return{type:"horizBrace",mode:r.mode,label:a,isOver:/^\\over/.test(a),base:e[0]}},htmlBuilder:Hr,mathmlBuilder:function(t,e){var r=Re(t.label);return new ve.MathNode(t.isOver?"mover":"munder",[Me(t.base,e),r])}}),Qt({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:function(t,e){var r=t.parser,a=e[1],n=Ft(e[0],"url").url;return r.settings.isTrusted({command:"\\href",url:n})?{type:"href",mode:r.mode,href:n,body:ee(a)}:r.formatUnsupportedCmd("\\href")},htmlBuilder:function(t,e){var r=se(t.body,e,!1);return Dt.makeAnchor(t.href,[],r,e)},mathmlBuilder:function(t,e){var r=Se(t.body,e);return r instanceof ge||(r=new ge("mrow",[r])),r.setAttribute("href",t.href),r}}),Qt({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:function(t,e){var r=t.parser,a=Ft(e[0],"url").url;if(!r.settings.isTrusted({command:"\\url",url:a}))return r.formatUnsupportedCmd("\\url");for(var n=[],i=0;i0&&(a=Tt(t.totalheight,e)-r,a=Number(a.toFixed(2)));var n=0;t.width.number>0&&(n=Tt(t.width,e));var i={height:r+a+"em"};n>0&&(i.width=n+"em"),a>0&&(i.verticalAlign=-a+"em");var o=new R(t.src,t.alt,i);return o.height=r,o.depth=a,o},mathmlBuilder:function(t,e){var r=new ve.MathNode("mglyph",[]);r.setAttribute("alt",t.alt);var a=Tt(t.height,e),n=0;if(t.totalheight.number>0&&(n=(n=Tt(t.totalheight,e)-a).toFixed(2),r.setAttribute("valign","-"+n+"em")),r.setAttribute("height",a+n+"em"),t.width.number>0){var i=Tt(t.width,e);r.setAttribute("width",i+"em")}return r.setAttribute("src",t.src),r}}),Qt({type:"kern",names:["\\kern","\\mkern","\\hskip","\\mskip"],props:{numArgs:1,argTypes:["size"],allowedInText:!0},handler:function(t,e){var r=t.parser,a=t.funcName,n=Ft(e[0],"size");if(r.settings.strict){var i="m"===a[1],o="mu"===n.value.unit;i?(o||r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+a+" supports only mu units, not "+n.value.unit+" units"),"math"!==r.mode&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+a+" works only in math mode")):o&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+a+" doesn't support mu units")}return{type:"kern",mode:r.mode,dimension:n.value}},htmlBuilder:function(t,e){return Dt.makeGlue(t.dimension,e)},mathmlBuilder:function(t,e){var r=Tt(t.dimension,e);return new ve.SpaceNode(r)}}),Qt({type:"lap",names:["\\mathllap","\\mathrlap","\\mathclap"],props:{numArgs:1,allowedInText:!0},handler:function(t,e){var r=t.parser,a=t.funcName,n=e[0];return{type:"lap",mode:r.mode,alignment:a.slice(5),body:n}},htmlBuilder:function(t,e){var r;"clap"===t.alignment?(r=Dt.makeSpan([],[ue(t.body,e)]),r=Dt.makeSpan(["inner"],[r],e)):r=Dt.makeSpan(["inner"],[ue(t.body,e)]);var a=Dt.makeSpan(["fix"],[]),n=Dt.makeSpan([t.alignment],[r,a],e),i=Dt.makeSpan(["strut"]);return i.style.height=n.height+n.depth+"em",i.style.verticalAlign=-n.depth+"em",n.children.unshift(i),n=Dt.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:n}]},e),Dt.makeSpan(["mord"],[n],e)},mathmlBuilder:function(t,e){var r=new ve.MathNode("mpadded",[Me(t.body,e)]);if("rlap"!==t.alignment){var a="llap"===t.alignment?"-1":"-0.5";r.setAttribute("lspace",a+"width")}return r.setAttribute("width","0px"),r}}),Qt({type:"styling",names:["\\(","$"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler:function(t,e){var r=t.funcName,a=t.parser,n=a.mode;a.switchMode("math");var i="\\("===r?"\\)":"$",o=a.parseExpression(!1,i);return a.expect(i),a.switchMode(n),{type:"styling",mode:a.mode,style:"text",body:o}}}),Qt({type:"text",names:["\\)","\\]"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler:function(t,e){throw new o("Mismatched "+t.funcName)}});var Dr=function(t,e){switch(e.style.size){case w.DISPLAY.size:return t.display;case w.TEXT.size:return t.text;case w.SCRIPT.size:return t.script;case w.SCRIPTSCRIPT.size:return t.scriptscript;default:return t.text}};Qt({type:"mathchoice",names:["\\mathchoice"],props:{numArgs:4},handler:function(t,e){return{type:"mathchoice",mode:t.parser.mode,display:ee(e[0]),text:ee(e[1]),script:ee(e[2]),scriptscript:ee(e[3])}},htmlBuilder:function(t,e){var r=Dr(t,e),a=se(r,e,!1);return Dt.makeFragment(a)},mathmlBuilder:function(t,e){var r=Dr(t,e);return Se(r,e)}});var Fr=function(t,e,r,a,n,i,o){var s,h,l;if(t=Dt.makeSpan([],[t]),e){var m=ue(e,a.havingStyle(n.sup()),a);h={elem:m,kern:Math.max(a.fontMetrics().bigOpSpacing1,a.fontMetrics().bigOpSpacing3-m.depth)}}if(r){var c=ue(r,a.havingStyle(n.sub()),a);s={elem:c,kern:Math.max(a.fontMetrics().bigOpSpacing2,a.fontMetrics().bigOpSpacing4-c.height)}}if(h&&s){var u=a.fontMetrics().bigOpSpacing5+s.elem.height+s.elem.depth+s.kern+t.depth+o;l=Dt.makeVList({positionType:"bottom",positionData:u,children:[{type:"kern",size:a.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:-i+"em"},{type:"kern",size:s.kern},{type:"elem",elem:t},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:i+"em"},{type:"kern",size:a.fontMetrics().bigOpSpacing5}]},a)}else if(s){var p=t.height-o;l=Dt.makeVList({positionType:"top",positionData:p,children:[{type:"kern",size:a.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:-i+"em"},{type:"kern",size:s.kern},{type:"elem",elem:t}]},a)}else{if(!h)return t;var d=t.depth+o;l=Dt.makeVList({positionType:"bottom",positionData:d,children:[{type:"elem",elem:t},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:i+"em"},{type:"kern",size:a.fontMetrics().bigOpSpacing5}]},a)}return Dt.makeSpan(["mop","op-limits"],[l],a)},Vr=["\\smallint"],Ur=function(t,e){var r,a,n,i=!1,o=Vt(t,"supsub");o?(r=o.sup,a=o.sub,n=Ft(o.base,"op"),i=!0):n=Ft(t,"op");var s,h=e.style,l=!1;if(h.size===w.DISPLAY.size&&n.symbol&&!c.contains(Vr,n.name)&&(l=!0),n.symbol){var m=l?"Size2-Regular":"Size1-Regular",u="";if("\\oiint"!==n.name&&"\\oiiint"!==n.name||(u=n.name.substr(1),n.name="oiint"===u?"\\iint":"\\iiint"),s=Dt.makeSymbol(n.name,m,"math",e,["mop","op-symbol",l?"large-op":"small-op"]),u.length>0){var p=s.italic,d=Dt.staticSvg(u+"Size"+(l?"2":"1"),e);s=Dt.makeVList({positionType:"individualShift",children:[{type:"elem",elem:s,shift:0},{type:"elem",elem:d,shift:l?.08:0}]},e),n.name="\\"+u,s.classes.unshift("mop"),s.italic=p}}else if(n.body){var f=se(n.body,e,!0);1===f.length&&f[0]instanceof E?(s=f[0]).classes[0]="mop":s=Dt.makeSpan(["mop"],Dt.tryCombineChars(f),e)}else{for(var g=[],x=1;x0){for(var h=n.body.map(function(t){var e=t.text;return"string"==typeof e?{type:"textord",mode:t.mode,text:e}:t}),l=se(h,e.withFont("mathrm"),!0),m=0;m=0?s.setAttribute("height","+"+n+"em"):(s.setAttribute("height",n+"em"),s.setAttribute("depth","+"+-n+"em")),s.setAttribute("voffset",n+"em"),s}});var jr=["\\tiny","\\sixptsize","\\scriptsize","\\footnotesize","\\small","\\normalsize","\\large","\\Large","\\LARGE","\\huge","\\Huge"];Qt({type:"sizing",names:jr,props:{numArgs:0,allowedInText:!0},handler:function(t,e){var r=t.breakOnTokenText,a=t.funcName,n=t.parser,i=n.parseExpression(!1,r);return{type:"sizing",mode:n.mode,size:jr.indexOf(a)+1,body:i}},htmlBuilder:function(t,e){var r=e.havingSize(t.size);return _r(t.body,r,e)},mathmlBuilder:function(t,e){var r=e.havingSize(t.size),a=ke(t.body,r),n=new ve.MathNode("mstyle",a);return n.setAttribute("mathsize",r.sizeMultiplier+"em"),n}}),Qt({type:"smash",names:["\\smash"],props:{numArgs:1,numOptionalArgs:1,allowedInText:!0},handler:function(t,e,r){var a=t.parser,n=!1,i=!1,o=r[0]&&Ft(r[0],"ordgroup");if(o)for(var s="",h=0;hr.height+r.depth+i&&(i=(i+c-r.height-r.depth)/2);var u=h.height-r.height-i-l;r.style.paddingLeft=m+"em";var p=Dt.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r,wrapperClasses:["svg-align"]},{type:"kern",size:-(r.height+u)},{type:"elem",elem:h},{type:"kern",size:l}]},e);if(t.index){var d=e.havingStyle(w.SCRIPTSCRIPT),f=ue(t.index,d,e),g=.6*(p.height-p.depth),x=Dt.makeVList({positionType:"shift",positionData:-g,children:[{type:"elem",elem:f}]},e),v=Dt.makeSpan(["root"],[x]);return Dt.makeSpan(["mord","sqrt"],[v,p],e)}return Dt.makeSpan(["mord","sqrt"],[p],e)},mathmlBuilder:function(t,e){var r=t.body,a=t.index;return a?new ve.MathNode("mroot",[Me(r,e),Me(a,e)]):new ve.MathNode("msqrt",[Me(r,e)])}});var $r={display:w.DISPLAY,text:w.TEXT,script:w.SCRIPT,scriptscript:w.SCRIPTSCRIPT};Qt({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0},handler:function(t,e){var r=t.breakOnTokenText,a=t.funcName,n=t.parser,i=n.parseExpression(!0,r),o=a.slice(1,a.length-5);return{type:"styling",mode:n.mode,style:o,body:i}},htmlBuilder:function(t,e){var r=$r[t.style],a=e.havingStyle(r).withFont("");return _r(t.body,a,e)},mathmlBuilder:function(t,e){var r=$r[t.style],a=e.havingStyle(r),n=ke(t.body,a),i=new ve.MathNode("mstyle",n),o={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]}[t.style];return i.setAttribute("scriptlevel",o[0]),i.setAttribute("displaystyle",o[1]),i}});te({type:"supsub",htmlBuilder:function(t,e){var r=function(t,e){var r=t.base;return r?"op"===r.type?r.limits&&(e.style.size===w.DISPLAY.size||r.alwaysHandleSupSub)?Ur:null:"operatorname"===r.type?r.alwaysHandleSupSub&&(e.style.size===w.DISPLAY.size||r.limits)?Xr:null:"accent"===r.type?c.isCharacterBox(r.base)?Ee:null:"horizBrace"===r.type&&!t.sub===r.isOver?Hr:null:null}(t,e);if(r)return r(t,e);var a,n,i,o=t.base,s=t.sup,h=t.sub,l=ue(o,e),m=e.fontMetrics(),u=0,p=0,d=o&&c.isCharacterBox(o);if(s){var f=e.havingStyle(e.style.sup());a=ue(s,f,e),d||(u=l.height-f.fontMetrics().supDrop*f.sizeMultiplier/e.sizeMultiplier)}if(h){var g=e.havingStyle(e.style.sub());n=ue(h,g,e),d||(p=l.depth+g.fontMetrics().subDrop*g.sizeMultiplier/e.sizeMultiplier)}i=e.style===w.DISPLAY?m.sup1:e.style.cramped?m.sup3:m.sup2;var x,v=e.sizeMultiplier,b=.5/m.ptPerEm/v+"em",y=null;if(n){var k=t.base&&"op"===t.base.type&&t.base.name&&("\\oiint"===t.base.name||"\\oiiint"===t.base.name);(l instanceof E||k)&&(y=-l.italic+"em")}if(a&&n){u=Math.max(u,i,a.depth+.25*m.xHeight),p=Math.max(p,m.sub2);var S=4*m.defaultRuleThickness;if(u-a.depth-(n.height-p)0&&(u+=M,p-=M)}var z=[{type:"elem",elem:n,shift:p,marginRight:b,marginLeft:y},{type:"elem",elem:a,shift:-u,marginRight:b}];x=Dt.makeVList({positionType:"individualShift",children:z},e)}else if(n){p=Math.max(p,m.sub1,n.height-.8*m.xHeight);var A=[{type:"elem",elem:n,marginLeft:y,marginRight:b}];x=Dt.makeVList({positionType:"shift",positionData:p,children:A},e)}else{if(!a)throw new Error("supsub must have either sup or sub.");u=Math.max(u,i,a.depth+.25*m.xHeight),x=Dt.makeVList({positionType:"shift",positionData:-u,children:[{type:"elem",elem:a,marginRight:b}]},e)}var T=me(l,"right")||"mord";return Dt.makeSpan([T],[l,Dt.makeSpan(["msupsub"],[x])],e)},mathmlBuilder:function(t,e){var r,a=!1,n=Vt(t.base,"horizBrace");n&&!!t.sup===n.isOver&&(a=!0,r=n.isOver),!t.base||"op"!==t.base.type&&"operatorname"!==t.base.type||(t.base.parentIsSupSub=!0);var i,o=[Me(t.base,e)];if(t.sub&&o.push(Me(t.sub,e)),t.sup&&o.push(Me(t.sup,e)),a)i=r?"mover":"munder";else if(t.sub)if(t.sup){var s=t.base;i=s&&"op"===s.type&&s.limits&&e.style===w.DISPLAY?"munderover":s&&"operatorname"===s.type&&s.alwaysHandleSupSub&&(e.style===w.DISPLAY||s.limits)?"munderover":"msubsup"}else{var h=t.base;i=h&&"op"===h.type&&h.limits&&(e.style===w.DISPLAY||h.alwaysHandleSupSub)?"munder":h&&"operatorname"===h.type&&h.alwaysHandleSupSub&&(h.limits||e.style===w.DISPLAY)?"munder":"msub"}else{var l=t.base;i=l&&"op"===l.type&&l.limits&&(e.style===w.DISPLAY||l.alwaysHandleSupSub)?"mover":l&&"operatorname"===l.type&&l.alwaysHandleSupSub&&(l.limits||e.style===w.DISPLAY)?"mover":"msup"}return new ve.MathNode(i,o)}}),te({type:"atom",htmlBuilder:function(t,e){return Dt.mathsym(t.text,t.mode,e,["m"+t.family])},mathmlBuilder:function(t,e){var r=new ve.MathNode("mo",[be(t.text,t.mode)]);if("bin"===t.family){var a=we(t,e);"bold-italic"===a&&r.setAttribute("mathvariant",a)}else"punct"===t.family?r.setAttribute("separator","true"):"open"!==t.family&&"close"!==t.family||r.setAttribute("stretchy","false");return r}});var Zr={mi:"italic",mn:"normal",mtext:"normal"};te({type:"mathord",htmlBuilder:function(t,e){return Dt.makeOrd(t,e,"mathord")},mathmlBuilder:function(t,e){var r=new ve.MathNode("mi",[be(t.text,t.mode,e)]),a=we(t,e)||"italic";return a!==Zr[r.type]&&r.setAttribute("mathvariant",a),r}}),te({type:"textord",htmlBuilder:function(t,e){return Dt.makeOrd(t,e,"textord")},mathmlBuilder:function(t,e){var r,a=be(t.text,t.mode,e),n=we(t,e)||"normal";return r="text"===t.mode?new ve.MathNode("mtext",[a]):/[0-9]/.test(t.text)?new ve.MathNode("mn",[a]):"\\prime"===t.text?new ve.MathNode("mo",[a]):new ve.MathNode("mi",[a]),n!==Zr[r.type]&&r.setAttribute("mathvariant",n),r}});var Kr={"\\nobreak":"nobreak","\\allowbreak":"allowbreak"},Jr={" ":{},"\\ ":{},"~":{className:"nobreak"},"\\space":{},"\\nobreakspace":{className:"nobreak"}};te({type:"spacing",htmlBuilder:function(t,e){if(Jr.hasOwnProperty(t.text)){var r=Jr[t.text].className||"";if("text"===t.mode){var a=Dt.makeOrd(t,e,"textord");return a.classes.push(r),a}return Dt.makeSpan(["mspace",r],[Dt.mathsym(t.text,t.mode,e)],e)}if(Kr.hasOwnProperty(t.text))return Dt.makeSpan(["mspace",Kr[t.text]],[],e);throw new o('Unknown type of space "'+t.text+'"')},mathmlBuilder:function(t,e){if(!Jr.hasOwnProperty(t.text)){if(Kr.hasOwnProperty(t.text))return new ve.MathNode("mspace");throw new o('Unknown type of space "'+t.text+'"')}return new ve.MathNode("mtext",[new ve.TextNode("\xa0")])}});var Qr=function(){var t=new ve.MathNode("mtd",[]);return t.setAttribute("width","50%"),t};te({type:"tag",mathmlBuilder:function(t,e){var r=new ve.MathNode("mtable",[new ve.MathNode("mtr",[Qr(),new ve.MathNode("mtd",[Se(t.body,e)]),Qr(),new ve.MathNode("mtd",[Se(t.tag,e)])])]);return r.setAttribute("width","100%"),r}});var ta={"\\text":void 0,"\\textrm":"textrm","\\textsf":"textsf","\\texttt":"texttt","\\textnormal":"textrm"},ea={"\\textbf":"textbf","\\textmd":"textmd"},ra={"\\textit":"textit","\\textup":"textup"},aa=function(t,e){var r=t.font;return r?ta[r]?e.withTextFontFamily(ta[r]):ea[r]?e.withTextFontWeight(ea[r]):e.withTextFontShape(ra[r]):e};Qt({type:"text",names:["\\text","\\textrm","\\textsf","\\texttt","\\textnormal","\\textbf","\\textmd","\\textit","\\textup"],props:{numArgs:1,argTypes:["text"],greediness:2,allowedInText:!0},handler:function(t,e){var r=t.parser,a=t.funcName,n=e[0];return{type:"text",mode:r.mode,body:ee(n),font:a}},htmlBuilder:function(t,e){var r=aa(t,e),a=se(t.body,r,!0);return Dt.makeSpan(["mord","text"],Dt.tryCombineChars(a),r)},mathmlBuilder:function(t,e){var r=aa(t,e);return Se(t.body,r)}}),Qt({type:"underline",names:["\\underline"],props:{numArgs:1,allowedInText:!0},handler:function(t,e){return{type:"underline",mode:t.parser.mode,body:e[0]}},htmlBuilder:function(t,e){var r=ue(t.body,e),a=Dt.makeLineSpan("underline-line",e),n=e.fontMetrics().defaultRuleThickness,i=Dt.makeVList({positionType:"top",positionData:r.height,children:[{type:"kern",size:n},{type:"elem",elem:a},{type:"kern",size:3*n},{type:"elem",elem:r}]},e);return Dt.makeSpan(["mord","underline"],[i],e)},mathmlBuilder:function(t,e){var r=new ve.MathNode("mo",[new ve.TextNode("\u203e")]);r.setAttribute("stretchy","true");var a=new ve.MathNode("munder",[Me(t.body,e),r]);return a.setAttribute("accentunder","true"),a}}),Qt({type:"verb",names:["\\verb"],props:{numArgs:0,allowedInText:!0},handler:function(t,e,r){throw new o("\\verb ended by end of line instead of matching delimiter")},htmlBuilder:function(t,e){for(var r=na(t),a=[],n=e.havingStyle(e.style.text()),i=0;i0&&(this.undefStack[this.undefStack.length-1][t]=e)}else{var n=this.undefStack[this.undefStack.length-1];n&&!n.hasOwnProperty(t)&&(n[t]=this.current[t])}this.current[t]=e},t}(),ca={},ua=ca;function pa(t,e){ca[t]=e}pa("\\@firstoftwo",function(t){return{tokens:t.consumeArgs(2)[0],numArgs:0}}),pa("\\@secondoftwo",function(t){return{tokens:t.consumeArgs(2)[1],numArgs:0}}),pa("\\@ifnextchar",function(t){var e=t.consumeArgs(3),r=t.future();return 1===e[0].length&&e[0][0].text===r.text?{tokens:e[1],numArgs:0}:{tokens:e[2],numArgs:0}}),pa("\\@ifstar","\\@ifnextchar *{\\@firstoftwo{#1}}"),pa("\\TextOrMath",function(t){var e=t.consumeArgs(2);return"text"===t.mode?{tokens:e[0],numArgs:0}:{tokens:e[1],numArgs:0}});var da={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};pa("\\char",function(t){var e,r=t.popToken(),a="";if("'"===r.text)e=8,r=t.popToken();else if('"'===r.text)e=16,r=t.popToken();else if("`"===r.text)if("\\"===(r=t.popToken()).text[0])a=r.text.charCodeAt(1);else{if("EOF"===r.text)throw new o("\\char` missing argument");a=r.text.charCodeAt(0)}else e=10;if(e){if(null==(a=da[r.text])||a>=e)throw new o("Invalid base-"+e+" digit "+r.text);for(var n;null!=(n=da[t.future().text])&&n":"\\dotsb","-":"\\dotsb","*":"\\dotsb",":":"\\dotsb","\\DOTSB":"\\dotsb","\\coprod":"\\dotsb","\\bigvee":"\\dotsb","\\bigwedge":"\\dotsb","\\biguplus":"\\dotsb","\\bigcap":"\\dotsb","\\bigcup":"\\dotsb","\\prod":"\\dotsb","\\sum":"\\dotsb","\\bigotimes":"\\dotsb","\\bigoplus":"\\dotsb","\\bigodot":"\\dotsb","\\bigsqcup":"\\dotsb","\\And":"\\dotsb","\\longrightarrow":"\\dotsb","\\Longrightarrow":"\\dotsb","\\longleftarrow":"\\dotsb","\\Longleftarrow":"\\dotsb","\\longleftrightarrow":"\\dotsb","\\Longleftrightarrow":"\\dotsb","\\mapsto":"\\dotsb","\\longmapsto":"\\dotsb","\\hookrightarrow":"\\dotsb","\\doteq":"\\dotsb","\\mathbin":"\\dotsb","\\mathrel":"\\dotsb","\\relbar":"\\dotsb","\\Relbar":"\\dotsb","\\xrightarrow":"\\dotsb","\\xleftarrow":"\\dotsb","\\DOTSI":"\\dotsi","\\int":"\\dotsi","\\oint":"\\dotsi","\\iint":"\\dotsi","\\iiint":"\\dotsi","\\iiiint":"\\dotsi","\\idotsint":"\\dotsi","\\DOTSX":"\\dotsx"};pa("\\dots",function(t){var e="\\dotso",r=t.expandAfterFuture().text;return r in xa?e=xa[r]:"\\not"===r.substr(0,4)?e="\\dotsb":r in j.math&&c.contains(["bin","rel"],j.math[r].group)&&(e="\\dotsb"),e});var va={")":!0,"]":!0,"\\rbrack":!0,"\\}":!0,"\\rbrace":!0,"\\rangle":!0,"\\rceil":!0,"\\rfloor":!0,"\\rgroup":!0,"\\rmoustache":!0,"\\right":!0,"\\bigr":!0,"\\biggr":!0,"\\Bigr":!0,"\\Biggr":!0,$:!0,";":!0,".":!0,",":!0};pa("\\dotso",function(t){return t.future().text in va?"\\ldots\\,":"\\ldots"}),pa("\\dotsc",function(t){var e=t.future().text;return e in va&&","!==e?"\\ldots\\,":"\\ldots"}),pa("\\cdots",function(t){return t.future().text in va?"\\@cdots\\,":"\\@cdots"}),pa("\\dotsb","\\cdots"),pa("\\dotsm","\\cdots"),pa("\\dotsi","\\!\\cdots"),pa("\\dotsx","\\ldots\\,"),pa("\\DOTSI","\\relax"),pa("\\DOTSB","\\relax"),pa("\\DOTSX","\\relax"),pa("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax"),pa("\\,","\\tmspace+{3mu}{.1667em}"),pa("\\thinspace","\\,"),pa("\\>","\\mskip{4mu}"),pa("\\:","\\tmspace+{4mu}{.2222em}"),pa("\\medspace","\\:"),pa("\\;","\\tmspace+{5mu}{.2777em}"),pa("\\thickspace","\\;"),pa("\\!","\\tmspace-{3mu}{.1667em}"),pa("\\negthinspace","\\!"),pa("\\negmedspace","\\tmspace-{4mu}{.2222em}"),pa("\\negthickspace","\\tmspace-{5mu}{.277em}"),pa("\\enspace","\\kern.5em "),pa("\\enskip","\\hskip.5em\\relax"),pa("\\quad","\\hskip1em\\relax"),pa("\\qquad","\\hskip2em\\relax"),pa("\\tag","\\@ifstar\\tag@literal\\tag@paren"),pa("\\tag@paren","\\tag@literal{({#1})}"),pa("\\tag@literal",function(t){if(t.macros.get("\\df@tag"))throw new o("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"}),pa("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}"),pa("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)"),pa("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}"),pa("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1"),pa("\\pmb","\\html@mathml{\\@binrel{#1}{\\mathrlap{#1}\\kern0.5px#1}}{\\mathbf{#1}}"),pa("\\\\","\\newline"),pa("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}");var ba=F["Main-Regular"]["T".charCodeAt(0)][1]-.7*F["Main-Regular"]["A".charCodeAt(0)][1]+"em";pa("\\LaTeX","\\textrm{\\html@mathml{L\\kern-.36em\\raisebox{"+ba+"}{\\scriptstyle A}\\kern-.15em\\TeX}{LaTeX}}"),pa("\\KaTeX","\\textrm{\\html@mathml{K\\kern-.17em\\raisebox{"+ba+"}{\\scriptstyle A}\\kern-.15em\\TeX}{KaTeX}}"),pa("\\hspace","\\@ifstar\\@hspacer\\@hspace"),pa("\\@hspace","\\hskip #1\\relax"),pa("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax"),pa("\\ordinarycolon",":"),pa("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}"),pa("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}'),pa("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}'),pa("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}'),pa("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}'),pa("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}'),pa("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}'),pa("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}'),pa("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}'),pa("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}'),pa("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}'),pa("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}'),pa("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}'),pa("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}'),pa("\u2237","\\dblcolon"),pa("\u2239","\\eqcolon"),pa("\u2254","\\coloneqq"),pa("\u2255","\\eqqcolon"),pa("\u2a74","\\Coloneqq"),pa("\\ratio","\\vcentcolon"),pa("\\coloncolon","\\dblcolon"),pa("\\colonequals","\\coloneqq"),pa("\\coloncolonequals","\\Coloneqq"),pa("\\equalscolon","\\eqqcolon"),pa("\\equalscoloncolon","\\Eqqcolon"),pa("\\colonminus","\\coloneq"),pa("\\coloncolonminus","\\Coloneq"),pa("\\minuscolon","\\eqcolon"),pa("\\minuscoloncolon","\\Eqcolon"),pa("\\coloncolonapprox","\\Colonapprox"),pa("\\coloncolonsim","\\Colonsim"),pa("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),pa("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}"),pa("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),pa("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}"),pa("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`\u220c}}"),pa("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}"),pa("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}"),pa("\\gvertneqq","\\html@mathml{\\@gvertneqq}{\u2269}"),pa("\\lvertneqq","\\html@mathml{\\@lvertneqq}{\u2268}"),pa("\\ngeqq","\\html@mathml{\\@ngeqq}{\u2271}"),pa("\\ngeqslant","\\html@mathml{\\@ngeqslant}{\u2271}"),pa("\\nleqq","\\html@mathml{\\@nleqq}{\u2270}"),pa("\\nleqslant","\\html@mathml{\\@nleqslant}{\u2270}"),pa("\\nshortmid","\\html@mathml{\\@nshortmid}{\u2224}"),pa("\\nshortparallel","\\html@mathml{\\@nshortparallel}{\u2226}"),pa("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{\u2288}"),pa("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{\u2289}"),pa("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{\u228a}"),pa("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{\u2acb}"),pa("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{\u228b}"),pa("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{\u2acc}"),pa("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`\u27e6}}"),pa("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`\u27e7}}"),pa("\u27e6","\\llbracket"),pa("\u27e7","\\rrbracket"),pa("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`\u2983}}"),pa("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`\u2984}}"),pa("\u2983","\\lBrace"),pa("\u2984","\\rBrace"),pa("\\darr","\\downarrow"),pa("\\dArr","\\Downarrow"),pa("\\Darr","\\Downarrow"),pa("\\lang","\\langle"),pa("\\rang","\\rangle"),pa("\\uarr","\\uparrow"),pa("\\uArr","\\Uparrow"),pa("\\Uarr","\\Uparrow"),pa("\\N","\\mathbb{N}"),pa("\\R","\\mathbb{R}"),pa("\\Z","\\mathbb{Z}"),pa("\\alef","\\aleph"),pa("\\alefsym","\\aleph"),pa("\\Alpha","\\mathrm{A}"),pa("\\Beta","\\mathrm{B}"),pa("\\bull","\\bullet"),pa("\\Chi","\\mathrm{X}"),pa("\\clubs","\\clubsuit"),pa("\\cnums","\\mathbb{C}"),pa("\\Complex","\\mathbb{C}"),pa("\\Dagger","\\ddagger"),pa("\\diamonds","\\diamondsuit"),pa("\\empty","\\emptyset"),pa("\\Epsilon","\\mathrm{E}"),pa("\\Eta","\\mathrm{H}"),pa("\\exist","\\exists"),pa("\\harr","\\leftrightarrow"),pa("\\hArr","\\Leftrightarrow"),pa("\\Harr","\\Leftrightarrow"),pa("\\hearts","\\heartsuit"),pa("\\image","\\Im"),pa("\\infin","\\infty"),pa("\\Iota","\\mathrm{I}"),pa("\\isin","\\in"),pa("\\Kappa","\\mathrm{K}"),pa("\\larr","\\leftarrow"),pa("\\lArr","\\Leftarrow"),pa("\\Larr","\\Leftarrow"),pa("\\lrarr","\\leftrightarrow"),pa("\\lrArr","\\Leftrightarrow"),pa("\\Lrarr","\\Leftrightarrow"),pa("\\Mu","\\mathrm{M}"),pa("\\natnums","\\mathbb{N}"),pa("\\Nu","\\mathrm{N}"),pa("\\Omicron","\\mathrm{O}"),pa("\\plusmn","\\pm"),pa("\\rarr","\\rightarrow"),pa("\\rArr","\\Rightarrow"),pa("\\Rarr","\\Rightarrow"),pa("\\real","\\Re"),pa("\\reals","\\mathbb{R}"),pa("\\Reals","\\mathbb{R}"),pa("\\Rho","\\mathrm{P}"),pa("\\sdot","\\cdot"),pa("\\sect","\\S"),pa("\\spades","\\spadesuit"),pa("\\sub","\\subset"),pa("\\sube","\\subseteq"),pa("\\supe","\\supseteq"),pa("\\Tau","\\mathrm{T}"),pa("\\thetasym","\\vartheta"),pa("\\weierp","\\wp"),pa("\\Zeta","\\mathrm{Z}"),pa("\\argmin","\\DOTSB\\operatorname*{arg\\,min}"),pa("\\argmax","\\DOTSB\\operatorname*{arg\\,max}"),pa("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits"),pa("\\blue","\\textcolor{##6495ed}{#1}"),pa("\\orange","\\textcolor{##ffa500}{#1}"),pa("\\pink","\\textcolor{##ff00af}{#1}"),pa("\\red","\\textcolor{##df0030}{#1}"),pa("\\green","\\textcolor{##28ae7b}{#1}"),pa("\\gray","\\textcolor{gray}{#1}"),pa("\\purple","\\textcolor{##9d38bd}{#1}"),pa("\\blueA","\\textcolor{##ccfaff}{#1}"),pa("\\blueB","\\textcolor{##80f6ff}{#1}"),pa("\\blueC","\\textcolor{##63d9ea}{#1}"),pa("\\blueD","\\textcolor{##11accd}{#1}"),pa("\\blueE","\\textcolor{##0c7f99}{#1}"),pa("\\tealA","\\textcolor{##94fff5}{#1}"),pa("\\tealB","\\textcolor{##26edd5}{#1}"),pa("\\tealC","\\textcolor{##01d1c1}{#1}"),pa("\\tealD","\\textcolor{##01a995}{#1}"),pa("\\tealE","\\textcolor{##208170}{#1}"),pa("\\greenA","\\textcolor{##b6ffb0}{#1}"),pa("\\greenB","\\textcolor{##8af281}{#1}"),pa("\\greenC","\\textcolor{##74cf70}{#1}"),pa("\\greenD","\\textcolor{##1fab54}{#1}"),pa("\\greenE","\\textcolor{##0d923f}{#1}"),pa("\\goldA","\\textcolor{##ffd0a9}{#1}"),pa("\\goldB","\\textcolor{##ffbb71}{#1}"),pa("\\goldC","\\textcolor{##ff9c39}{#1}"),pa("\\goldD","\\textcolor{##e07d10}{#1}"),pa("\\goldE","\\textcolor{##a75a05}{#1}"),pa("\\redA","\\textcolor{##fca9a9}{#1}"),pa("\\redB","\\textcolor{##ff8482}{#1}"),pa("\\redC","\\textcolor{##f9685d}{#1}"),pa("\\redD","\\textcolor{##e84d39}{#1}"),pa("\\redE","\\textcolor{##bc2612}{#1}"),pa("\\maroonA","\\textcolor{##ffbde0}{#1}"),pa("\\maroonB","\\textcolor{##ff92c6}{#1}"),pa("\\maroonC","\\textcolor{##ed5fa6}{#1}"),pa("\\maroonD","\\textcolor{##ca337c}{#1}"),pa("\\maroonE","\\textcolor{##9e034e}{#1}"),pa("\\purpleA","\\textcolor{##ddd7ff}{#1}"),pa("\\purpleB","\\textcolor{##c6b9fc}{#1}"),pa("\\purpleC","\\textcolor{##aa87ff}{#1}"),pa("\\purpleD","\\textcolor{##7854ab}{#1}"),pa("\\purpleE","\\textcolor{##543b78}{#1}"),pa("\\mintA","\\textcolor{##f5f9e8}{#1}"),pa("\\mintB","\\textcolor{##edf2df}{#1}"),pa("\\mintC","\\textcolor{##e0e5cc}{#1}"),pa("\\grayA","\\textcolor{##f6f7f7}{#1}"),pa("\\grayB","\\textcolor{##f0f1f2}{#1}"),pa("\\grayC","\\textcolor{##e3e5e6}{#1}"),pa("\\grayD","\\textcolor{##d6d8da}{#1}"),pa("\\grayE","\\textcolor{##babec2}{#1}"),pa("\\grayF","\\textcolor{##888d93}{#1}"),pa("\\grayG","\\textcolor{##626569}{#1}"),pa("\\grayH","\\textcolor{##3b3e40}{#1}"),pa("\\grayI","\\textcolor{##21242c}{#1}"),pa("\\kaBlue","\\textcolor{##314453}{#1}"),pa("\\kaGreen","\\textcolor{##71B307}{#1}");var ya={"\\relax":!0,"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0},wa=function(){function t(t,e,r){this.settings=void 0,this.expansionCount=void 0,this.lexer=void 0,this.macros=void 0,this.stack=void 0,this.mode=void 0,this.settings=e,this.expansionCount=0,this.feed(t),this.macros=new ma(ua,e.macros),this.mode=r,this.stack=[]}var e=t.prototype;return e.feed=function(t){this.lexer=new la(t,this.settings)},e.switchMode=function(t){this.mode=t},e.beginGroup=function(){this.macros.beginGroup()},e.endGroup=function(){this.macros.endGroup()},e.future=function(){return 0===this.stack.length&&this.pushToken(this.lexer.lex()),this.stack[this.stack.length-1]},e.popToken=function(){return this.future(),this.stack.pop()},e.pushToken=function(t){this.stack.push(t)},e.pushTokens=function(t){var e;(e=this.stack).push.apply(e,t)},e.consumeSpaces=function(){for(;;){if(" "!==this.future().text)break;this.stack.pop()}},e.consumeArgs=function(t){for(var e=[],r=0;rthis.settings.maxExpand)throw new o("Too many expansions: infinite loop or need to increase maxExpand setting");var a=r.tokens;if(r.numArgs)for(var n=this.consumeArgs(r.numArgs),i=(a=a.slice()).length-1;i>=0;--i){var s=a[i];if("#"===s.text){if(0===i)throw new o("Incomplete placeholder at end of macro body",s);if("#"===(s=a[--i]).text)a.splice(i+1,1);else{if(!/^[1-9]$/.test(s.text))throw new o("Not a valid argument number",s);var h;(h=a).splice.apply(h,[i,2].concat(n[+s.text-1]))}}}return this.pushTokens(a),a},e.expandAfterFuture=function(){return this.expandOnce(),this.future()},e.expandNextToken=function(){for(;;){var t=this.expandOnce();if(t instanceof n){if("\\relax"!==t.text)return this.stack.pop();this.stack.pop()}}throw new Error},e.expandMacro=function(t){if(this.macros.get(t)){var e=[],r=this.stack.length;for(this.pushToken(new n(t));this.stack.length>r;){this.expandOnce()instanceof n&&e.push(this.stack.pop())}return e}},e.expandMacroAsText=function(t){var e=this.expandMacro(t);return e?e.map(function(t){return t.text}).join(""):e},e._getExpansion=function(t){var e=this.macros.get(t);if(null==e)return e;var r="function"==typeof e?e(this):e;if("string"==typeof r){var a=0;if(-1!==r.indexOf("#"))for(var n=r.replace(/##/g,"");-1!==n.indexOf("#"+(a+1));)++a;for(var i=new la(r,this.settings),o=[],s=i.lex();"EOF"!==s.text;)o.push(s),s=i.lex();return o.reverse(),{tokens:o,numArgs:a}}return r},e.isDefined=function(t){return this.macros.has(t)||ia.hasOwnProperty(t)||j.math.hasOwnProperty(t)||j.text.hasOwnProperty(t)||ya.hasOwnProperty(t)},t}(),ka={"\u0301":{text:"\\'",math:"\\acute"},"\u0300":{text:"\\`",math:"\\grave"},"\u0308":{text:'\\"',math:"\\ddot"},"\u0303":{text:"\\~",math:"\\tilde"},"\u0304":{text:"\\=",math:"\\bar"},"\u0306":{text:"\\u",math:"\\breve"},"\u030c":{text:"\\v",math:"\\check"},"\u0302":{text:"\\^",math:"\\hat"},"\u0307":{text:"\\.",math:"\\dot"},"\u030a":{text:"\\r",math:"\\mathring"},"\u030b":{text:"\\H"}},Sa={"\xe1":"a\u0301","\xe0":"a\u0300","\xe4":"a\u0308","\u01df":"a\u0308\u0304","\xe3":"a\u0303","\u0101":"a\u0304","\u0103":"a\u0306","\u1eaf":"a\u0306\u0301","\u1eb1":"a\u0306\u0300","\u1eb5":"a\u0306\u0303","\u01ce":"a\u030c","\xe2":"a\u0302","\u1ea5":"a\u0302\u0301","\u1ea7":"a\u0302\u0300","\u1eab":"a\u0302\u0303","\u0227":"a\u0307","\u01e1":"a\u0307\u0304","\xe5":"a\u030a","\u01fb":"a\u030a\u0301","\u1e03":"b\u0307","\u0107":"c\u0301","\u010d":"c\u030c","\u0109":"c\u0302","\u010b":"c\u0307","\u010f":"d\u030c","\u1e0b":"d\u0307","\xe9":"e\u0301","\xe8":"e\u0300","\xeb":"e\u0308","\u1ebd":"e\u0303","\u0113":"e\u0304","\u1e17":"e\u0304\u0301","\u1e15":"e\u0304\u0300","\u0115":"e\u0306","\u011b":"e\u030c","\xea":"e\u0302","\u1ebf":"e\u0302\u0301","\u1ec1":"e\u0302\u0300","\u1ec5":"e\u0302\u0303","\u0117":"e\u0307","\u1e1f":"f\u0307","\u01f5":"g\u0301","\u1e21":"g\u0304","\u011f":"g\u0306","\u01e7":"g\u030c","\u011d":"g\u0302","\u0121":"g\u0307","\u1e27":"h\u0308","\u021f":"h\u030c","\u0125":"h\u0302","\u1e23":"h\u0307","\xed":"i\u0301","\xec":"i\u0300","\xef":"i\u0308","\u1e2f":"i\u0308\u0301","\u0129":"i\u0303","\u012b":"i\u0304","\u012d":"i\u0306","\u01d0":"i\u030c","\xee":"i\u0302","\u01f0":"j\u030c","\u0135":"j\u0302","\u1e31":"k\u0301","\u01e9":"k\u030c","\u013a":"l\u0301","\u013e":"l\u030c","\u1e3f":"m\u0301","\u1e41":"m\u0307","\u0144":"n\u0301","\u01f9":"n\u0300","\xf1":"n\u0303","\u0148":"n\u030c","\u1e45":"n\u0307","\xf3":"o\u0301","\xf2":"o\u0300","\xf6":"o\u0308","\u022b":"o\u0308\u0304","\xf5":"o\u0303","\u1e4d":"o\u0303\u0301","\u1e4f":"o\u0303\u0308","\u022d":"o\u0303\u0304","\u014d":"o\u0304","\u1e53":"o\u0304\u0301","\u1e51":"o\u0304\u0300","\u014f":"o\u0306","\u01d2":"o\u030c","\xf4":"o\u0302","\u1ed1":"o\u0302\u0301","\u1ed3":"o\u0302\u0300","\u1ed7":"o\u0302\u0303","\u022f":"o\u0307","\u0231":"o\u0307\u0304","\u0151":"o\u030b","\u1e55":"p\u0301","\u1e57":"p\u0307","\u0155":"r\u0301","\u0159":"r\u030c","\u1e59":"r\u0307","\u015b":"s\u0301","\u1e65":"s\u0301\u0307","\u0161":"s\u030c","\u1e67":"s\u030c\u0307","\u015d":"s\u0302","\u1e61":"s\u0307","\u1e97":"t\u0308","\u0165":"t\u030c","\u1e6b":"t\u0307","\xfa":"u\u0301","\xf9":"u\u0300","\xfc":"u\u0308","\u01d8":"u\u0308\u0301","\u01dc":"u\u0308\u0300","\u01d6":"u\u0308\u0304","\u01da":"u\u0308\u030c","\u0169":"u\u0303","\u1e79":"u\u0303\u0301","\u016b":"u\u0304","\u1e7b":"u\u0304\u0308","\u016d":"u\u0306","\u01d4":"u\u030c","\xfb":"u\u0302","\u016f":"u\u030a","\u0171":"u\u030b","\u1e7d":"v\u0303","\u1e83":"w\u0301","\u1e81":"w\u0300","\u1e85":"w\u0308","\u0175":"w\u0302","\u1e87":"w\u0307","\u1e98":"w\u030a","\u1e8d":"x\u0308","\u1e8b":"x\u0307","\xfd":"y\u0301","\u1ef3":"y\u0300","\xff":"y\u0308","\u1ef9":"y\u0303","\u0233":"y\u0304","\u0177":"y\u0302","\u1e8f":"y\u0307","\u1e99":"y\u030a","\u017a":"z\u0301","\u017e":"z\u030c","\u1e91":"z\u0302","\u017c":"z\u0307","\xc1":"A\u0301","\xc0":"A\u0300","\xc4":"A\u0308","\u01de":"A\u0308\u0304","\xc3":"A\u0303","\u0100":"A\u0304","\u0102":"A\u0306","\u1eae":"A\u0306\u0301","\u1eb0":"A\u0306\u0300","\u1eb4":"A\u0306\u0303","\u01cd":"A\u030c","\xc2":"A\u0302","\u1ea4":"A\u0302\u0301","\u1ea6":"A\u0302\u0300","\u1eaa":"A\u0302\u0303","\u0226":"A\u0307","\u01e0":"A\u0307\u0304","\xc5":"A\u030a","\u01fa":"A\u030a\u0301","\u1e02":"B\u0307","\u0106":"C\u0301","\u010c":"C\u030c","\u0108":"C\u0302","\u010a":"C\u0307","\u010e":"D\u030c","\u1e0a":"D\u0307","\xc9":"E\u0301","\xc8":"E\u0300","\xcb":"E\u0308","\u1ebc":"E\u0303","\u0112":"E\u0304","\u1e16":"E\u0304\u0301","\u1e14":"E\u0304\u0300","\u0114":"E\u0306","\u011a":"E\u030c","\xca":"E\u0302","\u1ebe":"E\u0302\u0301","\u1ec0":"E\u0302\u0300","\u1ec4":"E\u0302\u0303","\u0116":"E\u0307","\u1e1e":"F\u0307","\u01f4":"G\u0301","\u1e20":"G\u0304","\u011e":"G\u0306","\u01e6":"G\u030c","\u011c":"G\u0302","\u0120":"G\u0307","\u1e26":"H\u0308","\u021e":"H\u030c","\u0124":"H\u0302","\u1e22":"H\u0307","\xcd":"I\u0301","\xcc":"I\u0300","\xcf":"I\u0308","\u1e2e":"I\u0308\u0301","\u0128":"I\u0303","\u012a":"I\u0304","\u012c":"I\u0306","\u01cf":"I\u030c","\xce":"I\u0302","\u0130":"I\u0307","\u0134":"J\u0302","\u1e30":"K\u0301","\u01e8":"K\u030c","\u0139":"L\u0301","\u013d":"L\u030c","\u1e3e":"M\u0301","\u1e40":"M\u0307","\u0143":"N\u0301","\u01f8":"N\u0300","\xd1":"N\u0303","\u0147":"N\u030c","\u1e44":"N\u0307","\xd3":"O\u0301","\xd2":"O\u0300","\xd6":"O\u0308","\u022a":"O\u0308\u0304","\xd5":"O\u0303","\u1e4c":"O\u0303\u0301","\u1e4e":"O\u0303\u0308","\u022c":"O\u0303\u0304","\u014c":"O\u0304","\u1e52":"O\u0304\u0301","\u1e50":"O\u0304\u0300","\u014e":"O\u0306","\u01d1":"O\u030c","\xd4":"O\u0302","\u1ed0":"O\u0302\u0301","\u1ed2":"O\u0302\u0300","\u1ed6":"O\u0302\u0303","\u022e":"O\u0307","\u0230":"O\u0307\u0304","\u0150":"O\u030b","\u1e54":"P\u0301","\u1e56":"P\u0307","\u0154":"R\u0301","\u0158":"R\u030c","\u1e58":"R\u0307","\u015a":"S\u0301","\u1e64":"S\u0301\u0307","\u0160":"S\u030c","\u1e66":"S\u030c\u0307","\u015c":"S\u0302","\u1e60":"S\u0307","\u0164":"T\u030c","\u1e6a":"T\u0307","\xda":"U\u0301","\xd9":"U\u0300","\xdc":"U\u0308","\u01d7":"U\u0308\u0301","\u01db":"U\u0308\u0300","\u01d5":"U\u0308\u0304","\u01d9":"U\u0308\u030c","\u0168":"U\u0303","\u1e78":"U\u0303\u0301","\u016a":"U\u0304","\u1e7a":"U\u0304\u0308","\u016c":"U\u0306","\u01d3":"U\u030c","\xdb":"U\u0302","\u016e":"U\u030a","\u0170":"U\u030b","\u1e7c":"V\u0303","\u1e82":"W\u0301","\u1e80":"W\u0300","\u1e84":"W\u0308","\u0174":"W\u0302","\u1e86":"W\u0307","\u1e8c":"X\u0308","\u1e8a":"X\u0307","\xdd":"Y\u0301","\u1ef2":"Y\u0300","\u0178":"Y\u0308","\u1ef8":"Y\u0303","\u0232":"Y\u0304","\u0176":"Y\u0302","\u1e8e":"Y\u0307","\u0179":"Z\u0301","\u017d":"Z\u030c","\u1e90":"Z\u0302","\u017b":"Z\u0307","\u03ac":"\u03b1\u0301","\u1f70":"\u03b1\u0300","\u1fb1":"\u03b1\u0304","\u1fb0":"\u03b1\u0306","\u03ad":"\u03b5\u0301","\u1f72":"\u03b5\u0300","\u03ae":"\u03b7\u0301","\u1f74":"\u03b7\u0300","\u03af":"\u03b9\u0301","\u1f76":"\u03b9\u0300","\u03ca":"\u03b9\u0308","\u0390":"\u03b9\u0308\u0301","\u1fd2":"\u03b9\u0308\u0300","\u1fd1":"\u03b9\u0304","\u1fd0":"\u03b9\u0306","\u03cc":"\u03bf\u0301","\u1f78":"\u03bf\u0300","\u03cd":"\u03c5\u0301","\u1f7a":"\u03c5\u0300","\u03cb":"\u03c5\u0308","\u03b0":"\u03c5\u0308\u0301","\u1fe2":"\u03c5\u0308\u0300","\u1fe1":"\u03c5\u0304","\u1fe0":"\u03c5\u0306","\u03ce":"\u03c9\u0301","\u1f7c":"\u03c9\u0300","\u038e":"\u03a5\u0301","\u1fea":"\u03a5\u0300","\u03ab":"\u03a5\u0308","\u1fe9":"\u03a5\u0304","\u1fe8":"\u03a5\u0306","\u038f":"\u03a9\u0301","\u1ffa":"\u03a9\u0300"},Ma=function(){function t(t,e){this.mode=void 0,this.gullet=void 0,this.settings=void 0,this.leftrightDepth=void 0,this.nextToken=void 0,this.mode="math",this.gullet=new wa(t,e,this.mode),this.settings=e,this.leftrightDepth=0}var e=t.prototype;return e.expect=function(t,e){if(void 0===e&&(e=!0),this.fetch().text!==t)throw new o("Expected '"+t+"', got '"+this.fetch().text+"'",this.fetch());e&&this.consume()},e.consume=function(){this.nextToken=null},e.fetch=function(){return null==this.nextToken&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken},e.switchMode=function(t){this.mode=t,this.gullet.switchMode(t)},e.parse=function(){this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");var t=this.parseExpression(!1);return this.expect("EOF"),this.gullet.endGroup(),t},e.parseExpression=function(e,r){for(var a=[];;){"math"===this.mode&&this.consumeSpaces();var n=this.fetch();if(-1!==t.endOfExpression.indexOf(n.text))break;if(r&&n.text===r)break;if(e&&ia[n.text]&&ia[n.text].infix)break;var i=this.parseAtom(r);if(!i)break;a.push(i)}return"text"===this.mode&&this.formLigatures(a),this.handleInfixNodes(a)},e.handleInfixNodes=function(t){for(var e,r=-1,a=0;a0&&!l||0===s&&!l&&"math"===this.mode,c=this.parseGroupOfType("argument to '"+t+"'",h,l,a,m);if(!c){if(l){i.push(null);continue}throw new o("Expected group after '"+t+"'",this.fetch())}(l?i:n).push(c)}return{args:n,optArgs:i}},e.parseGroupOfType=function(t,e,r,a,n){switch(e){case"color":return n&&this.consumeSpaces(),this.parseColorGroup(r);case"size":return n&&this.consumeSpaces(),this.parseSizeGroup(r);case"url":return this.parseUrlGroup(r,n);case"math":case"text":return this.parseGroup(t,r,a,void 0,e,n);case"hbox":var i=this.parseGroup(t,r,a,void 0,"text",n);return i?{type:"styling",mode:i.mode,body:[i],style:"text"}:i;case"raw":if(n&&this.consumeSpaces(),r&&"{"===this.fetch().text)return null;var s=this.parseStringGroup("raw",r,!0);if(s)return{type:"raw",mode:"text",string:s.text};throw new o("Expected raw group",this.fetch());case"original":case null:case void 0:return this.parseGroup(t,r,a,void 0,void 0,n);default:throw new o("Unknown group type as "+t,this.fetch())}},e.consumeSpaces=function(){for(;" "===this.fetch().text;)this.consume()},e.parseStringGroup=function(t,e,r){var a=e?"[":"{",n=e?"]":"}",i=this.fetch();if(i.text!==a){if(e)return null;if(r&&"EOF"!==i.text&&/[^{}[\]]/.test(i.text))return this.consume(),i}var s=this.mode;this.mode="text",this.expect(a);for(var h,l="",m=this.fetch(),c=0,u=m;(h=this.fetch()).text!==n||r&&c>0;){switch(h.text){case"EOF":throw new o("Unexpected end of input in "+t,m.range(u,l));case a:c++;break;case n:c--}l+=(u=h).text,this.consume()}return this.expect(n),this.mode=s,m.range(u,l)},e.parseRegexGroup=function(t,e){var r=this.mode;this.mode="text";for(var a,n=this.fetch(),i=n,s="";"EOF"!==(a=this.fetch()).text&&t.test(s+a.text);)s+=(i=a).text,this.consume();if(""===s)throw new o("Invalid "+e+": '"+n.text+"'",n);return this.mode=r,n.range(i,s)},e.parseColorGroup=function(t){var e=this.parseStringGroup("color",t);if(!e)return null;var r=/^(#[a-f0-9]{3}|#?[a-f0-9]{6}|[a-z]+)$/i.exec(e.text);if(!r)throw new o("Invalid color: '"+e.text+"'",e);var a=r[0];return/^[0-9a-f]{6}$/i.test(a)&&(a="#"+a),{type:"color-token",mode:this.mode,color:a}},e.parseSizeGroup=function(t){var e,r=!1;if(!(e=t||"{"===this.fetch().text?this.parseStringGroup("size",t):this.parseRegexGroup(/^[-+]? *(?:$|\d+|\d+\.\d*|\.\d*) *[a-z]{0,2} *$/,"size")))return null;t||0!==e.text.length||(e.text="0pt",r=!0);var a=/([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(e.text);if(!a)throw new o("Invalid size: '"+e.text+"'",e);var n={number:+(a[1]+a[2]),unit:a[3]};if(!At(n))throw new o("Invalid unit: '"+n.unit+"'",e);return{type:"size",mode:this.mode,value:n,isBlank:r}},e.parseUrlGroup=function(t,e){this.gullet.lexer.setCatcode("%",13);var r=this.parseStringGroup("url",t,!0);if(this.gullet.lexer.setCatcode("%",14),!r)return null;var a=r.text.replace(/\\([#$%&~_^{}])/g,"$1");return{type:"url",mode:this.mode,url:a}},e.parseGroup=function(e,r,n,i,s,h){var l=this.mode;s&&this.switchMode(s),h&&this.consumeSpaces();var m,c=this.fetch(),u=c.text;if(r?"["===u:"{"===u||"\\begingroup"===u){this.consume();var p=t.endOfGroup[u];this.gullet.beginGroup();var d=this.parseExpression(!1,p),f=this.fetch();this.expect(p),this.gullet.endGroup(),m={type:"ordgroup",mode:this.mode,loc:a.range(c,f),body:d,semisimple:"\\begingroup"===u||void 0}}else if(r)m=null;else if(null==(m=this.parseFunction(i,e,n)||this.parseSymbol())&&"\\"===u[0]&&!ya.hasOwnProperty(u)){if(this.settings.throwOnError)throw new o("Undefined control sequence: "+u,c);m=this.formatUnsupportedCmd(u),this.consume()}return s&&this.switchMode(l),m},e.formLigatures=function(t){for(var e=t.length-1,r=0;r=0&&this.settings.reportNonstrict("unicodeTextInMathMode",'Latin-1/Unicode text character "'+e[0]+'" used in math mode',t);var h,l=j[this.mode][e].group,m=a.range(t);if(W.hasOwnProperty(l)){var c=l;h={type:"atom",mode:this.mode,family:c,loc:m,text:e}}else h={type:l,mode:this.mode,loc:m,text:e};i=h}else{if(!(e.charCodeAt(0)>=128))return null;this.settings.strict&&(M(e.charCodeAt(0))?"math"===this.mode&&this.settings.reportNonstrict("unicodeTextInMathMode",'Unicode text character "'+e[0]+'" used in math mode',t):this.settings.reportNonstrict("unknownSymbol",'Unrecognized Unicode character "'+e[0]+'" ('+e.charCodeAt(0)+")",t)),i={type:"textord",mode:"text",loc:a.range(t),text:e}}if(this.consume(),s)for(var u=0;uwn in jr?Nst(jr,wn,{enumerable:!0,configurable:!0,writable:!0,value:fn}):jr[wn]=fn;var vl=(jr,wn,fn)=>(Bst(jr,typeof wn!="symbol"?wn+"":wn,fn),fn);var jr=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function wn(t){var e=t.default;if(typeof e=="function"){var r=function(){return e.apply(this,arguments)};r.prototype=e.prototype}else r={};return Object.defineProperty(r,"__esModule",{value:!0}),Object.keys(t).forEach(function(n){var i=Object.getOwnPropertyDescriptor(t,n);Object.defineProperty(r,n,i.get?i:{enumerable:!0,get:function(){return t[n]}})}),r}function fn(t){throw new Error('Could not dynamically require "'+t+'". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.')}var b_={exports:{}};(function(t,e){(function(r,n){t.exports=n()})(jr,function(){var r;function n(){return r.apply(null,arguments)}function i(g){return g instanceof Array||Object.prototype.toString.call(g)==="[object Array]"}function a(g){return g!=null&&Object.prototype.toString.call(g)==="[object Object]"}function s(g,E){return Object.prototype.hasOwnProperty.call(g,E)}function o(g){if(Object.getOwnPropertyNames)return Object.getOwnPropertyNames(g).length===0;for(var E in g)if(s(g,E))return;return 1}function l(g){return g===void 0}function u(g){return typeof g=="number"||Object.prototype.toString.call(g)==="[object Number]"}function h(g){return g instanceof Date||Object.prototype.toString.call(g)==="[object Date]"}function d(g,E){for(var I=[],O=g.length,G=0;G>>0,O=0;Oue(g)?(ht=g+1,xt-ue(g)):(ht=g,xt);return{year:ht,dayOfYear:Mt}}function Ke(g,E,I){var O,G,ht=Ie(g.year(),E,I),ht=Math.floor((g.dayOfYear()-ht-1)/7)+1;return ht<1?O=ht+wr(G=g.year()-1,E,I):ht>wr(g.year(),E,I)?(O=ht-wr(g.year(),E,I),G=g.year()+1):(G=g.year(),O=ht),{week:O,year:G}}function wr(g,G,I){var O=Ie(g,G,I),G=Ie(g+1,G,I);return(ue(g)-O+G)/7}Y("w",["ww",2],"wo","week"),Y("W",["WW",2],"Wo","isoWeek"),W("week","w"),W("isoWeek","W"),Z("week",5),Z("isoWeek",5),ft("w",at),ft("ww",at,fe),ft("W",at),ft("WW",at,fe),we(["w","ww","W","WW"],function(g,E,I,O){E[O.substr(0,1)]=q(g)});function je(g,E){return g.slice(E,7).concat(g.slice(0,E))}Y("d",0,"do","day"),Y("dd",0,0,function(g){return this.localeData().weekdaysMin(this,g)}),Y("ddd",0,0,function(g){return this.localeData().weekdaysShort(this,g)}),Y("dddd",0,0,function(g){return this.localeData().weekdays(this,g)}),Y("e",0,0,"weekday"),Y("E",0,0,"isoWeekday"),W("day","d"),W("weekday","e"),W("isoWeekday","E"),Z("day",11),Z("weekday",11),Z("isoWeekday",11),ft("d",at),ft("e",at),ft("E",at),ft("dd",function(g,E){return E.weekdaysMinRegex(g)}),ft("ddd",function(g,E){return E.weekdaysShortRegex(g)}),ft("dddd",function(g,E){return E.weekdaysRegex(g)}),we(["dd","ddd","dddd"],function(g,E,I,O){O=I._locale.weekdaysParse(g,O,I._strict),O!=null?E.d=O:m(I).invalidWeekday=g}),we(["d","e","E"],function(g,E,I,O){E[O]=q(g)});var Ze="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),qt="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),st="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),At=Tt,Nt=Tt,Jt=Tt;function ze(){function g(Ot,de){return de.length-Ot.length}for(var E,I,O,G=[],ht=[],xt=[],Mt=[],Vt=0;Vt<7;Vt++)O=p([2e3,1]).day(Vt),E=Dt(this.weekdaysMin(O,"")),I=Dt(this.weekdaysShort(O,"")),O=Dt(this.weekdays(O,"")),G.push(E),ht.push(I),xt.push(O),Mt.push(E),Mt.push(I),Mt.push(O);G.sort(g),ht.sort(g),xt.sort(g),Mt.sort(g),this._weekdaysRegex=new RegExp("^("+Mt.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+xt.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+ht.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+G.join("|")+")","i")}function Pe(){return this.hours()%12||12}function qe(g,E){Y(g,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),E)})}function Tr(g,E){return E._meridiemParse}Y("H",["HH",2],0,"hour"),Y("h",["hh",2],0,Pe),Y("k",["kk",2],0,function(){return this.hours()||24}),Y("hmm",0,0,function(){return""+Pe.apply(this)+N(this.minutes(),2)}),Y("hmmss",0,0,function(){return""+Pe.apply(this)+N(this.minutes(),2)+N(this.seconds(),2)}),Y("Hmm",0,0,function(){return""+this.hours()+N(this.minutes(),2)}),Y("Hmmss",0,0,function(){return""+this.hours()+N(this.minutes(),2)+N(this.seconds(),2)}),qe("a",!0),qe("A",!1),W("hour","h"),Z("hour",13),ft("a",Tr),ft("A",Tr),ft("H",at),ft("h",at),ft("k",at),ft("HH",at,fe),ft("hh",at,fe),ft("kk",at,fe),ft("hmm",It),ft("hmmss",Lt),ft("Hmm",It),ft("Hmmss",Lt),Qt(["H","HH"],bt),Qt(["k","kk"],function(g,E,I){g=q(g),E[bt]=g===24?0:g}),Qt(["a","A"],function(g,E,I){I._isPm=I._locale.isPM(g),I._meridiem=g}),Qt(["h","hh"],function(g,E,I){E[bt]=q(g),m(I).bigHour=!0}),Qt("hmm",function(g,E,I){var O=g.length-2;E[bt]=q(g.substr(0,O)),E[Et]=q(g.substr(O)),m(I).bigHour=!0}),Qt("hmmss",function(g,E,I){var O=g.length-4,G=g.length-2;E[bt]=q(g.substr(0,O)),E[Et]=q(g.substr(O,2)),E[kt]=q(g.substr(G)),m(I).bigHour=!0}),Qt("Hmm",function(g,E,I){var O=g.length-2;E[bt]=q(g.substr(0,O)),E[Et]=q(g.substr(O))}),Qt("Hmmss",function(g,E,I){var O=g.length-4,G=g.length-2;E[bt]=q(g.substr(0,O)),E[Et]=q(g.substr(O,2)),E[kt]=q(g.substr(G))}),Tt=U("Hours",!0);var Ve,va={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",w:"a week",ww:"%d weeks",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:ne,monthsShort:ve,week:{dow:0,doy:6},weekdays:Ze,weekdaysMin:st,weekdaysShort:qt,meridiemParse:/[ap]\.?m?\.?/i},Ce={},Wi={};function E0(g){return g&&g.toLowerCase().replace("_","-")}function bu(g){for(var E,I,O,G,ht=0;ht=E&&function(xt,Mt){for(var Vt=Math.min(xt.length,Mt.length),Ot=0;Ot=E-1)break;E--}ht++}return Ve}function Ln(g){var E;if(Ce[g]===void 0&&!0&&t&&t.exports&&g.match("^[^/\\\\]*$")!=null)try{E=Ve._abbr,fn("./locale/"+g),Xt(E)}catch{Ce[g]=null}return Ce[g]}function Xt(g,E){return g&&((E=l(E)?ce(g):ee(g,E))?Ve=E:typeof console<"u"&&console.warn&&console.warn("Locale "+g+" not found. Did you forget to load it?")),Ve._abbr}function ee(g,E){if(E===null)return delete Ce[g],null;var I,O=va;if(E.abbr=g,Ce[g]!=null)L("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),O=Ce[g]._config;else if(E.parentLocale!=null)if(Ce[E.parentLocale]!=null)O=Ce[E.parentLocale]._config;else{if((I=Ln(E.parentLocale))==null)return Wi[E.parentLocale]||(Wi[E.parentLocale]=[]),Wi[E.parentLocale].push({name:g,config:E}),null;O=I._config}return Ce[g]=new w(B(O,E)),Wi[g]&&Wi[g].forEach(function(G){ee(G.name,G.config)}),Xt(g),Ce[g]}function ce(g){var E;if(!(g=g&&g._locale&&g._locale._abbr?g._locale._abbr:g))return Ve;if(!i(g)){if(E=Ln(g))return E;g=[g]}return bu(g)}function Pt(g){var E=g._a;return E&&m(g).overflow===-2&&(E=E[zt]<0||11yt(E[Ft],E[zt])?wt:E[bt]<0||24wr(ht,Vt,Ot)?m(O)._overflowWeeks=!0:de!=null?m(O)._overflowWeekday=!0:(ie=oe(ht,xt,Mt,Vt,Ot),O._a[Ft]=ie.year,O._dayOfYear=ie.dayOfYear)),g._dayOfYear!=null&&(G=Gi(g._a[Ft],I[Ft]),(g._dayOfYear>ue(G)||g._dayOfYear===0)&&(m(g)._overflowDayOfYear=!0),de=Hr(G,0,g._dayOfYear),g._a[zt]=de.getUTCMonth(),g._a[wt]=de.getUTCDate()),E=0;E<3&&g._a[E]==null;++E)g._a[E]=er[E]=I[E];for(;E<7;E++)g._a[E]=er[E]=g._a[E]==null?E===2?1:0:g._a[E];g._a[bt]===24&&g._a[Et]===0&&g._a[kt]===0&&g._a[Ut]===0&&(g._nextDay=!0,g._a[bt]=0),g._d=(g._useUTC?Hr:_a).apply(null,er),ht=g._useUTC?g._d.getUTCDay():g._d.getDay(),g._tzm!=null&&g._d.setUTCMinutes(g._d.getUTCMinutes()-g._tzm),g._nextDay&&(g._a[bt]=24),g._w&&g._w.d!==void 0&&g._w.d!==ht&&(m(g).weekdayMismatch=!0)}}function _u(g){if(g._f===n.ISO_8601)A0(g);else if(g._f===n.RFC_2822)Hi(g);else{g._a=[],m(g).empty=!0;for(var E,I,O,G,ht,xt=""+g._i,Mt=xt.length,Vt=0,Ot=lt(g._f,g._locale).match(z)||[],de=Ot.length,ie=0;ieg.valueOf():g.valueOf()"}),P.toJSON=function(){return this.isValid()?this.toISOString():null},P.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},P.unix=function(){return Math.floor(this.valueOf()/1e3)},P.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},P.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},P.eraName=function(){for(var g,E=this.localeData().eras(),I=0,O=E.length;Ithis.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},P.isLocal=function(){return!!this.isValid()&&!this._isUTC},P.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},P.isUtc=eR,P.isUTC=eR,P.zoneAbbr=function(){return this._isUTC?"UTC":""},P.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},P.dates=R("dates accessor is deprecated. Use date instead.",ls),P.months=R("months accessor is deprecated. Use month instead",se),P.years=R("years accessor is deprecated. Use year instead",N0),P.zone=R("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(g,E){return g!=null?(this.utcOffset(g=typeof g!="string"?-g:g,E),this):-this.utcOffset()}),P.isDSTShifted=R("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!l(this._isDSTShifted))return this._isDSTShifted;var g,E={};return T(E,this),(E=M0(E))._a?(g=(E._isUTC?p:De)(E._a),this._isDSTShifted=this.isValid()&&0{},debug:(...t)=>{},info:(...t)=>{},warn:(...t)=>{},error:(...t)=>{},fatal:(...t)=>{}},D0=function(t="fatal"){let e=ji.fatal;typeof t=="string"?(t=t.toLowerCase(),t in ji&&(e=ji[t])):typeof t=="number"&&(e=t),H.trace=()=>{},H.debug=()=>{},H.info=()=>{},H.warn=()=>{},H.error=()=>{},H.fatal=()=>{},e<=ji.fatal&&(H.fatal=console.error?console.error.bind(console,Nn("FATAL"),"color: orange"):console.log.bind(console,"\x1B[35m",Nn("FATAL"))),e<=ji.error&&(H.error=console.error?console.error.bind(console,Nn("ERROR"),"color: orange"):console.log.bind(console,"\x1B[31m",Nn("ERROR"))),e<=ji.warn&&(H.warn=console.warn?console.warn.bind(console,Nn("WARN"),"color: orange"):console.log.bind(console,"\x1B[33m",Nn("WARN"))),e<=ji.info&&(H.info=console.info?console.info.bind(console,Nn("INFO"),"color: lightblue"):console.log.bind(console,"\x1B[34m",Nn("INFO"))),e<=ji.debug&&(H.debug=console.debug?console.debug.bind(console,Nn("DEBUG"),"color: lightgreen"):console.log.bind(console,"\x1B[32m",Nn("DEBUG"))),e<=ji.trace&&(H.trace=console.debug?console.debug.bind(console,Nn("TRACE"),"color: lightgreen"):console.log.bind(console,"\x1B[32m",Nn("TRACE")))},Nn=t=>`%c${Xn().format("ss.SSS")} : ${t} : `;var O0={};Object.defineProperty(O0,"__esModule",{value:!0});var ki=O0.sanitizeUrl=void 0,mR=/^([^\w]*)(javascript|data|vbscript)/im,bR=/&#(\w+)(^\w|;)?/g,_R=/[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/gim,vR=/^([^:]+):/gm,xR=[".","/"];function kR(t){return xR.indexOf(t[0])>-1}function wR(t){return t.replace(bR,function(e,r){return String.fromCharCode(r)})}function TR(t){var e=wR(t||"").replace(_R,"").trim();if(!e)return"about:blank";if(kR(e))return e;var r=e.match(vR);if(!r)return e;var n=r[0];return mR.test(n)?"about:blank":e}ki=O0.sanitizeUrl=TR;function Qe(t,e){return t==null||e==null?NaN:te?1:t>=e?0:NaN}function __(t,e){return t==null||e==null?NaN:et?1:e>=t?0:NaN}function xu(t){let e,r,n;t.length!==2?(e=Qe,r=(o,l)=>Qe(t(o),l),n=(o,l)=>t(o)-l):(e=t===Qe||t===__?t:ER,r=t,n=t);function i(o,l,u=0,h=o.length){if(u>>1;r(o[d],l)<0?u=d+1:h=d}while(u>>1;r(o[d],l)<=0?u=d+1:h=d}while(uu&&n(o[d-1],l)>-n(o[d],l)?d-1:d}return{left:i,center:s,right:a}}function ER(){return 0}function v_(t){return t===null?NaN:+t}function*x_(t,e){if(e===void 0)for(let r of t)r!=null&&(r=+r)>=r&&(yield r);else{let r=-1;for(let n of t)(n=e(n,++r,t))!=null&&(n=+n)>=n&&(yield n)}}const k_=xu(Qe),w_=k_.right,CR=k_.left,SR=xu(v_).center,cs=w_;function AR(t,e){if(!((e=+e)>=0))throw new RangeError("invalid r");let r=t.length;if(!((r=Math.floor(r))>=0))throw new RangeError("invalid length");if(!r||!e)return t;const n=F0(e),i=t.slice();return n(t,i,0,r,1),n(i,t,0,r,1),n(t,i,0,r,1),t}const T_=E_(F0),MR=E_(LR);function E_(t){return function(e,r,n=r){if(!((r=+r)>=0))throw new RangeError("invalid rx");if(!((n=+n)>=0))throw new RangeError("invalid ry");let{data:i,width:a,height:s}=e;if(!((a=Math.floor(a))>=0))throw new RangeError("invalid width");if(!((s=Math.floor(s!==void 0?s:i.length/a))>=0))throw new RangeError("invalid height");if(!a||!s||!r&&!n)return e;const o=r&&t(r),l=n&&t(n),u=i.slice();return o&&l?(ro(o,u,i,a,s),ro(o,i,u,a,s),ro(o,u,i,a,s),no(l,i,u,a,s),no(l,u,i,a,s),no(l,i,u,a,s)):o?(ro(o,i,u,a,s),ro(o,u,i,a,s),ro(o,i,u,a,s)):l&&(no(l,i,u,a,s),no(l,u,i,a,s),no(l,i,u,a,s)),e}}function ro(t,e,r,n,i){for(let a=0,s=n*i;a{i<<=2,a<<=2,s<<=2,e(r,n,i+0,a+0,s),e(r,n,i+1,a+1,s),e(r,n,i+2,a+2,s),e(r,n,i+3,a+3,s)}}function F0(t){const e=Math.floor(t);if(e===t)return RR(t);const r=t-e,n=2*t+1;return(i,a,s,o,l)=>{if(!((o-=l)>=s))return;let u=e*a[s];const h=l*e,d=h+l;for(let f=s,p=s+h;f{if(!((a-=s)>=i))return;let o=t*n[i];const l=s*t;for(let u=i,h=i+l;u=n&&++r;else{let n=-1;for(let i of t)(i=e(i,++n,t))!=null&&(i=+i)>=i&&++r}return r}function IR(t){return t.length|0}function NR(t){return!(t>0)}function BR(t){return typeof t!="object"||"length"in t?t:Array.from(t)}function DR(t){return e=>t(...e)}function OR(...t){const e=typeof t[t.length-1]=="function"&&DR(t.pop());t=t.map(BR);const r=t.map(IR),n=t.length-1,i=new Array(n+1).fill(0),a=[];if(n<0||r.some(NR))return a;for(;;){a.push(i.map((o,l)=>t[l][o]));let s=n;for(;++i[s]===r[s];){if(s===0)return e?a.map(e):a;i[s--]=0}}}function FR(t,e){var r=0,n=0;return Float64Array.from(t,e===void 0?i=>r+=+i||0:i=>r+=+e(i,n++,t)||0)}function C_(t,e){let r=0,n,i=0,a=0;if(e===void 0)for(let s of t)s!=null&&(s=+s)>=s&&(n=s-i,i+=n/++r,a+=n*(s-i));else{let s=-1;for(let o of t)(o=e(o,++s,t))!=null&&(o=+o)>=o&&(n=o-i,i+=n/++r,a+=n*(o-i))}if(r>1)return a/(r-1)}function S_(t,e){const r=C_(t,e);return r&&Math.sqrt(r)}function xl(t,e){let r,n;if(e===void 0)for(const i of t)i!=null&&(r===void 0?i>=i&&(r=n=i):(r>i&&(r=i),n=a&&(r=n=a):(r>a&&(r=a),n0){for(s=e[--r];r>0&&(n=s,i=e[--r],s=n+i,a=i-(s-n),!a););r>0&&(a<0&&e[r-1]<0||a>0&&e[r-1]>0)&&(i=a*2,n=s+i,i==n-s&&(s=n))}return s}}function PR(t,e){const r=new _r;if(e===void 0)for(let n of t)(n=+n)&&r.add(n);else{let n=-1;for(let i of t)(i=+e(i,++n,t))&&r.add(i)}return+r}function qR(t,e){const r=new _r;let n=-1;return Float64Array.from(t,e===void 0?i=>r.add(+i||0):i=>r.add(+e(i,++n,t)||0))}class kl extends Map{constructor(e,r=L_){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:r}}),e!=null)for(const[n,i]of e)this.set(n,i)}get(e){return super.get(P0(this,e))}has(e){return super.has(P0(this,e))}set(e,r){return super.set(A_(this,e),r)}delete(e){return super.delete(M_(this,e))}}class us extends Set{constructor(e,r=L_){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:r}}),e!=null)for(const n of e)this.add(n)}has(e){return super.has(P0(this,e))}add(e){return super.add(A_(this,e))}delete(e){return super.delete(M_(this,e))}}function P0({_intern:t,_key:e},r){const n=e(r);return t.has(n)?t.get(n):r}function A_({_intern:t,_key:e},r){const n=e(r);return t.has(n)?t.get(n):(t.set(n,r),r)}function M_({_intern:t,_key:e},r){const n=e(r);return t.has(n)&&(r=t.get(n),t.delete(n)),r}function L_(t){return t!==null&&typeof t=="object"?t.valueOf():t}function io(t){return t}function R_(t,...e){return ao(t,io,io,e)}function I_(t,...e){return ao(t,Array.from,io,e)}function N_(t,e){for(let r=1,n=e.length;ri.pop().map(([a,s])=>[...i,a,s]));return t}function VR(t,...e){return N_(I_(t,...e),e)}function zR(t,e,...r){return N_(D_(t,e,...r),r)}function B_(t,e,...r){return ao(t,io,e,r)}function D_(t,e,...r){return ao(t,Array.from,e,r)}function YR(t,...e){return ao(t,io,O_,e)}function UR(t,...e){return ao(t,Array.from,O_,e)}function O_(t){if(t.length!==1)throw new Error("duplicate key");return t[0]}function ao(t,e,r,n){return function i(a,s){if(s>=n.length)return r(a);const o=new kl,l=n[s++];let u=-1;for(const h of a){const d=l(h,++u,a),f=o.get(d);f?f.push(h):o.set(d,[h])}for(const[h,d]of o)o.set(h,i(d,s));return e(o)}(t,0)}function F_(t,e){return Array.from(e,r=>t[r])}function q0(t,...e){if(typeof t[Symbol.iterator]!="function")throw new TypeError("values is not iterable");t=Array.from(t);let[r]=e;if(r&&r.length!==2||e.length>1){const n=Uint32Array.from(t,(i,a)=>a);return e.length>1?(e=e.map(i=>t.map(i)),n.sort((i,a)=>{for(const s of e){const o=so(s[i],s[a]);if(o)return o}})):(r=t.map(r),n.sort((i,a)=>so(r[i],r[a]))),F_(t,n)}return t.sort(V0(r))}function V0(t=Qe){if(t===Qe)return so;if(typeof t!="function")throw new TypeError("compare is not a function");return(e,r)=>{const n=t(e,r);return n||n===0?n:(t(r,r)===0)-(t(e,e)===0)}}function so(t,e){return(t==null||!(t>=t))-(e==null||!(e>=e))||(te?1:0)}function WR(t,e,r){return(e.length!==2?q0(B_(t,e,r),([n,i],[a,s])=>Qe(i,s)||Qe(n,a)):q0(R_(t,r),([n,i],[a,s])=>e(i,s)||Qe(n,a))).map(([n])=>n)}var HR=Array.prototype,GR=HR.slice;function wu(t){return()=>t}var z0=Math.sqrt(50),Y0=Math.sqrt(10),U0=Math.sqrt(2);function hs(t,e,r){var n,i=-1,a,s,o;if(e=+e,t=+t,r=+r,t===e&&r>0)return[t];if((n=e0){let l=Math.round(t/o),u=Math.round(e/o);for(l*oe&&--u,s=new Array(a=u-l+1);++ie&&--u,s=new Array(a=u-l+1);++i=0?(a>=z0?10:a>=Y0?5:a>=U0?2:1)*Math.pow(10,i):-Math.pow(10,-i)/(a>=z0?10:a>=Y0?5:a>=U0?2:1)}function wl(t,e,r){var n=Math.abs(e-t)/Math.max(0,r),i=Math.pow(10,Math.floor(Math.log(n)/Math.LN10)),a=n/i;return a>=z0?i*=10:a>=Y0?i*=5:a>=U0&&(i*=2),e0?(t=Math.floor(t/i)*i,e=Math.ceil(e/i)*i):i<0&&(t=Math.ceil(t*i)/i,e=Math.floor(e*i)/i),n=i}}function W0(t){return Math.ceil(Math.log(ku(t))/Math.LN2)+1}function q_(){var t=io,e=xl,r=W0;function n(i){Array.isArray(i)||(i=Array.from(i));var a,s=i.length,o,l,u=new Array(s);for(a=0;a=f)if(b>=f&&e===xl){const k=oo(d,f,x);isFinite(k)&&(k>0?f=(Math.floor(f/k)+1)*k:k<0&&(f=(Math.ceil(f*-k)+1)/-k))}else p.pop()}for(var m=p.length;p[0]<=d;)p.shift(),--m;for(;p[m-1]>f;)p.pop(),--m;var _=new Array(m+1),y;for(a=0;a<=m;++a)y=_[a]=[],y.x0=a>0?p[a-1]:d,y.x1=a0)for(a=0;a=n)&&(r=n);else{let n=-1;for(let i of t)(i=e(i,++n,t))!=null&&(r=i)&&(r=i)}return r}function H0(t,e){let r,n=-1,i=-1;if(e===void 0)for(const a of t)++i,a!=null&&(r=a)&&(r=a,n=i);else for(let a of t)(a=e(a,++i,t))!=null&&(r=a)&&(r=a,n=i);return n}function Tl(t,e){let r;if(e===void 0)for(const n of t)n!=null&&(r>n||r===void 0&&n>=n)&&(r=n);else{let n=-1;for(let i of t)(i=e(i,++n,t))!=null&&(r>i||r===void 0&&i>=i)&&(r=i)}return r}function G0(t,e){let r,n=-1,i=-1;if(e===void 0)for(const a of t)++i,a!=null&&(r>a||r===void 0&&a>=a)&&(r=a,n=i);else for(let a of t)(a=e(a,++i,t))!=null&&(r>a||r===void 0&&a>=a)&&(r=a,n=i);return n}function Tu(t,e,r=0,n=t.length-1,i){for(i=i===void 0?so:V0(i);n>r;){if(n-r>600){const l=n-r+1,u=e-r+1,h=Math.log(l),d=.5*Math.exp(2*h/3),f=.5*Math.sqrt(h*d*(l-d)/l)*(u-l/2<0?-1:1),p=Math.max(r,Math.floor(e-u*d/l+f)),m=Math.min(n,Math.floor(e+(l-u)*d/l+f));Tu(t,e,p,m,i)}const a=t[e];let s=r,o=n;for(El(t,r,e),i(t[n],a)>0&&El(t,r,n);s0;)--o}i(t[r],a)===0?El(t,r,o):(++o,El(t,o,n)),o<=e&&(r=o+1),e<=o&&(n=o-1)}return t}function El(t,e,r){const n=t[e];t[e]=t[r],t[r]=n}function V_(t,e=Qe){let r,n=!1;if(e.length===1){let i;for(const a of t){const s=e(a);(n?Qe(s,i)>0:Qe(s,s)===0)&&(r=a,i=s,n=!0)}}else for(const i of t)(n?e(i,r)>0:e(i,i)===0)&&(r=i,n=!0);return r}function Cl(t,e,r){if(t=Float64Array.from(x_(t,r)),!!(n=t.length)){if((e=+e)<=0||n<2)return Tl(t);if(e>=1)return lo(t);var n,i=(n-1)*e,a=Math.floor(i),s=lo(Tu(t,a).subarray(0,a+1)),o=Tl(t.subarray(a+1));return s+(o-s)*(i-a)}}function z_(t,e,r=v_){if(!!(n=t.length)){if((e=+e)<=0||n<2)return+r(t[0],0,t);if(e>=1)return+r(t[n-1],n-1,t);var n,i=(n-1)*e,a=Math.floor(i),s=+r(t[a],a,t),o=+r(t[a+1],a+1,t);return s+(o-s)*(i-a)}}function Y_(t,e,r){if(t=Float64Array.from(x_(t,r)),!!(n=t.length)){if((e=+e)<=0||n<2)return G0(t);if(e>=1)return H0(t);var n,i=Math.floor((n-1)*e),a=(o,l)=>so(t[o],t[l]),s=Tu(Uint32Array.from(t,(o,l)=>l),i,0,n-1,a);return V_(s.subarray(0,i+1),o=>t[o])}}function jR(t,e,r){return Math.ceil((r-e)/(2*(Cl(t,.75)-Cl(t,.25))*Math.pow(ku(t),-1/3)))}function $R(t,e,r){return Math.ceil((r-e)*Math.cbrt(ku(t))/(3.49*S_(t)))}function XR(t,e){let r=0,n=0;if(e===void 0)for(let i of t)i!=null&&(i=+i)>=i&&(++r,n+=i);else{let i=-1;for(let a of t)(a=e(a,++i,t))!=null&&(a=+a)>=a&&(++r,n+=a)}if(r)return n/r}function KR(t,e){return Cl(t,.5,e)}function ZR(t,e){return Y_(t,.5,e)}function*QR(t){for(const e of t)yield*e}function j0(t){return Array.from(QR(t))}function JR(t,e){const r=new kl;if(e===void 0)for(let a of t)a!=null&&a>=a&&r.set(a,(r.get(a)||0)+1);else{let a=-1;for(let s of t)(s=e(s,++a,t))!=null&&s>=s&&r.set(s,(r.get(s)||0)+1)}let n,i=0;for(const[a,s]of r)s>i&&(i=s,n=a);return n}function tI(t,e=eI){const r=[];let n,i=!1;for(const a of t)i&&r.push(e(n,a)),n=a,i=!0;return r}function eI(t,e){return[t,e]}function Ca(t,e,r){t=+t,e=+e,r=(i=arguments.length)<2?(e=t,t=0,1):i<3?1:+r;for(var n=-1,i=Math.max(0,Math.ceil((e-t)/r))|0,a=new Array(i);++ne(r[o],r[l]);let a,s;return Uint32Array.from(r,(o,l)=>l).sort(e===Qe?(o,l)=>so(r[o],r[l]):V0(i)).forEach((o,l)=>{const u=i(o,a===void 0?o:a);u>=0?((a===void 0||u>0)&&(a=o,s=l),n[o]=s):n[o]=NaN}),n}function nI(t,e=Qe){let r,n=!1;if(e.length===1){let i;for(const a of t){const s=e(a);(n?Qe(s,i)<0:Qe(s,s)===0)&&(r=a,i=s,n=!0)}}else for(const i of t)(n?e(i,r)<0:e(i,i)===0)&&(r=i,n=!0);return r}function U_(t,e=Qe){if(e.length===1)return G0(t,e);let r,n=-1,i=-1;for(const a of t)++i,(n<0?e(a,a)===0:e(a,r)<0)&&(r=a,n=i);return n}function iI(t,e=Qe){if(e.length===1)return H0(t,e);let r,n=-1,i=-1;for(const a of t)++i,(n<0?e(a,a)===0:e(a,r)>0)&&(r=a,n=i);return n}function aI(t,e){const r=U_(t,e);return r<0?void 0:r}const sI=W_(Math.random);function W_(t){return function(r,n=0,i=r.length){let a=i-(n=+n);for(;a;){const s=t()*a--|0,o=r[a+n];r[a+n]=r[s+n],r[s+n]=o}return r}}function oI(t,e){let r=0;if(e===void 0)for(let n of t)(n=+n)&&(r+=n);else{let n=-1;for(let i of t)(i=+e(i,++n,t))&&(r+=i)}return r}function H_(t){if(!(a=t.length))return[];for(var e=-1,r=Tl(t,lI),n=new Array(r);++ee(r,n,t))}function pI(t,e,r){if(typeof e!="function")throw new TypeError("reducer is not a function");const n=t[Symbol.iterator]();let i,a,s=-1;if(arguments.length<3){if({done:i,value:r}=n.next(),i)return;++s}for(;{done:i,value:a}=n.next(),!i;)r=e(r,a,++s,t);return r}function gI(t){if(typeof t[Symbol.iterator]!="function")throw new TypeError("values is not iterable");return Array.from(t).reverse()}function yI(t,...e){t=new us(t);for(const r of e)for(const n of r)t.delete(n);return t}function mI(t,e){const r=e[Symbol.iterator](),n=new us;for(const i of t){if(n.has(i))return!1;let a,s;for(;({value:a,done:s}=r.next())&&!s;){if(Object.is(i,a))return!1;n.add(a)}}return!0}function bI(t,...e){t=new us(t),e=e.map(_I);t:for(const r of t)for(const n of e)if(!n.has(r)){t.delete(r);continue t}return t}function _I(t){return t instanceof us?t:new us(t)}function G_(t,e){const r=t[Symbol.iterator](),n=new Set;for(const i of e){const a=j_(i);if(n.has(a))continue;let s,o;for(;{value:s,done:o}=r.next();){if(o)return!1;const l=j_(s);if(n.add(l),Object.is(a,l))break}}return!0}function j_(t){return t!==null&&typeof t=="object"?t.valueOf():t}function vI(t,e){return G_(e,t)}function xI(...t){const e=new us;for(const r of t)for(const n of r)e.add(n);return e}function kI(t){return t}var Eu=1,Cu=2,$0=3,Sl=4,$_=1e-6;function wI(t){return"translate("+t+",0)"}function TI(t){return"translate(0,"+t+")"}function EI(t){return e=>+t(e)}function CI(t,e){return e=Math.max(0,t.bandwidth()-e*2)/2,t.round()&&(e=Math.round(e)),r=>+t(r)+e}function SI(){return!this.__axis}function Su(t,e){var r=[],n=null,i=null,a=6,s=6,o=3,l=typeof window<"u"&&window.devicePixelRatio>1?0:.5,u=t===Eu||t===Sl?-1:1,h=t===Sl||t===Cu?"x":"y",d=t===Eu||t===$0?wI:TI;function f(p){var m=n==null?e.ticks?e.ticks.apply(e,r):e.domain():n,_=i==null?e.tickFormat?e.tickFormat.apply(e,r):kI:i,y=Math.max(a,0)+o,b=e.range(),x=+b[0]+l,k=+b[b.length-1]+l,T=(e.bandwidth?CI:EI)(e.copy(),l),C=p.selection?p.selection():p,M=C.selectAll(".domain").data([null]),S=C.selectAll(".tick").data(m,e).order(),R=S.exit(),A=S.enter().append("g").attr("class","tick"),L=S.select("line"),v=S.select("text");M=M.merge(M.enter().insert("path",".tick").attr("class","domain").attr("stroke","currentColor")),S=S.merge(A),L=L.merge(A.append("line").attr("stroke","currentColor").attr(h+"2",u*a)),v=v.merge(A.append("text").attr("fill","currentColor").attr(h,u*y).attr("dy",t===Eu?"0em":t===$0?"0.71em":"0.32em")),p!==C&&(M=M.transition(p),S=S.transition(p),L=L.transition(p),v=v.transition(p),R=R.transition(p).attr("opacity",$_).attr("transform",function(B){return isFinite(B=T(B))?d(B+l):this.getAttribute("transform")}),A.attr("opacity",$_).attr("transform",function(B){var w=this.parentNode.__axis;return d((w&&isFinite(w=w(B))?w:T(B))+l)})),R.remove(),M.attr("d",t===Sl||t===Cu?s?"M"+u*s+","+x+"H"+l+"V"+k+"H"+u*s:"M"+l+","+x+"V"+k:s?"M"+x+","+u*s+"V"+l+"H"+k+"V"+u*s:"M"+x+","+l+"H"+k),S.attr("opacity",1).attr("transform",function(B){return d(T(B)+l)}),L.attr(h+"2",u*a),v.attr(h,u*y).text(_),C.filter(SI).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor",t===Cu?"start":t===Sl?"end":"middle"),C.each(function(){this.__axis=T})}return f.scale=function(p){return arguments.length?(e=p,f):e},f.ticks=function(){return r=Array.from(arguments),f},f.tickArguments=function(p){return arguments.length?(r=p==null?[]:Array.from(p),f):r.slice()},f.tickValues=function(p){return arguments.length?(n=p==null?null:Array.from(p),f):n&&n.slice()},f.tickFormat=function(p){return arguments.length?(i=p,f):i},f.tickSize=function(p){return arguments.length?(a=s=+p,f):a},f.tickSizeInner=function(p){return arguments.length?(a=+p,f):a},f.tickSizeOuter=function(p){return arguments.length?(s=+p,f):s},f.tickPadding=function(p){return arguments.length?(o=+p,f):o},f.offset=function(p){return arguments.length?(l=+p,f):l},f}function X_(t){return Su(Eu,t)}function AI(t){return Su(Cu,t)}function K_(t){return Su($0,t)}function MI(t){return Su(Sl,t)}var LI={value:()=>{}};function fs(){for(var t=0,e=arguments.length,r={},n;t=0&&(n=r.slice(i+1),r=r.slice(0,i)),r&&!e.hasOwnProperty(r))throw new Error("unknown type: "+r);return{type:r,name:n}})}Au.prototype=fs.prototype={constructor:Au,on:function(t,e){var r=this._,n=RI(t+"",r),i,a=-1,s=n.length;if(arguments.length<2){for(;++a0)for(var r=new Array(i),n=0,i,a;n=0&&(e=t.slice(0,r))!=="xmlns"&&(t=t.slice(r+1)),K0.hasOwnProperty(e)?{space:K0[e],local:t}:t}function NI(t){return function(){var e=this.ownerDocument,r=this.namespaceURI;return r===X0&&e.documentElement.namespaceURI===X0?e.createElement(t):e.createElementNS(r,t)}}function BI(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}function Mu(t){var e=Al(t);return(e.local?BI:NI)(e)}function DI(){}function Lu(t){return t==null?DI:function(){return this.querySelector(t)}}function OI(t){typeof t!="function"&&(t=Lu(t));for(var e=this._groups,r=e.length,n=new Array(r),i=0;i=k&&(k=x+1);!(C=y[k])&&++k=0;)(s=n[i])&&(a&&s.compareDocumentPosition(a)^4&&a.parentNode.insertBefore(s,a),a=s);return this}function sN(t){t||(t=oN);function e(d,f){return d&&f?t(d.__data__,f.__data__):!d-!f}for(var r=this._groups,n=r.length,i=new Array(n),a=0;ae?1:t>=e?0:NaN}function lN(){var t=arguments[0];return arguments[0]=this,t.apply(null,arguments),this}function cN(){return Array.from(this)}function uN(){for(var t=this._groups,e=0,r=t.length;e1?this.each((e==null?xN:typeof e=="function"?wN:kN)(t,e,r==null?"":r)):ds(this.node(),t)}function ds(t,e){return t.style.getPropertyValue(e)||J0(t).getComputedStyle(t,null).getPropertyValue(e)}function EN(t){return function(){delete this[t]}}function CN(t,e){return function(){this[t]=e}}function SN(t,e){return function(){var r=e.apply(this,arguments);r==null?delete this[t]:this[t]=r}}function AN(t,e){return arguments.length>1?this.each((e==null?EN:typeof e=="function"?SN:CN)(t,e)):this.node()[t]}function e5(t){return t.trim().split(/^|\s+/)}function td(t){return t.classList||new r5(t)}function r5(t){this._node=t,this._names=e5(t.getAttribute("class")||"")}r5.prototype={add:function(t){var e=this._names.indexOf(t);e<0&&(this._names.push(t),this._node.setAttribute("class",this._names.join(" ")))},remove:function(t){var e=this._names.indexOf(t);e>=0&&(this._names.splice(e,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};function n5(t,e){for(var r=td(t),n=-1,i=e.length;++n=0&&(r=e.slice(n+1),e=e.slice(0,n)),{type:e,name:r}})}function rB(t){return function(){var e=this.__on;if(!!e){for(var r=0,n=-1,i=e.length,a;rTn(r,e))}function Iu(t){return typeof t=="string"?new $r([document.querySelectorAll(t)],[document.documentElement]):new $r([Q_(t)],ed)}const dB={passive:!1},Ml={capture:!0,passive:!1};function nd(t){t.stopImmediatePropagation()}function co(t){t.preventDefault(),t.stopImmediatePropagation()}function Nu(t){var e=t.document.documentElement,r=St(t).on("dragstart.drag",co,Ml);"onselectstart"in e?r.on("selectstart.drag",co,Ml):(e.__noselect=e.style.MozUserSelect,e.style.MozUserSelect="none")}function Bu(t,e){var r=t.document.documentElement,n=St(t).on("dragstart.drag",null);e&&(n.on("click.drag",co,Ml),setTimeout(function(){n.on("click.drag",null)},0)),"onselectstart"in r?n.on("selectstart.drag",null):(r.style.MozUserSelect=r.__noselect,delete r.__noselect)}const Du=t=>()=>t;function id(t,{sourceEvent:e,subject:r,target:n,identifier:i,active:a,x:s,y:o,dx:l,dy:u,dispatch:h}){Object.defineProperties(this,{type:{value:t,enumerable:!0,configurable:!0},sourceEvent:{value:e,enumerable:!0,configurable:!0},subject:{value:r,enumerable:!0,configurable:!0},target:{value:n,enumerable:!0,configurable:!0},identifier:{value:i,enumerable:!0,configurable:!0},active:{value:a,enumerable:!0,configurable:!0},x:{value:s,enumerable:!0,configurable:!0},y:{value:o,enumerable:!0,configurable:!0},dx:{value:l,enumerable:!0,configurable:!0},dy:{value:u,enumerable:!0,configurable:!0},_:{value:h}})}id.prototype.on=function(){var t=this._.on.apply(this._,arguments);return t===this._?this:t};function pB(t){return!t.ctrlKey&&!t.button}function gB(){return this.parentNode}function yB(t,e){return e==null?{x:t.x,y:t.y}:e}function mB(){return navigator.maxTouchPoints||"ontouchstart"in this}function bB(){var t=pB,e=gB,r=yB,n=mB,i={},a=fs("start","drag","end"),s=0,o,l,u,h,d=0;function f(T){T.on("mousedown.drag",p).filter(n).on("touchstart.drag",y).on("touchmove.drag",b,dB).on("touchend.drag touchcancel.drag",x).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function p(T,C){if(!(h||!t.call(this,T,C))){var M=k(this,e.call(this,T,C),T,C,"mouse");!M||(St(T.view).on("mousemove.drag",m,Ml).on("mouseup.drag",_,Ml),Nu(T.view),nd(T),u=!1,o=T.clientX,l=T.clientY,M("start",T))}}function m(T){if(co(T),!u){var C=T.clientX-o,M=T.clientY-l;u=C*C+M*M>d}i.mouse("drag",T)}function _(T){St(T.view).on("mousemove.drag mouseup.drag",null),Bu(T.view,u),co(T),i.mouse("end",T)}function y(T,C){if(!!t.call(this,T,C)){var M=T.changedTouches,S=e.call(this,T,C),R=M.length,A,L;for(A=0;A>8&15|e>>4&240,e>>4&15|e&240,(e&15)<<4|e&15,1):r===8?Ou(e>>24&255,e>>16&255,e>>8&255,(e&255)/255):r===4?Ou(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|e&240,((e&15)<<4|e&15)/255):null):(e=vB.exec(t))?new Er(e[1],e[2],e[3],1):(e=xB.exec(t))?new Er(e[1]*255/100,e[2]*255/100,e[3]*255/100,1):(e=kB.exec(t))?Ou(e[1],e[2],e[3],e[4]):(e=wB.exec(t))?Ou(e[1]*255/100,e[2]*255/100,e[3]*255/100,e[4]):(e=TB.exec(t))?p5(e[1],e[2]/100,e[3]/100,1):(e=EB.exec(t))?p5(e[1],e[2]/100,e[3]/100,e[4]):l5.hasOwnProperty(t)?h5(l5[t]):t==="transparent"?new Er(NaN,NaN,NaN,0):null}function h5(t){return new Er(t>>16&255,t>>8&255,t&255,1)}function Ou(t,e,r,n){return n<=0&&(t=e=r=NaN),new Er(t,e,r,n)}function ad(t){return t instanceof Sa||(t=Aa(t)),t?(t=t.rgb(),new Er(t.r,t.g,t.b,t.opacity)):new Er}function po(t,e,r,n){return arguments.length===1?ad(t):new Er(t,e,r,n==null?1:n)}function Er(t,e,r,n){this.r=+t,this.g=+e,this.b=+r,this.opacity=+n}uo(Er,po,Ll(Sa,{brighter(t){return t=t==null?ho:Math.pow(ho,t),new Er(this.r*t,this.g*t,this.b*t,this.opacity)},darker(t){return t=t==null?gs:Math.pow(gs,t),new Er(this.r*t,this.g*t,this.b*t,this.opacity)},rgb(){return this},clamp(){return new Er(ys(this.r),ys(this.g),ys(this.b),Fu(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:f5,formatHex:f5,formatHex8:AB,formatRgb:d5,toString:d5}));function f5(){return`#${ms(this.r)}${ms(this.g)}${ms(this.b)}`}function AB(){return`#${ms(this.r)}${ms(this.g)}${ms(this.b)}${ms((isNaN(this.opacity)?1:this.opacity)*255)}`}function d5(){const t=Fu(this.opacity);return`${t===1?"rgb(":"rgba("}${ys(this.r)}, ${ys(this.g)}, ${ys(this.b)}${t===1?")":`, ${t})`}`}function Fu(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))}function ys(t){return Math.max(0,Math.min(255,Math.round(t)||0))}function ms(t){return t=ys(t),(t<16?"0":"")+t.toString(16)}function p5(t,e,r,n){return n<=0?t=e=r=NaN:r<=0||r>=1?t=e=NaN:e<=0&&(t=NaN),new Kn(t,e,r,n)}function g5(t){if(t instanceof Kn)return new Kn(t.h,t.s,t.l,t.opacity);if(t instanceof Sa||(t=Aa(t)),!t)return new Kn;if(t instanceof Kn)return t;t=t.rgb();var e=t.r/255,r=t.g/255,n=t.b/255,i=Math.min(e,r,n),a=Math.max(e,r,n),s=NaN,o=a-i,l=(a+i)/2;return o?(e===a?s=(r-n)/o+(r0&&l<1?0:s,new Kn(s,o,l,t.opacity)}function Pu(t,e,r,n){return arguments.length===1?g5(t):new Kn(t,e,r,n==null?1:n)}function Kn(t,e,r,n){this.h=+t,this.s=+e,this.l=+r,this.opacity=+n}uo(Kn,Pu,Ll(Sa,{brighter(t){return t=t==null?ho:Math.pow(ho,t),new Kn(this.h,this.s,this.l*t,this.opacity)},darker(t){return t=t==null?gs:Math.pow(gs,t),new Kn(this.h,this.s,this.l*t,this.opacity)},rgb(){var t=this.h%360+(this.h<0)*360,e=isNaN(t)||isNaN(this.s)?0:this.s,r=this.l,n=r+(r<.5?r:1-r)*e,i=2*r-n;return new Er(sd(t>=240?t-240:t+120,i,n),sd(t,i,n),sd(t<120?t+240:t-120,i,n),this.opacity)},clamp(){return new Kn(y5(this.h),qu(this.s),qu(this.l),Fu(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const t=Fu(this.opacity);return`${t===1?"hsl(":"hsla("}${y5(this.h)}, ${qu(this.s)*100}%, ${qu(this.l)*100}%${t===1?")":`, ${t})`}`}}));function y5(t){return t=(t||0)%360,t<0?t+360:t}function qu(t){return Math.max(0,Math.min(1,t||0))}function sd(t,e,r){return(t<60?e+(r-e)*t/60:t<180?r:t<240?e+(r-e)*(240-t)/60:e)*255}const m5=Math.PI/180,b5=180/Math.PI,Vu=18,_5=.96422,v5=1,x5=.82521,k5=4/29,go=6/29,w5=3*go*go,MB=go*go*go;function T5(t){if(t instanceof Zn)return new Zn(t.l,t.a,t.b,t.opacity);if(t instanceof Ti)return C5(t);t instanceof Er||(t=ad(t));var e=ud(t.r),r=ud(t.g),n=ud(t.b),i=od((.2225045*e+.7168786*r+.0606169*n)/v5),a,s;return e===r&&r===n?a=s=i:(a=od((.4360747*e+.3850649*r+.1430804*n)/_5),s=od((.0139322*e+.0971045*r+.7141733*n)/x5)),new Zn(116*i-16,500*(a-i),200*(i-s),t.opacity)}function LB(t,e){return new Zn(t,0,0,e==null?1:e)}function zu(t,e,r,n){return arguments.length===1?T5(t):new Zn(t,e,r,n==null?1:n)}function Zn(t,e,r,n){this.l=+t,this.a=+e,this.b=+r,this.opacity=+n}uo(Zn,zu,Ll(Sa,{brighter(t){return new Zn(this.l+Vu*(t==null?1:t),this.a,this.b,this.opacity)},darker(t){return new Zn(this.l-Vu*(t==null?1:t),this.a,this.b,this.opacity)},rgb(){var t=(this.l+16)/116,e=isNaN(this.a)?t:t+this.a/500,r=isNaN(this.b)?t:t-this.b/200;return e=_5*ld(e),t=v5*ld(t),r=x5*ld(r),new Er(cd(3.1338561*e-1.6168667*t-.4906146*r),cd(-.9787684*e+1.9161415*t+.033454*r),cd(.0719453*e-.2289914*t+1.4052427*r),this.opacity)}}));function od(t){return t>MB?Math.pow(t,1/3):t/w5+k5}function ld(t){return t>go?t*t*t:w5*(t-k5)}function cd(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function ud(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function E5(t){if(t instanceof Ti)return new Ti(t.h,t.c,t.l,t.opacity);if(t instanceof Zn||(t=T5(t)),t.a===0&&t.b===0)return new Ti(NaN,0=1?(r=1,e-1):Math.floor(r*e),i=t[n],a=t[n+1],s=n>0?t[n-1]:2*i-a,o=n()=>t;function B5(t,e){return function(r){return t+r*e}}function NB(t,e,r){return t=Math.pow(t,r),e=Math.pow(e,r)-t,r=1/r,function(n){return Math.pow(t+n*e,r)}}function Hu(t,e){var r=e-t;return r?B5(t,r>180||r<-180?r-360*Math.round(r/360):r):Wu(isNaN(t)?e:t)}function BB(t){return(t=+t)==1?Cr:function(e,r){return r-e?NB(e,r,t):Wu(isNaN(e)?r:e)}}function Cr(t,e){var r=e-t;return r?B5(t,r):Wu(isNaN(t)?e:t)}const Nl=function t(e){var r=BB(e);function n(i,a){var s=r((i=po(i)).r,(a=po(a)).r),o=r(i.g,a.g),l=r(i.b,a.b),u=Cr(i.opacity,a.opacity);return function(h){return i.r=s(h),i.g=o(h),i.b=l(h),i.opacity=u(h),i+""}}return n.gamma=t,n}(1);function D5(t){return function(e){var r=e.length,n=new Array(r),i=new Array(r),a=new Array(r),s,o;for(s=0;sr&&(a=e.slice(r,a),o[s]?o[s]+=a:o[++s]=a),(n=n[0])===(i=i[0])?o[s]?o[s]+=i:o[++s]=i:(o[++s]=null,l.push({i:s,x:Bn(n,i)})),r=gd.lastIndex;return r180?h+=360:h-u>180&&(u+=360),f.push({i:d.push(i(d)+"rotate(",null,n)-2,x:Bn(u,h)})):h&&d.push(i(d)+"rotate("+h+n)}function o(u,h,d,f){u!==h?f.push({i:d.push(i(d)+"skewX(",null,n)-2,x:Bn(u,h)}):h&&d.push(i(d)+"skewX("+h+n)}function l(u,h,d,f,p,m){if(u!==d||h!==f){var _=p.push(i(p)+"scale(",null,",",null,")");m.push({i:_-4,x:Bn(u,d)},{i:_-2,x:Bn(h,f)})}else(d!==1||f!==1)&&p.push(i(p)+"scale("+d+","+f+")")}return function(u,h){var d=[],f=[];return u=t(u),h=t(h),a(u.translateX,u.translateY,h.translateX,h.translateY,d,f),s(u.rotate,h.rotate,d,f),o(u.skewX,h.skewX,d,f),l(u.scaleX,u.scaleY,h.scaleX,h.scaleY,d,f),u=h=null,function(p){for(var m=-1,_=f.length,y;++m<_;)d[(y=f[m]).i]=y.x(p);return d.join("")}}}var W5=U5(zB,"px, ","px)","deg)"),H5=U5(YB,", ",")",")"),UB=1e-12;function G5(t){return((t=Math.exp(t))+1/t)/2}function WB(t){return((t=Math.exp(t))-1/t)/2}function HB(t){return((t=Math.exp(2*t))-1)/(t+1)}const j5=function t(e,r,n){function i(a,s){var o=a[0],l=a[1],u=a[2],h=s[0],d=s[1],f=s[2],p=h-o,m=d-l,_=p*p+m*m,y,b;if(_=0&&t._call.call(void 0,e),t=t._next;--yo}function rv(){_s=(Ku=Fl.now())+Zu,yo=Bl=0;try{ev()}finally{yo=0,tD(),_s=0}}function JB(){var t=Fl.now(),e=t-Ku;e>J5&&(Zu-=e,Ku=t)}function tD(){for(var t,e=Xu,r,n=1/0;e;)e._call?(n>e._time&&(n=e._time),t=e,e=e._next):(r=e._next,e._next=null,e=t?t._next=r:Xu=r);Ol=t,bd(n)}function bd(t){if(!yo){Bl&&(Bl=clearTimeout(Bl));var e=t-_s;e>24?(t<1/0&&(Bl=setTimeout(rv,t-Fl.now()-Zu)),Dl&&(Dl=clearInterval(Dl))):(Dl||(Ku=Fl.now(),Dl=setInterval(JB,J5)),yo=1,tv(rv))}}function _d(t,e,r){var n=new ql;return e=e==null?0:+e,n.restart(i=>{n.stop(),t(i+e)},e,r),n}function eD(t,e,r){var n=new ql,i=e;return e==null?(n.restart(t,e,r),n):(n._restart=n.restart,n.restart=function(a,s,o){s=+s,o=o==null?Pl():+o,n._restart(function l(u){u+=i,n._restart(l,i+=s,o),a(u)},s,o)},n.restart(t,e,r),n)}var rD=fs("start","end","cancel","interrupt"),nD=[],nv=0,vd=1,xd=2,Ju=3,iv=4,kd=5,th=6;function eh(t,e,r,n,i,a){var s=t.__transition;if(!s)t.__transition={};else if(r in s)return;iD(t,r,{name:e,index:n,group:i,on:rD,tween:nD,time:a.time,delay:a.delay,duration:a.duration,ease:a.ease,timer:null,state:nv})}function wd(t,e){var r=Jn(t,e);if(r.state>nv)throw new Error("too late; already scheduled");return r}function Ei(t,e){var r=Jn(t,e);if(r.state>Ju)throw new Error("too late; already running");return r}function Jn(t,e){var r=t.__transition;if(!r||!(r=r[e]))throw new Error("transition not found");return r}function iD(t,e,r){var n=t.__transition,i;n[e]=r,r.timer=Qu(a,0,r.time);function a(u){r.state=vd,r.timer.restart(s,r.delay,r.time),r.delay<=u&&s(u-r.delay)}function s(u){var h,d,f,p;if(r.state!==vd)return l();for(h in n)if(p=n[h],p.name===r.name){if(p.state===Ju)return _d(s);p.state===iv?(p.state=th,p.timer.stop(),p.on.call("interrupt",t,t.__data__,p.index,p.group),delete n[h]):+hxd&&n.state=0&&(e=e.slice(0,r)),!e||e==="start"})}function BD(t,e,r){var n,i,a=ND(e)?wd:Ei;return function(){var s=a(this,t),o=s.on;o!==n&&(i=(n=o).copy()).on(e,r),s.on=i}}function DD(t,e){var r=this._id;return arguments.length<2?Jn(this.node(),r).on.on(t):this.each(BD(r,t,e))}function OD(t){return function(){var e=this.parentNode;for(var r in this.__transition)if(+r!==t)return;e&&e.removeChild(this)}}function FD(){return this.on("end.remove",OD(this._id))}function PD(t){var e=this._name,r=this._id;typeof t!="function"&&(t=Lu(t));for(var n=this._groups,i=n.length,a=new Array(i),s=0;s+t;function sO(t){return t*t}function oO(t){return t*(2-t)}function cv(t){return((t*=2)<=1?t*t:--t*(2-t)+1)/2}function lO(t){return t*t*t}function cO(t){return--t*t*t+1}function Ed(t){return((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2}var Cd=3,uO=function t(e){e=+e;function r(n){return Math.pow(n,e)}return r.exponent=t,r}(Cd),hO=function t(e){e=+e;function r(n){return 1-Math.pow(1-n,e)}return r.exponent=t,r}(Cd),uv=function t(e){e=+e;function r(n){return((n*=2)<=1?Math.pow(n,e):2-Math.pow(2-n,e))/2}return r.exponent=t,r}(Cd),hv=Math.PI,fv=hv/2;function fO(t){return+t==1?1:1-Math.cos(t*fv)}function dO(t){return Math.sin(t*fv)}function dv(t){return(1-Math.cos(hv*t))/2}function La(t){return(Math.pow(2,-10*t)-.0009765625)*1.0009775171065494}function pO(t){return La(1-+t)}function gO(t){return 1-La(t)}function pv(t){return((t*=2)<=1?La(1-t):2-La(t-1))/2}function yO(t){return 1-Math.sqrt(1-t*t)}function mO(t){return Math.sqrt(1- --t*t)}function gv(t){return((t*=2)<=1?1-Math.sqrt(1-t*t):Math.sqrt(1-(t-=2)*t)+1)/2}var Sd=4/11,bO=6/11,_O=8/11,vO=3/4,xO=9/11,kO=10/11,wO=15/16,TO=21/22,EO=63/64,rh=1/Sd/Sd;function CO(t){return 1-Vl(1-t)}function Vl(t){return(t=+t)vd&&n.name===e)return new Ci([[t]],DO,e,+i)}return null}const Rd=t=>()=>t;function FO(t,{sourceEvent:e,target:r,selection:n,mode:i,dispatch:a}){Object.defineProperties(this,{type:{value:t,enumerable:!0,configurable:!0},sourceEvent:{value:e,enumerable:!0,configurable:!0},target:{value:r,enumerable:!0,configurable:!0},selection:{value:n,enumerable:!0,configurable:!0},mode:{value:i,enumerable:!0,configurable:!0},_:{value:a}})}function PO(t){t.stopImmediatePropagation()}function Id(t){t.preventDefault(),t.stopImmediatePropagation()}var bv={name:"drag"},Nd={name:"space"},bo={name:"handle"},_o={name:"center"};const{abs:_v,max:Or,min:Fr}=Math;function vv(t){return[+t[0],+t[1]]}function Bd(t){return[vv(t[0]),vv(t[1])]}var nh={name:"x",handles:["w","e"].map(zl),input:function(t,e){return t==null?null:[[+t[0],e[0][1]],[+t[1],e[1][1]]]},output:function(t){return t&&[t[0][0],t[1][0]]}},ih={name:"y",handles:["n","s"].map(zl),input:function(t,e){return t==null?null:[[e[0][0],+t[0]],[e[1][0],+t[1]]]},output:function(t){return t&&[t[0][1],t[1][1]]}},qO={name:"xy",handles:["n","w","e","s","nw","ne","sw","se"].map(zl),input:function(t){return t==null?null:Bd(t)},output:function(t){return t}},Xi={overlay:"crosshair",selection:"move",n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},xv={e:"w",w:"e",nw:"ne",ne:"nw",se:"sw",sw:"se"},kv={n:"s",s:"n",nw:"sw",ne:"se",se:"ne",sw:"nw"},VO={overlay:1,selection:1,n:null,e:1,s:null,w:-1,nw:-1,ne:1,se:1,sw:-1},zO={overlay:1,selection:1,n:-1,e:null,s:1,w:null,nw:-1,ne:-1,se:1,sw:1};function zl(t){return{type:t}}function YO(t){return!t.ctrlKey&&!t.button}function UO(){var t=this.ownerSVGElement||this;return t.hasAttribute("viewBox")?(t=t.viewBox.baseVal,[[t.x,t.y],[t.x+t.width,t.y+t.height]]):[[0,0],[t.width.baseVal.value,t.height.baseVal.value]]}function WO(){return navigator.maxTouchPoints||"ontouchstart"in this}function Dd(t){for(;!t.__brush;)if(!(t=t.parentNode))return;return t.__brush}function HO(t){return t[0][0]===t[1][0]||t[0][1]===t[1][1]}function GO(t){var e=t.__brush;return e?e.dim.output(e.selection):null}function jO(){return Od(nh)}function $O(){return Od(ih)}function XO(){return Od(qO)}function Od(t){var e=UO,r=YO,n=WO,i=!0,a=fs("start","brush","end"),s=6,o;function l(y){var b=y.property("__brush",_).selectAll(".overlay").data([zl("overlay")]);b.enter().append("rect").attr("class","overlay").attr("pointer-events","all").attr("cursor",Xi.overlay).merge(b).each(function(){var k=Dd(this).extent;St(this).attr("x",k[0][0]).attr("y",k[0][1]).attr("width",k[1][0]-k[0][0]).attr("height",k[1][1]-k[0][1])}),y.selectAll(".selection").data([zl("selection")]).enter().append("rect").attr("class","selection").attr("cursor",Xi.selection).attr("fill","#777").attr("fill-opacity",.3).attr("stroke","#fff").attr("shape-rendering","crispEdges");var x=y.selectAll(".handle").data(t.handles,function(k){return k.type});x.exit().remove(),x.enter().append("rect").attr("class",function(k){return"handle handle--"+k.type}).attr("cursor",function(k){return Xi[k.type]}),y.each(u).attr("fill","none").attr("pointer-events","all").on("mousedown.brush",f).filter(n).on("touchstart.brush",f).on("touchmove.brush",p).on("touchend.brush touchcancel.brush",m).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}l.move=function(y,b,x){y.tween?y.on("start.brush",function(k){h(this,arguments).beforestart().start(k)}).on("interrupt.brush end.brush",function(k){h(this,arguments).end(k)}).tween("brush",function(){var k=this,T=k.__brush,C=h(k,arguments),M=T.selection,S=t.input(typeof b=="function"?b.apply(this,arguments):b,T.extent),R=Ma(M,S);function A(L){T.selection=L===1&&S===null?null:R(L),u.call(k),C.brush()}return M!==null&&S!==null?A:A(1)}):y.each(function(){var k=this,T=arguments,C=k.__brush,M=t.input(typeof b=="function"?b.apply(k,T):b,C.extent),S=h(k,T).beforestart();vs(k),C.selection=M===null?null:M,u.call(k),S.start(x).brush(x).end(x)})},l.clear=function(y,b){l.move(y,null,b)};function u(){var y=St(this),b=Dd(this).selection;b?(y.selectAll(".selection").style("display",null).attr("x",b[0][0]).attr("y",b[0][1]).attr("width",b[1][0]-b[0][0]).attr("height",b[1][1]-b[0][1]),y.selectAll(".handle").style("display",null).attr("x",function(x){return x.type[x.type.length-1]==="e"?b[1][0]-s/2:b[0][0]-s/2}).attr("y",function(x){return x.type[0]==="s"?b[1][1]-s/2:b[0][1]-s/2}).attr("width",function(x){return x.type==="n"||x.type==="s"?b[1][0]-b[0][0]+s:s}).attr("height",function(x){return x.type==="e"||x.type==="w"?b[1][1]-b[0][1]+s:s})):y.selectAll(".selection,.handle").style("display","none").attr("x",null).attr("y",null).attr("width",null).attr("height",null)}function h(y,b,x){var k=y.__brush.emitter;return k&&(!x||!k.clean)?k:new d(y,b,x)}function d(y,b,x){this.that=y,this.args=b,this.state=y.__brush,this.active=0,this.clean=x}d.prototype={beforestart:function(){return++this.active===1&&(this.state.emitter=this,this.starting=!0),this},start:function(y,b){return this.starting?(this.starting=!1,this.emit("start",y,b)):this.emit("brush",y),this},brush:function(y,b){return this.emit("brush",y,b),this},end:function(y,b){return--this.active===0&&(delete this.state.emitter,this.emit("end",y,b)),this},emit:function(y,b,x){var k=St(this.that).datum();a.call(y,this.that,new FO(y,{sourceEvent:b,target:l,selection:t.output(this.state.selection),mode:x,dispatch:a}),k)}};function f(y){if(o&&!y.touches||!r.apply(this,arguments))return;var b=this,x=y.target.__data__.type,k=(i&&y.metaKey?x="overlay":x)==="selection"?bv:i&&y.altKey?_o:bo,T=t===ih?null:VO[x],C=t===nh?null:zO[x],M=Dd(b),S=M.extent,R=M.selection,A=S[0][0],L,v,B=S[0][1],w,D,N=S[1][0],z,X,ct=S[1][1],J,Y,$=0,lt=0,ut,W=T&&C&&i&&y.shiftKey,tt,K,it=Array.from(y.touches||[y],at=>{const It=at.identifier;return at=Tn(at,b),at.point0=at.slice(),at.identifier=It,at});vs(b);var Z=h(b,arguments,!0).beforestart();if(x==="overlay"){R&&(ut=!0);const at=[it[0],it[1]||it[0]];M.selection=R=[[L=t===ih?A:Fr(at[0][0],at[1][0]),w=t===nh?B:Fr(at[0][1],at[1][1])],[z=t===ih?N:Or(at[0][0],at[1][0]),J=t===nh?ct:Or(at[0][1],at[1][1])]],it.length>1&&F(y)}else L=R[0][0],w=R[0][1],z=R[1][0],J=R[1][1];v=L,D=w,X=z,Y=J;var V=St(b).attr("pointer-events","none"),Q=V.selectAll(".overlay").attr("cursor",Xi[x]);if(y.touches)Z.moved=U,Z.ended=j;else{var q=St(y.view).on("mousemove.brush",U,!0).on("mouseup.brush",j,!0);i&&q.on("keydown.brush",P,!0).on("keyup.brush",et,!0),Nu(y.view)}u.call(b),Z.start(y,k.name);function U(at){for(const It of at.changedTouches||[at])for(const Lt of it)Lt.identifier===It.identifier&&(Lt.cur=Tn(It,b));if(W&&!tt&&!K&&it.length===1){const It=it[0];_v(It.cur[0]-It[0])>_v(It.cur[1]-It[1])?K=!0:tt=!0}for(const It of it)It.cur&&(It[0]=It.cur[0],It[1]=It.cur[1]);ut=!0,Id(at),F(at)}function F(at){const It=it[0],Lt=It.point0;var Rt;switch($=It[0]-Lt[0],lt=It[1]-Lt[1],k){case Nd:case bv:{T&&($=Or(A-L,Fr(N-z,$)),v=L+$,X=z+$),C&&(lt=Or(B-w,Fr(ct-J,lt)),D=w+lt,Y=J+lt);break}case bo:{it[1]?(T&&(v=Or(A,Fr(N,it[0][0])),X=Or(A,Fr(N,it[1][0])),T=1),C&&(D=Or(B,Fr(ct,it[0][1])),Y=Or(B,Fr(ct,it[1][1])),C=1)):(T<0?($=Or(A-L,Fr(N-L,$)),v=L+$,X=z):T>0&&($=Or(A-z,Fr(N-z,$)),v=L,X=z+$),C<0?(lt=Or(B-w,Fr(ct-w,lt)),D=w+lt,Y=J):C>0&&(lt=Or(B-J,Fr(ct-J,lt)),D=w,Y=J+lt));break}case _o:{T&&(v=Or(A,Fr(N,L-$*T)),X=Or(A,Fr(N,z+$*T))),C&&(D=Or(B,Fr(ct,w-lt*C)),Y=Or(B,Fr(ct,J+lt*C)));break}}X0&&(L=v-$),C<0?J=Y-lt:C>0&&(w=D-lt),k=Nd,Q.attr("cursor",Xi.selection),F(at));break}default:return}Id(at)}function et(at){switch(at.keyCode){case 16:{W&&(tt=K=W=!1,F(at));break}case 18:{k===_o&&(T<0?z=X:T>0&&(L=v),C<0?J=Y:C>0&&(w=D),k=bo,F(at));break}case 32:{k===Nd&&(at.altKey?(T&&(z=X-$*T,L=v+$*T),C&&(J=Y-lt*C,w=D+lt*C),k=_o):(T<0?z=X:T>0&&(L=v),C<0?J=Y:C>0&&(w=D),k=bo),Q.attr("cursor",Xi[x]),F(at));break}default:return}Id(at)}}function p(y){h(this,arguments).moved(y)}function m(y){h(this,arguments).ended(y)}function _(){var y=this.__brush||{selection:null};return y.extent=Bd(e.apply(this,arguments)),y.dim=t,y}return l.extent=function(y){return arguments.length?(e=typeof y=="function"?y:Rd(Bd(y)),l):e},l.filter=function(y){return arguments.length?(r=typeof y=="function"?y:Rd(!!y),l):r},l.touchable=function(y){return arguments.length?(n=typeof y=="function"?y:Rd(!!y),l):n},l.handleSize=function(y){return arguments.length?(s=+y,l):s},l.keyModifiers=function(y){return arguments.length?(i=!!y,l):i},l.on=function(){var y=a.on.apply(a,arguments);return y===a?l:y},l}var wv=Math.abs,vo=Math.cos,xo=Math.sin,Tv=Math.PI,ah=Tv/2,Ev=Tv*2,Cv=Math.max,Fd=1e-12;function Pd(t,e){return Array.from({length:e-t},(r,n)=>t+n)}function KO(t){return function(e,r){return t(e.source.value+e.target.value,r.source.value+r.target.value)}}function ZO(){return qd(!1,!1)}function QO(){return qd(!1,!0)}function JO(){return qd(!0,!1)}function qd(t,e){var r=0,n=null,i=null,a=null;function s(o){var l=o.length,u=new Array(l),h=Pd(0,l),d=new Array(l*l),f=new Array(l),p=0,m;o=Float64Array.from({length:l*l},e?(_,y)=>o[y%l][y/l|0]:(_,y)=>o[y/l|0][y%l]);for(let _=0;_n(u[y],u[b]));for(const y of h){const b=_;if(t){const x=Pd(~l+1,l).filter(k=>k<0?o[~k*l+y]:o[y*l+k]);i&&x.sort((k,T)=>i(k<0?-o[~k*l+y]:o[y*l+k],T<0?-o[~T*l+y]:o[y*l+T]));for(const k of x)if(k<0){const T=d[~k*l+y]||(d[~k*l+y]={source:null,target:null});T.target={index:y,startAngle:_,endAngle:_+=o[~k*l+y]*p,value:o[~k*l+y]}}else{const T=d[y*l+k]||(d[y*l+k]={source:null,target:null});T.source={index:y,startAngle:_,endAngle:_+=o[y*l+k]*p,value:o[y*l+k]}}f[y]={index:y,startAngle:b,endAngle:_,value:u[y]}}else{const x=Pd(0,l).filter(k=>o[y*l+k]||o[k*l+y]);i&&x.sort((k,T)=>i(o[y*l+k],o[y*l+T]));for(const k of x){let T;if(yxs)if(!(Math.abs(h*o-l*u)>xs)||!i)this._+="L"+(this._x1=t)+","+(this._y1=e);else{var f=r-a,p=n-s,m=o*o+l*l,_=f*f+p*p,y=Math.sqrt(m),b=Math.sqrt(d),x=i*Math.tan((Vd-Math.acos((m+d-_)/(2*y*b)))/2),k=x/b,T=x/y;Math.abs(k-1)>xs&&(this._+="L"+(t+k*u)+","+(e+k*h)),this._+="A"+i+","+i+",0,0,"+ +(h*f>u*p)+","+(this._x1=t+T*o)+","+(this._y1=e+T*l)}},arc:function(t,e,r,n,i,a){t=+t,e=+e,r=+r,a=!!a;var s=r*Math.cos(n),o=r*Math.sin(n),l=t+s,u=e+o,h=1^a,d=a?n-i:i-n;if(r<0)throw new Error("negative radius: "+r);this._x1===null?this._+="M"+l+","+u:(Math.abs(this._x1-l)>xs||Math.abs(this._y1-u)>xs)&&(this._+="L"+l+","+u),r&&(d<0&&(d=d%zd+zd),d>tF?this._+="A"+r+","+r+",0,1,"+h+","+(t-s)+","+(e-o)+"A"+r+","+r+",0,1,"+h+","+(this._x1=l)+","+(this._y1=u):d>xs&&(this._+="A"+r+","+r+",0,"+ +(d>=Vd)+","+h+","+(this._x1=t+r*Math.cos(i))+","+(this._y1=e+r*Math.sin(i))))},rect:function(t,e,r,n){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)+"h"+ +r+"v"+ +n+"h"+-r+"Z"},toString:function(){return this._}};var eF=Array.prototype.slice;function ks(t){return function(){return t}}function rF(t){return t.source}function nF(t){return t.target}function Sv(t){return t.radius}function iF(t){return t.startAngle}function aF(t){return t.endAngle}function sF(){return 0}function oF(){return 10}function Av(t){var e=rF,r=nF,n=Sv,i=Sv,a=iF,s=aF,o=sF,l=null;function u(){var h,d=e.apply(this,arguments),f=r.apply(this,arguments),p=o.apply(this,arguments)/2,m=eF.call(arguments),_=+n.apply(this,(m[0]=d,m)),y=a.apply(this,m)-ah,b=s.apply(this,m)-ah,x=+i.apply(this,(m[0]=f,m)),k=a.apply(this,m)-ah,T=s.apply(this,m)-ah;if(l||(l=h=Ra()),p>Fd&&(wv(b-y)>p*2+Fd?b>y?(y+=p,b-=p):(y-=p,b+=p):y=b=(y+b)/2,wv(T-k)>p*2+Fd?T>k?(k+=p,T-=p):(k-=p,T+=p):k=T=(k+T)/2),l.moveTo(_*vo(y),_*xo(y)),l.arc(0,0,_,y,b),y!==k||b!==T)if(t){var C=+t.apply(this,arguments),M=x-C,S=(k+T)/2;l.quadraticCurveTo(0,0,M*vo(k),M*xo(k)),l.lineTo(x*vo(S),x*xo(S)),l.lineTo(M*vo(T),M*xo(T))}else l.quadraticCurveTo(0,0,x*vo(k),x*xo(k)),l.arc(0,0,x,k,T);if(l.quadraticCurveTo(0,0,_*vo(y),_*xo(y)),l.closePath(),h)return l=null,h+""||null}return t&&(u.headRadius=function(h){return arguments.length?(t=typeof h=="function"?h:ks(+h),u):t}),u.radius=function(h){return arguments.length?(n=i=typeof h=="function"?h:ks(+h),u):n},u.sourceRadius=function(h){return arguments.length?(n=typeof h=="function"?h:ks(+h),u):n},u.targetRadius=function(h){return arguments.length?(i=typeof h=="function"?h:ks(+h),u):i},u.startAngle=function(h){return arguments.length?(a=typeof h=="function"?h:ks(+h),u):a},u.endAngle=function(h){return arguments.length?(s=typeof h=="function"?h:ks(+h),u):s},u.padAngle=function(h){return arguments.length?(o=typeof h=="function"?h:ks(+h),u):o},u.source=function(h){return arguments.length?(e=h,u):e},u.target=function(h){return arguments.length?(r=h,u):r},u.context=function(h){return arguments.length?(l=h==null?null:h,u):l},u}function lF(){return Av()}function cF(){return Av(oF)}var uF=Array.prototype,Mv=uF.slice;function hF(t,e){return t-e}function fF(t){for(var e=0,r=t.length,n=t[r-1][1]*t[0][0]-t[r-1][0]*t[0][1];++e()=>t;function dF(t,e){for(var r=-1,n=e.length,i;++rn!=p>n&&r<(f-u)*(n-h)/(p-h)+u&&(i=-i)}return i}function gF(t,e,r){var n;return yF(t,e,r)&&mF(t[n=+(t[0]===e[0])],r[n],e[n])}function yF(t,e,r){return(e[0]-t[0])*(r[1]-t[1])===(r[0]-t[0])*(e[1]-t[1])}function mF(t,e,r){return t<=e&&e<=r||r<=e&&e<=t}function bF(){}var Ki=[[],[[[1,1.5],[.5,1]]],[[[1.5,1],[1,1.5]]],[[[1.5,1],[.5,1]]],[[[1,.5],[1.5,1]]],[[[1,1.5],[.5,1]],[[1,.5],[1.5,1]]],[[[1,.5],[1,1.5]]],[[[1,.5],[.5,1]]],[[[.5,1],[1,.5]]],[[[1,1.5],[1,.5]]],[[[.5,1],[1,.5]],[[1.5,1],[1,1.5]]],[[[1.5,1],[1,.5]]],[[[.5,1],[1.5,1]]],[[[1,1.5],[1.5,1]]],[[[.5,1],[1,1.5]]],[]];function Ud(){var t=1,e=1,r=W0,n=l;function i(u){var h=r(u);if(Array.isArray(h))h=h.slice().sort(hF);else{const d=xl(u),f=wl(d[0],d[1],h);h=hs(Math.floor(d[0]/f)*f,Math.floor(d[1]/f-1)*f,h)}return h.map(d=>a(u,d))}function a(u,h){var d=[],f=[];return s(u,h,function(p){n(p,u,h),fF(p)>0?d.push([p]):f.push(p)}),f.forEach(function(p){for(var m=0,_=d.length,y;m<_;++m)if(dF((y=d[m])[0],p)!==-1){y.push(p);return}}),{type:"MultiPolygon",value:h,coordinates:d}}function s(u,h,d){var f=new Array,p=new Array,m,_,y,b,x,k;for(m=_=-1,b=u[0]>=h,Ki[b<<1].forEach(T);++m=h,Ki[y|b<<1].forEach(T);for(Ki[b<<0].forEach(T);++_=h,x=u[_*t]>=h,Ki[b<<1|x<<2].forEach(T);++m=h,k=x,x=u[_*t+m+1]>=h,Ki[y|b<<1|x<<2|k<<3].forEach(T);Ki[b|x<<3].forEach(T)}for(m=-1,x=u[_*t]>=h,Ki[x<<2].forEach(T);++m=h,Ki[x<<2|k<<3].forEach(T);Ki[x<<3].forEach(T);function T(C){var M=[C[0][0]+m,C[0][1]+_],S=[C[1][0]+m,C[1][1]+_],R=o(M),A=o(S),L,v;(L=p[R])?(v=f[A])?(delete p[L.end],delete f[v.start],L===v?(L.ring.push(S),d(L.ring)):f[L.start]=p[v.end]={start:L.start,end:v.end,ring:L.ring.concat(v.ring)}):(delete p[L.end],L.ring.push(S),p[L.end=A]=L):(L=f[A])?(v=p[R])?(delete f[L.start],delete p[v.end],L===v?(L.ring.push(S),d(L.ring)):f[v.start]=p[L.end]={start:v.start,end:L.end,ring:v.ring.concat(L.ring)}):(delete f[L.start],L.ring.unshift(M),f[L.start=R]=L):f[R]=p[A]={start:R,end:A,ring:[M,S]}}}function o(u){return u[0]*2+u[1]*(t+1)*4}function l(u,h,d){u.forEach(function(f){var p=f[0],m=f[1],_=p|0,y=m|0,b,x=h[y*t+_];p>0&&p0&&m=0&&d>=0))throw new Error("invalid size");return t=h,e=d,i},i.thresholds=function(u){return arguments.length?(r=typeof u=="function"?u:Array.isArray(u)?Ia(Mv.call(u)):Ia(u),i):r},i.smooth=function(u){return arguments.length?(n=u?l:bF,i):n===l},i}function _F(t){return t[0]}function vF(t){return t[1]}function xF(){return 1}function kF(){var t=_F,e=vF,r=xF,n=960,i=500,a=20,s=2,o=a*3,l=n+o*2>>s,u=i+o*2>>s,h=Ia(20);function d(x){var k=new Float32Array(l*u),T=Math.pow(2,-s),C=-1;for(const w of x){var M=(t(w,++C,x)+o)*T,S=(e(w,C,x)+o)*T,R=+r(w,C,x);if(M>=0&&M=0&&SM*C))(k).map((M,S)=>(M.value=+T[S],p(M)))}f.contours=function(x){var k=d(x),T=Ud().size([l,u]),C=Math.pow(2,2*s),M=S=>{S=+S;var R=p(T.contour(k,S*C));return R.value=S,R};return Object.defineProperty(M,"max",{get:()=>lo(k)/C}),M};function p(x){return x.coordinates.forEach(m),x}function m(x){x.forEach(_)}function _(x){x.forEach(y)}function y(x){x[0]=x[0]*Math.pow(2,s)-o,x[1]=x[1]*Math.pow(2,s)-o}function b(){return o=a*3,l=n+o*2>>s,u=i+o*2>>s,f}return f.x=function(x){return arguments.length?(t=typeof x=="function"?x:Ia(+x),f):t},f.y=function(x){return arguments.length?(e=typeof x=="function"?x:Ia(+x),f):e},f.weight=function(x){return arguments.length?(r=typeof x=="function"?x:Ia(+x),f):r},f.size=function(x){if(!arguments.length)return[n,i];var k=+x[0],T=+x[1];if(!(k>=0&&T>=0))throw new Error("invalid size");return n=k,i=T,b()},f.cellSize=function(x){if(!arguments.length)return 1<=1))throw new Error("invalid cell size");return s=Math.floor(Math.log(x)/Math.LN2),b()},f.thresholds=function(x){return arguments.length?(h=typeof x=="function"?x:Array.isArray(x)?Ia(Mv.call(x)):Ia(x),f):h},f.bandwidth=function(x){if(!arguments.length)return Math.sqrt(a*(a+1));if(!((x=+x)>=0))throw new Error("invalid bandwidth");return a=(Math.sqrt(4*x*x+1)-1)/2,b()},f}const Zi=11102230246251565e-32,Pr=134217729,wF=(3+8*Zi)*Zi;function Wd(t,e,r,n,i){let a,s,o,l,u=e[0],h=n[0],d=0,f=0;h>u==h>-u?(a=u,u=e[++d]):(a=h,h=n[++f]);let p=0;if(du==h>-u?(s=u+a,o=a-(s-u),u=e[++d]):(s=h+a,o=a-(s-h),h=n[++f]),a=s,o!==0&&(i[p++]=o);du==h>-u?(s=a+u,l=s-a,o=a-(s-l)+(u-l),u=e[++d]):(s=a+h,l=s-a,o=a-(s-l)+(h-l),h=n[++f]),a=s,o!==0&&(i[p++]=o);for(;d=D||-w>=D||(d=t-A,o=t-(A+d)+(d-i),d=r-L,u=r-(L+d)+(d-i),d=e-v,l=e-(v+d)+(d-a),d=n-B,h=n-(B+d)+(d-a),o===0&&l===0&&u===0&&h===0)||(D=SF*s+wF*Math.abs(w),w+=A*h+B*o-(v*u+L*l),w>=D||-w>=D))return w;T=o*B,f=Pr*o,p=f-(f-o),m=o-p,f=Pr*B,_=f-(f-B),y=B-_,C=m*y-(T-p*_-m*_-p*y),M=l*L,f=Pr*l,p=f-(f-l),m=l-p,f=Pr*L,_=f-(f-L),y=L-_,S=m*y-(M-p*_-m*_-p*y),b=C-S,d=C-b,Xr[0]=C-(b+d)+(d-S),x=T+b,d=x-T,k=T-(x-d)+(b-d),b=k-M,d=k-b,Xr[1]=k-(b+d)+(d-M),R=x+b,d=R-x,Xr[2]=x-(R-d)+(b-d),Xr[3]=R;const N=Wd(4,ko,4,Xr,Lv);T=A*h,f=Pr*A,p=f-(f-A),m=A-p,f=Pr*h,_=f-(f-h),y=h-_,C=m*y-(T-p*_-m*_-p*y),M=v*u,f=Pr*v,p=f-(f-v),m=v-p,f=Pr*u,_=f-(f-u),y=u-_,S=m*y-(M-p*_-m*_-p*y),b=C-S,d=C-b,Xr[0]=C-(b+d)+(d-S),x=T+b,d=x-T,k=T-(x-d)+(b-d),b=k-M,d=k-b,Xr[1]=k-(b+d)+(d-M),R=x+b,d=R-x,Xr[2]=x-(R-d)+(b-d),Xr[3]=R;const z=Wd(N,Lv,4,Xr,Rv);T=o*h,f=Pr*o,p=f-(f-o),m=o-p,f=Pr*h,_=f-(f-h),y=h-_,C=m*y-(T-p*_-m*_-p*y),M=l*u,f=Pr*l,p=f-(f-l),m=l-p,f=Pr*u,_=f-(f-u),y=u-_,S=m*y-(M-p*_-m*_-p*y),b=C-S,d=C-b,Xr[0]=C-(b+d)+(d-S),x=T+b,d=x-T,k=T-(x-d)+(b-d),b=k-M,d=k-b,Xr[1]=k-(b+d)+(d-M),R=x+b,d=R-x,Xr[2]=x-(R-d)+(b-d),Xr[3]=R;const X=Wd(z,Rv,4,Xr,Iv);return Iv[X-1]}function sh(t,e,r,n,i,a){const s=(e-a)*(r-i),o=(t-i)*(n-a),l=s-o;if(s===0||o===0||s>0!=o>0)return l;const u=Math.abs(s+o);return Math.abs(l)>=EF*u?l:-AF(t,e,r,n,i,a,u)}const Nv=Math.pow(2,-52),oh=new Uint32Array(512);class lh{static from(e,r=NF,n=BF){const i=e.length,a=new Float64Array(i*2);for(let s=0;s>1;if(r>0&&typeof e[0]!="number")throw new Error("Expected coords to contain numbers.");this.coords=e;const n=Math.max(2*r-5,0);this._triangles=new Uint32Array(n*3),this._halfedges=new Int32Array(n*3),this._hashSize=Math.ceil(Math.sqrt(r)),this._hullPrev=new Uint32Array(r),this._hullNext=new Uint32Array(r),this._hullTri=new Uint32Array(r),this._hullHash=new Int32Array(this._hashSize).fill(-1),this._ids=new Uint32Array(r),this._dists=new Float64Array(r),this.update()}update(){const{coords:e,_hullPrev:r,_hullNext:n,_hullTri:i,_hullHash:a}=this,s=e.length>>1;let o=1/0,l=1/0,u=-1/0,h=-1/0;for(let L=0;Lu&&(u=v),B>h&&(h=B),this._ids[L]=L}const d=(o+u)/2,f=(l+h)/2;let p=1/0,m,_,y;for(let L=0;L0&&(_=L,p=v)}let k=e[2*_],T=e[2*_+1],C=1/0;for(let L=0;Lw&&(L[v++]=D,w=this._dists[D])}this.hull=L.subarray(0,v),this.triangles=new Uint32Array(0),this.halfedges=new Uint32Array(0);return}if(sh(b,x,k,T,M,S)<0){const L=_,v=k,B=T;_=y,k=M,T=S,y=L,M=v,S=B}const R=IF(b,x,k,T,M,S);this._cx=R.x,this._cy=R.y;for(let L=0;L0&&Math.abs(D-v)<=Nv&&Math.abs(N-B)<=Nv||(v=D,B=N,w===m||w===_||w===y))continue;let z=0;for(let $=0,lt=this._hashKey(D,N);$=0;)if(X=ct,X===z){X=-1;break}if(X===-1)continue;let J=this._addTriangle(X,w,n[X],-1,-1,i[X]);i[w]=this._legalize(J+2),i[X]=J,A++;let Y=n[X];for(;ct=n[Y],sh(D,N,e[2*Y],e[2*Y+1],e[2*ct],e[2*ct+1])<0;)J=this._addTriangle(Y,w,ct,i[w],-1,i[Y]),i[w]=this._legalize(J+2),n[Y]=Y,A--,Y=ct;if(X===z)for(;ct=r[X],sh(D,N,e[2*ct],e[2*ct+1],e[2*X],e[2*X+1])<0;)J=this._addTriangle(ct,w,X,-1,i[X],i[ct]),this._legalize(J+2),i[ct]=J,n[X]=X,A--,X=ct;this._hullStart=r[w]=X,n[X]=r[Y]=w,n[w]=Y,a[this._hashKey(D,N)]=w,a[this._hashKey(e[2*X],e[2*X+1])]=X}this.hull=new Uint32Array(A);for(let L=0,v=this._hullStart;L0?3-r:1+r)/4}function Hd(t,e,r,n){const i=t-r,a=e-n;return i*i+a*a}function LF(t,e,r,n,i,a,s,o){const l=t-s,u=e-o,h=r-s,d=n-o,f=i-s,p=a-o,m=l*l+u*u,_=h*h+d*d,y=f*f+p*p;return l*(d*y-_*p)-u*(h*y-_*f)+m*(h*p-d*f)<0}function RF(t,e,r,n,i,a){const s=r-t,o=n-e,l=i-t,u=a-e,h=s*s+o*o,d=l*l+u*u,f=.5/(s*u-o*l),p=(u*h-o*d)*f,m=(s*d-l*h)*f;return p*p+m*m}function IF(t,e,r,n,i,a){const s=r-t,o=n-e,l=i-t,u=a-e,h=s*s+o*o,d=l*l+u*u,f=.5/(s*u-o*l),p=t+(u*h-o*d)*f,m=e+(s*d-l*h)*f;return{x:p,y:m}}function wo(t,e,r,n){if(n-r<=20)for(let i=r+1;i<=n;i++){const a=t[i],s=e[a];let o=i-1;for(;o>=r&&e[t[o]]>s;)t[o+1]=t[o--];t[o+1]=a}else{const i=r+n>>1;let a=r+1,s=n;Ul(t,i,a),e[t[r]]>e[t[n]]&&Ul(t,r,n),e[t[a]]>e[t[n]]&&Ul(t,a,n),e[t[r]]>e[t[a]]&&Ul(t,r,a);const o=t[a],l=e[o];for(;;){do a++;while(e[t[a]]l);if(s=s-r?(wo(t,e,a,n),wo(t,e,r,s-1)):(wo(t,e,r,s-1),wo(t,e,a,n))}}function Ul(t,e,r){const n=t[e];t[e]=t[r],t[r]=n}function NF(t){return t[0]}function BF(t){return t[1]}const Bv=1e-6;class ws{constructor(){this._x0=this._y0=this._x1=this._y1=null,this._=""}moveTo(e,r){this._+=`M${this._x0=this._x1=+e},${this._y0=this._y1=+r}`}closePath(){this._x1!==null&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")}lineTo(e,r){this._+=`L${this._x1=+e},${this._y1=+r}`}arc(e,r,n){e=+e,r=+r,n=+n;const i=e+n,a=r;if(n<0)throw new Error("negative radius");this._x1===null?this._+=`M${i},${a}`:(Math.abs(this._x1-i)>Bv||Math.abs(this._y1-a)>Bv)&&(this._+="L"+i+","+a),n&&(this._+=`A${n},${n},0,1,1,${e-n},${r}A${n},${n},0,1,1,${this._x1=i},${this._y1=a}`)}rect(e,r,n,i){this._+=`M${this._x0=this._x1=+e},${this._y0=this._y1=+r}h${+n}v${+i}h${-n}Z`}value(){return this._||null}}class Gd{constructor(){this._=[]}moveTo(e,r){this._.push([e,r])}closePath(){this._.push(this._[0].slice())}lineTo(e,r){this._.push([e,r])}value(){return this._.length?this._:null}}class Dv{constructor(e,[r,n,i,a]=[0,0,960,500]){if(!((i=+i)>=(r=+r))||!((a=+a)>=(n=+n)))throw new Error("invalid bounds");this.delaunay=e,this._circumcenters=new Float64Array(e.points.length*2),this.vectors=new Float64Array(e.points.length*2),this.xmax=i,this.xmin=r,this.ymax=a,this.ymin=n,this._init()}update(){return this.delaunay.update(),this._init(),this}_init(){const{delaunay:{points:e,hull:r,triangles:n},vectors:i}=this,a=this.circumcenters=this._circumcenters.subarray(0,n.length/3*2);for(let p=0,m=0,_=n.length,y,b;p<_;p+=3,m+=2){const x=n[p]*2,k=n[p+1]*2,T=n[p+2]*2,C=e[x],M=e[x+1],S=e[k],R=e[k+1],A=e[T],L=e[T+1],v=S-C,B=R-M,w=A-C,D=L-M,N=(v*D-B*w)*2;if(Math.abs(N)<1e-9){let z=1e9;const X=n[0]*2;z*=Math.sign((e[X]-C)*D-(e[X+1]-M)*w),y=(C+A)/2-z*D,b=(M+L)/2+z*w}else{const z=1/N,X=v*v+B*B,ct=w*w+D*D;y=C+(D*X-B*ct)*z,b=M+(v*ct-w*X)*z}a[m]=y,a[m+1]=b}let s=r[r.length-1],o,l=s*4,u,h=e[2*s],d,f=e[2*s+1];i.fill(0);for(let p=0;p1;)a-=2;for(let s=2;s4)for(let s=0;s0){if(r>=this.ymax)return null;(s=(this.ymax-r)/i)0){if(e>=this.xmax)return null;(s=(this.xmax-e)/n)this.xmax?2:0)|(rthis.ymax?8:0)}}const DF=2*Math.PI,To=Math.pow;function OF(t){return t[0]}function FF(t){return t[1]}function PF(t){const{triangles:e,coords:r}=t;for(let n=0;n1e-10)return!1}return!0}function qF(t,e,r){return[t+Math.sin(t+e)*r,e+Math.cos(t-e)*r]}class jd{static from(e,r=OF,n=FF,i){return new jd("length"in e?VF(e,r,n,i):Float64Array.from(zF(e,r,n,i)))}constructor(e){this._delaunator=new lh(e),this.inedges=new Int32Array(e.length/2),this._hullIndex=new Int32Array(e.length/2),this.points=this._delaunator.coords,this._init()}update(){return this._delaunator.update(),this._init(),this}_init(){const e=this._delaunator,r=this.points;if(e.hull&&e.hull.length>2&&PF(e)){this.collinear=Int32Array.from({length:r.length/2},(f,p)=>p).sort((f,p)=>r[2*f]-r[2*p]||r[2*f+1]-r[2*p+1]);const l=this.collinear[0],u=this.collinear[this.collinear.length-1],h=[r[2*l],r[2*l+1],r[2*u],r[2*u+1]],d=1e-8*Math.hypot(h[3]-h[1],h[2]-h[0]);for(let f=0,p=r.length/2;f0&&(this.triangles=new Int32Array(3).fill(-1),this.halfedges=new Int32Array(3).fill(-1),this.triangles[0]=i[0],s[i[0]]=1,i.length===2&&(s[i[1]]=0,this.triangles[1]=i[1],this.triangles[2]=i[1]))}voronoi(e){return new Dv(this,e)}*neighbors(e){const{inedges:r,hull:n,_hullIndex:i,halfedges:a,triangles:s,collinear:o}=this;if(o){const d=o.indexOf(e);d>0&&(yield o[d-1]),d=0&&a!==n&&a!==i;)n=a;return a}_step(e,r,n){const{inedges:i,hull:a,_hullIndex:s,halfedges:o,triangles:l,points:u}=this;if(i[e]===-1||!u.length)return(e+1)%(u.length>>1);let h=e,d=To(r-u[e*2],2)+To(n-u[e*2+1],2);const f=i[e];let p=f;do{let m=l[p];const _=To(r-u[m*2],2)+To(n-u[m*2+1],2);if(_9999?"+"+dn(t,6):dn(t,4)}function WF(t){var e=t.getUTCHours(),r=t.getUTCMinutes(),n=t.getUTCSeconds(),i=t.getUTCMilliseconds();return isNaN(t)?"Invalid Date":UF(t.getUTCFullYear())+"-"+dn(t.getUTCMonth()+1,2)+"-"+dn(t.getUTCDate(),2)+(i?"T"+dn(e,2)+":"+dn(r,2)+":"+dn(n,2)+"."+dn(i,3)+"Z":n?"T"+dn(e,2)+":"+dn(r,2)+":"+dn(n,2)+"Z":r||e?"T"+dn(e,2)+":"+dn(r,2)+"Z":"")}function ch(t){var e=new RegExp('["'+t+` +\r]`),r=t.charCodeAt(0);function n(d,f){var p,m,_=i(d,function(y,b){if(p)return p(y,b-1);m=y,p=f?YF(y,f):Fv(y)});return _.columns=m||[],_}function i(d,f){var p=[],m=d.length,_=0,y=0,b,x=m<=0,k=!1;d.charCodeAt(m-1)===Wl&&--m,d.charCodeAt(m-1)===Kd&&--m;function T(){if(x)return $d;if(k)return k=!1,Ov;var M,S=_,R;if(d.charCodeAt(S)===Xd){for(;_++=m?x=!0:(R=d.charCodeAt(_++))===Wl?k=!0:R===Kd&&(k=!0,d.charCodeAt(_)===Wl&&++_),d.slice(S+1,M-1).replace(/""/g,'"')}for(;_uh(e,r).then(n=>new DOMParser().parseFromString(n,t))}const yP=Zd("application/xml");var mP=Zd("text/html"),bP=Zd("image/svg+xml");function _P(t,e){var r,n=1;t==null&&(t=0),e==null&&(e=0);function i(){var a,s=r.length,o,l=0,u=0;for(a=0;a=(d=(o+u)/2))?o=d:u=d,(y=r>=(f=(l+h)/2))?l=f:h=f,i=a,!(a=a[b=y<<1|_]))return i[b]=s,t;if(p=+t._x.call(null,a.data),m=+t._y.call(null,a.data),e===p&&r===m)return s.next=a,i?i[b]=s:t._root=s,t;do i=i?i[b]=new Array(4):t._root=new Array(4),(_=e>=(d=(o+u)/2))?o=d:u=d,(y=r>=(f=(l+h)/2))?l=f:h=f;while((b=y<<1|_)===(x=(m>=f)<<1|p>=d));return i[x]=a,i[b]=s,t}function xP(t){var e,r,n=t.length,i,a,s=new Array(n),o=new Array(n),l=1/0,u=1/0,h=-1/0,d=-1/0;for(r=0;rh&&(h=i),ad&&(d=a));if(l>h||u>d)return this;for(this.cover(l,u).cover(h,d),r=0;rt||t>=i||n>e||e>=a;)switch(u=(eh||(o=m.y0)>d||(l=m.x1)=b)<<1|t>=y)&&(m=f[f.length-1],f[f.length-1]=f[f.length-1-_],f[f.length-1-_]=m)}else{var x=t-+this._x.call(null,p.data),k=e-+this._y.call(null,p.data),T=x*x+k*k;if(T=(f=(s+l)/2))?s=f:l=f,(_=d>=(p=(o+u)/2))?o=p:u=p,e=r,!(r=r[y=_<<1|m]))return this;if(!r.length)break;(e[y+1&3]||e[y+2&3]||e[y+3&3])&&(n=e,b=y)}for(;r.data!==t;)if(i=r,!(r=r.next))return this;return(a=r.next)&&delete r.next,i?(a?i.next=a:delete i.next,this):e?(a?e[y]=a:delete e[y],(r=e[0]||e[1]||e[2]||e[3])&&r===(e[3]||e[2]||e[1]||e[0])&&!r.length&&(n?n[b]=r:this._root=r),this):(this._root=a,this)}function SP(t){for(var e=0,r=t.length;ef.index){var v=p-R.x-R.vx,B=m-R.y-R.vy,w=v*v+B*B;wp+L||Mm+L||Su.r&&(u.r=u[h].r)}function l(){if(!!e){var u,h=e.length,d;for(r=new Array(h),u=0;u[e(C,M,s),C])),T;for(y=0,o=new Array(b);y(t=(zP*t+YP)%Hv)/Hv}function WP(t){return t.x}function HP(t){return t.y}var GP=10,jP=Math.PI*(3-Math.sqrt(5));function $P(t){var e,r=1,n=.001,i=1-Math.pow(n,1/300),a=0,s=.6,o=new Map,l=Qu(d),u=fs("tick","end"),h=UP();t==null&&(t=[]);function d(){f(),u.call("tick",e),r1?(y==null?o.delete(_):o.set(_,m(y)),e):o.get(_)},find:function(_,y,b){var x=0,k=t.length,T,C,M,S,R;for(b==null?b=1/0:b*=b,x=0;x1?(u.on(_,y),e):u.on(_)}}}function XP(){var t,e,r,n,i=vr(-30),a,s=1,o=1/0,l=.81;function u(p){var m,_=t.length,y=hh(t,WP,HP).visitAfter(d);for(n=p,m=0;m<_;++m)e=t[m],y.visit(f)}function h(){if(!!t){var p,m=t.length,_;for(a=new Array(m),p=0;p=o)return;(p.data!==e||p.next)&&(b===0&&(b=Na(r),T+=b*b),x===0&&(x=Na(r),T+=x*x),T=1e21?t.toLocaleString("en").replace(/,/g,""):t.toString(10)}function fh(t,e){if((r=(t=e?t.toExponential(e-1):t.toExponential()).indexOf("e"))<0)return null;var r,n=t.slice(0,r);return[n.length>1?n[0]+n.slice(2):n,+t.slice(r+1)]}function Eo(t){return t=fh(Math.abs(t)),t?t[1]:NaN}function tq(t,e){return function(r,n){for(var i=r.length,a=[],s=0,o=t[0],l=0;i>0&&o>0&&(l+o+1>n&&(o=Math.max(1,n-l)),a.push(r.substring(i-=o,i+o)),!((l+=o+1)>n));)o=t[s=(s+1)%t.length];return a.reverse().join(e)}}function eq(t){return function(e){return e.replace(/[0-9]/g,function(r){return t[+r]})}}var rq=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function Co(t){if(!(e=rq.exec(t)))throw new Error("invalid format: "+t);var e;return new dh({fill:e[1],align:e[2],sign:e[3],symbol:e[4],zero:e[5],width:e[6],comma:e[7],precision:e[8]&&e[8].slice(1),trim:e[9],type:e[10]})}Co.prototype=dh.prototype;function dh(t){this.fill=t.fill===void 0?" ":t.fill+"",this.align=t.align===void 0?">":t.align+"",this.sign=t.sign===void 0?"-":t.sign+"",this.symbol=t.symbol===void 0?"":t.symbol+"",this.zero=!!t.zero,this.width=t.width===void 0?void 0:+t.width,this.comma=!!t.comma,this.precision=t.precision===void 0?void 0:+t.precision,this.trim=!!t.trim,this.type=t.type===void 0?"":t.type+""}dh.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(this.width===void 0?"":Math.max(1,this.width|0))+(this.comma?",":"")+(this.precision===void 0?"":"."+Math.max(0,this.precision|0))+(this.trim?"~":"")+this.type};function nq(t){t:for(var e=t.length,r=1,n=-1,i;r0&&(n=0);break}return n>0?t.slice(0,n)+t.slice(i+1):t}var Gv;function iq(t,e){var r=fh(t,e);if(!r)return t+"";var n=r[0],i=r[1],a=i-(Gv=Math.max(-8,Math.min(8,Math.floor(i/3)))*3)+1,s=n.length;return a===s?n:a>s?n+new Array(a-s+1).join("0"):a>0?n.slice(0,a)+"."+n.slice(a):"0."+new Array(1-a).join("0")+fh(t,Math.max(0,e+a-1))[0]}function jv(t,e){var r=fh(t,e);if(!r)return t+"";var n=r[0],i=r[1];return i<0?"0."+new Array(-i).join("0")+n:n.length>i+1?n.slice(0,i+1)+"."+n.slice(i+1):n+new Array(i-n.length+2).join("0")}const $v={"%":(t,e)=>(t*100).toFixed(e),b:t=>Math.round(t).toString(2),c:t=>t+"",d:JP,e:(t,e)=>t.toExponential(e),f:(t,e)=>t.toFixed(e),g:(t,e)=>t.toPrecision(e),o:t=>Math.round(t).toString(8),p:(t,e)=>jv(t*100,e),r:jv,s:iq,X:t=>Math.round(t).toString(16).toUpperCase(),x:t=>Math.round(t).toString(16)};function Xv(t){return t}var Kv=Array.prototype.map,Zv=["y","z","a","f","p","n","\xB5","m","","k","M","G","T","P","E","Z","Y"];function Qv(t){var e=t.grouping===void 0||t.thousands===void 0?Xv:tq(Kv.call(t.grouping,Number),t.thousands+""),r=t.currency===void 0?"":t.currency[0]+"",n=t.currency===void 0?"":t.currency[1]+"",i=t.decimal===void 0?".":t.decimal+"",a=t.numerals===void 0?Xv:eq(Kv.call(t.numerals,String)),s=t.percent===void 0?"%":t.percent+"",o=t.minus===void 0?"\u2212":t.minus+"",l=t.nan===void 0?"NaN":t.nan+"";function u(d){d=Co(d);var f=d.fill,p=d.align,m=d.sign,_=d.symbol,y=d.zero,b=d.width,x=d.comma,k=d.precision,T=d.trim,C=d.type;C==="n"?(x=!0,C="g"):$v[C]||(k===void 0&&(k=12),T=!0,C="g"),(y||f==="0"&&p==="=")&&(y=!0,f="0",p="=");var M=_==="$"?r:_==="#"&&/[boxX]/.test(C)?"0"+C.toLowerCase():"",S=_==="$"?n:/[%p]/.test(C)?s:"",R=$v[C],A=/[defgprs%]/.test(C);k=k===void 0?6:/[gprs]/.test(C)?Math.max(1,Math.min(21,k)):Math.max(0,Math.min(20,k));function L(v){var B=M,w=S,D,N,z;if(C==="c")w=R(v)+w,v="";else{v=+v;var X=v<0||1/v<0;if(v=isNaN(v)?l:R(Math.abs(v),k),T&&(v=nq(v)),X&&+v==0&&m!=="+"&&(X=!1),B=(X?m==="("?m:o:m==="-"||m==="("?"":m)+B,w=(C==="s"?Zv[8+Gv/3]:"")+w+(X&&m==="("?")":""),A){for(D=-1,N=v.length;++Dz||z>57){w=(z===46?i+v.slice(D+1):v.slice(D))+w,v=v.slice(0,D);break}}}x&&!y&&(v=e(v,1/0));var ct=B.length+v.length+w.length,J=ct>1)+B+v+w+J.slice(ct);break;default:v=J+B+v+w;break}return a(v)}return L.toString=function(){return d+""},L}function h(d,f){var p=u((d=Co(d),d.type="f",d)),m=Math.max(-8,Math.min(8,Math.floor(Eo(f)/3)))*3,_=Math.pow(10,-m),y=Zv[8+m/3];return function(b){return p(_*b)+y}}return{format:u,formatPrefix:h}}var ph,gh,Jd;Jv({thousands:",",grouping:[3],currency:["$",""]});function Jv(t){return ph=Qv(t),gh=ph.format,Jd=ph.formatPrefix,ph}function t6(t){return Math.max(0,-Eo(Math.abs(t)))}function e6(t,e){return Math.max(0,Math.max(-8,Math.min(8,Math.floor(Eo(e)/3)))*3-Eo(Math.abs(t)))}function r6(t,e){return t=Math.abs(t),e=Math.abs(e)-t,Math.max(0,Eo(e)-Eo(t))+1}var te=1e-6,Hl=1e-12,Ae=Math.PI,rr=Ae/2,yh=Ae/4,Qr=Ae*2,Ue=180/Ae,re=Ae/180,Ne=Math.abs,So=Math.atan,Jr=Math.atan2,Kt=Math.cos,mh=Math.ceil,n6=Math.exp,t2=Math.hypot,bh=Math.log,e2=Math.pow,Ht=Math.sin,Dn=Math.sign||function(t){return t>0?1:t<0?-1:0},Sr=Math.sqrt,r2=Math.tan;function i6(t){return t>1?0:t<-1?Ae:Math.acos(t)}function tn(t){return t>1?rr:t<-1?-rr:Math.asin(t)}function a6(t){return(t=Ht(t/2))*t}function Je(){}function _h(t,e){t&&o6.hasOwnProperty(t.type)&&o6[t.type](t,e)}var s6={Feature:function(t,e){_h(t.geometry,e)},FeatureCollection:function(t,e){for(var r=t.features,n=-1,i=r.length;++n=0?1:-1,i=n*r,a=Kt(e),s=Ht(e),o=s2*s,l=a2*a+o*Kt(i),u=o*n*Ht(i);vh.add(Jr(u,l)),i2=t,a2=a,s2=s}function lq(t){return xh=new _r,ti(t,Si),xh*2}function kh(t){return[Jr(t[1],t[0]),tn(t[2])]}function Cs(t){var e=t[0],r=t[1],n=Kt(r);return[n*Kt(e),n*Ht(e),Ht(r)]}function wh(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]}function Ao(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function o2(t,e){t[0]+=e[0],t[1]+=e[1],t[2]+=e[2]}function Th(t,e){return[t[0]*e,t[1]*e,t[2]*e]}function Eh(t){var e=Sr(t[0]*t[0]+t[1]*t[1]+t[2]*t[2]);t[0]/=e,t[1]/=e,t[2]/=e}var tr,pn,nr,En,Ss,f6,d6,Mo,Gl,Ba,Qi,Ji={point:l2,lineStart:g6,lineEnd:y6,polygonStart:function(){Ji.point=m6,Ji.lineStart=cq,Ji.lineEnd=uq,Gl=new _r,Si.polygonStart()},polygonEnd:function(){Si.polygonEnd(),Ji.point=l2,Ji.lineStart=g6,Ji.lineEnd=y6,vh<0?(tr=-(nr=180),pn=-(En=90)):Gl>te?En=90:Gl<-te&&(pn=-90),Qi[0]=tr,Qi[1]=nr},sphere:function(){tr=-(nr=180),pn=-(En=90)}};function l2(t,e){Ba.push(Qi=[tr=t,nr=t]),eEn&&(En=e)}function p6(t,e){var r=Cs([t*re,e*re]);if(Mo){var n=Ao(Mo,r),i=[n[1],-n[0],0],a=Ao(i,n);Eh(a),a=kh(a);var s=t-Ss,o=s>0?1:-1,l=a[0]*Ue*o,u,h=Ne(s)>180;h^(o*SsEn&&(En=u)):(l=(l+360)%360-180,h^(o*SsEn&&(En=e))),h?tCn(tr,nr)&&(nr=t):Cn(t,nr)>Cn(tr,nr)&&(tr=t):nr>=tr?(tnr&&(nr=t)):t>Ss?Cn(tr,t)>Cn(tr,nr)&&(nr=t):Cn(t,nr)>Cn(tr,nr)&&(tr=t)}else Ba.push(Qi=[tr=t,nr=t]);eEn&&(En=e),Mo=r,Ss=t}function g6(){Ji.point=p6}function y6(){Qi[0]=tr,Qi[1]=nr,Ji.point=l2,Mo=null}function m6(t,e){if(Mo){var r=t-Ss;Gl.add(Ne(r)>180?r+(r>0?360:-360):r)}else f6=t,d6=e;Si.point(t,e),p6(t,e)}function cq(){Si.lineStart()}function uq(){m6(f6,d6),Si.lineEnd(),Ne(Gl)>te&&(tr=-(nr=180)),Qi[0]=tr,Qi[1]=nr,Mo=null}function Cn(t,e){return(e-=t)<0?e+360:e}function hq(t,e){return t[0]-e[0]}function b6(t,e){return t[0]<=t[1]?t[0]<=e&&e<=t[1]:eCn(n[0],n[1])&&(n[1]=i[1]),Cn(i[0],n[1])>Cn(n[0],n[1])&&(n[0]=i[0])):a.push(n=i);for(s=-1/0,r=a.length-1,e=0,n=a[r];e<=r;n=i,++e)i=a[e],(o=Cn(n[1],i[0]))>s&&(s=o,tr=i[0],nr=n[1])}return Ba=Qi=null,tr===1/0||pn===1/0?[[NaN,NaN],[NaN,NaN]]:[[tr,pn],[nr,En]]}var jl,Ch,Sh,Ah,Mh,Lh,Rh,Ih,c2,u2,h2,_6,v6,en,rn,nn,ei={sphere:Je,point:f2,lineStart:x6,lineEnd:k6,polygonStart:function(){ei.lineStart=gq,ei.lineEnd=yq},polygonEnd:function(){ei.lineStart=x6,ei.lineEnd=k6}};function f2(t,e){t*=re,e*=re;var r=Kt(e);$l(r*Kt(t),r*Ht(t),Ht(e))}function $l(t,e,r){++jl,Sh+=(t-Sh)/jl,Ah+=(e-Ah)/jl,Mh+=(r-Mh)/jl}function x6(){ei.point=dq}function dq(t,e){t*=re,e*=re;var r=Kt(e);en=r*Kt(t),rn=r*Ht(t),nn=Ht(e),ei.point=pq,$l(en,rn,nn)}function pq(t,e){t*=re,e*=re;var r=Kt(e),n=r*Kt(t),i=r*Ht(t),a=Ht(e),s=Jr(Sr((s=rn*a-nn*i)*s+(s=nn*n-en*a)*s+(s=en*i-rn*n)*s),en*n+rn*i+nn*a);Ch+=s,Lh+=s*(en+(en=n)),Rh+=s*(rn+(rn=i)),Ih+=s*(nn+(nn=a)),$l(en,rn,nn)}function k6(){ei.point=f2}function gq(){ei.point=mq}function yq(){w6(_6,v6),ei.point=f2}function mq(t,e){_6=t,v6=e,t*=re,e*=re,ei.point=w6;var r=Kt(e);en=r*Kt(t),rn=r*Ht(t),nn=Ht(e),$l(en,rn,nn)}function w6(t,e){t*=re,e*=re;var r=Kt(e),n=r*Kt(t),i=r*Ht(t),a=Ht(e),s=rn*a-nn*i,o=nn*n-en*a,l=en*i-rn*n,u=t2(s,o,l),h=tn(u),d=u&&-h/u;c2.add(d*s),u2.add(d*o),h2.add(d*l),Ch+=h,Lh+=h*(en+(en=n)),Rh+=h*(rn+(rn=i)),Ih+=h*(nn+(nn=a)),$l(en,rn,nn)}function bq(t){jl=Ch=Sh=Ah=Mh=Lh=Rh=Ih=0,c2=new _r,u2=new _r,h2=new _r,ti(t,ei);var e=+c2,r=+u2,n=+h2,i=t2(e,r,n);return iAe?t+Math.round(-t/Qr)*Qr:t,e]}p2.invert=p2;function g2(t,e,r){return(t%=Qr)?e||r?d2(E6(t),C6(e,r)):E6(t):e||r?C6(e,r):p2}function T6(t){return function(e,r){return e+=t,[e>Ae?e-Qr:e<-Ae?e+Qr:e,r]}}function E6(t){var e=T6(t);return e.invert=T6(-t),e}function C6(t,e){var r=Kt(t),n=Ht(t),i=Kt(e),a=Ht(e);function s(o,l){var u=Kt(l),h=Kt(o)*u,d=Ht(o)*u,f=Ht(l),p=f*r+h*n;return[Jr(d*i-p*a,h*r-f*n),tn(p*i+d*a)]}return s.invert=function(o,l){var u=Kt(l),h=Kt(o)*u,d=Ht(o)*u,f=Ht(l),p=f*i-d*a;return[Jr(d*i+f*a,h*r+p*n),tn(p*r-h*n)]},s}function S6(t){t=g2(t[0]*re,t[1]*re,t.length>2?t[2]*re:0);function e(r){return r=t(r[0]*re,r[1]*re),r[0]*=Ue,r[1]*=Ue,r}return e.invert=function(r){return r=t.invert(r[0]*re,r[1]*re),r[0]*=Ue,r[1]*=Ue,r},e}function A6(t,e,r,n,i,a){if(!!r){var s=Kt(e),o=Ht(e),l=n*r;i==null?(i=e+n*Qr,a=e-l/2):(i=M6(s,i),a=M6(s,a),(n>0?ia)&&(i+=n*Qr));for(var u,h=i;n>0?h>a:h1&&t.push(t.pop().concat(t.shift()))},result:function(){var r=t;return t=[],e=null,r}}}function Nh(t,e){return Ne(t[0]-e[0])=0;--o)i.point((d=h[o])[0],d[1]);else n(f.x,f.p.x,-1,i);f=f.p}f=f.o,h=f.z,p=!p}while(!f.v);i.lineEnd()}}}function I6(t){if(!!(e=t.length)){for(var e,r=0,n=t[0],i;++r=0?1:-1,L=A*R,v=L>Ae,B=y*M;if(l.add(Jr(B*A*Ht(L),b*S+B*Kt(L))),s+=v?R+A*Qr:R,v^m>=r^T>=r){var w=Ao(Cs(p),Cs(k));Eh(w);var D=Ao(a,w);Eh(D);var N=(v^R>=0?-1:1)*tn(D[2]);(n>N||n===N&&(w[0]||w[1]))&&(o+=v^R>=0?1:-1)}}return(s<-te||s0){for(l||(i.polygonStart(),l=!0),i.lineStart(),M=0;M1&&T&2&&C.push(C.pop().concat(C.shift())),h.push(C.filter(vq))}}return f}}function vq(t){return t.length>1}function xq(t,e){return((t=t.x)[0]<0?t[1]-rr-te:rr-t[1])-((e=e.x)[0]<0?e[1]-rr-te:rr-e[1])}const m2=B6(function(){return!0},kq,Tq,[-Ae,-rr]);function kq(t){var e=NaN,r=NaN,n=NaN,i;return{lineStart:function(){t.lineStart(),i=1},point:function(a,s){var o=a>0?Ae:-Ae,l=Ne(a-e);Ne(l-Ae)0?rr:-rr),t.point(n,r),t.lineEnd(),t.lineStart(),t.point(o,r),t.point(a,r),i=0):n!==o&&l>=Ae&&(Ne(e-n)te?So((Ht(e)*(a=Kt(n))*Ht(r)-Ht(n)*(i=Kt(e))*Ht(t))/(i*a*s)):(e+n)/2}function Tq(t,e,r,n){var i;if(t==null)i=r*rr,n.point(-Ae,i),n.point(0,i),n.point(Ae,i),n.point(Ae,0),n.point(Ae,-i),n.point(0,-i),n.point(-Ae,-i),n.point(-Ae,0),n.point(-Ae,i);else if(Ne(t[0]-e[0])>te){var a=t[0]0,i=Ne(e)>te;function a(h,d,f,p){A6(p,t,r,f,h,d)}function s(h,d){return Kt(h)*Kt(d)>e}function o(h){var d,f,p,m,_;return{lineStart:function(){m=p=!1,_=1},point:function(y,b){var x=[y,b],k,T=s(y,b),C=n?T?0:u(y,b):T?u(y+(y<0?Ae:-Ae),b):0;if(!d&&(m=p=T)&&h.lineStart(),T!==p&&(k=l(d,x),(!k||Nh(d,k)||Nh(x,k))&&(x[2]=1)),T!==p)_=0,T?(h.lineStart(),k=l(x,d),h.point(k[0],k[1])):(k=l(d,x),h.point(k[0],k[1],2),h.lineEnd()),d=k;else if(i&&d&&n^T){var M;!(C&f)&&(M=l(x,d,!0))&&(_=0,n?(h.lineStart(),h.point(M[0][0],M[0][1]),h.point(M[1][0],M[1][1]),h.lineEnd()):(h.point(M[1][0],M[1][1]),h.lineEnd(),h.lineStart(),h.point(M[0][0],M[0][1],3)))}T&&(!d||!Nh(d,x))&&h.point(x[0],x[1]),d=x,p=T,f=C},lineEnd:function(){p&&h.lineEnd(),d=null},clean:function(){return _|(m&&p)<<1}}}function l(h,d,f){var p=Cs(h),m=Cs(d),_=[1,0,0],y=Ao(p,m),b=wh(y,y),x=y[0],k=b-x*x;if(!k)return!f&&h;var T=e*b/k,C=-e*x/k,M=Ao(_,y),S=Th(_,T),R=Th(y,C);o2(S,R);var A=M,L=wh(S,A),v=wh(A,A),B=L*L-v*(wh(S,S)-1);if(!(B<0)){var w=Sr(B),D=Th(A,(-L-w)/v);if(o2(D,S),D=kh(D),!f)return D;var N=h[0],z=d[0],X=h[1],ct=d[1],J;z0^D[1]<(Ne(D[0]-N)Ae^(N<=D[0]&&D[0]<=z)){var ut=Th(A,(-L+w)/v);return o2(ut,S),[D,kh(ut)]}}}function u(h,d){var f=n?t:Ae-t,p=0;return h<-f?p|=1:h>f&&(p|=2),d<-f?p|=4:d>f&&(p|=8),p}return B6(s,o,a,n?[0,-t]:[-Ae,t-Ae])}function Eq(t,e,r,n,i,a){var s=t[0],o=t[1],l=e[0],u=e[1],h=0,d=1,f=l-s,p=u-o,m;if(m=r-s,!(!f&&m>0)){if(m/=f,f<0){if(m0){if(m>d)return;m>h&&(h=m)}if(m=i-s,!(!f&&m<0)){if(m/=f,f<0){if(m>d)return;m>h&&(h=m)}else if(f>0){if(m0)){if(m/=p,p<0){if(m0){if(m>d)return;m>h&&(h=m)}if(m=a-o,!(!p&&m<0)){if(m/=p,p<0){if(m>d)return;m>h&&(h=m)}else if(p>0){if(m0&&(t[0]=s+h*f,t[1]=o+h*p),d<1&&(e[0]=s+d*f,e[1]=o+d*p),!0}}}}}var Xl=1e9,Dh=-Xl;function Oh(t,e,r,n){function i(u,h){return t<=u&&u<=r&&e<=h&&h<=n}function a(u,h,d,f){var p=0,m=0;if(u==null||(p=s(u,d))!==(m=s(h,d))||l(u,h)<0^d>0)do f.point(p===0||p===3?t:r,p>1?n:e);while((p=(p+d+4)%4)!==m);else f.point(h[0],h[1])}function s(u,h){return Ne(u[0]-t)0?0:3:Ne(u[0]-r)0?2:1:Ne(u[1]-e)0?1:0:h>0?3:2}function o(u,h){return l(u.x,h.x)}function l(u,h){var d=s(u,1),f=s(h,1);return d!==f?d-f:d===0?h[1]-u[1]:d===1?u[0]-h[0]:d===2?u[1]-h[1]:h[0]-u[0]}return function(u){var h=u,d=L6(),f,p,m,_,y,b,x,k,T,C,M,S={point:R,lineStart:B,lineEnd:w,polygonStart:L,polygonEnd:v};function R(N,z){i(N,z)&&h.point(N,z)}function A(){for(var N=0,z=0,X=p.length;zn&&(W-lt)*(n-ut)>(tt-ut)*(t-lt)&&++N:tt<=n&&(W-lt)*(n-ut)<(tt-ut)*(t-lt)&&--N;return N}function L(){h=d,f=[],p=[],M=!0}function v(){var N=A(),z=M&&N,X=(f=j0(f)).length;(z||X)&&(u.polygonStart(),z&&(u.lineStart(),a(null,null,1,u),u.lineEnd()),X&&R6(f,o,N,a,u),u.polygonEnd()),h=u,f=p=m=null}function B(){S.point=D,p&&p.push(m=[]),C=!0,T=!1,x=k=NaN}function w(){f&&(D(_,y),b&&T&&d.rejoin(),f.push(d.result())),S.point=R,T&&h.lineEnd()}function D(N,z){var X=i(N,z);if(p&&m.push([N,z]),C)_=N,y=z,b=X,C=!1,X&&(h.lineStart(),h.point(N,z));else if(X&&T)h.point(N,z);else{var ct=[x=Math.max(Dh,Math.min(Xl,x)),k=Math.max(Dh,Math.min(Xl,k))],J=[N=Math.max(Dh,Math.min(Xl,N)),z=Math.max(Dh,Math.min(Xl,z))];Eq(ct,J,t,e,r,n)?(T||(h.lineStart(),h.point(ct[0],ct[1])),h.point(J[0],J[1]),X||h.lineEnd(),M=!1):X&&(h.lineStart(),h.point(N,z),M=!1)}x=N,k=z,T=X}return S}}function Cq(){var t=0,e=0,r=960,n=500,i,a,s;return s={stream:function(o){return i&&a===o?i:i=Oh(t,e,r,n)(a=o)},extent:function(o){return arguments.length?(t=+o[0][0],e=+o[0][1],r=+o[1][0],n=+o[1][1],i=a=null,s):[[t,e],[r,n]]}}}var b2,_2,Fh,Ph,Ro={sphere:Je,point:Je,lineStart:Sq,lineEnd:Je,polygonStart:Je,polygonEnd:Je};function Sq(){Ro.point=Mq,Ro.lineEnd=Aq}function Aq(){Ro.point=Ro.lineEnd=Je}function Mq(t,e){t*=re,e*=re,_2=t,Fh=Ht(e),Ph=Kt(e),Ro.point=Lq}function Lq(t,e){t*=re,e*=re;var r=Ht(e),n=Kt(e),i=Ne(t-_2),a=Kt(i),s=Ht(i),o=n*s,l=Ph*r-Fh*n*a,u=Fh*r+Ph*n*a;b2.add(Jr(Sr(o*o+l*l),u)),_2=t,Fh=r,Ph=n}function O6(t){return b2=new _r,ti(t,Ro),+b2}var v2=[null,null],Rq={type:"LineString",coordinates:v2};function qh(t,e){return v2[0]=t,v2[1]=e,O6(Rq)}var F6={Feature:function(t,e){return Vh(t.geometry,e)},FeatureCollection:function(t,e){for(var r=t.features,n=-1,i=r.length;++n0&&(i=qh(t[a],t[a-1]),i>0&&r<=i&&n<=i&&(r+n-i)*(1-Math.pow((r-n)/i,2))te}).map(f)).concat(Ca(mh(a/u)*u,i,u).filter(function(k){return Ne(k%d)>te}).map(p))}return b.lines=function(){return x().map(function(k){return{type:"LineString",coordinates:k}})},b.outline=function(){return{type:"Polygon",coordinates:[m(n).concat(_(s).slice(1),m(r).reverse().slice(1),_(o).reverse().slice(1))]}},b.extent=function(k){return arguments.length?b.extentMajor(k).extentMinor(k):b.extentMinor()},b.extentMajor=function(k){return arguments.length?(n=+k[0][0],r=+k[1][0],o=+k[0][1],s=+k[1][1],n>r&&(k=n,n=r,r=k),o>s&&(k=o,o=s,s=k),b.precision(y)):[[n,o],[r,s]]},b.extentMinor=function(k){return arguments.length?(e=+k[0][0],t=+k[1][0],a=+k[0][1],i=+k[1][1],e>t&&(k=e,e=t,t=k),a>i&&(k=a,a=i,i=k),b.precision(y)):[[e,a],[t,i]]},b.step=function(k){return arguments.length?b.stepMajor(k).stepMinor(k):b.stepMinor()},b.stepMajor=function(k){return arguments.length?(h=+k[0],d=+k[1],b):[h,d]},b.stepMinor=function(k){return arguments.length?(l=+k[0],u=+k[1],b):[l,u]},b.precision=function(k){return arguments.length?(y=+k,f=U6(a,i,90),p=W6(e,t,y),m=U6(o,s,90),_=W6(n,r,y),b):y},b.extentMajor([[-180,-90+te],[180,90-te]]).extentMinor([[-180,-80-te],[180,80+te]])}function Bq(){return H6()()}function Dq(t,e){var r=t[0]*re,n=t[1]*re,i=e[0]*re,a=e[1]*re,s=Kt(n),o=Ht(n),l=Kt(a),u=Ht(a),h=s*Kt(r),d=s*Ht(r),f=l*Kt(i),p=l*Ht(i),m=2*tn(Sr(a6(a-n)+s*l*a6(i-r))),_=Ht(m),y=m?function(b){var x=Ht(b*=m)/_,k=Ht(m-b)/_,T=k*h+x*f,C=k*d+x*p,M=k*o+x*u;return[Jr(C,T)*Ue,Jr(M,Sr(T*T+C*C))*Ue]}:function(){return[r*Ue,n*Ue]};return y.distance=m,y}const Kl=t=>t;var x2=new _r,k2=new _r,G6,j6,w2,T2,Da={point:Je,lineStart:Je,lineEnd:Je,polygonStart:function(){Da.lineStart=Oq,Da.lineEnd=Pq},polygonEnd:function(){Da.lineStart=Da.lineEnd=Da.point=Je,x2.add(Ne(k2)),k2=new _r},result:function(){var t=x2/2;return x2=new _r,t}};function Oq(){Da.point=Fq}function Fq(t,e){Da.point=$6,G6=w2=t,j6=T2=e}function $6(t,e){k2.add(T2*t-w2*e),w2=t,T2=e}function Pq(){$6(G6,j6)}const X6=Da;var Io=1/0,zh=Io,Zl=-Io,Yh=Zl,qq={point:Vq,lineStart:Je,lineEnd:Je,polygonStart:Je,polygonEnd:Je,result:function(){var t=[[Io,zh],[Zl,Yh]];return Zl=Yh=-(zh=Io=1/0),t}};function Vq(t,e){tZl&&(Zl=t),eYh&&(Yh=e)}const Uh=qq;var E2=0,C2=0,Ql=0,Wh=0,Hh=0,No=0,S2=0,A2=0,Jl=0,K6,Z6,Ai,Mi,ri={point:As,lineStart:Q6,lineEnd:J6,polygonStart:function(){ri.lineStart=Uq,ri.lineEnd=Wq},polygonEnd:function(){ri.point=As,ri.lineStart=Q6,ri.lineEnd=J6},result:function(){var t=Jl?[S2/Jl,A2/Jl]:No?[Wh/No,Hh/No]:Ql?[E2/Ql,C2/Ql]:[NaN,NaN];return E2=C2=Ql=Wh=Hh=No=S2=A2=Jl=0,t}};function As(t,e){E2+=t,C2+=e,++Ql}function Q6(){ri.point=zq}function zq(t,e){ri.point=Yq,As(Ai=t,Mi=e)}function Yq(t,e){var r=t-Ai,n=e-Mi,i=Sr(r*r+n*n);Wh+=i*(Ai+t)/2,Hh+=i*(Mi+e)/2,No+=i,As(Ai=t,Mi=e)}function J6(){ri.point=As}function Uq(){ri.point=Hq}function Wq(){tx(K6,Z6)}function Hq(t,e){ri.point=tx,As(K6=Ai=t,Z6=Mi=e)}function tx(t,e){var r=t-Ai,n=e-Mi,i=Sr(r*r+n*n);Wh+=i*(Ai+t)/2,Hh+=i*(Mi+e)/2,No+=i,i=Mi*t-Ai*e,S2+=i*(Ai+t),A2+=i*(Mi+e),Jl+=i*3,As(Ai=t,Mi=e)}const ex=ri;function rx(t){this._context=t}rx.prototype={_radius:4.5,pointRadius:function(t){return this._radius=t,this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){this._line===0&&this._context.closePath(),this._point=NaN},point:function(t,e){switch(this._point){case 0:{this._context.moveTo(t,e),this._point=1;break}case 1:{this._context.lineTo(t,e);break}default:{this._context.moveTo(t+this._radius,e),this._context.arc(t,e,this._radius,0,Qr);break}}},result:Je};var M2=new _r,L2,nx,ix,tc,ec,Gh={point:Je,lineStart:function(){Gh.point=Gq},lineEnd:function(){L2&&ax(nx,ix),Gh.point=Je},polygonStart:function(){L2=!0},polygonEnd:function(){L2=null},result:function(){var t=+M2;return M2=new _r,t}};function Gq(t,e){Gh.point=ax,nx=tc=t,ix=ec=e}function ax(t,e){tc-=t,ec-=e,M2.add(Sr(tc*tc+ec*ec)),tc=t,ec=e}const sx=Gh;function ox(){this._string=[]}ox.prototype={_radius:4.5,_circle:lx(4.5),pointRadius:function(t){return(t=+t)!==this._radius&&(this._radius=t,this._circle=null),this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){this._line===0&&this._string.push("Z"),this._point=NaN},point:function(t,e){switch(this._point){case 0:{this._string.push("M",t,",",e),this._point=1;break}case 1:{this._string.push("L",t,",",e);break}default:{this._circle==null&&(this._circle=lx(this._radius)),this._string.push("M",t,",",e,this._circle);break}}},result:function(){if(this._string.length){var t=this._string.join("");return this._string=[],t}else return null}};function lx(t){return"m0,"+t+"a"+t+","+t+" 0 1,1 0,"+-2*t+"a"+t+","+t+" 0 1,1 0,"+2*t+"z"}function jq(t,e){var r=4.5,n,i;function a(s){return s&&(typeof r=="function"&&i.pointRadius(+r.apply(this,arguments)),ti(s,n(i))),i.result()}return a.area=function(s){return ti(s,n(X6)),X6.result()},a.measure=function(s){return ti(s,n(sx)),sx.result()},a.bounds=function(s){return ti(s,n(Uh)),Uh.result()},a.centroid=function(s){return ti(s,n(ex)),ex.result()},a.projection=function(s){return arguments.length?(n=s==null?(t=null,Kl):(t=s).stream,a):t},a.context=function(s){return arguments.length?(i=s==null?(e=null,new ox):new rx(e=s),typeof r!="function"&&i.pointRadius(r),a):e},a.pointRadius=function(s){return arguments.length?(r=typeof s=="function"?s:(i.pointRadius(+s),+s),a):r},a.projection(t).context(e)}function $q(t){return{stream:rc(t)}}function rc(t){return function(e){var r=new R2;for(var n in t)r[n]=t[n];return r.stream=e,r}}function R2(){}R2.prototype={constructor:R2,point:function(t,e){this.stream.point(t,e)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}};function I2(t,e,r){var n=t.clipExtent&&t.clipExtent();return t.scale(150).translate([0,0]),n!=null&&t.clipExtent(null),ti(r,t.stream(Uh)),e(Uh.result()),n!=null&&t.clipExtent(n),t}function jh(t,e,r){return I2(t,function(n){var i=e[1][0]-e[0][0],a=e[1][1]-e[0][1],s=Math.min(i/(n[1][0]-n[0][0]),a/(n[1][1]-n[0][1])),o=+e[0][0]+(i-s*(n[1][0]+n[0][0]))/2,l=+e[0][1]+(a-s*(n[1][1]+n[0][1]))/2;t.scale(150*s).translate([o,l])},r)}function N2(t,e,r){return jh(t,[[0,0],e],r)}function B2(t,e,r){return I2(t,function(n){var i=+e,a=i/(n[1][0]-n[0][0]),s=(i-a*(n[1][0]+n[0][0]))/2,o=-a*n[0][1];t.scale(150*a).translate([s,o])},r)}function D2(t,e,r){return I2(t,function(n){var i=+e,a=i/(n[1][1]-n[0][1]),s=-a*n[0][0],o=(i-a*(n[1][1]+n[0][1]))/2;t.scale(150*a).translate([s,o])},r)}var cx=16,Xq=Kt(30*re);function ux(t,e){return+e?Zq(t,e):Kq(t)}function Kq(t){return rc({point:function(e,r){e=t(e,r),this.stream.point(e[0],e[1])}})}function Zq(t,e){function r(n,i,a,s,o,l,u,h,d,f,p,m,_,y){var b=u-n,x=h-i,k=b*b+x*x;if(k>4*e&&_--){var T=s+f,C=o+p,M=l+m,S=Sr(T*T+C*C+M*M),R=tn(M/=S),A=Ne(Ne(M)-1)e||Ne((b*w+x*D)/k-.5)>.3||s*f+o*p+l*m2?N[2]%360*re:0,w()):[o*Ue,l*Ue,u*Ue]},v.angle=function(N){return arguments.length?(d=N%360*re,w()):d*Ue},v.reflectX=function(N){return arguments.length?(f=N?-1:1,w()):f<0},v.reflectY=function(N){return arguments.length?(p=N?-1:1,w()):p<0},v.precision=function(N){return arguments.length?(M=ux(S,C=N*N),D()):Sr(C)},v.fitExtent=function(N,z){return jh(v,N,z)},v.fitSize=function(N,z){return N2(v,N,z)},v.fitWidth=function(N,z){return B2(v,N,z)},v.fitHeight=function(N,z){return D2(v,N,z)};function w(){var N=hx(r,0,0,f,p,d).apply(null,e(a,s)),z=hx(r,n-N[0],i-N[1],f,p,d);return h=g2(o,l,u),S=d2(e,z),R=d2(h,S),M=ux(S,C),D()}function D(){return A=L=null,v}return function(){return e=t.apply(this,arguments),v.invert=e.invert&&B,w()}}function F2(t){var e=0,r=Ae/3,n=O2(t),i=n(e,r);return i.parallels=function(a){return arguments.length?n(e=a[0]*re,r=a[1]*re):[e*Ue,r*Ue]},i}function eV(t){var e=Kt(t);function r(n,i){return[n*e,Ht(i)/e]}return r.invert=function(n,i){return[n/e,tn(i*e)]},r}function fx(t,e){var r=Ht(t),n=(r+Ht(e))/2;if(Ne(n)=.12&&y<.234&&_>=-.425&&_<-.214?i:y>=.166&&y<.234&&_>=-.214&&_<-.115?s:r).invert(f)},h.stream=function(f){return t&&e===f?t:t=rV([r.stream(e=f),i.stream(f),s.stream(f)])},h.precision=function(f){return arguments.length?(r.precision(f),i.precision(f),s.precision(f),d()):r.precision()},h.scale=function(f){return arguments.length?(r.scale(f),i.scale(f*.35),s.scale(f),h.translate(r.translate())):r.scale()},h.translate=function(f){if(!arguments.length)return r.translate();var p=r.scale(),m=+f[0],_=+f[1];return n=r.translate(f).clipExtent([[m-.455*p,_-.238*p],[m+.455*p,_+.238*p]]).stream(u),a=i.translate([m-.307*p,_+.201*p]).clipExtent([[m-.425*p+te,_+.12*p+te],[m-.214*p-te,_+.234*p-te]]).stream(u),o=s.translate([m-.205*p,_+.212*p]).clipExtent([[m-.214*p+te,_+.166*p+te],[m-.115*p-te,_+.234*p-te]]).stream(u),d()},h.fitExtent=function(f,p){return jh(h,f,p)},h.fitSize=function(f,p){return N2(h,f,p)},h.fitWidth=function(f,p){return B2(h,f,p)},h.fitHeight=function(f,p){return D2(h,f,p)};function d(){return t=e=null,h}return h.scale(1070)}function px(t){return function(e,r){var n=Kt(e),i=Kt(r),a=t(n*i);return a===1/0?[2,0]:[a*i*Ht(e),a*Ht(r)]}}function nc(t){return function(e,r){var n=Sr(e*e+r*r),i=t(n),a=Ht(i),s=Kt(i);return[Jr(e*a,n*s),tn(n&&r*a/n)]}}var P2=px(function(t){return Sr(2/(1+t))});P2.invert=nc(function(t){return 2*tn(t/2)});function iV(){return Li(P2).scale(124.75).clipAngle(180-.001)}var q2=px(function(t){return(t=i6(t))&&t/Ht(t)});q2.invert=nc(function(t){return t});function aV(){return Li(q2).scale(79.4188).clipAngle(180-.001)}function ic(t,e){return[t,bh(r2((rr+e)/2))]}ic.invert=function(t,e){return[t,2*So(n6(e))-rr]};function sV(){return gx(ic).scale(961/Qr)}function gx(t){var e=Li(t),r=e.center,n=e.scale,i=e.translate,a=e.clipExtent,s=null,o,l,u;e.scale=function(d){return arguments.length?(n(d),h()):n()},e.translate=function(d){return arguments.length?(i(d),h()):i()},e.center=function(d){return arguments.length?(r(d),h()):r()},e.clipExtent=function(d){return arguments.length?(d==null?s=o=l=u=null:(s=+d[0][0],o=+d[0][1],l=+d[1][0],u=+d[1][1]),h()):s==null?null:[[s,o],[l,u]]};function h(){var d=Ae*n(),f=e(S6(e.rotate()).invert([0,0]));return a(s==null?[[f[0]-d,f[1]-d],[f[0]+d,f[1]+d]]:t===ic?[[Math.max(f[0]-d,s),o],[Math.min(f[0]+d,l),u]]:[[s,Math.max(f[1]-d,o)],[l,Math.min(f[1]+d,u)]])}return h()}function Xh(t){return r2((rr+t)/2)}function yx(t,e){var r=Kt(t),n=t===e?Ht(t):bh(r/Kt(e))/bh(Xh(e)/Xh(t)),i=r*e2(Xh(t),n)/n;if(!n)return ic;function a(s,o){i>0?o<-rr+te&&(o=-rr+te):o>rr-te&&(o=rr-te);var l=i/e2(Xh(o),n);return[l*Ht(n*s),i-l*Kt(n*s)]}return a.invert=function(s,o){var l=i-o,u=Dn(n)*Sr(s*s+l*l),h=Jr(s,Ne(l))*Dn(l);return l*n<0&&(h-=Ae*Dn(s)*Dn(l)),[h/n,2*So(e2(i/u,1/n))-rr]},a}function oV(){return F2(yx).scale(109.5).parallels([30,30])}function ac(t,e){return[t,e]}ac.invert=ac;function lV(){return Li(ac).scale(152.63)}function mx(t,e){var r=Kt(t),n=t===e?Ht(t):(r-Kt(e))/(e-t),i=r/n+t;if(Ne(n)te&&--n>0);return[t/(.8707+(a=r*r)*(-.131979+a*(-.013791+a*a*a*(.003971-.001529*a)))),r]};function pV(){return Li(Y2).scale(175.295)}function U2(t,e){return[Kt(e)*Ht(t),Ht(e)]}U2.invert=nc(tn);function gV(){return Li(U2).scale(249.5).clipAngle(90+te)}function W2(t,e){var r=Kt(e),n=1+Kt(t)*r;return[r*Ht(t)/n,Ht(e)/n]}W2.invert=nc(function(t){return 2*So(t)});function yV(){return Li(W2).scale(250).clipAngle(142)}function H2(t,e){return[bh(r2((rr+e)/2)),-t]}H2.invert=function(t,e){return[-e,2*So(n6(t))-rr]};function mV(){var t=gx(H2),e=t.center,r=t.rotate;return t.center=function(n){return arguments.length?e([-n[1],n[0]]):(n=e(),[n[1],-n[0]])},t.rotate=function(n){return arguments.length?r([n[0],n[1],n.length>2?n[2]+90:90]):(n=r(),[n[0],n[1],n[2]-90])},r([0,0,90]).scale(159.155)}function bV(t,e){return t.parent===e.parent?1:2}function _V(t){return t.reduce(vV,0)/t.length}function vV(t,e){return t+e.x}function xV(t){return 1+t.reduce(kV,0)}function kV(t,e){return Math.max(t,e.y)}function wV(t){for(var e;e=t.children;)t=e[0];return t}function TV(t){for(var e;e=t.children;)t=e[e.length-1];return t}function EV(){var t=bV,e=1,r=1,n=!1;function i(a){var s,o=0;a.eachAfter(function(f){var p=f.children;p?(f.x=_V(p),f.y=xV(p)):(f.x=s?o+=t(f,s):0,f.y=0,s=f)});var l=wV(a),u=TV(a),h=l.x-t(l,u)/2,d=u.x+t(u,l)/2;return a.eachAfter(n?function(f){f.x=(f.x-a.x)*e,f.y=(a.y-f.y)*r}:function(f){f.x=(f.x-h)/(d-h)*e,f.y=(1-(a.y?f.y/a.y:1))*r})}return i.separation=function(a){return arguments.length?(t=a,i):t},i.size=function(a){return arguments.length?(n=!1,e=+a[0],r=+a[1],i):n?null:[e,r]},i.nodeSize=function(a){return arguments.length?(n=!0,e=+a[0],r=+a[1],i):n?[e,r]:null},i}function CV(t){var e=0,r=t.children,n=r&&r.length;if(!n)e=1;else for(;--n>=0;)e+=r[n].value;t.value=e}function SV(){return this.eachAfter(CV)}function AV(t,e){let r=-1;for(const n of this)t.call(e,n,++r,this);return this}function MV(t,e){for(var r=this,n=[r],i,a,s=-1;r=n.pop();)if(t.call(e,r,++s,this),i=r.children)for(a=i.length-1;a>=0;--a)n.push(i[a]);return this}function LV(t,e){for(var r=this,n=[r],i=[],a,s,o,l=-1;r=n.pop();)if(i.push(r),a=r.children)for(s=0,o=a.length;s=0;)r+=n[i].value;e.value=r})}function NV(t){return this.eachBefore(function(e){e.children&&e.children.sort(t)})}function BV(t){for(var e=this,r=DV(e,t),n=[e];e!==r;)e=e.parent,n.push(e);for(var i=n.length;t!==r;)n.splice(i,0,t),t=t.parent;return n}function DV(t,e){if(t===e)return t;var r=t.ancestors(),n=e.ancestors(),i=null;for(t=r.pop(),e=n.pop();t===e;)i=t,t=r.pop(),e=n.pop();return i}function OV(){for(var t=this,e=[t];t=t.parent;)e.push(t);return e}function FV(){return Array.from(this)}function PV(){var t=[];return this.eachBefore(function(e){e.children||t.push(e)}),t}function qV(){var t=this,e=[];return t.each(function(r){r!==t&&e.push({source:r.parent,target:r})}),e}function*VV(){var t=this,e,r=[t],n,i,a;do for(e=r.reverse(),r=[];t=e.pop();)if(yield t,n=t.children)for(i=0,a=n.length;i=0;--o)i.push(a=s[o]=new Ms(s[o])),a.parent=n,a.depth=n.depth+1;return r.eachBefore(bx)}function zV(){return G2(this).eachBefore(WV)}function YV(t){return t.children}function UV(t){return Array.isArray(t)?t[1]:null}function WV(t){t.data.value!==void 0&&(t.value=t.data.value),t.data=t.data.data}function bx(t){var e=0;do t.height=e;while((t=t.parent)&&t.height<++e)}function Ms(t){this.data=t,this.depth=this.height=0,this.parent=null}Ms.prototype=G2.prototype={constructor:Ms,count:SV,each:AV,eachAfter:LV,eachBefore:MV,find:RV,sum:IV,sort:NV,path:BV,ancestors:OV,descendants:FV,leaves:PV,links:qV,copy:zV,[Symbol.iterator]:VV};function Zh(t){return t==null?null:_x(t)}function _x(t){if(typeof t!="function")throw new Error;return t}function Ls(){return 0}function Bo(t){return function(){return t}}const HV=1664525,GV=1013904223,vx=4294967296;function j2(){let t=1;return()=>(t=(HV*t+GV)%vx)/vx}function jV(t){return typeof t=="object"&&"length"in t?t:Array.from(t)}function $V(t,e){let r=t.length,n,i;for(;r;)i=e()*r--|0,n=t[r],t[r]=t[i],t[i]=n;return t}function XV(t){return xx(t,j2())}function xx(t,e){for(var r=0,n=(t=$V(Array.from(t),e)).length,i=[],a,s;r0&&r*r>n*n+i*i}function $2(t,e){for(var r=0;r1e-6?(v+Math.sqrt(v*v-4*L*B))/(2*L):B/v);return{x:n+M+S*w,y:i+R+A*w,r:w}}function Tx(t,e,r){var n=t.x-e.x,i,a,s=t.y-e.y,o,l,u=n*n+s*s;u?(a=e.r+r.r,a*=a,l=t.r+r.r,l*=l,a>l?(i=(u+l-a)/(2*u),o=Math.sqrt(Math.max(0,l/u-i*i)),r.x=t.x-i*n-o*s,r.y=t.y-i*s+o*n):(i=(u+a-l)/(2*u),o=Math.sqrt(Math.max(0,a/u-i*i)),r.x=e.x+i*n-o*s,r.y=e.y+i*s+o*n)):(r.x=e.x+r.r,r.y=e.y)}function Ex(t,e){var r=t.r+e.r-1e-6,n=e.x-t.x,i=e.y-t.y;return r>0&&r*r>n*n+i*i}function Cx(t){var e=t._,r=t.next._,n=e.r+r.r,i=(e.x*r.r+r.x*e.r)/n,a=(e.y*r.r+r.y*e.r)/n;return i*i+a*a}function Jh(t){this._=t,this.next=null,this.previous=null}function Sx(t,e){if(!(a=(t=jV(t)).length))return 0;var r,n,i,a,s,o,l,u,h,d,f;if(r=t[0],r.x=0,r.y=0,!(a>1))return r.r;if(n=t[1],r.x=-n.r,n.x=r.r,n.y=0,!(a>2))return r.r+n.r;Tx(n,r,i=t[2]),r=new Jh(r),n=new Jh(n),i=new Jh(i),r.next=i.previous=n,n.next=r.previous=i,i.next=n.previous=r;t:for(l=3;loz(r(T,C,i))),x=b.map(Ix),k=new Set(b).add("");for(const T of x)k.has(T)||(k.add(T),b.push(T),x.push(Ix(T)),a.push(K2));s=(T,C)=>b[C],o=(T,C)=>x[C]}for(h=0,l=a.length;h=0&&(p=a[b],p.data===K2);--b)p.data=null}if(d.parent=nz,d.eachBefore(function(b){b.depth=b.parent.depth+1,--l}).eachBefore(bx),d.parent=null,l>0)throw new Error("cycle");return d}return n.id=function(i){return arguments.length?(t=Zh(i),n):t},n.parentId=function(i){return arguments.length?(e=Zh(i),n):e},n.path=function(i){return arguments.length?(r=Zh(i),n):r},n}function oz(t){t=`${t}`;let e=t.length;return Z2(t,e-1)&&!Z2(t,e-2)&&(t=t.slice(0,-1)),t[0]==="/"?t:`/${t}`}function Ix(t){let e=t.length;if(e<2)return"";for(;--e>1&&!Z2(t,e););return t.slice(0,e)}function Z2(t,e){if(t[e]==="/"){let r=0;for(;e>0&&t[--e]==="\\";)++r;if((r&1)===0)return!0}return!1}function lz(t,e){return t.parent===e.parent?1:2}function Q2(t){var e=t.children;return e?e[0]:t.t}function J2(t){var e=t.children;return e?e[e.length-1]:t.t}function cz(t,e,r){var n=r/(e.i-t.i);e.c-=n,e.s+=r,t.c+=n,e.z+=r,e.m+=r}function uz(t){for(var e=0,r=0,n=t.children,i=n.length,a;--i>=0;)a=n[i],a.z+=e,a.m+=e,e+=a.s+(r+=a.c)}function hz(t,e,r){return t.a.parent===e.parent?t.a:r}function tf(t,e){this._=t,this.parent=null,this.children=null,this.A=null,this.a=this,this.z=0,this.m=0,this.c=0,this.s=0,this.t=null,this.i=e}tf.prototype=Object.create(Ms.prototype);function fz(t){for(var e=new tf(t,0),r,n=[e],i,a,s,o;r=n.pop();)if(a=r._.children)for(r.children=new Array(o=a.length),s=o-1;s>=0;--s)n.push(i=r.children[s]=new tf(a[s],s)),i.parent=r;return(e.parent=new tf(null,0)).children=[e],e}function dz(){var t=lz,e=1,r=1,n=null;function i(u){var h=fz(u);if(h.eachAfter(a),h.parent.m=-h.z,h.eachBefore(s),n)u.eachBefore(l);else{var d=u,f=u,p=u;u.eachBefore(function(x){x.xf.x&&(f=x),x.depth>p.depth&&(p=x)});var m=d===f?1:t(d,f)/2,_=m-d.x,y=e/(f.x+m+_),b=r/(p.depth||1);u.eachBefore(function(x){x.x=(x.x+_)*y,x.y=x.depth*b})}return u}function a(u){var h=u.children,d=u.parent.children,f=u.i?d[u.i-1]:null;if(h){uz(u);var p=(h[0].z+h[h.length-1].z)/2;f?(u.z=f.z+t(u._,f._),u.m=u.z-p):u.z=p}else f&&(u.z=f.z+t(u._,f._));u.parent.A=o(u,f,u.parent.A||d[0])}function s(u){u._.x=u.z+u.parent.m,u.m+=u.parent.m}function o(u,h,d){if(h){for(var f=u,p=u,m=h,_=f.parent.children[0],y=f.m,b=p.m,x=m.m,k=_.m,T;m=J2(m),f=Q2(f),m&&f;)_=Q2(_),p=J2(p),p.a=u,T=m.z+x-f.z-y+t(m._,f._),T>0&&(cz(hz(m,u,d),u,T),y+=T,b+=T),x+=m.m,y+=f.m,k+=_.m,b+=p.m;m&&!J2(p)&&(p.t=m,p.m+=x-b),f&&!Q2(_)&&(_.t=f,_.m+=y-k,d=u)}return d}function l(u){u.x*=e,u.y=u.depth*r}return i.separation=function(u){return arguments.length?(t=u,i):t},i.size=function(u){return arguments.length?(n=!1,e=+u[0],r=+u[1],i):n?null:[e,r]},i.nodeSize=function(u){return arguments.length?(n=!0,e=+u[0],r=+u[1],i):n?[e,r]:null},i}function ef(t,e,r,n,i){for(var a=t.children,s,o=-1,l=a.length,u=t.value&&(i-r)/t.value;++ox&&(x=u),M=y*y*C,k=Math.max(x/M,M/b),k>T){y-=u;break}T=k}s.push(l={value:y,dice:p1?n:1)},r}(Nx);function pz(){var t=Dx,e=!1,r=1,n=1,i=[0],a=Ls,s=Ls,o=Ls,l=Ls,u=Ls;function h(f){return f.x0=f.y0=0,f.x1=r,f.y1=n,f.eachBefore(d),i=[0],e&&f.eachBefore(Lx),f}function d(f){var p=i[f.depth],m=f.x0+p,_=f.y0+p,y=f.x1-p,b=f.y1-p;y=f-1){var x=a[d];x.x0=m,x.y0=_,x.x1=y,x.y1=b;return}for(var k=u[d],T=p/2+k,C=d+1,M=f-1;C>>1;u[S]b-_){var L=p?(m*A+y*R)/p:y;h(d,C,R,m,_,L,b),h(C,f,A,L,_,y,b)}else{var v=p?(_*A+b*R)/p:b;h(d,C,R,m,_,y,v),h(C,f,A,m,v,y,b)}}}function yz(t,e,r,n,i){(t.depth&1?ef:hc)(t,e,r,n,i)}const mz=function t(e){function r(n,i,a,s,o){if((l=n._squarify)&&l.ratio===e)for(var l,u,h,d,f=-1,p,m=l.length,_=n.value;++f1?n:1)},r}(Nx);function bz(t){for(var e=-1,r=t.length,n,i=t[r-1],a=0;++e1&&vz(t[r[n-2]],t[r[n-1]],t[i])<=0;)--n;r[n++]=i}return r.slice(0,n)}function kz(t){if((r=t.length)<3)return null;var e,r,n=new Array(r),i=new Array(r);for(e=0;e=0;--e)u.push(t[n[a[e]][2]]);for(e=+o;ea!=o>a&&i<(s-l)*(a-u)/(o-u)+l&&(h=!h),s=l,o=u;return h}function Tz(t){for(var e=-1,r=t.length,n=t[r-1],i,a,s=n[0],o=n[1],l=0;++e1);return n+i*o*Math.sqrt(-2*Math.log(s)/s)}}return r.source=t,r}(Ir),Sz=function t(e){var r=tp.source(e);function n(){var i=r.apply(this,arguments);return function(){return Math.exp(i())}}return n.source=t,n}(Ir),Fx=function t(e){function r(n){return(n=+n)<=0?()=>0:function(){for(var i=0,a=n;a>1;--a)i+=e();return i+a*e()}}return r.source=t,r}(Ir),Az=function t(e){var r=Fx.source(e);function n(i){if((i=+i)==0)return e;var a=r(i);return function(){return a()/i}}return n.source=t,n}(Ir),Mz=function t(e){function r(n){return function(){return-Math.log1p(-e())/n}}return r.source=t,r}(Ir),Lz=function t(e){function r(n){if((n=+n)<0)throw new RangeError("invalid alpha");return n=1/-n,function(){return Math.pow(1-e(),n)}}return r.source=t,r}(Ir),Rz=function t(e){function r(n){if((n=+n)<0||n>1)throw new RangeError("invalid p");return function(){return Math.floor(e()+n)}}return r.source=t,r}(Ir),Px=function t(e){function r(n){if((n=+n)<0||n>1)throw new RangeError("invalid p");return n===0?()=>1/0:n===1?()=>1:(n=Math.log1p(-n),function(){return 1+Math.floor(Math.log1p(-e())/n)})}return r.source=t,r}(Ir),ep=function t(e){var r=tp.source(e)();function n(i,a){if((i=+i)<0)throw new RangeError("invalid k");if(i===0)return()=>0;if(a=a==null?1:+a,i===1)return()=>-Math.log1p(-e())*a;var s=(i<1?i+1:i)-1/3,o=1/(3*Math.sqrt(s)),l=i<1?()=>Math.pow(e(),1/i):()=>1;return function(){do{do var u=r(),h=1+o*u;while(h<=0);h*=h*h;var d=1-e()}while(d>=1-.0331*u*u*u*u&&Math.log(d)>=.5*u*u+s*(1-h+Math.log(h)));return s*h*l()*a}}return n.source=t,n}(Ir),qx=function t(e){var r=ep.source(e);function n(i,a){var s=r(i),o=r(a);return function(){var l=s();return l===0?0:l/(l+o())}}return n.source=t,n}(Ir),Vx=function t(e){var r=Px.source(e),n=qx.source(e);function i(a,s){return a=+a,(s=+s)>=1?()=>a:s<=0?()=>0:function(){for(var o=0,l=a,u=s;l*u>16&&l*(1-u)>16;){var h=Math.floor((l+1)*u),d=n(h,l-h+1)();d<=u?(o+=h,l-=h,u=(u-d)/(1-d)):(l=h-1,u/=d)}for(var f=u<.5,p=f?u:1-u,m=r(p),_=m(),y=0;_<=l;++y)_+=m();return o+(f?y:l-y)}}return i.source=t,i}(Ir),Iz=function t(e){function r(n,i,a){var s;return(n=+n)==0?s=o=>-Math.log(o):(n=1/n,s=o=>Math.pow(o,n)),i=i==null?0:+i,a=a==null?1:+a,function(){return i+a*s(-Math.log1p(-e()))}}return r.source=t,r}(Ir),Nz=function t(e){function r(n,i){return n=n==null?0:+n,i=i==null?1:+i,function(){return n+i*Math.tan(Math.PI*e())}}return r.source=t,r}(Ir),Bz=function t(e){function r(n,i){return n=n==null?0:+n,i=i==null?1:+i,function(){var a=e();return n+i*Math.log(a/(1-a))}}return r.source=t,r}(Ir),Dz=function t(e){var r=ep.source(e),n=Vx.source(e);function i(a){return function(){for(var s=0,o=a;o>16;){var l=Math.floor(.875*o),u=r(l)();if(u>o)return s+n(l-1,o/u)();s+=l,o-=u}for(var h=-Math.log1p(-e()),d=0;h<=o;++d)h-=Math.log1p(-e());return s+d}}return i.source=t,i}(Ir),Oz=1664525,Fz=1013904223,zx=1/4294967296;function Pz(t=Math.random()){let e=(0<=t&&t<1?t/zx:Math.abs(t))|0;return()=>(e=Oz*e+Fz|0,zx*(e>>>0))}function On(t,e){switch(arguments.length){case 0:break;case 1:this.range(t);break;default:this.range(e).domain(t);break}return this}function ta(t,e){switch(arguments.length){case 0:break;case 1:{typeof t=="function"?this.interpolator(t):this.range(t);break}default:{this.domain(t),typeof e=="function"?this.interpolator(e):this.range(e);break}}return this}const rp=Symbol("implicit");function rf(){var t=new kl,e=[],r=[],n=rp;function i(a){let s=t.get(a);if(s===void 0){if(n!==rp)return n;t.set(a,s=e.push(a)-1)}return r[s%r.length]}return i.domain=function(a){if(!arguments.length)return e.slice();e=[],t=new kl;for(const s of a)t.has(s)||t.set(s,e.push(s)-1);return i},i.range=function(a){return arguments.length?(r=Array.from(a),i):r.slice()},i.unknown=function(a){return arguments.length?(n=a,i):n},i.copy=function(){return rf(e,r).unknown(n)},On.apply(i,arguments),i}function np(){var t=rf().unknown(void 0),e=t.domain,r=t.range,n=0,i=1,a,s,o=!1,l=0,u=0,h=.5;delete t.unknown;function d(){var f=e().length,p=ie&&(r=t,t=e,e=r),function(n){return Math.max(t,Math.min(e,n))}}function Yz(t,e,r){var n=t[0],i=t[1],a=e[0],s=e[1];return i2?Uz:Yz,l=u=null,d}function d(f){return f==null||isNaN(f=+f)?a:(l||(l=o(t.map(n),e,r)))(n(s(f)))}return d.invert=function(f){return s(i((u||(u=o(e,t.map(n),Bn)))(f)))},d.domain=function(f){return arguments.length?(t=Array.from(f,nf),h()):t.slice()},d.range=function(f){return arguments.length?(e=Array.from(f),h()):e.slice()},d.rangeRound=function(f){return e=Array.from(f),r=Gu,h()},d.clamp=function(f){return arguments.length?(s=f?!0:an,h()):s!==an},d.interpolate=function(f){return arguments.length?(r=f,h()):r},d.unknown=function(f){return arguments.length?(a=f,d):a},function(f,p){return n=f,i=p,h()}}function ap(){return af()(an,an)}function Wx(t,e,r,n){var i=wl(t,e,r),a;switch(n=Co(n==null?",f":n),n.type){case"s":{var s=Math.max(Math.abs(t),Math.abs(e));return n.precision==null&&!isNaN(a=e6(i,s))&&(n.precision=a),Jd(n,s)}case"":case"e":case"g":case"p":case"r":{n.precision==null&&!isNaN(a=r6(i,Math.max(Math.abs(t),Math.abs(e))))&&(n.precision=a-(n.type==="e"));break}case"f":case"%":{n.precision==null&&!isNaN(a=t6(i))&&(n.precision=a-(n.type==="%")*2);break}}return gh(n)}function Oa(t){var e=t.domain;return t.ticks=function(r){var n=e();return hs(n[0],n[n.length-1],r==null?10:r)},t.tickFormat=function(r,n){var i=e();return Wx(i[0],i[i.length-1],r==null?10:r,n)},t.nice=function(r){r==null&&(r=10);var n=e(),i=0,a=n.length-1,s=n[i],o=n[a],l,u,h=10;for(o0;){if(u=oo(s,o,r),u===l)return n[i]=s,n[a]=o,e(n);if(u>0)s=Math.floor(s/u)*u,o=Math.ceil(o/u)*u;else if(u<0)s=Math.ceil(s*u)/u,o=Math.floor(o*u)/u;else break;l=u}return t},t}function sp(){var t=ap();return t.copy=function(){return fc(t,sp())},On.apply(t,arguments),Oa(t)}function Hx(t){var e;function r(n){return n==null||isNaN(n=+n)?e:n}return r.invert=r,r.domain=r.range=function(n){return arguments.length?(t=Array.from(n,nf),r):t.slice()},r.unknown=function(n){return arguments.length?(e=n,r):e},r.copy=function(){return Hx(t).unknown(e)},t=arguments.length?Array.from(t,nf):[0,1],Oa(r)}function Gx(t,e){t=t.slice();var r=0,n=t.length-1,i=t[r],a=t[n],s;return aMath.pow(t,e)}function $z(t){return t===Math.E?Math.log:t===10&&Math.log10||t===2&&Math.log2||(t=Math.log(t),e=>Math.log(e)/t)}function Xx(t){return(e,r)=>-t(-e,r)}function op(t){const e=t(jx,$x),r=e.domain;let n=10,i,a;function s(){return i=$z(n),a=jz(n),r()[0]<0?(i=Xx(i),a=Xx(a),t(Wz,Hz)):t(jx,$x),e}return e.base=function(o){return arguments.length?(n=+o,s()):n},e.domain=function(o){return arguments.length?(r(o),s()):r()},e.ticks=o=>{const l=r();let u=l[0],h=l[l.length-1];const d=h0){for(;f<=p;++f)for(m=1;mh)break;b.push(_)}}else for(;f<=p;++f)for(m=n-1;m>=1;--m)if(_=f>0?m/a(-f):m*a(f),!(_h)break;b.push(_)}b.length*2{if(o==null&&(o=10),l==null&&(l=n===10?"s":","),typeof l!="function"&&(!(n%1)&&(l=Co(l)).precision==null&&(l.trim=!0),l=gh(l)),o===1/0)return l;const u=Math.max(1,n*o/e.ticks().length);return h=>{let d=h/a(Math.round(i(h)));return d*nr(Gx(r(),{floor:o=>a(Math.floor(i(o))),ceil:o=>a(Math.ceil(i(o)))})),e}function Kx(){const t=op(af()).domain([1,10]);return t.copy=()=>fc(t,Kx()).base(t.base()),On.apply(t,arguments),t}function Zx(t){return function(e){return Math.sign(e)*Math.log1p(Math.abs(e/t))}}function Qx(t){return function(e){return Math.sign(e)*Math.expm1(Math.abs(e))*t}}function lp(t){var e=1,r=t(Zx(e),Qx(e));return r.constant=function(n){return arguments.length?t(Zx(e=+n),Qx(e)):e},Oa(r)}function Jx(){var t=lp(af());return t.copy=function(){return fc(t,Jx()).constant(t.constant())},On.apply(t,arguments)}function t8(t){return function(e){return e<0?-Math.pow(-e,t):Math.pow(e,t)}}function Xz(t){return t<0?-Math.sqrt(-t):Math.sqrt(t)}function Kz(t){return t<0?-t*t:t*t}function cp(t){var e=t(an,an),r=1;function n(){return r===1?t(an,an):r===.5?t(Xz,Kz):t(t8(r),t8(1/r))}return e.exponent=function(i){return arguments.length?(r=+i,n()):r},Oa(e)}function up(){var t=cp(af());return t.copy=function(){return fc(t,up()).exponent(t.exponent())},On.apply(t,arguments),t}function Zz(){return up.apply(null,arguments).exponent(.5)}function e8(t){return Math.sign(t)*t*t}function Qz(t){return Math.sign(t)*Math.sqrt(Math.abs(t))}function r8(){var t=ap(),e=[0,1],r=!1,n;function i(a){var s=Qz(t(a));return isNaN(s)?n:r?Math.round(s):s}return i.invert=function(a){return t.invert(e8(a))},i.domain=function(a){return arguments.length?(t.domain(a),i):t.domain()},i.range=function(a){return arguments.length?(t.range((e=Array.from(a,nf)).map(e8)),i):e.slice()},i.rangeRound=function(a){return i.range(a).round(!0)},i.round=function(a){return arguments.length?(r=!!a,i):r},i.clamp=function(a){return arguments.length?(t.clamp(a),i):t.clamp()},i.unknown=function(a){return arguments.length?(n=a,i):n},i.copy=function(){return r8(t.domain(),e).round(r).clamp(t.clamp()).unknown(n)},On.apply(i,arguments),Oa(i)}function n8(){var t=[],e=[],r=[],n;function i(){var s=0,o=Math.max(1,e.length);for(r=new Array(o-1);++s0?r[o-1]:t[0],o=r?[n[r-1],e]:[n[u-1],n[u]]},s.unknown=function(l){return arguments.length&&(a=l),s},s.thresholds=function(){return n.slice()},s.copy=function(){return i8().domain([t,e]).range(i).unknown(a)},On.apply(Oa(s),arguments)}function a8(){var t=[.5],e=[0,1],r,n=1;function i(a){return a!=null&&a<=a?e[cs(t,a,0,n)]:r}return i.domain=function(a){return arguments.length?(t=Array.from(a),n=Math.min(t.length,e.length-1),i):t.slice()},i.range=function(a){return arguments.length?(e=Array.from(a),n=Math.min(t.length,e.length-1),i):e.slice()},i.invertExtent=function(a){var s=e.indexOf(a);return[t[s-1],t[s]]},i.unknown=function(a){return arguments.length?(r=a,i):r},i.copy=function(){return a8().domain(t).range(e).unknown(r)},On.apply(i,arguments)}var hp=new Date,fp=new Date;function xr(t,e,r,n){function i(a){return t(a=arguments.length===0?new Date:new Date(+a)),a}return i.floor=function(a){return t(a=new Date(+a)),a},i.ceil=function(a){return t(a=new Date(a-1)),e(a,1),t(a),a},i.round=function(a){var s=i(a),o=i.ceil(a);return a-s0))return l;do l.push(u=new Date(+a)),e(a,o),t(a);while(u=s)for(;t(s),!a(s);)s.setTime(s-1)},function(s,o){if(s>=s)if(o<0)for(;++o<=0;)for(;e(s,-1),!a(s););else for(;--o>=0;)for(;e(s,1),!a(s););})},r&&(i.count=function(a,s){return hp.setTime(+a),fp.setTime(+s),t(hp),t(fp),Math.floor(r(hp,fp))},i.every=function(a){return a=Math.floor(a),!isFinite(a)||!(a>0)?null:a>1?i.filter(n?function(s){return n(s)%a===0}:function(s){return i.count(0,s)%a===0}):i}),i}var sf=xr(function(){},function(t,e){t.setTime(+t+e)},function(t,e){return e-t});sf.every=function(t){return t=Math.floor(t),!isFinite(t)||!(t>0)?null:t>1?xr(function(e){e.setTime(Math.floor(e/t)*t)},function(e,r){e.setTime(+e+r*t)},function(e,r){return(r-e)/t}):sf};const dp=sf;var s8=sf.range;const ea=1e3,Fn=ea*60,ra=Fn*60,Rs=ra*24,pp=Rs*7,o8=Rs*30,gp=Rs*365;var l8=xr(function(t){t.setTime(t-t.getMilliseconds())},function(t,e){t.setTime(+t+e*ea)},function(t,e){return(e-t)/ea},function(t){return t.getUTCSeconds()});const Fa=l8;var c8=l8.range,u8=xr(function(t){t.setTime(t-t.getMilliseconds()-t.getSeconds()*ea)},function(t,e){t.setTime(+t+e*Fn)},function(t,e){return(e-t)/Fn},function(t){return t.getMinutes()});const yp=u8;var Jz=u8.range,h8=xr(function(t){t.setTime(t-t.getMilliseconds()-t.getSeconds()*ea-t.getMinutes()*Fn)},function(t,e){t.setTime(+t+e*ra)},function(t,e){return(e-t)/ra},function(t){return t.getHours()});const mp=h8;var tY=h8.range,f8=xr(t=>t.setHours(0,0,0,0),(t,e)=>t.setDate(t.getDate()+e),(t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*Fn)/Rs,t=>t.getDate()-1);const dc=f8;var eY=f8.range;function Is(t){return xr(function(e){e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)},function(e,r){e.setDate(e.getDate()+r*7)},function(e,r){return(r-e-(r.getTimezoneOffset()-e.getTimezoneOffset())*Fn)/pp})}var Do=Is(0),pc=Is(1),d8=Is(2),p8=Is(3),Ns=Is(4),g8=Is(5),y8=Is(6),m8=Do.range,rY=pc.range,nY=d8.range,iY=p8.range,aY=Ns.range,sY=g8.range,oY=y8.range,b8=xr(function(t){t.setDate(1),t.setHours(0,0,0,0)},function(t,e){t.setMonth(t.getMonth()+e)},function(t,e){return e.getMonth()-t.getMonth()+(e.getFullYear()-t.getFullYear())*12},function(t){return t.getMonth()});const bp=b8;var lY=b8.range,_p=xr(function(t){t.setMonth(0,1),t.setHours(0,0,0,0)},function(t,e){t.setFullYear(t.getFullYear()+e)},function(t,e){return e.getFullYear()-t.getFullYear()},function(t){return t.getFullYear()});_p.every=function(t){return!isFinite(t=Math.floor(t))||!(t>0)?null:xr(function(e){e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)},function(e,r){e.setFullYear(e.getFullYear()+r*t)})};const Pa=_p;var cY=_p.range,_8=xr(function(t){t.setUTCSeconds(0,0)},function(t,e){t.setTime(+t+e*Fn)},function(t,e){return(e-t)/Fn},function(t){return t.getUTCMinutes()});const vp=_8;var uY=_8.range,v8=xr(function(t){t.setUTCMinutes(0,0,0)},function(t,e){t.setTime(+t+e*ra)},function(t,e){return(e-t)/ra},function(t){return t.getUTCHours()});const xp=v8;var hY=v8.range,x8=xr(function(t){t.setUTCHours(0,0,0,0)},function(t,e){t.setUTCDate(t.getUTCDate()+e)},function(t,e){return(e-t)/Rs},function(t){return t.getUTCDate()-1});const gc=x8;var fY=x8.range;function Bs(t){return xr(function(e){e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)},function(e,r){e.setUTCDate(e.getUTCDate()+r*7)},function(e,r){return(r-e)/pp})}var Oo=Bs(0),yc=Bs(1),k8=Bs(2),w8=Bs(3),Ds=Bs(4),T8=Bs(5),E8=Bs(6),C8=Oo.range,dY=yc.range,pY=k8.range,gY=w8.range,yY=Ds.range,mY=T8.range,bY=E8.range,S8=xr(function(t){t.setUTCDate(1),t.setUTCHours(0,0,0,0)},function(t,e){t.setUTCMonth(t.getUTCMonth()+e)},function(t,e){return e.getUTCMonth()-t.getUTCMonth()+(e.getUTCFullYear()-t.getUTCFullYear())*12},function(t){return t.getUTCMonth()});const kp=S8;var _Y=S8.range,wp=xr(function(t){t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)},function(t,e){t.setUTCFullYear(t.getUTCFullYear()+e)},function(t,e){return e.getUTCFullYear()-t.getUTCFullYear()},function(t){return t.getUTCFullYear()});wp.every=function(t){return!isFinite(t=Math.floor(t))||!(t>0)?null:xr(function(e){e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)},function(e,r){e.setUTCFullYear(e.getUTCFullYear()+r*t)})};const qa=wp;var vY=wp.range;function A8(t,e,r,n,i,a){const s=[[Fa,1,ea],[Fa,5,5*ea],[Fa,15,15*ea],[Fa,30,30*ea],[a,1,Fn],[a,5,5*Fn],[a,15,15*Fn],[a,30,30*Fn],[i,1,ra],[i,3,3*ra],[i,6,6*ra],[i,12,12*ra],[n,1,Rs],[n,2,2*Rs],[r,1,pp],[e,1,o8],[e,3,3*o8],[t,1,gp]];function o(u,h,d){const f=hy).right(s,f);if(p===s.length)return t.every(wl(u/gp,h/gp,d));if(p===0)return dp.every(Math.max(wl(u,h,d),1));const[m,_]=s[f/s[p-1][2]53)return null;"w"in U||(U.w=1),"Z"in U?(j=Ep(mc(U.y,0,1)),P=j.getUTCDay(),j=P>4||P===0?yc.ceil(j):yc(j),j=gc.offset(j,(U.V-1)*7),U.y=j.getUTCFullYear(),U.m=j.getUTCMonth(),U.d=j.getUTCDate()+(U.w+6)%7):(j=Tp(mc(U.y,0,1)),P=j.getDay(),j=P>4||P===0?pc.ceil(j):pc(j),j=dc.offset(j,(U.V-1)*7),U.y=j.getFullYear(),U.m=j.getMonth(),U.d=j.getDate()+(U.w+6)%7)}else("W"in U||"U"in U)&&("w"in U||(U.w="u"in U?U.u%7:"W"in U?1:0),P="Z"in U?Ep(mc(U.y,0,1)).getUTCDay():Tp(mc(U.y,0,1)).getDay(),U.m=0,U.d="W"in U?(U.w+6)%7+U.W*7-(P+5)%7:U.w+U.U*7-(P+6)%7);return"Z"in U?(U.H+=U.Z/100|0,U.M+=U.Z%100,Ep(U)):Tp(U)}}function R(V,Q,q,U){for(var F=0,j=Q.length,P=q.length,et,at;F=P)return-1;if(et=Q.charCodeAt(F++),et===37){if(et=Q.charAt(F++),at=C[et in B8?Q.charAt(F++):et],!at||(U=at(V,q,U))<0)return-1}else if(et!=q.charCodeAt(U++))return-1}return U}function A(V,Q,q){var U=u.exec(Q.slice(q));return U?(V.p=h.get(U[0].toLowerCase()),q+U[0].length):-1}function L(V,Q,q){var U=p.exec(Q.slice(q));return U?(V.w=m.get(U[0].toLowerCase()),q+U[0].length):-1}function v(V,Q,q){var U=d.exec(Q.slice(q));return U?(V.w=f.get(U[0].toLowerCase()),q+U[0].length):-1}function B(V,Q,q){var U=b.exec(Q.slice(q));return U?(V.m=x.get(U[0].toLowerCase()),q+U[0].length):-1}function w(V,Q,q){var U=_.exec(Q.slice(q));return U?(V.m=y.get(U[0].toLowerCase()),q+U[0].length):-1}function D(V,Q,q){return R(V,e,Q,q)}function N(V,Q,q){return R(V,r,Q,q)}function z(V,Q,q){return R(V,n,Q,q)}function X(V){return s[V.getDay()]}function ct(V){return a[V.getDay()]}function J(V){return l[V.getMonth()]}function Y(V){return o[V.getMonth()]}function $(V){return i[+(V.getHours()>=12)]}function lt(V){return 1+~~(V.getMonth()/3)}function ut(V){return s[V.getUTCDay()]}function W(V){return a[V.getUTCDay()]}function tt(V){return l[V.getUTCMonth()]}function K(V){return o[V.getUTCMonth()]}function it(V){return i[+(V.getUTCHours()>=12)]}function Z(V){return 1+~~(V.getUTCMonth()/3)}return{format:function(V){var Q=M(V+="",k);return Q.toString=function(){return V},Q},parse:function(V){var Q=S(V+="",!1);return Q.toString=function(){return V},Q},utcFormat:function(V){var Q=M(V+="",T);return Q.toString=function(){return V},Q},utcParse:function(V){var Q=S(V+="",!0);return Q.toString=function(){return V},Q}}}var B8={"-":"",_:" ",0:"0"},Ar=/^\s*\d+/,xY=/^%/,kY=/[\\^$*+?|[\]().{}]/g;function Oe(t,e,r){var n=t<0?"-":"",i=(n?-t:t)+"",a=i.length;return n+(a[e.toLowerCase(),r]))}function TY(t,e,r){var n=Ar.exec(e.slice(r,r+1));return n?(t.w=+n[0],r+n[0].length):-1}function EY(t,e,r){var n=Ar.exec(e.slice(r,r+1));return n?(t.u=+n[0],r+n[0].length):-1}function CY(t,e,r){var n=Ar.exec(e.slice(r,r+2));return n?(t.U=+n[0],r+n[0].length):-1}function SY(t,e,r){var n=Ar.exec(e.slice(r,r+2));return n?(t.V=+n[0],r+n[0].length):-1}function AY(t,e,r){var n=Ar.exec(e.slice(r,r+2));return n?(t.W=+n[0],r+n[0].length):-1}function D8(t,e,r){var n=Ar.exec(e.slice(r,r+4));return n?(t.y=+n[0],r+n[0].length):-1}function O8(t,e,r){var n=Ar.exec(e.slice(r,r+2));return n?(t.y=+n[0]+(+n[0]>68?1900:2e3),r+n[0].length):-1}function MY(t,e,r){var n=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(r,r+6));return n?(t.Z=n[1]?0:-(n[2]+(n[3]||"00")),r+n[0].length):-1}function LY(t,e,r){var n=Ar.exec(e.slice(r,r+1));return n?(t.q=n[0]*3-3,r+n[0].length):-1}function RY(t,e,r){var n=Ar.exec(e.slice(r,r+2));return n?(t.m=n[0]-1,r+n[0].length):-1}function F8(t,e,r){var n=Ar.exec(e.slice(r,r+2));return n?(t.d=+n[0],r+n[0].length):-1}function IY(t,e,r){var n=Ar.exec(e.slice(r,r+3));return n?(t.m=0,t.d=+n[0],r+n[0].length):-1}function P8(t,e,r){var n=Ar.exec(e.slice(r,r+2));return n?(t.H=+n[0],r+n[0].length):-1}function NY(t,e,r){var n=Ar.exec(e.slice(r,r+2));return n?(t.M=+n[0],r+n[0].length):-1}function BY(t,e,r){var n=Ar.exec(e.slice(r,r+2));return n?(t.S=+n[0],r+n[0].length):-1}function DY(t,e,r){var n=Ar.exec(e.slice(r,r+3));return n?(t.L=+n[0],r+n[0].length):-1}function OY(t,e,r){var n=Ar.exec(e.slice(r,r+6));return n?(t.L=Math.floor(n[0]/1e3),r+n[0].length):-1}function FY(t,e,r){var n=xY.exec(e.slice(r,r+1));return n?r+n[0].length:-1}function PY(t,e,r){var n=Ar.exec(e.slice(r));return n?(t.Q=+n[0],r+n[0].length):-1}function qY(t,e,r){var n=Ar.exec(e.slice(r));return n?(t.s=+n[0],r+n[0].length):-1}function q8(t,e){return Oe(t.getDate(),e,2)}function VY(t,e){return Oe(t.getHours(),e,2)}function zY(t,e){return Oe(t.getHours()%12||12,e,2)}function YY(t,e){return Oe(1+dc.count(Pa(t),t),e,3)}function V8(t,e){return Oe(t.getMilliseconds(),e,3)}function UY(t,e){return V8(t,e)+"000"}function WY(t,e){return Oe(t.getMonth()+1,e,2)}function HY(t,e){return Oe(t.getMinutes(),e,2)}function GY(t,e){return Oe(t.getSeconds(),e,2)}function jY(t){var e=t.getDay();return e===0?7:e}function $Y(t,e){return Oe(Do.count(Pa(t)-1,t),e,2)}function z8(t){var e=t.getDay();return e>=4||e===0?Ns(t):Ns.ceil(t)}function XY(t,e){return t=z8(t),Oe(Ns.count(Pa(t),t)+(Pa(t).getDay()===4),e,2)}function KY(t){return t.getDay()}function ZY(t,e){return Oe(pc.count(Pa(t)-1,t),e,2)}function QY(t,e){return Oe(t.getFullYear()%100,e,2)}function JY(t,e){return t=z8(t),Oe(t.getFullYear()%100,e,2)}function tU(t,e){return Oe(t.getFullYear()%1e4,e,4)}function eU(t,e){var r=t.getDay();return t=r>=4||r===0?Ns(t):Ns.ceil(t),Oe(t.getFullYear()%1e4,e,4)}function rU(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+Oe(e/60|0,"0",2)+Oe(e%60,"0",2)}function Y8(t,e){return Oe(t.getUTCDate(),e,2)}function nU(t,e){return Oe(t.getUTCHours(),e,2)}function iU(t,e){return Oe(t.getUTCHours()%12||12,e,2)}function aU(t,e){return Oe(1+gc.count(qa(t),t),e,3)}function U8(t,e){return Oe(t.getUTCMilliseconds(),e,3)}function sU(t,e){return U8(t,e)+"000"}function oU(t,e){return Oe(t.getUTCMonth()+1,e,2)}function lU(t,e){return Oe(t.getUTCMinutes(),e,2)}function cU(t,e){return Oe(t.getUTCSeconds(),e,2)}function uU(t){var e=t.getUTCDay();return e===0?7:e}function hU(t,e){return Oe(Oo.count(qa(t)-1,t),e,2)}function W8(t){var e=t.getUTCDay();return e>=4||e===0?Ds(t):Ds.ceil(t)}function fU(t,e){return t=W8(t),Oe(Ds.count(qa(t),t)+(qa(t).getUTCDay()===4),e,2)}function dU(t){return t.getUTCDay()}function pU(t,e){return Oe(yc.count(qa(t)-1,t),e,2)}function gU(t,e){return Oe(t.getUTCFullYear()%100,e,2)}function yU(t,e){return t=W8(t),Oe(t.getUTCFullYear()%100,e,2)}function mU(t,e){return Oe(t.getUTCFullYear()%1e4,e,4)}function bU(t,e){var r=t.getUTCDay();return t=r>=4||r===0?Ds(t):Ds.ceil(t),Oe(t.getUTCFullYear()%1e4,e,4)}function _U(){return"+0000"}function H8(){return"%"}function G8(t){return+t}function j8(t){return Math.floor(+t/1e3)}var Fo,vc,$8,of,Cp;X8({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});function X8(t){return Fo=N8(t),vc=Fo.format,$8=Fo.parse,of=Fo.utcFormat,Cp=Fo.utcParse,Fo}var K8="%Y-%m-%dT%H:%M:%S.%LZ";function vU(t){return t.toISOString()}var xU=Date.prototype.toISOString?vU:of(K8);const kU=xU;function wU(t){var e=new Date(t);return isNaN(e)?null:e}var TU=+new Date("2000-01-01T00:00:00.000Z")?wU:Cp(K8);const EU=TU;function CU(t){return new Date(t)}function SU(t){return t instanceof Date?+t:+new Date(+t)}function Sp(t,e,r,n,i,a,s,o,l,u){var h=ap(),d=h.invert,f=h.domain,p=u(".%L"),m=u(":%S"),_=u("%I:%M"),y=u("%I %p"),b=u("%a %d"),x=u("%b %d"),k=u("%B"),T=u("%Y");function C(M){return(l(M)e(i/(t.length-1)))},r.quantiles=function(n){return Array.from({length:n+1},(i,a)=>Cl(t,a/n))},r.copy=function(){return e7(e).domain(t)},ta.apply(r,arguments)}function cf(){var t=0,e=.5,r=1,n=1,i,a,s,o,l,u=an,h,d=!1,f;function p(_){return isNaN(_=+_)?f:(_=.5+((_=+h(_))-a)*(n*_O5(t[t.length-1]);var a7=new Array(3).concat("d8b365f5f5f55ab4ac","a6611adfc27d80cdc1018571","a6611adfc27df5f5f580cdc1018571","8c510ad8b365f6e8c3c7eae55ab4ac01665e","8c510ad8b365f6e8c3f5f5f5c7eae55ab4ac01665e","8c510abf812ddfc27df6e8c3c7eae580cdc135978f01665e","8c510abf812ddfc27df6e8c3f5f5f5c7eae580cdc135978f01665e","5430058c510abf812ddfc27df6e8c3c7eae580cdc135978f01665e003c30","5430058c510abf812ddfc27df6e8c3f5f5f5c7eae580cdc135978f01665e003c30").map(Ee);const zU=We(a7);var s7=new Array(3).concat("af8dc3f7f7f77fbf7b","7b3294c2a5cfa6dba0008837","7b3294c2a5cff7f7f7a6dba0008837","762a83af8dc3e7d4e8d9f0d37fbf7b1b7837","762a83af8dc3e7d4e8f7f7f7d9f0d37fbf7b1b7837","762a839970abc2a5cfe7d4e8d9f0d3a6dba05aae611b7837","762a839970abc2a5cfe7d4e8f7f7f7d9f0d3a6dba05aae611b7837","40004b762a839970abc2a5cfe7d4e8d9f0d3a6dba05aae611b783700441b","40004b762a839970abc2a5cfe7d4e8f7f7f7d9f0d3a6dba05aae611b783700441b").map(Ee);const YU=We(s7);var o7=new Array(3).concat("e9a3c9f7f7f7a1d76a","d01c8bf1b6dab8e1864dac26","d01c8bf1b6daf7f7f7b8e1864dac26","c51b7de9a3c9fde0efe6f5d0a1d76a4d9221","c51b7de9a3c9fde0eff7f7f7e6f5d0a1d76a4d9221","c51b7dde77aef1b6dafde0efe6f5d0b8e1867fbc414d9221","c51b7dde77aef1b6dafde0eff7f7f7e6f5d0b8e1867fbc414d9221","8e0152c51b7dde77aef1b6dafde0efe6f5d0b8e1867fbc414d9221276419","8e0152c51b7dde77aef1b6dafde0eff7f7f7e6f5d0b8e1867fbc414d9221276419").map(Ee);const UU=We(o7);var l7=new Array(3).concat("998ec3f7f7f7f1a340","5e3c99b2abd2fdb863e66101","5e3c99b2abd2f7f7f7fdb863e66101","542788998ec3d8daebfee0b6f1a340b35806","542788998ec3d8daebf7f7f7fee0b6f1a340b35806","5427888073acb2abd2d8daebfee0b6fdb863e08214b35806","5427888073acb2abd2d8daebf7f7f7fee0b6fdb863e08214b35806","2d004b5427888073acb2abd2d8daebfee0b6fdb863e08214b358067f3b08","2d004b5427888073acb2abd2d8daebf7f7f7fee0b6fdb863e08214b358067f3b08").map(Ee);const WU=We(l7);var c7=new Array(3).concat("ef8a62f7f7f767a9cf","ca0020f4a58292c5de0571b0","ca0020f4a582f7f7f792c5de0571b0","b2182bef8a62fddbc7d1e5f067a9cf2166ac","b2182bef8a62fddbc7f7f7f7d1e5f067a9cf2166ac","b2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac","b2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac","67001fb2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac053061","67001fb2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac053061").map(Ee);const HU=We(c7);var u7=new Array(3).concat("ef8a62ffffff999999","ca0020f4a582bababa404040","ca0020f4a582ffffffbababa404040","b2182bef8a62fddbc7e0e0e09999994d4d4d","b2182bef8a62fddbc7ffffffe0e0e09999994d4d4d","b2182bd6604df4a582fddbc7e0e0e0bababa8787874d4d4d","b2182bd6604df4a582fddbc7ffffffe0e0e0bababa8787874d4d4d","67001fb2182bd6604df4a582fddbc7e0e0e0bababa8787874d4d4d1a1a1a","67001fb2182bd6604df4a582fddbc7ffffffe0e0e0bababa8787874d4d4d1a1a1a").map(Ee);const GU=We(u7);var h7=new Array(3).concat("fc8d59ffffbf91bfdb","d7191cfdae61abd9e92c7bb6","d7191cfdae61ffffbfabd9e92c7bb6","d73027fc8d59fee090e0f3f891bfdb4575b4","d73027fc8d59fee090ffffbfe0f3f891bfdb4575b4","d73027f46d43fdae61fee090e0f3f8abd9e974add14575b4","d73027f46d43fdae61fee090ffffbfe0f3f8abd9e974add14575b4","a50026d73027f46d43fdae61fee090e0f3f8abd9e974add14575b4313695","a50026d73027f46d43fdae61fee090ffffbfe0f3f8abd9e974add14575b4313695").map(Ee);const jU=We(h7);var f7=new Array(3).concat("fc8d59ffffbf91cf60","d7191cfdae61a6d96a1a9641","d7191cfdae61ffffbfa6d96a1a9641","d73027fc8d59fee08bd9ef8b91cf601a9850","d73027fc8d59fee08bffffbfd9ef8b91cf601a9850","d73027f46d43fdae61fee08bd9ef8ba6d96a66bd631a9850","d73027f46d43fdae61fee08bffffbfd9ef8ba6d96a66bd631a9850","a50026d73027f46d43fdae61fee08bd9ef8ba6d96a66bd631a9850006837","a50026d73027f46d43fdae61fee08bffffbfd9ef8ba6d96a66bd631a9850006837").map(Ee);const $U=We(f7);var d7=new Array(3).concat("fc8d59ffffbf99d594","d7191cfdae61abdda42b83ba","d7191cfdae61ffffbfabdda42b83ba","d53e4ffc8d59fee08be6f59899d5943288bd","d53e4ffc8d59fee08bffffbfe6f59899d5943288bd","d53e4ff46d43fdae61fee08be6f598abdda466c2a53288bd","d53e4ff46d43fdae61fee08bffffbfe6f598abdda466c2a53288bd","9e0142d53e4ff46d43fdae61fee08be6f598abdda466c2a53288bd5e4fa2","9e0142d53e4ff46d43fdae61fee08bffffbfe6f598abdda466c2a53288bd5e4fa2").map(Ee);const XU=We(d7);var p7=new Array(3).concat("e5f5f999d8c92ca25f","edf8fbb2e2e266c2a4238b45","edf8fbb2e2e266c2a42ca25f006d2c","edf8fbccece699d8c966c2a42ca25f006d2c","edf8fbccece699d8c966c2a441ae76238b45005824","f7fcfde5f5f9ccece699d8c966c2a441ae76238b45005824","f7fcfde5f5f9ccece699d8c966c2a441ae76238b45006d2c00441b").map(Ee);const KU=We(p7);var g7=new Array(3).concat("e0ecf49ebcda8856a7","edf8fbb3cde38c96c688419d","edf8fbb3cde38c96c68856a7810f7c","edf8fbbfd3e69ebcda8c96c68856a7810f7c","edf8fbbfd3e69ebcda8c96c68c6bb188419d6e016b","f7fcfde0ecf4bfd3e69ebcda8c96c68c6bb188419d6e016b","f7fcfde0ecf4bfd3e69ebcda8c96c68c6bb188419d810f7c4d004b").map(Ee);const ZU=We(g7);var y7=new Array(3).concat("e0f3dba8ddb543a2ca","f0f9e8bae4bc7bccc42b8cbe","f0f9e8bae4bc7bccc443a2ca0868ac","f0f9e8ccebc5a8ddb57bccc443a2ca0868ac","f0f9e8ccebc5a8ddb57bccc44eb3d32b8cbe08589e","f7fcf0e0f3dbccebc5a8ddb57bccc44eb3d32b8cbe08589e","f7fcf0e0f3dbccebc5a8ddb57bccc44eb3d32b8cbe0868ac084081").map(Ee);const QU=We(y7);var m7=new Array(3).concat("fee8c8fdbb84e34a33","fef0d9fdcc8afc8d59d7301f","fef0d9fdcc8afc8d59e34a33b30000","fef0d9fdd49efdbb84fc8d59e34a33b30000","fef0d9fdd49efdbb84fc8d59ef6548d7301f990000","fff7ecfee8c8fdd49efdbb84fc8d59ef6548d7301f990000","fff7ecfee8c8fdd49efdbb84fc8d59ef6548d7301fb300007f0000").map(Ee);const JU=We(m7);var b7=new Array(3).concat("ece2f0a6bddb1c9099","f6eff7bdc9e167a9cf02818a","f6eff7bdc9e167a9cf1c9099016c59","f6eff7d0d1e6a6bddb67a9cf1c9099016c59","f6eff7d0d1e6a6bddb67a9cf3690c002818a016450","fff7fbece2f0d0d1e6a6bddb67a9cf3690c002818a016450","fff7fbece2f0d0d1e6a6bddb67a9cf3690c002818a016c59014636").map(Ee);const tW=We(b7);var _7=new Array(3).concat("ece7f2a6bddb2b8cbe","f1eef6bdc9e174a9cf0570b0","f1eef6bdc9e174a9cf2b8cbe045a8d","f1eef6d0d1e6a6bddb74a9cf2b8cbe045a8d","f1eef6d0d1e6a6bddb74a9cf3690c00570b0034e7b","fff7fbece7f2d0d1e6a6bddb74a9cf3690c00570b0034e7b","fff7fbece7f2d0d1e6a6bddb74a9cf3690c00570b0045a8d023858").map(Ee);const eW=We(_7);var v7=new Array(3).concat("e7e1efc994c7dd1c77","f1eef6d7b5d8df65b0ce1256","f1eef6d7b5d8df65b0dd1c77980043","f1eef6d4b9dac994c7df65b0dd1c77980043","f1eef6d4b9dac994c7df65b0e7298ace125691003f","f7f4f9e7e1efd4b9dac994c7df65b0e7298ace125691003f","f7f4f9e7e1efd4b9dac994c7df65b0e7298ace125698004367001f").map(Ee);const rW=We(v7);var x7=new Array(3).concat("fde0ddfa9fb5c51b8a","feebe2fbb4b9f768a1ae017e","feebe2fbb4b9f768a1c51b8a7a0177","feebe2fcc5c0fa9fb5f768a1c51b8a7a0177","feebe2fcc5c0fa9fb5f768a1dd3497ae017e7a0177","fff7f3fde0ddfcc5c0fa9fb5f768a1dd3497ae017e7a0177","fff7f3fde0ddfcc5c0fa9fb5f768a1dd3497ae017e7a017749006a").map(Ee);const nW=We(x7);var k7=new Array(3).concat("edf8b17fcdbb2c7fb8","ffffcca1dab441b6c4225ea8","ffffcca1dab441b6c42c7fb8253494","ffffccc7e9b47fcdbb41b6c42c7fb8253494","ffffccc7e9b47fcdbb41b6c41d91c0225ea80c2c84","ffffd9edf8b1c7e9b47fcdbb41b6c41d91c0225ea80c2c84","ffffd9edf8b1c7e9b47fcdbb41b6c41d91c0225ea8253494081d58").map(Ee);const iW=We(k7);var w7=new Array(3).concat("f7fcb9addd8e31a354","ffffccc2e69978c679238443","ffffccc2e69978c67931a354006837","ffffccd9f0a3addd8e78c67931a354006837","ffffccd9f0a3addd8e78c67941ab5d238443005a32","ffffe5f7fcb9d9f0a3addd8e78c67941ab5d238443005a32","ffffe5f7fcb9d9f0a3addd8e78c67941ab5d238443006837004529").map(Ee);const aW=We(w7);var T7=new Array(3).concat("fff7bcfec44fd95f0e","ffffd4fed98efe9929cc4c02","ffffd4fed98efe9929d95f0e993404","ffffd4fee391fec44ffe9929d95f0e993404","ffffd4fee391fec44ffe9929ec7014cc4c028c2d04","ffffe5fff7bcfee391fec44ffe9929ec7014cc4c028c2d04","ffffe5fff7bcfee391fec44ffe9929ec7014cc4c02993404662506").map(Ee);const sW=We(T7);var E7=new Array(3).concat("ffeda0feb24cf03b20","ffffb2fecc5cfd8d3ce31a1c","ffffb2fecc5cfd8d3cf03b20bd0026","ffffb2fed976feb24cfd8d3cf03b20bd0026","ffffb2fed976feb24cfd8d3cfc4e2ae31a1cb10026","ffffccffeda0fed976feb24cfd8d3cfc4e2ae31a1cb10026","ffffccffeda0fed976feb24cfd8d3cfc4e2ae31a1cbd0026800026").map(Ee);const oW=We(E7);var C7=new Array(3).concat("deebf79ecae13182bd","eff3ffbdd7e76baed62171b5","eff3ffbdd7e76baed63182bd08519c","eff3ffc6dbef9ecae16baed63182bd08519c","eff3ffc6dbef9ecae16baed64292c62171b5084594","f7fbffdeebf7c6dbef9ecae16baed64292c62171b5084594","f7fbffdeebf7c6dbef9ecae16baed64292c62171b508519c08306b").map(Ee);const lW=We(C7);var S7=new Array(3).concat("e5f5e0a1d99b31a354","edf8e9bae4b374c476238b45","edf8e9bae4b374c47631a354006d2c","edf8e9c7e9c0a1d99b74c47631a354006d2c","edf8e9c7e9c0a1d99b74c47641ab5d238b45005a32","f7fcf5e5f5e0c7e9c0a1d99b74c47641ab5d238b45005a32","f7fcf5e5f5e0c7e9c0a1d99b74c47641ab5d238b45006d2c00441b").map(Ee);const cW=We(S7);var A7=new Array(3).concat("f0f0f0bdbdbd636363","f7f7f7cccccc969696525252","f7f7f7cccccc969696636363252525","f7f7f7d9d9d9bdbdbd969696636363252525","f7f7f7d9d9d9bdbdbd969696737373525252252525","fffffff0f0f0d9d9d9bdbdbd969696737373525252252525","fffffff0f0f0d9d9d9bdbdbd969696737373525252252525000000").map(Ee);const uW=We(A7);var M7=new Array(3).concat("efedf5bcbddc756bb1","f2f0f7cbc9e29e9ac86a51a3","f2f0f7cbc9e29e9ac8756bb154278f","f2f0f7dadaebbcbddc9e9ac8756bb154278f","f2f0f7dadaebbcbddc9e9ac8807dba6a51a34a1486","fcfbfdefedf5dadaebbcbddc9e9ac8807dba6a51a34a1486","fcfbfdefedf5dadaebbcbddc9e9ac8807dba6a51a354278f3f007d").map(Ee);const hW=We(M7);var L7=new Array(3).concat("fee0d2fc9272de2d26","fee5d9fcae91fb6a4acb181d","fee5d9fcae91fb6a4ade2d26a50f15","fee5d9fcbba1fc9272fb6a4ade2d26a50f15","fee5d9fcbba1fc9272fb6a4aef3b2ccb181d99000d","fff5f0fee0d2fcbba1fc9272fb6a4aef3b2ccb181d99000d","fff5f0fee0d2fcbba1fc9272fb6a4aef3b2ccb181da50f1567000d").map(Ee);const fW=We(L7);var R7=new Array(3).concat("fee6cefdae6be6550d","feeddefdbe85fd8d3cd94701","feeddefdbe85fd8d3ce6550da63603","feeddefdd0a2fdae6bfd8d3ce6550da63603","feeddefdd0a2fdae6bfd8d3cf16913d948018c2d04","fff5ebfee6cefdd0a2fdae6bfd8d3cf16913d948018c2d04","fff5ebfee6cefdd0a2fdae6bfd8d3cf16913d94801a636037f2704").map(Ee);const dW=We(R7);function pW(t){return t=Math.max(0,Math.min(1,t)),"rgb("+Math.max(0,Math.min(255,Math.round(-4.54-t*(35.34-t*(2381.73-t*(6402.7-t*(7024.72-t*2710.57)))))))+", "+Math.max(0,Math.min(255,Math.round(32.49+t*(170.73+t*(52.82-t*(131.46-t*(176.58-t*67.37)))))))+", "+Math.max(0,Math.min(255,Math.round(81.24+t*(442.36-t*(2482.43-t*(6167.24-t*(6614.94-t*2475.67)))))))+")"}const gW=$u(Qn(300,.5,0),Qn(-240,.5,1));var yW=$u(Qn(-100,.75,.35),Qn(80,1.5,.8)),mW=$u(Qn(260,.75,.35),Qn(80,1.5,.8)),uf=Qn();function bW(t){(t<0||t>1)&&(t-=Math.floor(t));var e=Math.abs(t-.5);return uf.h=360*t-100,uf.s=1.5-1.5*e,uf.l=.8-.9*e,uf+""}var hf=po(),_W=Math.PI/3,vW=Math.PI*2/3;function xW(t){var e;return t=(.5-t)*Math.PI,hf.r=255*(e=Math.sin(t))*e,hf.g=255*(e=Math.sin(t+_W))*e,hf.b=255*(e=Math.sin(t+vW))*e,hf+""}function kW(t){return t=Math.max(0,Math.min(1,t)),"rgb("+Math.max(0,Math.min(255,Math.round(34.61+t*(1172.33-t*(10793.56-t*(33300.12-t*(38394.49-t*14825.05)))))))+", "+Math.max(0,Math.min(255,Math.round(23.31+t*(557.33+t*(1225.33-t*(3574.96-t*(1073.77+t*707.56)))))))+", "+Math.max(0,Math.min(255,Math.round(27.2+t*(3211.1-t*(15327.97-t*(27814-t*(22569.18-t*6838.66)))))))+")"}function ff(t){var e=t.length;return function(r){return t[Math.max(0,Math.min(e-1,Math.floor(r*e)))]}}const wW=ff(Ee("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725"));var TW=ff(Ee("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")),EW=ff(Ee("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")),CW=ff(Ee("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921"));function xe(t){return function(){return t}}const I7=Math.abs,qr=Math.atan2,na=Math.cos,SW=Math.max,Po=Math.min,gn=Math.sin,Ge=Math.sqrt,Vr=1e-12,za=Math.PI,df=za/2,Ya=2*za;function AW(t){return t>1?0:t<-1?za:Math.acos(t)}function N7(t){return t>=1?df:t<=-1?-df:Math.asin(t)}function MW(t){return t.innerRadius}function LW(t){return t.outerRadius}function RW(t){return t.startAngle}function IW(t){return t.endAngle}function NW(t){return t&&t.padAngle}function BW(t,e,r,n,i,a,s,o){var l=r-t,u=n-e,h=s-i,d=o-a,f=d*l-h*u;if(!(f*fD*D+N*N&&(R=L,A=v),{cx:R,cy:A,x01:-h,y01:-d,x11:R*(i/C-1),y11:A*(i/C-1)}}function gf(){var t=MW,e=LW,r=xe(0),n=null,i=RW,a=IW,s=NW,o=null;function l(){var u,h,d=+t.apply(this,arguments),f=+e.apply(this,arguments),p=i.apply(this,arguments)-df,m=a.apply(this,arguments)-df,_=I7(m-p),y=m>p;if(o||(o=u=Ra()),fVr))o.moveTo(0,0);else if(_>Ya-Vr)o.moveTo(f*na(p),f*gn(p)),o.arc(0,0,f,p,m,!y),d>Vr&&(o.moveTo(d*na(m),d*gn(m)),o.arc(0,0,d,m,p,y));else{var b=p,x=m,k=p,T=m,C=_,M=_,S=s.apply(this,arguments)/2,R=S>Vr&&(n?+n.apply(this,arguments):Ge(d*d+f*f)),A=Po(I7(f-d)/2,+r.apply(this,arguments)),L=A,v=A,B,w;if(R>Vr){var D=N7(R/d*gn(S)),N=N7(R/f*gn(S));(C-=D*2)>Vr?(D*=y?1:-1,k+=D,T-=D):(C=0,k=T=(p+m)/2),(M-=N*2)>Vr?(N*=y?1:-1,b+=N,x-=N):(M=0,b=x=(p+m)/2)}var z=f*na(b),X=f*gn(b),ct=d*na(T),J=d*gn(T);if(A>Vr){var Y=f*na(x),$=f*gn(x),lt=d*na(k),ut=d*gn(k),W;if(_Vr?v>Vr?(B=pf(lt,ut,z,X,f,v,y),w=pf(Y,$,ct,J,f,v,y),o.moveTo(B.cx+B.x01,B.cy+B.y01),vVr)||!(C>Vr)?o.lineTo(ct,J):L>Vr?(B=pf(ct,J,Y,$,d,-L,y),w=pf(z,X,lt,ut,d,-L,y),o.lineTo(B.cx+B.x01,B.cy+B.y01),L=f;--p)o.point(x[p],k[p]);o.lineEnd(),o.areaEnd()}y&&(x[d]=+t(_,d,h),k[d]=+e(_,d,h),o.point(n?+n(_,d,h):x[d],r?+r(_,d,h):k[d]))}if(b)return o=null,b+""||null}function u(){return Ua().defined(i).curve(s).context(a)}return l.x=function(h){return arguments.length?(t=typeof h=="function"?h:xe(+h),n=null,l):t},l.x0=function(h){return arguments.length?(t=typeof h=="function"?h:xe(+h),l):t},l.x1=function(h){return arguments.length?(n=h==null?null:typeof h=="function"?h:xe(+h),l):n},l.y=function(h){return arguments.length?(e=typeof h=="function"?h:xe(+h),r=null,l):e},l.y0=function(h){return arguments.length?(e=typeof h=="function"?h:xe(+h),l):e},l.y1=function(h){return arguments.length?(r=h==null?null:typeof h=="function"?h:xe(+h),l):r},l.lineX0=l.lineY0=function(){return u().x(t).y(e)},l.lineY1=function(){return u().x(t).y(r)},l.lineX1=function(){return u().x(n).y(e)},l.defined=function(h){return arguments.length?(i=typeof h=="function"?h:xe(!!h),l):i},l.curve=function(h){return arguments.length?(s=h,a!=null&&(o=s(a)),l):s},l.context=function(h){return arguments.length?(h==null?a=o=null:o=s(a=h),l):a},l}function OW(t,e){return et?1:e>=t?0:NaN}function FW(t){return t}function O7(){var t=FW,e=OW,r=null,n=xe(0),i=xe(Ya),a=xe(0);function s(o){var l,u=(o=yf(o)).length,h,d,f=0,p=new Array(u),m=new Array(u),_=+n.apply(this,arguments),y=Math.min(Ya,Math.max(-Ya,i.apply(this,arguments)-_)),b,x=Math.min(Math.abs(y)/u,a.apply(this,arguments)),k=x*(y<0?-1:1),T;for(l=0;l0&&(f+=T);for(e!=null?p.sort(function(C,M){return e(m[C],m[M])}):r!=null&&p.sort(function(C,M){return r(o[C],o[M])}),l=0,d=f?(y-u*k)/f:0;l0?T*d:0)+k,m[h]={data:o[h],index:l,value:T,startAngle:_,endAngle:b,padAngle:x};return m}return s.value=function(o){return arguments.length?(t=typeof o=="function"?o:xe(+o),s):t},s.sortValues=function(o){return arguments.length?(e=o,r=null,s):e},s.sort=function(o){return arguments.length?(r=o,e=null,s):r},s.startAngle=function(o){return arguments.length?(n=typeof o=="function"?o:xe(+o),s):n},s.endAngle=function(o){return arguments.length?(i=typeof o=="function"?o:xe(+o),s):i},s.padAngle=function(o){return arguments.length?(a=typeof o=="function"?o:xe(+o),s):a},s}var F7=Ip(yn);function P7(t){this._curve=t}P7.prototype={areaStart:function(){this._curve.areaStart()},areaEnd:function(){this._curve.areaEnd()},lineStart:function(){this._curve.lineStart()},lineEnd:function(){this._curve.lineEnd()},point:function(t,e){this._curve.point(e*Math.sin(t),e*-Math.cos(t))}};function Ip(t){function e(r){return new P7(t(r))}return e._curve=t,e}function xc(t){var e=t.curve;return t.angle=t.x,delete t.x,t.radius=t.y,delete t.y,t.curve=function(r){return arguments.length?e(Ip(r)):e()._curve},t}function q7(){return xc(Ua().curve(F7))}function V7(){var t=D7().curve(F7),e=t.curve,r=t.lineX0,n=t.lineX1,i=t.lineY0,a=t.lineY1;return t.angle=t.x,delete t.x,t.startAngle=t.x0,delete t.x0,t.endAngle=t.x1,delete t.x1,t.radius=t.y,delete t.y,t.innerRadius=t.y0,delete t.y0,t.outerRadius=t.y1,delete t.y1,t.lineStartAngle=function(){return xc(r())},delete t.lineX0,t.lineEndAngle=function(){return xc(n())},delete t.lineX1,t.lineInnerRadius=function(){return xc(i())},delete t.lineY0,t.lineOuterRadius=function(){return xc(a())},delete t.lineY1,t.curve=function(s){return arguments.length?e(Ip(s)):e()._curve},t}function kc(t,e){return[(e=+e)*Math.cos(t-=Math.PI/2),e*Math.sin(t)]}class z7{constructor(e,r){this._context=e,this._x=r}areaStart(){this._line=0}areaEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line}point(e,r){switch(e=+e,r=+r,this._point){case 0:{this._point=1,this._line?this._context.lineTo(e,r):this._context.moveTo(e,r);break}case 1:this._point=2;default:{this._x?this._context.bezierCurveTo(this._x0=(this._x0+e)/2,this._y0,this._x0,r,e,r):this._context.bezierCurveTo(this._x0,this._y0=(this._y0+r)/2,e,this._y0,e,r);break}}this._x0=e,this._y0=r}}class PW{constructor(e){this._context=e}lineStart(){this._point=0}lineEnd(){}point(e,r){if(e=+e,r=+r,this._point++===0)this._x0=e,this._y0=r;else{const n=kc(this._x0,this._y0),i=kc(this._x0,this._y0=(this._y0+r)/2),a=kc(e,this._y0),s=kc(e,r);this._context.moveTo(...n),this._context.bezierCurveTo(...i,...a,...s)}}}function Y7(t){return new z7(t,!0)}function U7(t){return new z7(t,!1)}function qW(t){return new PW(t)}function VW(t){return t.source}function zW(t){return t.target}function mf(t){let e=VW,r=zW,n=Lp,i=Rp,a=null,s=null;function o(){let l;const u=DW.call(arguments),h=e.apply(this,u),d=r.apply(this,u);if(a==null&&(s=t(l=Ra())),s.lineStart(),u[0]=h,s.point(+n.apply(this,u),+i.apply(this,u)),u[0]=d,s.point(+n.apply(this,u),+i.apply(this,u)),s.lineEnd(),l)return s=null,l+""||null}return o.source=function(l){return arguments.length?(e=l,o):e},o.target=function(l){return arguments.length?(r=l,o):r},o.x=function(l){return arguments.length?(n=typeof l=="function"?l:xe(+l),o):n},o.y=function(l){return arguments.length?(i=typeof l=="function"?l:xe(+l),o):i},o.context=function(l){return arguments.length?(l==null?a=s=null:s=t(a=l),o):a},o}function YW(){return mf(Y7)}function UW(){return mf(U7)}function WW(){const t=mf(qW);return t.angle=t.x,delete t.x,t.radius=t.y,delete t.y,t}const HW=Ge(3),W7={draw(t,e){const r=Ge(e+Po(e/28,.75))*.59436,n=r/2,i=n*HW;t.moveTo(0,r),t.lineTo(0,-r),t.moveTo(-i,-n),t.lineTo(i,n),t.moveTo(-i,n),t.lineTo(i,-n)}},bf={draw(t,e){const r=Ge(e/za);t.moveTo(r,0),t.arc(0,0,r,0,Ya)}},H7={draw(t,e){const r=Ge(e/5)/2;t.moveTo(-3*r,-r),t.lineTo(-r,-r),t.lineTo(-r,-3*r),t.lineTo(r,-3*r),t.lineTo(r,-r),t.lineTo(3*r,-r),t.lineTo(3*r,r),t.lineTo(r,r),t.lineTo(r,3*r),t.lineTo(-r,3*r),t.lineTo(-r,r),t.lineTo(-3*r,r),t.closePath()}},G7=Ge(1/3),GW=G7*2,j7={draw(t,e){const r=Ge(e/GW),n=r*G7;t.moveTo(0,-r),t.lineTo(n,0),t.lineTo(0,r),t.lineTo(-n,0),t.closePath()}},$7={draw(t,e){const r=Ge(e)*.62625;t.moveTo(0,-r),t.lineTo(r,0),t.lineTo(0,r),t.lineTo(-r,0),t.closePath()}},X7={draw(t,e){const r=Ge(e-Po(e/7,2))*.87559;t.moveTo(-r,0),t.lineTo(r,0),t.moveTo(0,r),t.lineTo(0,-r)}},K7={draw(t,e){const r=Ge(e),n=-r/2;t.rect(n,n,r,r)}},Z7={draw(t,e){const r=Ge(e)*.4431;t.moveTo(r,r),t.lineTo(r,-r),t.lineTo(-r,-r),t.lineTo(-r,r),t.closePath()}},jW=.8908130915292852,Q7=gn(za/10)/gn(7*za/10),$W=gn(Ya/10)*Q7,XW=-na(Ya/10)*Q7,J7={draw(t,e){const r=Ge(e*jW),n=$W*r,i=XW*r;t.moveTo(0,-r),t.lineTo(n,i);for(let a=1;a<5;++a){const s=Ya*a/5,o=na(s),l=gn(s);t.lineTo(l*r,-o*r),t.lineTo(o*n-l*i,l*n+o*i)}t.closePath()}},Np=Ge(3),tk={draw(t,e){const r=-Ge(e/(Np*3));t.moveTo(0,r*2),t.lineTo(-Np*r,-r),t.lineTo(Np*r,-r),t.closePath()}},KW=Ge(3),ek={draw(t,e){const r=Ge(e)*.6824,n=r/2,i=r*KW/2;t.moveTo(0,-r),t.lineTo(i,n),t.lineTo(-i,n),t.closePath()}},Pn=-.5,qn=Ge(3)/2,Bp=1/Ge(12),ZW=(Bp/2+1)*3,rk={draw(t,e){const r=Ge(e/ZW),n=r/2,i=r*Bp,a=n,s=r*Bp+r,o=-a,l=s;t.moveTo(n,i),t.lineTo(a,s),t.lineTo(o,l),t.lineTo(Pn*n-qn*i,qn*n+Pn*i),t.lineTo(Pn*a-qn*s,qn*a+Pn*s),t.lineTo(Pn*o-qn*l,qn*o+Pn*l),t.lineTo(Pn*n+qn*i,Pn*i-qn*n),t.lineTo(Pn*a+qn*s,Pn*s-qn*a),t.lineTo(Pn*o+qn*l,Pn*l-qn*o),t.closePath()}},nk={draw(t,e){const r=Ge(e-Po(e/6,1.7))*.6189;t.moveTo(-r,-r),t.lineTo(r,r),t.moveTo(-r,r),t.lineTo(r,-r)}},ik=[bf,H7,j7,K7,J7,tk,rk],QW=[bf,X7,nk,ek,W7,Z7,$7];function JW(t,e){let r=null;t=typeof t=="function"?t:xe(t||bf),e=typeof e=="function"?e:xe(e===void 0?64:+e);function n(){let i;if(r||(r=i=Ra()),t.apply(this,arguments).draw(r,+e.apply(this,arguments)),i)return r=null,i+""||null}return n.type=function(i){return arguments.length?(t=typeof i=="function"?i:xe(i),n):t},n.size=function(i){return arguments.length?(e=typeof i=="function"?i:xe(+i),n):e},n.context=function(i){return arguments.length?(r=i==null?null:i,n):r},n}function Wa(){}function _f(t,e,r){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+e)/6,(t._y0+4*t._y1+r)/6)}function vf(t){this._context=t}vf.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:_f(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:_f(this,t,e);break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};function Os(t){return new vf(t)}function ak(t){this._context=t}ak.prototype={areaStart:Wa,areaEnd:Wa,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:{this._context.moveTo(this._x2,this._y2),this._context.closePath();break}case 2:{this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break}case 3:{this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4);break}}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x2=t,this._y2=e;break;case 1:this._point=2,this._x3=t,this._y3=e;break;case 2:this._point=3,this._x4=t,this._y4=e,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+e)/6);break;default:_f(this,t,e);break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};function sk(t){return new ak(t)}function ok(t){this._context=t}ok.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var r=(this._x0+4*this._x1+t)/6,n=(this._y0+4*this._y1+e)/6;this._line?this._context.lineTo(r,n):this._context.moveTo(r,n);break;case 3:this._point=4;default:_f(this,t,e);break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};function lk(t){return new ok(t)}function ck(t,e){this._basis=new vf(t),this._beta=e}ck.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var t=this._x,e=this._y,r=t.length-1;if(r>0)for(var n=t[0],i=e[0],a=t[r]-n,s=e[r]-i,o=-1,l;++o<=r;)l=o/r,this._basis.point(this._beta*t[o]+(1-this._beta)*(n+l*a),this._beta*e[o]+(1-this._beta)*(i+l*s));this._x=this._y=null,this._basis.lineEnd()},point:function(t,e){this._x.push(+t),this._y.push(+e)}};const tH=function t(e){function r(n){return e===1?new vf(n):new ck(n,e)}return r.beta=function(n){return t(+n)},r}(.85);function xf(t,e,r){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-e),t._y2+t._k*(t._y1-r),t._x2,t._y2)}function Dp(t,e){this._context=t,this._k=(1-e)/6}Dp.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:xf(this,this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2,this._x1=t,this._y1=e;break;case 2:this._point=3;default:xf(this,t,e);break}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const eH=function t(e){function r(n){return new Dp(n,e)}return r.tension=function(n){return t(+n)},r}(0);function Op(t,e){this._context=t,this._k=(1-e)/6}Op.prototype={areaStart:Wa,areaEnd:Wa,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:{this._context.moveTo(this._x3,this._y3),this._context.closePath();break}case 2:{this._context.lineTo(this._x3,this._y3),this._context.closePath();break}case 3:{this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5);break}}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:xf(this,t,e);break}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const rH=function t(e){function r(n){return new Op(n,e)}return r.tension=function(n){return t(+n)},r}(0);function Fp(t,e){this._context=t,this._k=(1-e)/6}Fp.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:xf(this,t,e);break}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const nH=function t(e){function r(n){return new Fp(n,e)}return r.tension=function(n){return t(+n)},r}(0);function Pp(t,e,r){var n=t._x1,i=t._y1,a=t._x2,s=t._y2;if(t._l01_a>Vr){var o=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,l=3*t._l01_a*(t._l01_a+t._l12_a);n=(n*o-t._x0*t._l12_2a+t._x2*t._l01_2a)/l,i=(i*o-t._y0*t._l12_2a+t._y2*t._l01_2a)/l}if(t._l23_a>Vr){var u=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,h=3*t._l23_a*(t._l23_a+t._l12_a);a=(a*u+t._x1*t._l23_2a-e*t._l12_2a)/h,s=(s*u+t._y1*t._l23_2a-r*t._l12_2a)/h}t._context.bezierCurveTo(n,i,a,s,t._x2,t._y2)}function uk(t,e){this._context=t,this._alpha=e}uk.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var r=this._x2-t,n=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(r*r+n*n,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3;default:Pp(this,t,e);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const iH=function t(e){function r(n){return e?new uk(n,e):new Dp(n,0)}return r.alpha=function(n){return t(+n)},r}(.5);function hk(t,e){this._context=t,this._alpha=e}hk.prototype={areaStart:Wa,areaEnd:Wa,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:{this._context.moveTo(this._x3,this._y3),this._context.closePath();break}case 2:{this._context.lineTo(this._x3,this._y3),this._context.closePath();break}case 3:{this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5);break}}},point:function(t,e){if(t=+t,e=+e,this._point){var r=this._x2-t,n=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(r*r+n*n,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:Pp(this,t,e);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const aH=function t(e){function r(n){return e?new hk(n,e):new Op(n,0)}return r.alpha=function(n){return t(+n)},r}(.5);function fk(t,e){this._context=t,this._alpha=e}fk.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var r=this._x2-t,n=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(r*r+n*n,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Pp(this,t,e);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const sH=function t(e){function r(n){return e?new fk(n,e):new Fp(n,0)}return r.alpha=function(n){return t(+n)},r}(.5);function dk(t){this._context=t}dk.prototype={areaStart:Wa,areaEnd:Wa,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(t,e){t=+t,e=+e,this._point?this._context.lineTo(t,e):(this._point=1,this._context.moveTo(t,e))}};function pk(t){return new dk(t)}function gk(t){return t<0?-1:1}function yk(t,e,r){var n=t._x1-t._x0,i=e-t._x1,a=(t._y1-t._y0)/(n||i<0&&-0),s=(r-t._y1)/(i||n<0&&-0),o=(a*i+s*n)/(n+i);return(gk(a)+gk(s))*Math.min(Math.abs(a),Math.abs(s),.5*Math.abs(o))||0}function mk(t,e){var r=t._x1-t._x0;return r?(3*(t._y1-t._y0)/r-e)/2:e}function qp(t,e,r){var n=t._x0,i=t._y0,a=t._x1,s=t._y1,o=(a-n)/3;t._context.bezierCurveTo(n+o,i+o*e,a-o,s-o*r,a,s)}function kf(t){this._context=t}kf.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:qp(this,this._t0,mk(this,this._t0));break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){var r=NaN;if(t=+t,e=+e,!(t===this._x1&&e===this._y1)){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,qp(this,mk(this,r=yk(this,t,e)),r);break;default:qp(this,this._t0,r=yk(this,t,e));break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e,this._t0=r}}};function bk(t){this._context=new _k(t)}(bk.prototype=Object.create(kf.prototype)).point=function(t,e){kf.prototype.point.call(this,e,t)};function _k(t){this._context=t}_k.prototype={moveTo:function(t,e){this._context.moveTo(e,t)},closePath:function(){this._context.closePath()},lineTo:function(t,e){this._context.lineTo(e,t)},bezierCurveTo:function(t,e,r,n,i,a){this._context.bezierCurveTo(e,t,n,r,a,i)}};function vk(t){return new kf(t)}function xk(t){return new bk(t)}function kk(t){this._context=t}kk.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=[],this._y=[]},lineEnd:function(){var t=this._x,e=this._y,r=t.length;if(r)if(this._line?this._context.lineTo(t[0],e[0]):this._context.moveTo(t[0],e[0]),r===2)this._context.lineTo(t[1],e[1]);else for(var n=wk(t),i=wk(e),a=0,s=1;s=0;--e)i[e]=(s[e]-i[e+1])/a[e];for(a[r-1]=(t[r]+i[r-1])/2,e=0;e=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:{if(this._t<=0)this._context.lineTo(this._x,e),this._context.lineTo(t,e);else{var r=this._x*(1-this._t)+t*this._t;this._context.lineTo(r,this._y),this._context.lineTo(r,e)}break}}this._x=t,this._y=e}};function Ek(t){return new wf(t,.5)}function Ck(t){return new wf(t,0)}function Sk(t){return new wf(t,1)}function qo(t,e){if((s=t.length)>1)for(var r=1,n,i,a=t[e[0]],s,o=a.length;r=0;)r[e]=e;return r}function oH(t,e){return t[e]}function lH(t){const e=[];return e.key=t,e}function cH(){var t=xe([]),e=Vo,r=qo,n=oH;function i(a){var s=Array.from(t.apply(this,arguments),lH),o,l=s.length,u=-1,h;for(const d of a)for(o=0,++u;o0){for(var r,n,i=0,a=t[0].length,s;i0)for(var r,n=0,i,a,s,o,l,u=t[e[0]].length;n0?(i[0]=s,i[1]=s+=a):a<0?(i[1]=o,i[0]=o+=a):(i[0]=0,i[1]=a)}function fH(t,e){if((i=t.length)>0){for(var r=0,n=t[e[0]],i,a=n.length;r0)||!((a=(i=t[e[0]]).length)>0))){for(var r=0,n=1,i,a,s;na&&(a=i,r=e);return r}function Mk(t){var e=t.map(Lk);return Vo(t).sort(function(r,n){return e[r]-e[n]})}function Lk(t){for(var e=0,r=-1,n=t.length,i;++r()=>t;function bH(t,{sourceEvent:e,target:r,transform:n,dispatch:i}){Object.defineProperties(this,{type:{value:t,enumerable:!0,configurable:!0},sourceEvent:{value:e,enumerable:!0,configurable:!0},target:{value:r,enumerable:!0,configurable:!0},transform:{value:n,enumerable:!0,configurable:!0},_:{value:i}})}function Ri(t,e,r){this.k=t,this.x=e,this.y=r}Ri.prototype={constructor:Ri,scale:function(t){return t===1?this:new Ri(this.k*t,this.x,this.y)},translate:function(t,e){return t===0&e===0?this:new Ri(this.k,this.x+this.k*t,this.y+this.k*e)},apply:function(t){return[t[0]*this.k+this.x,t[1]*this.k+this.y]},applyX:function(t){return t*this.k+this.x},applyY:function(t){return t*this.k+this.y},invert:function(t){return[(t[0]-this.x)/this.k,(t[1]-this.y)/this.k]},invertX:function(t){return(t-this.x)/this.k},invertY:function(t){return(t-this.y)/this.k},rescaleX:function(t){return t.copy().domain(t.range().map(this.invertX,this).map(t.invert,t))},rescaleY:function(t){return t.copy().domain(t.range().map(this.invertY,this).map(t.invert,t))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};var Ef=new Ri(1,0,0);Rk.prototype=Ri.prototype;function Rk(t){for(;!t.__zoom;)if(!(t=t.parentNode))return Ef;return t.__zoom}function Vp(t){t.stopImmediatePropagation()}function wc(t){t.preventDefault(),t.stopImmediatePropagation()}function _H(t){return(!t.ctrlKey||t.type==="wheel")&&!t.button}function vH(){var t=this;return t instanceof SVGElement?(t=t.ownerSVGElement||t,t.hasAttribute("viewBox")?(t=t.viewBox.baseVal,[[t.x,t.y],[t.x+t.width,t.y+t.height]]):[[0,0],[t.width.baseVal.value,t.height.baseVal.value]]):[[0,0],[t.clientWidth,t.clientHeight]]}function Ik(){return this.__zoom||Ef}function xH(t){return-t.deltaY*(t.deltaMode===1?.05:t.deltaMode?1:.002)*(t.ctrlKey?10:1)}function kH(){return navigator.maxTouchPoints||"ontouchstart"in this}function wH(t,e,r){var n=t.invertX(e[0][0])-r[0][0],i=t.invertX(e[1][0])-r[1][0],a=t.invertY(e[0][1])-r[0][1],s=t.invertY(e[1][1])-r[1][1];return t.translate(i>n?(n+i)/2:Math.min(0,n)||Math.max(0,i),s>a?(a+s)/2:Math.min(0,a)||Math.max(0,s))}function TH(){var t=_H,e=vH,r=wH,n=xH,i=kH,a=[0,1/0],s=[[-1/0,-1/0],[1/0,1/0]],o=250,l=j5,u=fs("start","zoom","end"),h,d,f,p=500,m=150,_=0,y=10;function b(D){D.property("__zoom",Ik).on("wheel.zoom",R,{passive:!1}).on("mousedown.zoom",A).on("dblclick.zoom",L).filter(i).on("touchstart.zoom",v).on("touchmove.zoom",B).on("touchend.zoom touchcancel.zoom",w).style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}b.transform=function(D,N,z,X){var ct=D.selection?D.selection():D;ct.property("__zoom",Ik),D!==ct?C(D,N,z,X):ct.interrupt().each(function(){M(this,arguments).event(X).start().zoom(null,typeof N=="function"?N.apply(this,arguments):N).end()})},b.scaleBy=function(D,N,z,X){b.scaleTo(D,function(){var ct=this.__zoom.k,J=typeof N=="function"?N.apply(this,arguments):N;return ct*J},z,X)},b.scaleTo=function(D,N,z,X){b.transform(D,function(){var ct=e.apply(this,arguments),J=this.__zoom,Y=z==null?T(ct):typeof z=="function"?z.apply(this,arguments):z,$=J.invert(Y),lt=typeof N=="function"?N.apply(this,arguments):N;return r(k(x(J,lt),Y,$),ct,s)},z,X)},b.translateBy=function(D,N,z,X){b.transform(D,function(){return r(this.__zoom.translate(typeof N=="function"?N.apply(this,arguments):N,typeof z=="function"?z.apply(this,arguments):z),e.apply(this,arguments),s)},null,X)},b.translateTo=function(D,N,z,X,ct){b.transform(D,function(){var J=e.apply(this,arguments),Y=this.__zoom,$=X==null?T(J):typeof X=="function"?X.apply(this,arguments):X;return r(Ef.translate($[0],$[1]).scale(Y.k).translate(typeof N=="function"?-N.apply(this,arguments):-N,typeof z=="function"?-z.apply(this,arguments):-z),J,s)},X,ct)};function x(D,N){return N=Math.max(a[0],Math.min(a[1],N)),N===D.k?D:new Ri(N,D.x,D.y)}function k(D,N,z){var X=N[0]-z[0]*D.k,ct=N[1]-z[1]*D.k;return X===D.x&&ct===D.y?D:new Ri(D.k,X,ct)}function T(D){return[(+D[0][0]+ +D[1][0])/2,(+D[0][1]+ +D[1][1])/2]}function C(D,N,z,X){D.on("start.zoom",function(){M(this,arguments).event(X).start()}).on("interrupt.zoom end.zoom",function(){M(this,arguments).event(X).end()}).tween("zoom",function(){var ct=this,J=arguments,Y=M(ct,J).event(X),$=e.apply(ct,J),lt=z==null?T($):typeof z=="function"?z.apply(ct,J):z,ut=Math.max($[1][0]-$[0][0],$[1][1]-$[0][1]),W=ct.__zoom,tt=typeof N=="function"?N.apply(ct,J):N,K=l(W.invert(lt).concat(ut/W.k),tt.invert(lt).concat(ut/tt.k));return function(it){if(it===1)it=tt;else{var Z=K(it),V=ut/Z[2];it=new Ri(V,lt[0]-Z[0]*V,lt[1]-Z[1]*V)}Y.zoom(null,it)}})}function M(D,N,z){return!z&&D.__zooming||new S(D,N)}function S(D,N){this.that=D,this.args=N,this.active=0,this.sourceEvent=null,this.extent=e.apply(D,N),this.taps=0}S.prototype={event:function(D){return D&&(this.sourceEvent=D),this},start:function(){return++this.active===1&&(this.that.__zooming=this,this.emit("start")),this},zoom:function(D,N){return this.mouse&&D!=="mouse"&&(this.mouse[1]=N.invert(this.mouse[0])),this.touch0&&D!=="touch"&&(this.touch0[1]=N.invert(this.touch0[0])),this.touch1&&D!=="touch"&&(this.touch1[1]=N.invert(this.touch1[0])),this.that.__zoom=N,this.emit("zoom"),this},end:function(){return--this.active===0&&(delete this.that.__zooming,this.emit("end")),this},emit:function(D){var N=St(this.that).datum();u.call(D,this.that,new bH(D,{sourceEvent:this.sourceEvent,target:b,type:D,transform:this.that.__zoom,dispatch:u}),N)}};function R(D,...N){if(!t.apply(this,arguments))return;var z=M(this,N).event(D),X=this.__zoom,ct=Math.max(a[0],Math.min(a[1],X.k*Math.pow(2,n.apply(this,arguments)))),J=Tn(D);if(z.wheel)(z.mouse[0][0]!==J[0]||z.mouse[0][1]!==J[1])&&(z.mouse[1]=X.invert(z.mouse[0]=J)),clearTimeout(z.wheel);else{if(X.k===ct)return;z.mouse=[J,X.invert(J)],vs(this),z.start()}wc(D),z.wheel=setTimeout(Y,m),z.zoom("mouse",r(k(x(X,ct),z.mouse[0],z.mouse[1]),z.extent,s));function Y(){z.wheel=null,z.end()}}function A(D,...N){if(f||!t.apply(this,arguments))return;var z=D.currentTarget,X=M(this,N,!0).event(D),ct=St(D.view).on("mousemove.zoom",lt,!0).on("mouseup.zoom",ut,!0),J=Tn(D,z),Y=D.clientX,$=D.clientY;Nu(D.view),Vp(D),X.mouse=[J,this.__zoom.invert(J)],vs(this),X.start();function lt(W){if(wc(W),!X.moved){var tt=W.clientX-Y,K=W.clientY-$;X.moved=tt*tt+K*K>_}X.event(W).zoom("mouse",r(k(X.that.__zoom,X.mouse[0]=Tn(W,z),X.mouse[1]),X.extent,s))}function ut(W){ct.on("mousemove.zoom mouseup.zoom",null),Bu(W.view,X.moved),wc(W),X.event(W).end()}}function L(D,...N){if(!!t.apply(this,arguments)){var z=this.__zoom,X=Tn(D.changedTouches?D.changedTouches[0]:D,this),ct=z.invert(X),J=z.k*(D.shiftKey?.5:2),Y=r(k(x(z,J),X,ct),e.apply(this,N),s);wc(D),o>0?St(this).transition().duration(o).call(C,Y,X,D):St(this).call(b.transform,Y,X,D)}}function v(D,...N){if(!!t.apply(this,arguments)){var z=D.touches,X=z.length,ct=M(this,N,D.changedTouches.length===X).event(D),J,Y,$,lt;for(Vp(D),Y=0;Y"u"||!Reflect.construct||Reflect.construct.sham)return!1;if(typeof Proxy=="function")return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch{return!1}}function Cf(t,e,r){return CH()?Cf=Reflect.construct:Cf=function(i,a,s){var o=[null];o.push.apply(o,a);var l=Function.bind.apply(i,o),u=new l;return s&&zp(u,s.prototype),u},Cf.apply(null,arguments)}function ni(t){return SH(t)||AH(t)||MH(t)||LH()}function SH(t){if(Array.isArray(t))return Yp(t)}function AH(t){if(typeof Symbol<"u"&&t[Symbol.iterator]!=null||t["@@iterator"]!=null)return Array.from(t)}function MH(t,e){if(!!t){if(typeof t=="string")return Yp(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);if(r==="Object"&&t.constructor&&(r=t.constructor.name),r==="Map"||r==="Set")return Array.from(t);if(r==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return Yp(t,e)}}function Yp(t,e){(e==null||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r1?r-1:0),i=1;i/gm),HH=Ii(/^data-[\-\w.\u00B7-\uFFFF]/),GH=Ii(/^aria-[\-\w]+$/),jH=Ii(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),$H=Ii(/^(?:\w+script|data):/i),XH=Ii(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),KH=Ii(/^html$/i),ZH=function(){return typeof window>"u"?null:window},QH=function(e,r){if(Ha(e)!=="object"||typeof e.createPolicy!="function")return null;var n=null,i="data-tt-policy-suffix";r.currentScript&&r.currentScript.hasAttribute(i)&&(n=r.currentScript.getAttribute(i));var a="dompurify"+(n?"#"+n:"");try{return e.createPolicy(a,{createHTML:function(o){return o},createScriptURL:function(o){return o}})}catch{return console.warn("TrustedTypes policy "+a+" could not be created."),null}};function Vk(){var t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:ZH(),e=function(st){return Vk(st)};if(e.version="2.4.0",e.removed=[],!t||!t.document||t.document.nodeType!==9)return e.isSupported=!1,e;var r=t.document,n=t.document,i=t.DocumentFragment,a=t.HTMLTemplateElement,s=t.Node,o=t.Element,l=t.NodeFilter,u=t.NamedNodeMap,h=u===void 0?t.NamedNodeMap||t.MozNamedAttrMap:u,d=t.HTMLFormElement,f=t.DOMParser,p=t.trustedTypes,m=o.prototype,_=Mf(m,"cloneNode"),y=Mf(m,"nextSibling"),b=Mf(m,"childNodes"),x=Mf(m,"parentNode");if(typeof a=="function"){var k=n.createElement("template");k.content&&k.content.ownerDocument&&(n=k.content.ownerDocument)}var T=QH(p,r),C=T?T.createHTML(""):"",M=n,S=M.implementation,R=M.createNodeIterator,A=M.createDocumentFragment,L=M.getElementsByTagName,v=r.importNode,B={};try{B=Fs(n).documentMode?n.documentMode:{}}catch{}var w={};e.isSupported=typeof x=="function"&&S&&typeof S.createHTMLDocument<"u"&&B!==9;var D=UH,N=WH,z=HH,X=GH,ct=$H,J=XH,Y=jH,$=null,lt=Me({},[].concat(ni(Ok),ni(Hp),ni(Gp),ni(jp),ni(Fk))),ut=null,W=Me({},[].concat(ni(Pk),ni($p),ni(qk),ni(Lf))),tt=Object.seal(Object.create(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),K=null,it=null,Z=!0,V=!0,Q=!1,q=!1,U=!1,F=!1,j=!1,P=!1,et=!1,at=!1,It=!0,Lt=!1,Rt="user-content-",Ct=!0,pt=!1,mt={},vt=null,Tt=Me({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]),ft=null,le=Me({},["audio","video","img","source","image","track"]),Dt=null,Gt=Me({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),$t="http://www.w3.org/1998/Math/MathML",Qt="http://www.w3.org/2000/svg",we="http://www.w3.org/1999/xhtml",jt=we,Ft=!1,zt,wt=["application/xhtml+xml","text/html"],bt="text/html",Et,kt=null,Ut=n.createElement("form"),gt=function(st){return st instanceof RegExp||st instanceof Function},he=function(st){kt&&kt===st||((!st||Ha(st)!=="object")&&(st={}),st=Fs(st),zt=wt.indexOf(st.PARSER_MEDIA_TYPE)===-1?zt=bt:zt=st.PARSER_MEDIA_TYPE,Et=zt==="application/xhtml+xml"?function(At){return At}:Af,$="ALLOWED_TAGS"in st?Me({},st.ALLOWED_TAGS,Et):lt,ut="ALLOWED_ATTR"in st?Me({},st.ALLOWED_ATTR,Et):W,Dt="ADD_URI_SAFE_ATTR"in st?Me(Fs(Gt),st.ADD_URI_SAFE_ATTR,Et):Gt,ft="ADD_DATA_URI_TAGS"in st?Me(Fs(le),st.ADD_DATA_URI_TAGS,Et):le,vt="FORBID_CONTENTS"in st?Me({},st.FORBID_CONTENTS,Et):Tt,K="FORBID_TAGS"in st?Me({},st.FORBID_TAGS,Et):{},it="FORBID_ATTR"in st?Me({},st.FORBID_ATTR,Et):{},mt="USE_PROFILES"in st?st.USE_PROFILES:!1,Z=st.ALLOW_ARIA_ATTR!==!1,V=st.ALLOW_DATA_ATTR!==!1,Q=st.ALLOW_UNKNOWN_PROTOCOLS||!1,q=st.SAFE_FOR_TEMPLATES||!1,U=st.WHOLE_DOCUMENT||!1,P=st.RETURN_DOM||!1,et=st.RETURN_DOM_FRAGMENT||!1,at=st.RETURN_TRUSTED_TYPE||!1,j=st.FORCE_BODY||!1,It=st.SANITIZE_DOM!==!1,Lt=st.SANITIZE_NAMED_PROPS||!1,Ct=st.KEEP_CONTENT!==!1,pt=st.IN_PLACE||!1,Y=st.ALLOWED_URI_REGEXP||Y,jt=st.NAMESPACE||we,st.CUSTOM_ELEMENT_HANDLING&>(st.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(tt.tagNameCheck=st.CUSTOM_ELEMENT_HANDLING.tagNameCheck),st.CUSTOM_ELEMENT_HANDLING&>(st.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(tt.attributeNameCheck=st.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),st.CUSTOM_ELEMENT_HANDLING&&typeof st.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements=="boolean"&&(tt.allowCustomizedBuiltInElements=st.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),q&&(V=!1),et&&(P=!0),mt&&($=Me({},ni(Fk)),ut=[],mt.html===!0&&(Me($,Ok),Me(ut,Pk)),mt.svg===!0&&(Me($,Hp),Me(ut,$p),Me(ut,Lf)),mt.svgFilters===!0&&(Me($,Gp),Me(ut,$p),Me(ut,Lf)),mt.mathMl===!0&&(Me($,jp),Me(ut,qk),Me(ut,Lf))),st.ADD_TAGS&&($===lt&&($=Fs($)),Me($,st.ADD_TAGS,Et)),st.ADD_ATTR&&(ut===W&&(ut=Fs(ut)),Me(ut,st.ADD_ATTR,Et)),st.ADD_URI_SAFE_ATTR&&Me(Dt,st.ADD_URI_SAFE_ATTR,Et),st.FORBID_CONTENTS&&(vt===Tt&&(vt=Fs(vt)),Me(vt,st.FORBID_CONTENTS,Et)),Ct&&($["#text"]=!0),U&&Me($,["html","head","body"]),$.table&&(Me($,["tbody"]),delete K.tbody),sn&&sn(st),kt=st)},yt=Me({},["mi","mo","mn","ms","mtext"]),ne=Me({},["foreignobject","desc","title","annotation-xml"]),ve=Me({},["title","style","font","a","script"]),ye=Me({},Hp);Me(ye,Gp),Me(ye,zH);var be=Me({},jp);Me(be,YH);var Te=function(st){var At=x(st);(!At||!At.tagName)&&(At={namespaceURI:we,tagName:"template"});var Nt=Af(st.tagName),Jt=Af(At.tagName);return st.namespaceURI===Qt?At.namespaceURI===we?Nt==="svg":At.namespaceURI===$t?Nt==="svg"&&(Jt==="annotation-xml"||yt[Jt]):Boolean(ye[Nt]):st.namespaceURI===$t?At.namespaceURI===we?Nt==="math":At.namespaceURI===Qt?Nt==="math"&&ne[Jt]:Boolean(be[Nt]):st.namespaceURI===we?At.namespaceURI===Qt&&!ne[Jt]||At.namespaceURI===$t&&!yt[Jt]?!1:!be[Nt]&&(ve[Nt]||!ye[Nt]):!1},Wt=function(st){Tc(e.removed,{element:st});try{st.parentNode.removeChild(st)}catch{try{st.outerHTML=C}catch{st.remove()}}},se=function(st,At){try{Tc(e.removed,{attribute:At.getAttributeNode(st),from:At})}catch{Tc(e.removed,{attribute:null,from:At})}if(At.removeAttribute(st),st==="is"&&!ut[st])if(P||et)try{Wt(At)}catch{}else try{At.setAttribute(st,"")}catch{}},me=function(st){var At,Nt;if(j)st=""+st;else{var Jt=FH(st,/^[\r\n\t ]+/);Nt=Jt&&Jt[0]}zt==="application/xhtml+xml"&&(st=''+st+"");var ze=T?T.createHTML(st):st;if(jt===we)try{At=new f().parseFromString(ze,zt)}catch{}if(!At||!At.documentElement){At=S.createDocument(jt,"template",null);try{At.documentElement.innerHTML=Ft?"":ze}catch{}}var Pe=At.body||At.documentElement;return st&&Nt&&Pe.insertBefore(n.createTextNode(Nt),Pe.childNodes[0]||null),jt===we?L.call(At,U?"html":"body")[0]:U?At.documentElement:Pe},ue=function(st){return R.call(st.ownerDocument||st,st,l.SHOW_ELEMENT|l.SHOW_COMMENT|l.SHOW_TEXT,null,!1)},_a=function(st){return st instanceof d&&(typeof st.nodeName!="string"||typeof st.textContent!="string"||typeof st.removeChild!="function"||!(st.attributes instanceof h)||typeof st.removeAttribute!="function"||typeof st.setAttribute!="function"||typeof st.namespaceURI!="string"||typeof st.insertBefore!="function")},Hr=function(st){return Ha(s)==="object"?st instanceof s:st&&Ha(st)==="object"&&typeof st.nodeType=="number"&&typeof st.nodeName=="string"},Ie=function(st,At,Nt){!w[st]||OH(w[st],function(Jt){Jt.call(e,At,Nt,kt)})},oe=function(st){var At;if(Ie("beforeSanitizeElements",st,null),_a(st)||on(/[\u0080-\uFFFF]/,st.nodeName))return Wt(st),!0;var Nt=Et(st.nodeName);if(Ie("uponSanitizeElement",st,{tagName:Nt,allowedTags:$}),st.hasChildNodes()&&!Hr(st.firstElementChild)&&(!Hr(st.content)||!Hr(st.content.firstElementChild))&&on(/<[/\w]/g,st.innerHTML)&&on(/<[/\w]/g,st.textContent)||Nt==="select"&&on(/