
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>diss带码</title>
  
  <subtitle>码动人生</subtitle>
  <link href="/atom.xml" rel="self"/>
  
  <link href="https://dumplingbao.github.io/"/>
  <updated>2023-01-11T05:02:34.787Z</updated>
  <id>https://dumplingbao.github.io/</id>
  
  <author>
    <name>dumplingbao</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title>datart系列04：基于threejs自定义插件3D-MAP</title>
    <link href="https://dumplingbao.github.io/2023/01/11/datart-bi-04/"/>
    <id>https://dumplingbao.github.io/2023/01/11/datart-bi-04/</id>
    <published>2023-01-11T05:01:08.000Z</published>
    <updated>2023-01-11T05:02:34.787Z</updated>
    
    <content type="html"><![CDATA[<h2 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h2><p>datart自定义插件的方式，基于threejs自定义插件3D-MAP。</p><h2 id="应用场景"><a href="#应用场景" class="headerlink" title="应用场景"></a>应用场景</h2><p>根据经纬度进行的城市数据展示场景，适用数据大屏，3D地图等</p><a id="more"></a><h2 id="验证数据"><a href="#验证数据" class="headerlink" title="验证数据"></a>验证数据</h2><p>见插件文件：<code>air_quality.sql</code>、<code>air_quality_sd.sql</code></p><h2 id="前置条件"><a href="#前置条件" class="headerlink" title="前置条件"></a>前置条件</h2><ol><li>三个纬度、一个指标</li><li>三个纬度有顺序要求（1、需要显示的名称，2、经度，3、纬度）</li></ol><p>备注：三个维度有顺序要求是为了保证不改动源码扩展插件，动源码有两种解决方式如下：</p><p>第一种：增加经度、纬度的维度类型，根据类型判断</p><p>第二种：扩展经度、纬度的维度拖入框，类似双Y轴方式</p><h2 id="规则设定"><a href="#规则设定" class="headerlink" title="规则设定"></a>规则设定</h2><ul><li><p><strong>地图：</strong>地图json文件url地址</p></li><li><p><strong>基准值：</strong>适配不同数据级别展示，推荐设置样本数据最大值</p></li><li><p><strong>缩放级别：</strong>地图缩放等级，适配不同区域展示情况</p></li><li><p><strong>效果：</strong>水波、气泡、热力图</p></li><li><p><strong>中心坐标：</strong>设置中心坐标的经度、纬度，控制地图显示区域</p></li></ul><h2 id="使用说明"><a href="#使用说明" class="headerlink" title="使用说明"></a>使用说明</h2><p>插件地址：<a href="https://github.com/dumplingbao/datar-plug" target="_blank" rel="noopener">https://github.com/dumplingbao/datar-plug</a></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line">&lt;div id=&quot;container&quot;&gt;&lt;/div&gt;</span><br><span class="line">  &lt;script&gt;</span><br><span class="line">    let f1 = new dumplingbaoThree.Map(</span><br><span class="line">      document.getElementById(&apos;container&apos;),</span><br><span class="line">      &#123;</span><br><span class="line">        data: &#123;</span><br><span class="line">          // 城市数据</span><br><span class="line">          cityData:</span><br><span class="line">            [</span><br><span class="line">              &#123;</span><br><span class="line">                  city: &quot;青岛&quot;,</span><br><span class="line">                  value: 100,</span><br><span class="line">                  EN: [120.3844, 36.1052],//经纬度</span><br><span class="line">              &#125;,</span><br><span class="line">              &#123;</span><br><span class="line">                  city: &quot;济南&quot;,</span><br><span class="line">                  value: 89,</span><br><span class="line">                  EN: [117.00, 36.40],</span><br><span class="line">              &#125;</span><br><span class="line">          ]</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;,</span><br><span class="line">      &#123;</span><br><span class="line">        // config: &#123;</span><br><span class="line">        //   mapJson: &apos;https://geo.datav.aliyun.com/areas_v3/bound/370000_full.json&apos;,</span><br><span class="line">        //   valueMax: 100,</span><br><span class="line">        //   level: 3,</span><br><span class="line">        //   longitude: 118.77,</span><br><span class="line">        //   latitude: 36.40</span><br><span class="line">        // &#125;,</span><br><span class="line">        config: &#123;</span><br><span class="line">          // 地图json地址</span><br><span class="line">          mapJson: &apos;https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json&apos;,</span><br><span class="line">          // 基准值，推进样本数据最大值</span><br><span class="line">          valueMax: 100,</span><br><span class="line">          // 缩放级别</span><br><span class="line">          level: 16,</span><br><span class="line">          // 中心坐标经度</span><br><span class="line">          longitude: 105.11,</span><br><span class="line">           // 中心坐标纬度</span><br><span class="line">          latitude: 35.98</span><br><span class="line">        &#125;,</span><br><span class="line">      &#125;</span><br><span class="line">    );</span><br><span class="line">  &lt;/script&gt;</span><br></pre></td></tr></table></figure><h2 id="备注："><a href="#备注：" class="headerlink" title="备注："></a>备注：</h2><ol><li>根据datart插件使用说明进行操作</li><li>根据需要优化后提交官方自定义插件库，部分规则依据当前使用的版本，命名规则等未按官方提供插件库的方式</li><li>地图json文件推荐，阿里云datav：<a href="http://datav.aliyun.com/portal/school/atlas/area_selector" target="_blank" rel="noopener">http://datav.aliyun.com/portal/school/atlas/area_selector</a></li><li>私有化部署，只需把文件放到私有化文件服务器或者可访问的地址即可</li><li>省份地图，推荐缩放级别在3或4即可，省份中心坐标自行百度</li><li>插件存在已知bug，后续修复，正常使用满足</li></ol><h2 id="效果展示"><a href="#效果展示" class="headerlink" title="效果展示"></a>效果展示</h2><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/datart/04/3d-01.png" alt="3d-01"></p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/datart/04/3d-02.png" alt="3d-02"></p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/datart/04/3d-sd.png" alt="3d-sd"></p>]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;概述&quot;&gt;&lt;a href=&quot;#概述&quot; class=&quot;headerlink&quot; title=&quot;概述&quot;&gt;&lt;/a&gt;概述&lt;/h2&gt;&lt;p&gt;datart自定义插件的方式，基于threejs自定义插件3D-MAP。&lt;/p&gt;
&lt;h2 id=&quot;应用场景&quot;&gt;&lt;a href=&quot;#应用场景&quot; class=&quot;headerlink&quot; title=&quot;应用场景&quot;&gt;&lt;/a&gt;应用场景&lt;/h2&gt;&lt;p&gt;根据经纬度进行的城市数据展示场景，适用数据大屏，3D地图等&lt;/p&gt;
    
    </summary>
    
      <category term="可视化工具" scheme="https://dumplingbao.github.io/categories/%E5%8F%AF%E8%A7%86%E5%8C%96%E5%B7%A5%E5%85%B7/"/>
    
      <category term="Datart" scheme="https://dumplingbao.github.io/categories/Datart/"/>
    
    
      <category term="BI" scheme="https://dumplingbao.github.io/tags/BI/"/>
    
      <category term="Datart" scheme="https://dumplingbao.github.io/tags/Datart/"/>
    
  </entry>
  
  <entry>
    <title>datart系列03：图表插件开发</title>
    <link href="https://dumplingbao.github.io/2022/04/15/datart-bi-03/"/>
    <id>https://dumplingbao.github.io/2022/04/15/datart-bi-03/</id>
    <published>2022-04-15T00:00:00.000Z</published>
    <updated>2022-04-15T00:03:00.415Z</updated>
    
    <content type="html"><![CDATA[<h2 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h2><p>开篇写过，datart借助自定义插件的方式，实现自定义扩展插件，就有了无限的可能。</p><p>通过最近一段时间的使用，datart自定义插件的方式同时把原来的不可能或很麻烦的二次开发变成了可能。</p><p>本身一些复杂的定制化的需求就需要独立于BI之外去做，借助自定义插件既保留的原来的灵活性，又可以抽离形成标准化，本身BI系统就是希望通过标准化来进行数据的分析展示</p><a id="more"></a><h2 id="示例：库存01"><a href="#示例：库存01" class="headerlink" title="示例：库存01"></a>示例：库存01</h2><h3 id="数据结构"><a href="#数据结构" class="headerlink" title="数据结构"></a>数据结构</h3><p><img src="https://cdn.disscode.cn/blog/datart/03/1m-1.png" alt="1m-1"></p><h3 id="展示效果"><a href="#展示效果" class="headerlink" title="展示效果"></a>展示效果</h3><p><img src="https://cdn.disscode.cn/blog/datart/03/1-01.jpg" alt="1-01"></p><p><img src="https://cdn.disscode.cn/blog/datart/03/1-02.jpg" alt="1-02"></p><h2 id="示例：库存02"><a href="#示例：库存02" class="headerlink" title="示例：库存02"></a>示例：库存02</h2><p><img src="https://cdn.disscode.cn/blog/datart/03/2-01.jpg" alt="2-01"></p><p><img src="https://cdn.disscode.cn/blog/datart/03/2-02.jpg" alt="2-02"></p><h2 id="示例：库存03"><a href="#示例：库存03" class="headerlink" title="示例：库存03"></a>示例：库存03</h2><h3 id="数据结构-1"><a href="#数据结构-1" class="headerlink" title="数据结构"></a>数据结构</h3><p><img src="https://cdn.disscode.cn/blog/datart/03/3m-1.png" alt="3m-1"></p><h3 id="展示效果-1"><a href="#展示效果-1" class="headerlink" title="展示效果"></a>展示效果</h3><p><img src="https://cdn.disscode.cn/blog/datart/03/3-01.jpg" alt="3-01"></p><p><img src="https://cdn.disscode.cn/blog/datart/03/3-02.jpg" alt="3-02"></p>]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;概述&quot;&gt;&lt;a href=&quot;#概述&quot; class=&quot;headerlink&quot; title=&quot;概述&quot;&gt;&lt;/a&gt;概述&lt;/h2&gt;&lt;p&gt;开篇写过，datart借助自定义插件的方式，实现自定义扩展插件，就有了无限的可能。&lt;/p&gt;
&lt;p&gt;通过最近一段时间的使用，datart自定义插件的方式同时把原来的不可能或很麻烦的二次开发变成了可能。&lt;/p&gt;
&lt;p&gt;本身一些复杂的定制化的需求就需要独立于BI之外去做，借助自定义插件既保留的原来的灵活性，又可以抽离形成标准化，本身BI系统就是希望通过标准化来进行数据的分析展示&lt;/p&gt;
    
    </summary>
    
      <category term="可视化工具" scheme="https://dumplingbao.github.io/categories/%E5%8F%AF%E8%A7%86%E5%8C%96%E5%B7%A5%E5%85%B7/"/>
    
      <category term="Datart" scheme="https://dumplingbao.github.io/categories/Datart/"/>
    
    
      <category term="BI" scheme="https://dumplingbao.github.io/tags/BI/"/>
    
      <category term="Datart" scheme="https://dumplingbao.github.io/tags/Datart/"/>
    
  </entry>
  
  <entry>
    <title>datart系列02：图表插件开发作品</title>
    <link href="https://dumplingbao.github.io/2022/04/05/datart-bi-02/"/>
    <id>https://dumplingbao.github.io/2022/04/05/datart-bi-02/</id>
    <published>2022-04-05T03:00:00.000Z</published>
    <updated>2022-04-05T15:11:35.674Z</updated>
    
    <content type="html"><![CDATA[<h2 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h2><p>今天整理了两个为未能参赛的作品，个人感觉还是比较好的两个点，就索性整理发出来。</p><a id="more"></a><h2 id="作品：手绘风格（D3）"><a href="#作品：手绘风格（D3）" class="headerlink" title="作品：手绘风格（D3）"></a>作品：手绘风格（D3）</h2><p>这个上一篇中说到了，也是时间的问题，未能找到原因，本以为是iframe嵌套导致的，后来官方给了去掉iframe的配置的方法进行了尝试，发现不是这个原因。</p><p>其实到现在也没有完全定位不能正常的渲染的原因，今天就换了种实现方式，放弃直接用开源的轮子，直接写源代码到插件里面，发现能够正常展示了，后续在把其它图表的补充完整。效果如下：</p><p><img src="https://cdn.disscode.cn/blog/datart/02/xkcd01.jpg" alt="xkcd01"></p><p><img src="https://cdn.disscode.cn/blog/datart/02/xkcd02.jpg" alt="xkcd01"></p><p><img src="https://cdn.disscode.cn/blog/datart/02/xkcd03.jpg" alt="xkcd01"></p><h2 id="作品：3D地图（CesiumJs）"><a href="#作品：3D地图（CesiumJs）" class="headerlink" title="作品：3D地图（CesiumJs）"></a>作品：3D地图（CesiumJs）</h2><p>关于Threejs、WebGL、CesiumJs这里不做赘述，虽然CesiumJs受众相对较小，而且偏重GIS，但是利用cesiumjs做数字孪生应该也有很多了，所以就集成到datar插件试一下，而且CesiumJs号称永久开源免费，但是这个完全不在参赛作品计划内，原因很简单，用到了付费插件，虽然费用很低，做项目没有任何问题，但是参赛开源就不好了。但是CesiumJs作为datart插件集成还是很简单的，单纯的3D地球，肯定满足不了实际场景，但是花点实际研究研究API搞点特效出来，还是不难的，而且CesiumJs好用，效果出众，下面就看一下效果：</p><p><img src="https://cdn.disscode.cn/blog/datart/02/cesium01.jpg" alt="xkcd01"></p><p><img src="https://cdn.disscode.cn/blog/datart/02/cesium04.jpg" alt="xkcd01"></p>]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;概述&quot;&gt;&lt;a href=&quot;#概述&quot; class=&quot;headerlink&quot; title=&quot;概述&quot;&gt;&lt;/a&gt;概述&lt;/h2&gt;&lt;p&gt;今天整理了两个为未能参赛的作品，个人感觉还是比较好的两个点，就索性整理发出来。&lt;/p&gt;
    
    </summary>
    
      <category term="可视化工具" scheme="https://dumplingbao.github.io/categories/%E5%8F%AF%E8%A7%86%E5%8C%96%E5%B7%A5%E5%85%B7/"/>
    
      <category term="Datart" scheme="https://dumplingbao.github.io/categories/Datart/"/>
    
    
      <category term="BI" scheme="https://dumplingbao.github.io/tags/BI/"/>
    
      <category term="Datart" scheme="https://dumplingbao.github.io/tags/Datart/"/>
    
  </entry>
  
  <entry>
    <title>datart系列01：图表插件开发作品大赛</title>
    <link href="https://dumplingbao.github.io/2022/03/27/datart-bi-01/"/>
    <id>https://dumplingbao.github.io/2022/03/27/datart-bi-01/</id>
    <published>2022-03-27T02:00:00.000Z</published>
    <updated>2022-03-27T14:19:10.625Z</updated>
    
    <content type="html"><![CDATA[<h2 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h2><p>2022年的第一篇，最近疫情+航空事故，虽是春暖花开，还是宅在家开码。借着datart图表插件开发作品大赛，给开了个头，datart的头，写作的头，但愿后续多写，今年估计的写的方向也会比较分散。</p><p>这一篇就当是参加图表插件开发作品大赛的一次开篇总结，也算是预热，这次采用datart自定义插件的形式，全部用自定义插件的方式，不改动源代码，不管怎么说，datart自定义插件发现越用越丝滑，很看好这一特性。后续再写datart源码及二次开发。</p><a id="more"></a><h2 id="作品："><a href="#作品：" class="headerlink" title="作品："></a>作品：</h2><h3 id="作品1：海洋鱼馆（动画）"><a href="#作品1：海洋鱼馆（动画）" class="headerlink" title="作品1：海洋鱼馆（动画）"></a>作品1：海洋鱼馆（动画）</h3><p>这个作品算是魔改，但确实有着特殊的应用场景</p><p>这个在Davinci的时候做过扩展，这次全新的素材</p><p>造了鱼馆的轮子来适配datart的插件，后期我们再展开思路讲实现，并开源出来（包括素材）</p><p><img src="https://cdn.disscode.cn/blog/datart/01/yg.jpg" alt></p><h3 id="作品2：地图（echarts）"><a href="#作品2：地图（echarts）" class="headerlink" title="作品2：地图（echarts）"></a>作品2：地图（echarts）</h3><p>这个也在Davinci扩展了，这次也是做了集成，场景没什么好说的，直接看效果，这个本来也想套一层封装，发现有点问题，直接用原生js做的集成</p><p><img src="https://cdn.disscode.cn/blog/datart/01/map.jpg" alt></p><h3 id="作品3：智能仓库（threejs）"><a href="#作品3：智能仓库（threejs）" class="headerlink" title="作品3：智能仓库（threejs）"></a>作品3：智能仓库（threejs）</h3><p>智能数字化车间，3D车间模型等等，这种3D场景化很多人都追求，甚至是偏执。查了资料，看了Threejs官网所有的demo，逛了社区，确实没找到高大上且合适的场景化模型。就从网上找了个智能仓库的场景做了集成，个人理解这种3D场景就是先做场景化的模型（这种模型确实需要专业人来做，上手有门槛），在场景位置上展示数据或者图表。这个也是造了适配datart的轮子，算是个demo，半成品吧，后期展开讲，也开源出来，有专业水平的可以做模型然后集成到datart。</p><p><img src="https://cdn.disscode.cn/blog/datart/01/threejs.jpg" alt></p><h3 id="作品4：手绘风格（D3）"><a href="#作品4：手绘风格（D3）" class="headerlink" title="作品4：手绘风格（D3）"></a>作品4：手绘风格（D3）</h3><p>这个效果没做成功，在Davinci的时候因为受限于echarts就没有做，这次可以扩展D3，本以为这个应该是最简单，确没有成功，初步判断应该是iframe嵌套导致滤镜不成功，没找到合适的方案。不过除了滤镜D3其它的效果集成还是没有任何问题的，后续再研究。</p><p><img src="https://cdn.disscode.cn/blog/datart/01/xkcd.jpg" alt></p><h2 id="总结："><a href="#总结：" class="headerlink" title="总结："></a>总结：</h2><p>总结一下datart自定义插件，对于前端来说可能算不上新技术，但是对于BI来说就是很好一次微创新：</p><ul><li>特殊化定制，满足个性化需求</li><li>上手容易，官方这块文档很详细</li><li>扩展灵活，很丝滑</li><li>像D3这种灵活性很高的，本是就具备无限可能，所以datart也具备无限可能</li></ul>]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;概述&quot;&gt;&lt;a href=&quot;#概述&quot; class=&quot;headerlink&quot; title=&quot;概述&quot;&gt;&lt;/a&gt;概述&lt;/h2&gt;&lt;p&gt;2022年的第一篇，最近疫情+航空事故，虽是春暖花开，还是宅在家开码。借着datart图表插件开发作品大赛，给开了个头，datart的头，写作的头，但愿后续多写，今年估计的写的方向也会比较分散。&lt;/p&gt;
&lt;p&gt;这一篇就当是参加图表插件开发作品大赛的一次开篇总结，也算是预热，这次采用datart自定义插件的形式，全部用自定义插件的方式，不改动源代码，不管怎么说，datart自定义插件发现越用越丝滑，很看好这一特性。后续再写datart源码及二次开发。&lt;/p&gt;
    
    </summary>
    
      <category term="可视化工具" scheme="https://dumplingbao.github.io/categories/%E5%8F%AF%E8%A7%86%E5%8C%96%E5%B7%A5%E5%85%B7/"/>
    
      <category term="Datart" scheme="https://dumplingbao.github.io/categories/Datart/"/>
    
    
      <category term="BI" scheme="https://dumplingbao.github.io/tags/BI/"/>
    
      <category term="Datart" scheme="https://dumplingbao.github.io/tags/Datart/"/>
    
  </entry>
  
  <entry>
    <title>我的2021年新Mac设置</title>
    <link href="https://dumplingbao.github.io/2021/11/27/mac-01/"/>
    <id>https://dumplingbao.github.io/2021/11/27/mac-01/</id>
    <published>2021-11-27T15:48:58.000Z</published>
    <updated>2021-11-28T07:51:01.302Z</updated>
    
    <content type="html"><![CDATA[<p>看到<a href="https://www.swyx.io/" target="_blank" rel="noopener">SHAWN <strong>@SWYX</strong> WANG</a>的<code>My 2021 New Mac Setup</code>的文章，相同的是都是用Mac作为程序开发，因此借着我的新Mac，我也进行了整理，写下这一份整理笔记。</p><a id="more"></a><h1 id="系统设置"><a href="#系统设置" class="headerlink" title="系统设置"></a>系统设置</h1><p>这个根据个人不同的喜好</p><ul><li>修复触控板方向：触控板 -&gt; 滚动和缩放 - 自然关闭</li><li>禁用 Spotlight 搜索除应用程序和系统首选项之外的所有杂项</li><li>禁用询问 Siri</li><li>禁用字典查找：触控板 -&gt; 指向和点击 -&gt; 查找和数据检测器关闭</li><li>首选项 → 显示文件扩展名</li><li>从 程序坞（Dock） 中删除所有内容，除了：Finder、系统偏好设置和垃圾箱</li><li>启用三指拖移：辅助功能 -&gt; 指针控制 -&gt; 启用拖移。（备注：启用后原三指操作变为四指）</li></ul><h1 id="浏览器设置"><a href="#浏览器设置" class="headerlink" title="浏览器设置"></a>浏览器设置</h1><p>Chrome自然必不可少，下载安装即可，设置为默认</p><p><strong>扩展程序</strong>：</p><ul><li><p><a href="https://chrome.google.com/webstore/detail/morpheon-dark/mafbdhjdkjnoafhfelkjpchpaepjknad?hl=en" target="_blank" rel="noopener">Morpheon 黑暗主题</a></p></li><li><p><a href="https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en" target="_blank" rel="noopener">React Devtools</a></p></li><li><p><a href="https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd?hl=zh-CN" target="_blank" rel="noopener">Vue.js devtools</a></p></li><li><p><a href="https://chrome.google.com/webstore/detail/github-chart/apaldppjjcjgjddfobajdclccgkbkkje?hl=zh-CN" target="_blank" rel="noopener">GitHub-Chart</a></p></li><li><p><a href="https://chrome.google.com/webstore/detail/go-get-for-github/ahkfiobnoafagbaaghmbbopfdpdbaidi?hl=zh-CN" target="_blank" rel="noopener">go get for Github</a></p></li><li><p><a href="https://chrome.google.com/webstore/detail/markdown-nice/blndbjkicjhcbpldeamfbdoeekcbampi?hl=zh-CN" target="_blank" rel="noopener">Markdown Nice</a></p></li><li><p><a href="https://chrome.google.com/webstore/detail/octotree-github-code-tree/bkhaagjahfmjljalopjnoealnfndnagc?hl=zh-CN" target="_blank" rel="noopener">Octotree - GitHub code tree</a></p></li><li><p><a href="https://chrome.google.com/webstore/detail/sourcegraph/dgjhfomjieaadpoljlnidmbgkdffpack?hl=zh-CN" target="_blank" rel="noopener">Sourcegraph</a></p></li></ul><h1 id="终端设置"><a href="#终端设置" class="headerlink" title="终端设置"></a>终端设置</h1><p>命令行真的是程序员必备的了，这个终端就很重要了，Mac的终端默认是bash，这个可真是太bash了，连<code>ll</code>命令都不行，当然可以配置。还是不推荐bash（就像window下的cmd，宁愿选择git下的bash），这个确实没法让我们起飞。</p><p>备注：bash就是shell一种增强版本，就是经常在sh文件里看到的<code>#! /bin/bash</code></p><p>shell有很多种，常用的基本上就是<code>bash</code>、<code>zsh</code>、<code>fish</code>了，他们的区别无外乎就是命令、格式（包括高亮、特殊格式显示）、提示信息等方面上的区分。</p><p>可以先看一下Mac提供了哪些shell（可以直接到bin目录下看），可以通过偏好设置就像修改，也可以直接通过下面的命令设置，设置完成需要重新进入终端</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"># 查看所有的shell</span><br><span class="line">cat /etc/shells</span><br><span class="line"># 查看系统用户默认shell</span><br><span class="line">cat /etc/passwd | grep sh</span><br><span class="line">## 系统默认的终端为bash，切换该终端为zsh</span><br><span class="line">chsh -s /bin/zsh</span><br><span class="line"># 切回默认终端bash</span><br><span class="line">chsh -s /bin/bash</span><br><span class="line"># 切换终端fish</span><br><span class="line">chsh -s /bin/fish</span><br></pre></td></tr></table></figure><p>没有需要安装，这里我安装的zsh而且是<a href="https://ohmyz.sh/#install" target="_blank" rel="noopener">Oh My Zsh</a>，安装简单，直接看官网。</p><p>Oh My Zsh可以设置主题和插件，提示信息非常nice，详细配置不再赘述，我摘了一段和zsh的区别：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">#  Zsh 是一个shell，就像bash或fish 一样，它解释命令并运行它们。Oh My Zsh 是一个构建在 zsh 之上的框架，其结构允许它拥有插件和主题，并从一开始就提供我们认为最好的设置。您可以在没有 Oh My Zsh 的情况下使用 zsh，但如果您没有 zsh，则无法使用 Oh My Zsh。</span><br></pre></td></tr></table></figure><p>如果需要fish的，推荐阮一峰的文章：<a href="http://www.ruanyifeng.com/blog/2017/05/fish_shell.html" target="_blank" rel="noopener">Fish shell 入门教程</a></p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/mac/terminal.png" alt="terminal"></p><h2 id="超级终端（Hyper-Terminal）"><a href="#超级终端（Hyper-Terminal）" class="headerlink" title="超级终端（Hyper Terminal）"></a>超级终端（<a href="https://hyper.is/" target="_blank" rel="noopener">Hyper Terminal</a>）</h2><p><a href="https://hyper.is/" target="_blank" rel="noopener">Hyper Terminal</a>，一个通用的串行交互软件，可以通过串口、调制解调器或以太网连接，使用该程序连接到其他计算机、Telnet 站点、公告板系统 （BBS）、联机服务和主机、嵌入式系统等。</p><p>超级终端还能对外观进行主题设置并可以安装插件，配置直接通过修改<code>.hyper.js</code>即可。</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/mac/hyperpower.gif" alt="hyper"></p><h1 id="环境及应用程序安装"><a href="#环境及应用程序安装" class="headerlink" title="环境及应用程序安装"></a>环境及应用程序安装</h1><h2 id="关闭SIP"><a href="#关闭SIP" class="headerlink" title="关闭SIP"></a>关闭SIP</h2><p>关闭SIP（SIP 全称为「System Integrity Protection」即「系统完整性保护」）还是有必要的，关闭之后才能修改某些文件的权限，一般建议修改完再打开，长期关闭回更方便，即使有些软件sudo进行安装也可以，还是关闭了吧。</p><p>以前的快捷键Command+R进入到恢复模式，M1芯片直接按住电源按钮即可进入。</p><p>顶部菜单拉中打开终端，输入：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">csrutil disable</span><br></pre></td></tr></table></figure><p>然后重启，设置权限就可以了</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">sudo chmod -R 777 目标文件夹</span><br><span class="line">或者</span><br><span class="line">sudo chmod a+w 目标文件夹</span><br></pre></td></tr></table></figure><h2 id="Homebrew"><a href="#Homebrew" class="headerlink" title="Homebrew"></a>Homebrew</h2><p>安装：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/bin/bash -c <span class="string">"<span class="variable">$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)</span>"</span></span><br></pre></td></tr></table></figure><p>如果443，修改host文件</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">sudo vi /etc/hosts</span><br><span class="line"># 加入</span><br><span class="line">199.232.4.133 raw.githubusercontent.com</span><br></pre></td></tr></table></figure><p>或者使用国内源</p><p>使用国内源：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/bin/zsh -c &quot;$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)&quot;</span><br></pre></td></tr></table></figure><p>配置的中科大的资源</p><h2 id="jdk"><a href="#jdk" class="headerlink" title="jdk"></a>jdk</h2><p>官网下载安装（1.8），默认不需要配置环境变量</p><h2 id="maven"><a href="#maven" class="headerlink" title="maven"></a>maven</h2><p>官网下载最新版，解压配置环境变量即可</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"> // vi ~/.bash_profile</span><br><span class="line"></span><br><span class="line">export MAVEN_HOME=/Users/bao/software/apache-maven-3.8.4</span><br><span class="line">export PATH=$PATH:$MAVEN_HOME/bin</span><br></pre></td></tr></table></figure><h2 id="git"><a href="#git" class="headerlink" title="git"></a>git</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">brew install git</span><br><span class="line">git --version</span><br><span class="line">git config --global user.name &quot;用户名&quot;</span><br><span class="line">git config --global user.email &quot;邮箱&quot;</span><br></pre></td></tr></table></figure><h2 id="nodejs"><a href="#nodejs" class="headerlink" title="nodejs"></a>nodejs</h2><p>直接安装</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"> ~/ brew install node</span><br><span class="line"> ~/ node -v</span><br></pre></td></tr></table></figure><p>但是实际工作会涉及到多node版本的问题，建议还是用<code>n</code>或者<code>mvn</code>来管理，这里我们用<code>n</code>，个人感觉好用轻巧</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"> ~/ brew install n</span><br><span class="line"> ~/ n stable     // 安装最新稳定版</span><br><span class="line"> ~/ n 14.17.0</span><br><span class="line">// 历史版本地址：https://nodejs.org/zh-cn/download/releases/</span><br><span class="line"> ~/ n ls         // 列出所有版本</span><br><span class="line">node/14.17.0</span><br><span class="line">node/16.13.0</span><br><span class="line"> ~/ n            // 切换版本</span><br><span class="line"> ~/ n rm &lt;version&gt;  // 删除某个版本</span><br></pre></td></tr></table></figure><p>如果已经安装了，node卸载方法</p><p>验证</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"> ~/ which node</span><br><span class="line">/User/&lt;your&apos;s-user-name&gt;/.nvm/versions/node/&lt;latest-node-lts-version&gt;/bin/node</span><br></pre></td></tr></table></figure><p>卸载</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"> ~/ rm -rf /usr/local/&#123;bin/&#123;node,npm&#125;,lib/node_modules/npm,lib/node,share/man/*/node.*&#125;</span><br></pre></td></tr></table></figure><h2 id="IntelliJ-IDEA-（v2021-2-3）"><a href="#IntelliJ-IDEA-（v2021-2-3）" class="headerlink" title="IntelliJ IDEA （v2021.2.3）"></a>IntelliJ IDEA （v2021.2.3）</h2><p>官网下载，需破解</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/mac/idea.png" alt="idea"></p><h2 id="VSCode"><a href="#VSCode" class="headerlink" title="VSCode"></a>VSCode</h2><p>官网下载即可，简单</p><h2 id="其它"><a href="#其它" class="headerlink" title="其它"></a>其它</h2><ul><li>Redis Desktop Manager（需破解）</li><li>Navicat Premium 15（需破解）</li><li>UltraEdit（需破解）</li><li>FinalShell</li></ul><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/mac/deskbook.gif" alt="desk"></p><h1 id="其它应用"><a href="#其它应用" class="headerlink" title="其它应用"></a>其它应用</h1><ul><li>CleanMyMac X （电脑清理、破解版）</li><li>WPS Office</li><li>超级右键</li><li>iShot（截图工具）</li><li>Typora（Markdown编辑工具）</li><li>AppDelete（软件卸载、破解版）</li><li>Photoshop</li><li>Parallels Desktop（Linux、win11、破解版）</li><li>MindNode（思维导图）</li></ul><h1 id="最后一游"><a href="#最后一游" class="headerlink" title="最后一游"></a>最后一游</h1><p>Wonderbox</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/mac/Wonderbox.jpg" alt="Wonderbox"></p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;看到&lt;a href=&quot;https://www.swyx.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;SHAWN &lt;strong&gt;@SWYX&lt;/strong&gt; WANG&lt;/a&gt;的&lt;code&gt;My 2021 New Mac Setup&lt;/code&gt;的文章，相同的是都是用Mac作为程序开发，因此借着我的新Mac，我也进行了整理，写下这一份整理笔记。&lt;/p&gt;
    
    </summary>
    
      <category term="MacBook" scheme="https://dumplingbao.github.io/categories/MacBook/"/>
    
      <category term="Mac" scheme="https://dumplingbao.github.io/categories/Mac/"/>
    
    
      <category term="MacBook" scheme="https://dumplingbao.github.io/tags/MacBook/"/>
    
  </entry>
  
  <entry>
    <title>小程序：Painter画布</title>
    <link href="https://dumplingbao.github.io/2021/08/03/wx-painter/"/>
    <id>https://dumplingbao.github.io/2021/08/03/wx-painter/</id>
    <published>2021-08-03T15:37:18.000Z</published>
    <updated>2021-11-26T18:18:19.598Z</updated>
    
    <content type="html"><![CDATA[<p>Painter这个小程序画布组件应该很多人在用，github上超3K的star就已经说明这个组件的强大了。这里我们用这个组件实现短讯（如24小时动态）的分享和海报生成。</p><a id="more"></a><h2 id="效果"><a href="#效果" class="headerlink" title="效果"></a>效果</h2><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/wx/pt/p001.jpg" alt="p001"></p><p>图二生成的图片，也是分享出去的效果，可以点击分享跳转到短讯的详情即可，分享到群如下：</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/wx/pt/p002.jpg" alt="p002"></p><h2 id="介绍"><a href="#介绍" class="headerlink" title="介绍"></a>介绍</h2><p>Painter组件地址：<a href="https://github.com/Kujiale-Mobile/Painter" target="_blank" rel="noopener">https://github.com/Kujiale-Mobile/Painter</a></p><p>可以通过源代码看一下组件的实现方式，其实Painter的readMe里面已经把组件的实现方式描述的很详细了，组件接收json格式，然后通过pen.js（画笔）画出json格式不同类型（文本、图片、矩形、qrcode ）的view绘制，这种方式设计巧妙，对于很多复杂的情况需求都能满足。而且代码完善，优化调整也很方便。</p><p>Painter提供的工具能够将json数据直接转换效果，方便调试，链接地址：</p><p>链接1：<a href="https://painterjs.github.io/" target="_blank" rel="noopener">https://painterjs.github.io/</a></p><p>链接2：<a href="https://lingxiaoyi.github.io/painter-custom-poster/" target="_blank" rel="noopener">https://lingxiaoyi.github.io/painter-custom-poster/</a></p><p>我们上面短讯的效果，只需利用Painter封装两个组件，一个用于分享，一个用于生成海报，控制两个组件显示隐藏即可。通过按钮传递标题、时间、标签、内容等信息，并通过组件接收，然后拼装json文件传递给Painter组件。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&lt;!-- 分享绘图组件 --&gt;</span><br><span class="line">&lt;share-box wx:if=&quot;&#123;&#123;isCanDraw&#125;&#125;&quot; isCanDraw=&quot;&#123;&#123;isCanDraw&#125;&#125;&quot; time=&quot;&#123;&#123;timeShare&#125;&#125;&quot; source=&quot;&#123;&#123;sourceShare&#125;&#125;&quot; id=&quot;&#123;&#123;idShare&#125;&#125;&quot; title=&quot;&#123;&#123;titleShare&#125;&#125;&quot;  content=&quot;&#123;&#123;contentShare&#125;&#125;&quot; bind:close=&quot;handleClose&quot;  bind:initData=&quot;initData&quot; bind:createPoster=&quot;createPoster&quot;/&gt;</span><br><span class="line"></span><br><span class="line">&lt;!-- 海报组件 --&gt;</span><br><span class="line">&lt;poster-box isPoster=&quot;&#123;&#123;isPoster&#125;&#125;&quot; time=&quot;&#123;&#123;timeShare&#125;&#125;&quot; source=&quot;&#123;&#123;sourceShare&#125;&#125;&quot; id=&quot;&#123;&#123;idShare&#125;&#125;&quot; title=&quot;&#123;&#123;titleShare&#125;&#125;&quot;  content=&quot;&#123;&#123;contentShare&#125;&#125;&quot; bind:closePoster=&quot;handleClosePoster&quot;/&gt;</span><br></pre></td></tr></table></figure><p>此外，我们利用lin-ui实现了日期的吸顶效果（备：lin-ui对于吸顶效果的封装很易用，可以尝试一下）、内容展示的卡片效果，不再赘述，详细实现可直接查看下面的代码地址。</p><h2 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h2><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/wx/ssn/diss.jpg" alt="diss"></p><p>已提交github，扫码关注公众号（diss带码），回复：webview，获得源码github地址</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Painter这个小程序画布组件应该很多人在用，github上超3K的star就已经说明这个组件的强大了。这里我们用这个组件实现短讯（如24小时动态）的分享和海报生成。&lt;/p&gt;
    
    </summary>
    
      <category term="小程序" scheme="https://dumplingbao.github.io/categories/%E5%B0%8F%E7%A8%8B%E5%BA%8F/"/>
    
      <category term="微信" scheme="https://dumplingbao.github.io/categories/%E5%BE%AE%E4%BF%A1/"/>
    
    
      <category term="小程序" scheme="https://dumplingbao.github.io/tags/%E5%B0%8F%E7%A8%8B%E5%BA%8F/"/>
    
  </entry>
  
  <entry>
    <title>小程序：mqtt+webview控制显示内容</title>
    <link href="https://dumplingbao.github.io/2021/07/22/wx-mqtt/"/>
    <id>https://dumplingbao.github.io/2021/07/22/wx-mqtt/</id>
    <published>2021-07-22T15:48:58.000Z</published>
    <updated>2021-11-26T18:18:19.598Z</updated>
    
    <content type="html"><![CDATA[<p>看到mqtt+webview似乎不知道能做什么，mqtt微消息服务更适用iot物联网，这个应该熟悉，但是似乎还是得从webview说起。webview的场景不仅仅是手机端的APP或者小程序用到，好多基于android主板显示的设备、大屏等webview都发挥了很大的作用。这里我们一是验证小程序的mqtt，二是通过mqtt控制设备自动切换显示内容，这样试想一下，其实就是远程操控设备显示内容的一种很好的方式。</p><a id="more"></a><h2 id="效果"><a href="#效果" class="headerlink" title="效果"></a>效果</h2><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/wx/mq/mqtt.gif" alt="01"></p><h2 id="mqtt小程序端"><a href="#mqtt小程序端" class="headerlink" title="mqtt小程序端"></a>mqtt小程序端</h2><p>需要mqtt.js客户端库：<a href="https://github.com/mqttjs/MQTT.js" target="_blank" rel="noopener">https://github.com/mqttjs/MQTT.js</a></p><p>小程序配置：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><span class="line">const app = getApp()</span><br><span class="line">var mqtt = require(&apos;../../../utils/mqtt.min&apos;)</span><br><span class="line">var client = null</span><br><span class="line"></span><br><span class="line">Page(&#123;</span><br><span class="line"></span><br><span class="line">  /**</span><br><span class="line">   * 页面的初始数据</span><br><span class="line">   */</span><br><span class="line">  data: &#123;</span><br><span class="line">    webUrl: &apos;https://www.baidu.com&apos;</span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  /**</span><br><span class="line">   * 生命周期函数--监听页面加载</span><br><span class="line">   */</span><br><span class="line">  onLoad: function (options) &#123;</span><br><span class="line">    this.connnectMqtt()</span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  connnectMqtt: function ()&#123;</span><br><span class="line">    var that = this</span><br><span class="line">    const options = &#123;</span><br><span class="line">      connectTimeout: 4000, // 超时时间</span><br><span class="line">      clientId: &apos;mqtt_&apos; + Math.random().toString(16).substr(2, 8),</span><br><span class="line">      port: 8083,  //重点注意这个坑</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    client = mqtt.connect(&quot;wx://xx.xx.xx.xx/mqtt&quot;, options);</span><br><span class="line">    client.on(&apos;reconnect&apos;, (error) =&gt; &#123;</span><br><span class="line">        console.log(&apos;正在重连:&apos;, error)</span><br><span class="line">    &#125;)</span><br><span class="line"></span><br><span class="line">    client.on(&apos;error&apos;, (error) =&gt; &#123;</span><br><span class="line">        console.log(&apos;连接失败:&apos;, error)</span><br><span class="line">    &#125;)</span><br><span class="line">    client.on(&apos;connect&apos;, (e) =&gt; &#123;</span><br><span class="line">        console.log(&apos;成功连接服务器&apos;)</span><br><span class="line">  　　　　　　　//订阅一个主题</span><br><span class="line">        client.subscribe(&apos;test&apos;, &#123;</span><br><span class="line">            qos: 0</span><br><span class="line">        &#125;, function(err) &#123;</span><br><span class="line">            if (!err) &#123;</span><br><span class="line">                console.log(&quot;订阅成功&quot;)</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;)</span><br><span class="line">    &#125;)</span><br><span class="line">    client.on(&apos;message&apos;, function (topic, message) &#123;</span><br><span class="line">        console.log(&apos;received msg:&apos; + message.toString());</span><br><span class="line">        that.setData(&#123;</span><br><span class="line">          webUrl: message.toString()</span><br><span class="line">        &#125;)</span><br><span class="line">        console.log(that.data.webUrl)</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125; </span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;web-view src=&quot;&#123;&#123;webUrl&#125;&#125;&quot; bindmessage=&quot;getmessage&quot;&gt;&lt;/web-view&gt;</span><br></pre></td></tr></table></figure><h2 id="mqtt服务端安装"><a href="#mqtt服务端安装" class="headerlink" title="mqtt服务端安装"></a>mqtt服务端安装</h2><p><em>EMQ X</em> 是一款完全开源，高度可伸缩，高可用的分布式 MQTT 消息服务器</p><p>git地址：<a href="https://gitee.com/emqx/emqx" target="_blank" rel="noopener">https://gitee.com/emqx/emqx</a></p><h3 id="docker安装步骤"><a href="#docker安装步骤" class="headerlink" title="docker安装步骤"></a>docker安装步骤</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ docker search emqx // 查看版本</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ docker pull emqx/emqx // 拉取镜像</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ docker run -dit --name emqx -p 18083:18083 -p 1883:1883 -p 8083:8083 -p 8084:8084 emqx/emqx:latest // 运行</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ docker exec -it  emqx /bin/sh // 进入命名</span><br></pre></td></tr></table></figure><h3 id="web管理界面"><a href="#web管理界面" class="headerlink" title="web管理界面"></a>web管理界面</h3><p><code>http://127.0.0.1:18083</code></p><p><code>#账号： admin</code></p><p><code>#密码: public</code></p><h3 id="端口介绍"><a href="#端口介绍" class="headerlink" title="端口介绍"></a>端口介绍</h3><p><code>1883：MQTT 协议端口</code></p><p><code>8883：MQTT/SSL 端口</code></p><p><code>8083：MQTT/WebSocket 端口</code></p><p><code>8080：HTTP API 端口</code></p><p><code>18083：Dashboard 管理控制台端口</code></p><h2 id="mqtt客户端工具"><a href="#mqtt客户端工具" class="headerlink" title="mqtt客户端工具"></a>mqtt客户端工具</h2><p>我们没必要写后台代码，直接用个mqtt客户端工具做测试，用的MQTTX，这个就根据个人习惯选了</p><p>MQTTX地址：<a href="https://github.com/emqx/MQTTX/releases" target="_blank" rel="noopener">https://github.com/emqx/MQTTX/releases</a></p><p>安装完成配置验证即可。</p><h2 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h2><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/wx/ssn/diss.jpg" alt="diss"></p><p>已提交github，扫码关注公众号（diss带码），回复：webview，获得源码github地址</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;看到mqtt+webview似乎不知道能做什么，mqtt微消息服务更适用iot物联网，这个应该熟悉，但是似乎还是得从webview说起。webview的场景不仅仅是手机端的APP或者小程序用到，好多基于android主板显示的设备、大屏等webview都发挥了很大的作用。这里我们一是验证小程序的mqtt，二是通过mqtt控制设备自动切换显示内容，这样试想一下，其实就是远程操控设备显示内容的一种很好的方式。&lt;/p&gt;
    
    </summary>
    
      <category term="小程序" scheme="https://dumplingbao.github.io/categories/%E5%B0%8F%E7%A8%8B%E5%BA%8F/"/>
    
      <category term="微信" scheme="https://dumplingbao.github.io/categories/%E5%BE%AE%E4%BF%A1/"/>
    
    
      <category term="小程序" scheme="https://dumplingbao.github.io/tags/%E5%B0%8F%E7%A8%8B%E5%BA%8F/"/>
    
  </entry>
  
  <entry>
    <title>小程序：webview + PDF预览</title>
    <link href="https://dumplingbao.github.io/2021/07/20/wx-pdf/"/>
    <id>https://dumplingbao.github.io/2021/07/20/wx-pdf/</id>
    <published>2021-07-20T15:58:06.000Z</published>
    <updated>2021-11-26T18:18:19.598Z</updated>
    
    <content type="html"><![CDATA[<p>一般文件预览除了图片基本主要指office的文件预览，不同文件（word、Excel、pdf）格式差异大，所以很难有共性。相对来说PDF的预览会相对简单一些，而且大都能转换成pdf，我们就已pdf为例。小程序官方未提供，目前能找到和想到的方式，如下：</p><a id="more"></a><h2 id="第一：采用wx-openDocument"><a href="#第一：采用wx-openDocument" class="headerlink" title="第一：采用wx.openDocument"></a>第一：采用wx.openDocument</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">wx.downloadFile(&#123;</span><br><span class="line">    url: &apos;www.file.com/file.ppt&apos;,//可以是后台传过来的路径</span><br><span class="line">    success: function(res) &#123;</span><br><span class="line">        const filePath = res.tempFilePath</span><br><span class="line">        wx.openDocument(&#123;</span><br><span class="line">            filePath: filePath,</span><br><span class="line">            success: function(res) &#123;</span><br><span class="line">                //成功</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure><p>效果：</p><p>说明：这种实际上是先下载了临时路径，好处是pdf、word、Excel都能预览，坏处是这种方式不一定能接受。</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/wx/pdf/pdf001.jpg" alt="001"></p><h2 id="第二：webview-第三方pdf库"><a href="#第二：webview-第三方pdf库" class="headerlink" title="第二：webview+第三方pdf库"></a>第二：webview+第三方pdf库</h2><p>pdfjs是个很好的pdf预览的js库，可以不用改造直接使用，简单部署个服务，或者通过nginx配置一下即可，这里我们直接通过cdn阿里oss文件服务器来运行</p><p>pdfjs获取地址：<a href="https://github.com/mozilla/pdf.js" target="_blank" rel="noopener">https://github.com/mozilla/pdf.js</a></p><p>oss服务demo：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://byfile.disscode.cn/pdfjs-2.8/web/viewer.html?file=https://byfile.disscode.cn/blog/2021/wx/pdf/01.pdf</span><br></pre></td></tr></table></figure><p>小程序配置就很简单了，就是通过webview的方式调用pdfjs服务，只需传递pdf文件地址即可</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;web-view src=&quot;https://byfile.disscode.cn/pdfjs-2.8/web/viewer.html?file=&#123;&#123;url&#125;&#125;&quot;&gt;&lt;/web-view&gt;</span><br></pre></td></tr></table></figure><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/wx/pdf/pdf002.jpg" alt="002"></p><p>备注：PDF.js访问远程服务器（非同域名下）报file origin does not match viewer’s</p><p>需要将pdfjs下面的viewer.js中注释掉代码</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">// if (origin !== viewerOrigin &amp;&amp; protocol !== &apos;blob:&apos;) &#123;</span><br><span class="line">//   throw new Error(&apos;file origin does not match viewer\&apos;s&apos;);</span><br><span class="line">// &#125;</span><br></pre></td></tr></table></figure><h2 id="第三：延伸markdown文件渲染"><a href="#第三：延伸markdown文件渲染" class="headerlink" title="第三：延伸markdown文件渲染"></a>第三：延伸markdown文件渲染</h2><p>markdown格式的内容渲染已有组件可以支持，尝试markdown的文件直接进行渲染，这里直接找到第三方库marked.js进行尝试</p><p>github地址：<a href="https://github.com/markedjs/marked" target="_blank" rel="noopener">https://github.com/markedjs/marked</a></p><p>同样制作oss服务的demo</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://byfile.disscode.cn/marked/marked.html?file=https://byfile.disscode.cn/blog/2021/wx/mk/%E3%80%90BLOG%E3%80%91hexo%E6%90%AD%E5%BB%BAblog%E6%95%99%E7%A8%8B.md</span><br></pre></td></tr></table></figure><p>小程序同样是webview的方式：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;web-view src=&quot;https://byfile.disscode.cn/marked/marked.html?file=&#123;&#123;url&#125;&#125;&quot;&gt;&lt;/web-view&gt;</span><br></pre></td></tr></table></figure><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/wx/mk/mk01.jpg" alt="mk01"></p><p>但是，markdown采用这种方式直接渲染文件，发现图片、换行等样式渲染还是有问题的，所以期待更多尝试。</p><p>备注：测试去掉域名的校验，要么就添加到小程序业务域名里面，否则不能正常访问</p><h2 id="第四：代码"><a href="#第四：代码" class="headerlink" title="第四：代码"></a>第四：代码</h2><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/wx/ssn/diss.jpg" alt="diss"></p><p>已提交github，扫码关注公众号（diss带码），回复：webview，获得源码github地址</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;一般文件预览除了图片基本主要指office的文件预览，不同文件（word、Excel、pdf）格式差异大，所以很难有共性。相对来说PDF的预览会相对简单一些，而且大都能转换成pdf，我们就已pdf为例。小程序官方未提供，目前能找到和想到的方式，如下：&lt;/p&gt;
    
    </summary>
    
      <category term="小程序" scheme="https://dumplingbao.github.io/categories/%E5%B0%8F%E7%A8%8B%E5%BA%8F/"/>
    
      <category term="微信" scheme="https://dumplingbao.github.io/categories/%E5%BE%AE%E4%BF%A1/"/>
    
    
      <category term="小程序" scheme="https://dumplingbao.github.io/tags/%E5%B0%8F%E7%A8%8B%E5%BA%8F/"/>
    
  </entry>
  
  <entry>
    <title>小程序：数十年Lite</title>
    <link href="https://dumplingbao.github.io/2021/07/17/wx-ssn/"/>
    <id>https://dumplingbao.github.io/2021/07/17/wx-ssn/</id>
    <published>2021-07-17T04:00:00.000Z</published>
    <updated>2021-11-26T18:18:19.598Z</updated>
    
    <content type="html"><![CDATA[<h2 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h2><p>端午参加毕业十周年聚会，聚会之前花了几天时间撸了个小程序，聚会结束了，十年也真的过去了。</p><a id="more"></a><h2 id="效果"><a href="#效果" class="headerlink" title="效果"></a>效果</h2><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/wx/ssn/01.jpg" alt="01" style="zoom: 50%;"><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/wx/ssn/02.jpg" alt="02" style="zoom: 50%;"><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/wx/ssn/03.jpg" alt="03" style="zoom: 50%;"><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/wx/ssn/04.jpg" alt="04" style="zoom: 50%;"><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/wx/ssn/05.jpg" alt="04" style="zoom:50%;"><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/wx/ssn/06.jpg" alt="06" style="zoom:50%;"><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/wx/ssn/07.jpg" alt="07" style="zoom:50%;"><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/wx/ssn/08.jpg" alt="08" style="zoom:50%;"></p><h2 id="组件介绍"><a href="#组件介绍" class="headerlink" title="组件介绍"></a>组件介绍</h2><h3 id="ColorUI"><a href="#ColorUI" class="headerlink" title="ColorUI"></a>ColorUI</h3><p>很棒的小程序UI，而且很大一个特点是特别的简洁，组件也很完善</p><p>github地址：<a href="https://github.com/weilanwl/ColorUI/" target="_blank" rel="noopener">https://github.com/weilanwl/ColorUI/</a></p><p>效果地址：<a href="http://demo.color-ui.com/" target="_blank" rel="noopener">http://demo.color-ui.com/</a></p><h3 id="Painter"><a href="#Painter" class="headerlink" title="Painter"></a>Painter</h3><p>这个用来生成图片、海报确实好用</p><p>github地址：<a href="https://github.com/Kujiale-Mobile/Painter" target="_blank" rel="noopener">https://github.com/Kujiale-Mobile/Painter</a></p><h2 id="菊码"><a href="#菊码" class="headerlink" title="菊码"></a>菊码</h2><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/wx/ssn/ju.png" alt="ju"></p><h2 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h2><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/wx/ssn/diss.jpg" alt="diss"></p><p>已提交github，扫码关注公众号（diss带码），回复：数十年，获得源码github地址</p><p>备注：后端采用springboot + MongoDB，源码已去除后端，可以直接运行，数据目前读取的json文件</p><p>温馨提示：发布动态（上传图片）功能涉及个人小程序审核就去掉了，但是可以当成后台工具，要么就单独做个后台管理的web端</p>]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;概述&quot;&gt;&lt;a href=&quot;#概述&quot; class=&quot;headerlink&quot; title=&quot;概述&quot;&gt;&lt;/a&gt;概述&lt;/h2&gt;&lt;p&gt;端午参加毕业十周年聚会，聚会之前花了几天时间撸了个小程序，聚会结束了，十年也真的过去了。&lt;/p&gt;
    
    </summary>
    
      <category term="小程序" scheme="https://dumplingbao.github.io/categories/%E5%B0%8F%E7%A8%8B%E5%BA%8F/"/>
    
      <category term="微信" scheme="https://dumplingbao.github.io/categories/%E5%BE%AE%E4%BF%A1/"/>
    
    
      <category term="小程序" scheme="https://dumplingbao.github.io/tags/%E5%B0%8F%E7%A8%8B%E5%BA%8F/"/>
    
  </entry>
  
  <entry>
    <title>验证码：五福临门</title>
    <link href="https://dumplingbao.github.io/2021/03/05/bless-01/"/>
    <id>https://dumplingbao.github.io/2021/03/05/bless-01/</id>
    <published>2021-03-04T16:00:00.000Z</published>
    <updated>2021-11-26T18:18:19.595Z</updated>
    
    <content type="html"><![CDATA[<h2 id="一看"><a href="#一看" class="headerlink" title="一看"></a>一看</h2><p>验证码这个既熟悉又常用的功能，一提起来你就会想起各种各样的验证码，一个偶然的机会，就冒出来做个验证码，慢慢的就演变成现在的五福临门验证码。先看一下效果图：</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/bless/bless.gif" alt="bless"></p><a id="more"></a><h2 id="由来"><a href="#由来" class="headerlink" title="由来"></a>由来</h2><ol><li>春节前看到一篇关于验证码的文章，动态刷新、滑动验证，这里的动，总感觉没有“动”</li><li>加上之前做的游鱼，就想让它动起来，所以最初就是在滑块验证码的基础上，让滑块在外面游动起来</li><li>后来支付宝集五福，让我突然感觉可以考虑，五个福字随机掉下来一个在外面游动，然后滑动原位置，正好符合春节的气息</li><li>再后来参与了支付宝打印福字的活动，然后就手写了五福，这样不仅是随机五福，还可以随机不同主题的五福了</li><li>春节前开始的，前期做了技术验证，春节陆陆续续进行了实现</li><li>后来找资料做轨迹校验，断断续续，今天暂时把前端部分发出来，后端验证决定后续再补一篇</li></ol><p>下面是个设计效果图：</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/bless/wflm.png" alt="wflm"></p><h2 id="认知"><a href="#认知" class="headerlink" title="认知"></a>认知</h2><p>验证码虽然已经司空见惯了，但是还是想讲一下验证的一些接触，从中也能体会乐趣。</p><p>起初进入技术行业，还是一个验证码不流行的阶段，计算机识别技术更是起步，所以扭曲、污染的文字无法辨识，所以最初见到的就是4个字母数字，一条飞线。</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/bless/01.png" alt="01"></p><p>慢慢的越来越流行，越来越多样，越来越看不懂</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/bless/02.png" alt="02"></p><p>越来越烧脑，亦或是恶搞</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/bless/03.png" alt="03"></p><p>新时代的验证码越来越多样，出现了两极分化，一种让你赏心悦目，一种让你抢不到票</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/bless/yzm.jpg" alt="yzm"></p><p>验证码在技术里面或许是小场面，但却蕴藏着大智慧，而且是紧跟时代的产物，根据人们需求的变化而变化，当然破解和识别技术的提升也在嘶声呐喊和“催更”</p><h2 id="技术"><a href="#技术" class="headerlink" title="技术"></a>技术</h2><p>验证码可以防止：恶意破解密码、<a href="https://baike.baidu.com/item/刷票/6540942" target="_blank" rel="noopener">刷票</a>、论坛灌水等</p><ul><li><p>软件包：成熟的插件和软件包，直接引入使用就可以了</p></li><li><p>第三方：网易易盾等，购买按官方文档使用</p><p>网易易盾：<a href="https://dun.163.com/" target="_blank" rel="noopener">https://dun.163.com/</a></p></li><li><p>无痕验证：阿里云-人机验证</p><p>  <a href="https://help.aliyun.com/product/28308.html" target="_blank" rel="noopener">https://help.aliyun.com/product/28308.html</a></p><p>  用过阿里云的都知道，阿里云登录输入账号密码就可以了，点击登录也没有多余的操作，以为就没有验证，其实阿里做的是无痕验证，即使没有可视化的验证码出现，其实已经对你登录做了人机的校验了，所以不要以为没有可见的验证码就误以为没有验证。</p></li></ul><h2 id="实现"><a href="#实现" class="headerlink" title="实现"></a>实现</h2><p>技术栈：前端nodejs+vue，后端java+redis</p><p>滑块验证：vue-drag-drop</p><p>游动：animateplus</p><p>目前的前端部分演示demo（目前只支持pc端）：<a href="http://bless.disscode.cn/#/loginSlider" target="_blank" rel="noopener">http://bless.disscode.cn/#/loginSlider</a></p><h2 id="五福临门"><a href="#五福临门" class="headerlink" title="五福临门"></a>五福临门</h2><p>一曰寿，二曰富，三曰康宁，四曰攸好德，五曰考终命</p><p>五福含意：第一福是“长寿”、第二福是“富贵”、第三福是“康宁”、第四福是“好德”、第五福是“善终”。有人简称为寿富康德善。</p>]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;一看&quot;&gt;&lt;a href=&quot;#一看&quot; class=&quot;headerlink&quot; title=&quot;一看&quot;&gt;&lt;/a&gt;一看&lt;/h2&gt;&lt;p&gt;验证码这个既熟悉又常用的功能，一提起来你就会想起各种各样的验证码，一个偶然的机会，就冒出来做个验证码，慢慢的就演变成现在的五福临门验证码。先看一下效果图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/bless/bless.gif&quot; alt=&quot;bless&quot;&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="验证码" scheme="https://dumplingbao.github.io/categories/%E9%AA%8C%E8%AF%81%E7%A0%81/"/>
    
    
      <category term="验证码" scheme="https://dumplingbao.github.io/tags/%E9%AA%8C%E8%AF%81%E7%A0%81/"/>
    
  </entry>
  
  <entry>
    <title>开源论坛：社区选择Discourse</title>
    <link href="https://dumplingbao.github.io/2021/03/02/dis-01/"/>
    <id>https://dumplingbao.github.io/2021/03/02/dis-01/</id>
    <published>2021-03-02T15:00:00.000Z</published>
    <updated>2021-11-26T18:18:19.596Z</updated>
    
    <content type="html"><![CDATA[<p>回想以往逛论坛、贴吧的年代，似乎渐行渐远，现在人类追求的多样性超出想象，但论坛并未走下神坛，只是换了一种或者是以多种方式存在。社区、小组、圈子等都有更多的载体和工具，今天就说一下开源论坛discourse。</p><p>Discourse应该也已经20多年了，并不新鲜，也是因为平常经常浏览的技术社区用的就是discourse，所以就搭建一下，深入感受一下discourse，以备后用。</p><a id="more"></a><p>Discourse总体下来，觉得挺适合做社区，尤其是技术性比较聚集的论坛</p><ul><li>开源论坛</li><li>创始人想要让改变十年未变的互联网论坛模样</li><li>基于Ruby on Rails 和 Ember.js 开发，数据库使用 PostgreSQL 和 Redis</li><li>最大的特点是简洁和专业性，以话题为关系聚集用户</li></ul><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/2021/dis/dis.png" alt="dis"></p><h2 id="Discourse官网："><a href="#Discourse官网：" class="headerlink" title="Discourse官网："></a>Discourse官网：</h2><ul><li>官方网站：<a href="https://www.discourse.org/" target="_blank" rel="noopener">https://www.discourse.org/</a></li><li>官方社区：<a href="https://meta.discourse.org/" target="_blank" rel="noopener">https://meta.discourse.org/</a></li><li>Github项目：<a href="https://github.com/discourse/discourse" target="_blank" rel="noopener">https://github.com/discourse/discourse</a></li></ul><h2 id="搭建步骤"><a href="#搭建步骤" class="headerlink" title="搭建步骤"></a>搭建步骤</h2><h3 id="安装git和Docker"><a href="#安装git和Docker" class="headerlink" title="安装git和Docker"></a>安装git和Docker</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">apt-get install git</span><br><span class="line">wget -qO- https://get.docker.io/ | sh</span><br></pre></td></tr></table></figure><h3 id="安装Discourse"><a href="#安装Discourse" class="headerlink" title="安装Discourse"></a>安装Discourse</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">mkdir /var/discourse</span><br><span class="line">git clone https://github.com/discourse/discourse_docker.git /var/discourse</span><br><span class="line">cd /var/discourse</span><br><span class="line">cp samples/standalone.yml containers/app.yml（or ./discourse-setup 初始化）</span><br></pre></td></tr></table></figure><h3 id="修改配置文件"><a href="#修改配置文件" class="headerlink" title="修改配置文件"></a>修改配置文件</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">vim containers/app.yml</span><br><span class="line"></span><br><span class="line">UNICORN_WORKERS（如果是1Gb内存就是2，2GB内存以上就是3-4）</span><br><span class="line">DISCOURSE_DEVELOPER_EMAILS管理员邮箱</span><br><span class="line">DISCOURSE_HOSTNAME 绑定的域名</span><br><span class="line">DISCOURSE_SMTP_ADDRESS是邮局服务器</span><br><span class="line">DISCOURSE_SMTP_PORT是SMTP的端口</span><br><span class="line">DISCOURSE_SMTP_USER_NAME账号</span><br><span class="line">DISCOURSE_SMTP_PASSWORD密码</span><br></pre></td></tr></table></figure><p>特别注意的是：端口号465是没有效果的</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">DISCOURSE_SMTP_PORT: 587</span><br></pre></td></tr></table></figure><p>以上配置完了，会收不到邮件有两种方式修改</p><p>第一种：用官方的工具launcher创建管理员账号</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">cd /var/discourse</span><br><span class="line">./launcher enter app</span><br><span class="line">rake admin:create</span><br></pre></td></tr></table></figure><ul><li>创建管理员账号，按要求输入管理员邮箱和登录密码</li><li>登录网站，用刚才创建的账号直接登录。</li><li>在settings页面设置notification email为发件邮箱，就是之前配置文件里面写的那个邮箱。</li><li>在邮件测试页面发一封测试邮件，应该测试成功了。</li></ul><p>第二种：编辑发件邮箱</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">vim containers/app.yml</span><br><span class="line">//定位文件底部，打开注释</span><br><span class="line">- exec: rails r &quot;SiteSetting.notification_email=&apos;xxx@qq.com&apos;&quot;</span><br><span class="line">//重新build一下</span><br><span class="line">./launcher rebuild app</span><br></pre></td></tr></table></figure><h3 id="修改完成后，重新构建"><a href="#修改完成后，重新构建" class="headerlink" title="修改完成后，重新构建"></a>修改完成后，重新构建</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./launcher rebuild app</span><br></pre></td></tr></table></figure><h3 id="nginx与discourse"><a href="#nginx与discourse" class="headerlink" title="nginx与discourse"></a>nginx与discourse</h3><p>discourse配置修改：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">cd /var/discourse</span><br><span class="line">vim containers/app.yml</span><br></pre></td></tr></table></figure><p>修改：(设置端口代理)</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">expose:</span><br><span class="line">  - &quot;9090:80&quot;   # http</span><br></pre></td></tr></table></figure><p>最后运行</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./launcher rebuild app</span><br></pre></td></tr></table></figure><h3 id="nginx增加配置："><a href="#nginx增加配置：" class="headerlink" title="nginx增加配置："></a>nginx增加配置：</h3><p>增加discourse.conf即可</p><h3 id="添加Github第三方登录"><a href="#添加Github第三方登录" class="headerlink" title="添加Github第三方登录"></a>添加Github第三方登录</h3><p>打开<a href="https://github.com/settings/applications/" target="_blank" rel="noopener">Github application</a>，进入Developer applications，新建应用程序</p><p>Homepage url为你的discourse地址，authorization callback url为你的discourse地址加上/auth/github/callback，然后复制Client ID和Client Secret，<br>最后打开discourse，进入管理－设置－登录，找到下图所示三个字段，勾选填入刚才复制的内容</p><p>然后确定、完成。</p><p>点击=&gt;完成！</p><h3 id="常见问题"><a href="#常见问题" class="headerlink" title="常见问题"></a>常见问题</h3><p>计算技术论坛关于discourse的问题：<a href="https://www.ossez.com/search?q=discourse" target="_blank" rel="noopener">https://www.ossez.com/search?q=discourse</a></p><h2 id="其它"><a href="#其它" class="headerlink" title="其它"></a>其它</h2><p>体验了一下Discourse的管理界面和可配置的操作，后台支持定制化的配置和插件化，而且确实很简洁，并能够提供对外API，有时间可以继续探究</p><p>我的discourse地址：<a href="https://lt.disscode.cn/" target="_blank" rel="noopener">https://lt.disscode.cn/</a></p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;回想以往逛论坛、贴吧的年代，似乎渐行渐远，现在人类追求的多样性超出想象，但论坛并未走下神坛，只是换了一种或者是以多种方式存在。社区、小组、圈子等都有更多的载体和工具，今天就说一下开源论坛discourse。&lt;/p&gt;
&lt;p&gt;Discourse应该也已经20多年了，并不新鲜，也是因为平常经常浏览的技术社区用的就是discourse，所以就搭建一下，深入感受一下discourse，以备后用。&lt;/p&gt;
    
    </summary>
    
      <category term="discourse" scheme="https://dumplingbao.github.io/categories/discourse/"/>
    
    
      <category term="discourse" scheme="https://dumplingbao.github.io/tags/discourse/"/>
    
  </entry>
  
  <entry>
    <title>牛年开篇：网站拜年</title>
    <link href="https://dumplingbao.github.io/2021/02/24/web-niu/"/>
    <id>https://dumplingbao.github.io/2021/02/24/web-niu/</id>
    <published>2021-02-24T15:48:57.000Z</published>
    <updated>2021-11-26T18:18:19.597Z</updated>
    
    <content type="html"><![CDATA[<h1 id="牛年开篇：网站拜年"><a href="#牛年开篇：网站拜年" class="headerlink" title="牛年开篇：网站拜年"></a>牛年开篇：网站拜年</h1><p>开启新年第一篇，本应该在春节假期完成，趁着马上元宵节，就以此开篇。</p><p>重新调整了一下个人网站，来个新年新气象，也希望牛年牛转乾坤，更上一层楼。</p><p>力求简单，做几点要求：</p><ul><li>个人网站，我们还是区分一下企业和产品网站</li><li>前端展示，先不牵扯后端，当然也是为了快速部署</li><li>新年元素、牛元素</li><li>兼容手机端<a id="more"></a></li></ul><p>达成几个目的：</p><ul><li>迎接新的一年</li><li>宣传，似乎这个是必不可少，即使没有什么可宣传的内容</li><li>github网络的限制，导致博客受限，同时选择了简书，后期考虑通过网站，进而做调整</li><li>服务器的充分利用</li></ul><p>网站地址：<a href="https://disscode.cn" target="_blank" rel="noopener">https://disscode.cn</a></p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/web/w01.png" alt="web01"></p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/web/w02.png" alt="web02"></p><h2 id="建站方式"><a href="#建站方式" class="headerlink" title="建站方式"></a>建站方式</h2><ul><li><p>服务器：云服务器，扩展性、灵活性高（推荐）</p></li><li><p>虚拟主机：这个的经济优势很明显</p></li><li><p>第三方：快捷建站网站</p></li></ul><h2 id="域名"><a href="#域名" class="headerlink" title="域名"></a>域名</h2><p>无论何种方式，有个自己的域名这个是最好的、也算是必须的，申请渠道很多，申请一个即可（备注：需要备案）</p><h2 id="ssl证书"><a href="#ssl证书" class="headerlink" title="ssl证书"></a>ssl证书</h2><p>ssl证书其实是挺贵的，但是可以用免费的，ssl证书其实对于网站来说也是必不可少的，没有证书的网站就感觉别扭</p><p>推荐免费证书：</p><ul><li><a href="https://letsencrypt.org/" target="_blank" rel="noopener">Let’s Encrypt</a> </li><li><a href="https://www.ohttps.com/" target="_blank" rel="noopener">ohttps</a></li><li>阿里云、腾讯云等</li></ul><h2 id="网站代码"><a href="#网站代码" class="headerlink" title="网站代码"></a>网站代码</h2><p>技术栈：nodejs + react</p><p>找了一些网站，最好选了个开源的网站代码，推荐一下，记得点赞</p><p>github地址：<a href="https://github.com/ArthurYung/react-my-website" target="_blank" rel="noopener">https://github.com/ArthurYung/react-my-website</a></p><h2 id="发布"><a href="#发布" class="headerlink" title="发布"></a>发布</h2><p>如果是服务器，采用Nginx来部署就很简单了</p>]]></content>
    
    <summary type="html">
    
      &lt;h1 id=&quot;牛年开篇：网站拜年&quot;&gt;&lt;a href=&quot;#牛年开篇：网站拜年&quot; class=&quot;headerlink&quot; title=&quot;牛年开篇：网站拜年&quot;&gt;&lt;/a&gt;牛年开篇：网站拜年&lt;/h1&gt;&lt;p&gt;开启新年第一篇，本应该在春节假期完成，趁着马上元宵节，就以此开篇。&lt;/p&gt;
&lt;p&gt;重新调整了一下个人网站，来个新年新气象，也希望牛年牛转乾坤，更上一层楼。&lt;/p&gt;
&lt;p&gt;力求简单，做几点要求：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;个人网站，我们还是区分一下企业和产品网站&lt;/li&gt;
&lt;li&gt;前端展示，先不牵扯后端，当然也是为了快速部署&lt;/li&gt;
&lt;li&gt;新年元素、牛元素&lt;/li&gt;
&lt;li&gt;兼容手机端
    
    </summary>
    
      <category term="网站" scheme="https://dumplingbao.github.io/categories/%E7%BD%91%E7%AB%99/"/>
    
    
      <category term="网站" scheme="https://dumplingbao.github.io/tags/%E7%BD%91%E7%AB%99/"/>
    
  </entry>
  
  <entry>
    <title>github自定义主页秀</title>
    <link href="https://dumplingbao.github.io/2020/09/03/github-custom-home/"/>
    <id>https://dumplingbao.github.io/2020/09/03/github-custom-home/</id>
    <published>2020-09-03T15:28:35.000Z</published>
    <updated>2021-11-26T18:18:19.596Z</updated>
    
    <content type="html"><![CDATA[<p><i><b>github自定义主页秀</b></i></p><hr><p>​    <code>github</code>支持自定义主页已经有一段时间了，今天尝试了一下。详细教程可以从网上搜索一下，比较简单，也可以直接到我的<code>github</code>（下面有链接）复制一下，记得点赞奥。</p><a id="more"></a><h3 id="😎-秀一秀"><a href="#😎-秀一秀" class="headerlink" title="😎 秀一秀"></a>😎 秀一秀</h3><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/github/github01.jpg" alt="github01"></p><h3 id="🔨-创建"><a href="#🔨-创建" class="headerlink" title="🔨 创建"></a>🔨 创建</h3><p>​    很简单，创建与github账号同名公开的仓库，并初始化<code>README.md</code>，完成</p><h3 id="🔧-美景"><a href="#🔧-美景" class="headerlink" title="🔧 美景"></a>🔧 美景</h3><p>​    每日刷新或者随机（自己去选对应的类型的api）</p><p>​    <a href="https://api.lyiqk.cn/" target="_blank" rel="noopener">https://api.lyiqk.cn/</a></p><p>​    备注：<code>github</code>由于缓存了图片，不会每次都刷新</p><p>​    建议用必应每日一图：<a href="https://api.lyiqk.cn/bing" target="_blank" rel="noopener">https://api.lyiqk.cn/bing</a></p><h3 id="🔑-我的自定义主页"><a href="#🔑-我的自定义主页" class="headerlink" title="🔑 我的自定义主页"></a>🔑 我的自定义主页</h3><p>​    连接地址：<a href="https://github.com/dumplingbao/dumplingbao" target="_blank" rel="noopener">https://github.com/dumplingbao/dumplingbao</a></p><p>​    备注：由于是<code>markdown</code>格式，预览效果与实际展示有所不同</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;i&gt;&lt;b&gt;github自定义主页秀&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;hr&gt;

&lt;p&gt;​    &lt;code&gt;github&lt;/code&gt;支持自定义主页已经有一段时间了，今天尝试了一下。详细教程可以从网上搜索一下，比较简单，也可以直接到我的&lt;code&gt;github&lt;/code&gt;（下面有链接）复制一下，记得点赞奥。&lt;/p&gt;
    
    </summary>
    
      <category term="github" scheme="https://dumplingbao.github.io/categories/github/"/>
    
    
      <category term="github" scheme="https://dumplingbao.github.io/tags/github/"/>
    
  </entry>
  
  <entry>
    <title>Davinci-二次开发系列08：mongoDB（JDBC查询）四种解决方案</title>
    <link href="https://dumplingbao.github.io/2020/08/24/davinci-dev-mongo/"/>
    <id>https://dumplingbao.github.io/2020/08/24/davinci-dev-mongo/</id>
    <published>2020-08-24T04:00:00.000Z</published>
    <updated>2021-11-26T18:18:19.596Z</updated>
    
    <content type="html"><![CDATA[<p>​    关于Davinci使用mongoDB的问题，就一直没有断过。我们不管怎么评价mongoDB，似乎年轻的mongoDB俨然是主流数据库了。而且现在对于BI来说能不能支持主流的NoSQL数据库，已经成为一个很重要的衡量标准。目前BI通过JDBC的方式访问NoSQL数据库还是首选，但是mongo官方未提供JDBC驱动包，这里介绍四种mongo-JDBC查询数据的解决方案：（备注：mongo-JDBC问题不仅限于Davinci，也不限于BI，一些实际应用中也会碰到）</p><table><thead><tr><th>序号</th><th>方案</th><th>备注</th><th>综述</th></tr></thead><tbody><tr><td>1</td><td>利用presto连接</td><td>facebook开源SQL查询引擎</td><td>优点：开源、免费、兼容性良好<br>缺点：需要单独部署服务</td></tr><tr><td>2</td><td>1、unityjdbc破解版<br>2、unityjdbc试用版</td><td>商业化产品</td><td>优点：集成简单、不需要单独部署<br>缺点：收费、_id字段值不显示<br>试用版本地mongo支持需要解决<br>破解版只能简单的查询、子查询等有问题，存在问题比较多</td></tr><tr><td>3</td><td>mongo-bi连接器</td><td>mongo官方</td><td>优点：官方出品、免费、兼容性极好<br>缺点：需要单独部署服务<br>推荐用此方式</td></tr><tr><td>4</td><td>开源手写驱动包</td><td>开源</td><td>优点：灵活性可控<br>缺点：成本高、耗精力</td></tr></tbody></table><a id="more"></a><h1 id="利用presto连接"><a href="#利用presto连接" class="headerlink" title="利用presto连接"></a>利用presto连接</h1><p>​    Presto是一个facebook开源的分布式SQL查询引擎，而且支持跨库查询，当然也支持mongoDB，Davinci通过presto做类似的桥接，然后也能实现mongoDB的jdbc查询，如果公司使用presto，采用这种方案也是不错的选择，兼容性可以。</p><p>​    这里我们重点介绍后面两种，没有实际进行尝试，大家可以尝试一下，简单介绍一下步骤：</p><p>​    第一：首先需要安装presto-server服务，看好版本，支持MongoDB的才可以</p><p>​    第二：配置mongodb.properties</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">connector.name=mongodb</span><br><span class="line">mongodb.seeds=ip:port</span><br><span class="line">mongodb.schema-collection=admin</span><br></pre></td></tr></table></figure><p>​    第三：Davinci配置数据源    </p><p>​    <code>jdbc:presto://ip:port/mongodb/test</code></p><p>​    第四：view实现JDBC查询</p><p>​    <code>select * from mongodb.数据库名.集合</code></p><h1 id="unityjdbc"><a href="#unityjdbc" class="headerlink" title="unityjdbc"></a>unityjdbc</h1><p>​    由于<a href="http://www.unityjdbc.com/" target="_blank" rel="noopener">unityjdbc</a>是收费的，这里我们用网上的破解版和试用版都试一下。</p><h2 id="官方试用版"><a href="#官方试用版" class="headerlink" title="官方试用版"></a>官方试用版</h2><p>​    第一：试用版，去官网<a href="http://www.unityjdbc.com/" target="_blank" rel="noopener">unityjdbc</a>下载<code>JDBC Driver for MongoDB</code>，这里我们用的是``这个版本下载地址：<a href="http://www.unityjdbc.com/download.php?type=mongodb" target="_blank" rel="noopener">http://www.unityjdbc.com/download.php?type=mongodb</a></p><p>​    第二：下载下来的<code>UnityJDBC_Trial_Install.jar</code> 需要<code>java -jar</code>安装，安装完获取<code>unityJdbc.jar</code>（或者<code>mongodb_unityjdbc_full.jar这个jar</code>包也可以）</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/08/mongo_uj00.jpg" alt="mongo_uj00"></p><p>​    第三：<code>mongodb-driver</code>的依赖默认是注释掉的，将注释去掉，并将<code>unityJdbc.jar</code>引入到工程里面或者复制进去，在porm里面引入本地依赖</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">&lt;!--mongodb --&gt;</span><br><span class="line">&lt;dependency&gt;</span><br><span class="line">&lt;groupId&gt;org.mongodb&lt;/groupId&gt;</span><br><span class="line">&lt;artifactId&gt;mongodb-driver&lt;/artifactId&gt;</span><br><span class="line">&lt;version&gt;3.6.3&lt;/version&gt;</span><br><span class="line">&lt;/dependency&gt;</span><br><span class="line">&lt;dependency&gt;</span><br><span class="line">&lt;groupId&gt;unityjdbc&lt;/groupId&gt;</span><br><span class="line">&lt;artifactId&gt;unityjdbc&lt;/artifactId&gt;</span><br><span class="line">&lt;scope&gt;system&lt;/scope&gt;</span><br><span class="line">&lt;systemPath&gt;$&#123;project.basedir&#125;/lib/unityjdbc.jar&lt;/systemPath&gt;</span><br><span class="line">&lt;/dependency&gt;</span><br></pre></td></tr></table></figure><p>​    第四：Davinci配置数据源（强调一下，我用官方的包，连接本地mongo报hostname的错误，就先用官方的测试库）</p><p><code>jdbc:mongo://localhost:27017/数据库</code> </p><p>官方测试地址 <code>jdbc:mongo://ds029847.mongolab.com:29847/tpch</code></p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/08/mongo_uj01.jpg" alt="mongo-uj01"></p><h3 id="创建view-id不能正常显示）"><a href="#创建view-id不能正常显示）" class="headerlink" title="创建view(_id不能正常显示）"></a>创建view(_id不能正常显示）</h3><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/08/mongo-uj07.jpg" alt="mongo_uj07"></p><h3 id="创建widget"><a href="#创建widget" class="headerlink" title="创建widget"></a>创建widget</h3><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/08/mongo-uj08.jpg" alt="mongo_uj08"></p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/08/mongo-uj09.jpg" alt="mongo_uj09"></p><h3 id="子查询"><a href="#子查询" class="headerlink" title="子查询"></a>子查询</h3><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/08/mongo-uj10.jpg" alt="mongo_uj10"></p><h3 id="关联查询"><a href="#关联查询" class="headerlink" title="关联查询"></a>关联查询</h3><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/08/mongo-uj11.jpg" alt="mongo_uj11"></p><h2 id="网传破解版"><a href="#网传破解版" class="headerlink" title="网传破解版"></a>网传破解版</h2><p>试了一下分享出来的破解版，除去上面的安装步骤，直接引入即可</p><p>创建数据源，这个包比试用版好的是本地mongo能直接使用</p><p><code>jdbc:mongo://localhost:27017/数据库</code></p><h3 id="创建view（-id不显示、集合列表不显示）"><a href="#创建view（-id不显示、集合列表不显示）" class="headerlink" title="创建view（_id不显示、集合列表不显示）"></a>创建view（_id不显示、集合列表不显示）</h3><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/08/mongo_uj02.jpg" alt="mongo_uj02"></p><h3 id="创建widget-1"><a href="#创建widget-1" class="headerlink" title="创建widget"></a>创建widget</h3><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/08/mongo_uj03.jpg" alt="mongo_uj03"></p><p>从错误上来就不能很好的兼容，子查询关联查询更是不能正常使用</p><h1 id="mongo-bi连接器"><a href="#mongo-bi连接器" class="headerlink" title="mongo-bi连接器"></a>mongo-bi连接器</h1><p>​    mongo官方没有提供mongo的JDBC驱动，但是提供了mongo-bi-connector，允许使用所选的BI工具通过标准SQL查询对MongoDB数据进行可视化。</p><p>​    搜了一下资料，BI Connector 可以使用 SQL 或 ODBC 数据源方式直接访问 MongoDB，MongoDB 早期版本直接使用 Postgresql FDW 来实现 SQL 到 MQL 的转换，后来实现更加轻量级的 mongosqld 来支持 BI 工具的连接。这里我们就尝试一下mongosqld，来验证一下。</p><h3 id="下载并安装mongo-bi-connector"><a href="#下载并安装mongo-bi-connector" class="headerlink" title="下载并安装mongo-bi-connector"></a>下载并安装mongo-bi-connector</h3><p>​    官方下载：<a href="https://www.mongodb.com/try/download/bi-connector，支持windows、linux版本" target="_blank" rel="noopener">https://www.mongodb.com/try/download/bi-connector，支持windows、linux版本</a></p><p>​    默认安装即可</p><h3 id="配置文件"><a href="#配置文件" class="headerlink" title="配置文件"></a>配置文件</h3><p>​    默认配置即可，如果有mongo做了限制，或者调整端口，修改<code>mongosqld-config.yml</code>，详细配置看官网</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">net:</span><br><span class="line">  bindIp: &quot;127.0.0.1&quot; # To bind to multiple IP addresses</span><br><span class="line">  port: 3307</span><br><span class="line">  mongodb:</span><br><span class="line">  net:</span><br><span class="line">    uri: &quot;mongodb://127.0.0.1:27017&quot;</span><br><span class="line">    ssl:</span><br><span class="line">      enabled: false</span><br><span class="line">    auth:</span><br><span class="line">      username: xxx</span><br><span class="line">      password: xxx</span><br><span class="line">      source: xxx</span><br><span class="line">      mechanism: SCRAM-SHA-1</span><br></pre></td></tr></table></figure><h3 id="启动mongosqld"><a href="#启动mongosqld" class="headerlink" title="启动mongosqld"></a>启动mongosqld</h3><p>​    我使用的windows版本双击<code>mongosqld.exe</code>运行即可</p><h3 id="maven引入依赖包"><a href="#maven引入依赖包" class="headerlink" title="maven引入依赖包"></a>maven引入依赖包</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">&lt;!-- 这个包必须有 --&gt;</span><br><span class="line">&lt;dependency&gt;</span><br><span class="line">&lt;groupId&gt;mysql&lt;/groupId&gt;</span><br><span class="line">&lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;</span><br><span class="line">&lt;version&gt;5.1.44&lt;/version&gt;</span><br><span class="line">&lt;/dependency&gt;</span><br><span class="line">&lt;!-- 非必须，这个是JDBC认证插件，如果你做测试或者你的mongo本身在裸奔，就没必要了 --&gt;</span><br><span class="line">&lt;dependency&gt;</span><br><span class="line">   &lt;groupId&gt;mysql&lt;/groupId&gt;</span><br><span class="line">   &lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;</span><br><span class="line">   &lt;version&gt;5.1.42&lt;/version&gt;</span><br><span class="line">&lt;/dependency&gt;</span><br></pre></td></tr></table></figure><h3 id="创建数据源"><a href="#创建数据源" class="headerlink" title="创建数据源"></a>创建数据源</h3><p>备注：这里使用mysql即可</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/08/mongo-bi01.jpg" alt="mongo-bi01"></p><h3 id="创建view（-id和集合列表均正常）"><a href="#创建view（-id和集合列表均正常）" class="headerlink" title="创建view（_id和集合列表均正常）"></a>创建view（_id和集合列表均正常）</h3><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/08/mongo-bi02.jpg" alt="mongo-bi02"></p><h3 id="创建widget-2"><a href="#创建widget-2" class="headerlink" title="创建widget"></a>创建widget</h3><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/08/mongo-bi03.jpg" alt="mongo-bi03"></p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/08/mongo-bi04.jpg" alt="mongo-bi04"></p><h3 id="子查询-1"><a href="#子查询-1" class="headerlink" title="子查询"></a>子查询</h3><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/08/mongo-bi05.jpg" alt="mongo-bi05"></p><h3 id="关联查询-1"><a href="#关联查询-1" class="headerlink" title="关联查询"></a>关联查询</h3><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/08/mongo-bi06.jpg" alt="mongo-bi06"></p><h1 id="开源手写驱动包"><a href="#开源手写驱动包" class="headerlink" title="开源手写驱动包"></a>开源手写驱动包</h1><p>​    这个绝对是一个解决方案，其实工作中就会封装mongo的一些比如关联查询类似的组件，写这个驱动包也未必没有优势，我觉着如果上面的方案兼容sql的场景如果存在问题，那么自己写的驱动包改造就容易的多，第三方的包就没那么好改了。</p><p>​    这里推荐一个mongo的JDBC开源驱动包，如果有自己想写的想法仅供参考。</p><p>​    连接：<a href="https://gitee.com/f4haofeng/mongodb-jdbc/tree/master/src/main/java/com/mongodb" target="_blank" rel="noopener">https://gitee.com/f4haofeng/mongodb-jdbc/tree/master/src/main/java/com/mongodb</a></p><h1 id="综上所述"><a href="#综上所述" class="headerlink" title="综上所述"></a>综上所述</h1><p>​    其实，表格里面已经比较了，根据个人需求选择即可，还是推荐使用mongo官方的BI连接器的方式，虽然我们没有对性能进行比较，但从使用性、兼容性、子查询、关联查询等方面比较，BI连接器的方式完全能够胜任。</p><h1 id="交流学习"><a href="#交流学习" class="headerlink" title="交流学习"></a>交流学习</h1><p>学习Metabase、Davinci等开源BI，群号：72569367，感兴趣的可以加一下。</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;​    关于Davinci使用mongoDB的问题，就一直没有断过。我们不管怎么评价mongoDB，似乎年轻的mongoDB俨然是主流数据库了。而且现在对于BI来说能不能支持主流的NoSQL数据库，已经成为一个很重要的衡量标准。目前BI通过JDBC的方式访问NoSQL数据库还是首选，但是mongo官方未提供JDBC驱动包，这里介绍四种mongo-JDBC查询数据的解决方案：（备注：mongo-JDBC问题不仅限于Davinci，也不限于BI，一些实际应用中也会碰到）&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;序号&lt;/th&gt;
&lt;th&gt;方案&lt;/th&gt;
&lt;th&gt;备注&lt;/th&gt;
&lt;th&gt;综述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;利用presto连接&lt;/td&gt;
&lt;td&gt;facebook开源SQL查询引擎&lt;/td&gt;
&lt;td&gt;优点：开源、免费、兼容性良好&lt;br&gt;缺点：需要单独部署服务&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;1、unityjdbc破解版&lt;br&gt;2、unityjdbc试用版&lt;/td&gt;
&lt;td&gt;商业化产品&lt;/td&gt;
&lt;td&gt;优点：集成简单、不需要单独部署&lt;br&gt;缺点：收费、_id字段值不显示&lt;br&gt;试用版本地mongo支持需要解决&lt;br&gt;破解版只能简单的查询、子查询等有问题，存在问题比较多&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;mongo-bi连接器&lt;/td&gt;
&lt;td&gt;mongo官方&lt;/td&gt;
&lt;td&gt;优点：官方出品、免费、兼容性极好&lt;br&gt;缺点：需要单独部署服务&lt;br&gt;推荐用此方式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;开源手写驱动包&lt;/td&gt;
&lt;td&gt;开源&lt;/td&gt;
&lt;td&gt;优点：灵活性可控&lt;br&gt;缺点：成本高、耗精力&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
    
    </summary>
    
      <category term="可视化工具" scheme="https://dumplingbao.github.io/categories/%E5%8F%AF%E8%A7%86%E5%8C%96%E5%B7%A5%E5%85%B7/"/>
    
      <category term="Davinci" scheme="https://dumplingbao.github.io/categories/Davinci/"/>
    
    
      <category term="BI" scheme="https://dumplingbao.github.io/tags/BI/"/>
    
      <category term="Davinci" scheme="https://dumplingbao.github.io/tags/Davinci/"/>
    
  </entry>
  
  <entry>
    <title>Davinci-二次开发系列07：BI新元素尝试</title>
    <link href="https://dumplingbao.github.io/2020/08/20/davinci-dev-newel/"/>
    <id>https://dumplingbao.github.io/2020/08/20/davinci-dev-newel/</id>
    <published>2020-08-20T04:00:00.000Z</published>
    <updated>2021-11-26T18:18:19.596Z</updated>
    
    <content type="html"><![CDATA[<p>​    忙于工作，停更很长时间了，最近继续开搞，先写此一篇。生活犹如演绎，写作算是解说，先看效果：</p><p>​    <img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/07/seas_xgt01.gif" alt="seas-xgt01"></p><a id="more"></a><h1 id="由来"><a href="#由来" class="headerlink" title="由来"></a>由来</h1><p>​    想在BI里面引入一些别具一格的新元素，这个想法由来已久，本来是想做下面的这种效果：</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/chart/chart.gif" alt="xkcd"></p><p>​    这个是<a href="https://github.com/timqian/chart.xkcd" target="_blank" rel="noopener">chart.xkcd</a> 手绘风格图表库，我之前写过一篇介绍，详细介绍可以查看<a href="https://dumplingbao.github.io/2019/08/20/char-xkcd/">手绘风格的图表库（char.xkcd）</a>，可是由于davinci采用的是echarts，通过尝试未找到合适的很好的解决方案，只能暂时搁置了。</p><p>​    所以先做了这个鱼馆的场景，缘起于之前做过的项目，类似于一个积分系统，从积分到最终呈现单独做的。试想一下，如果有这样的BI工具，支持这样的场景，也就能根据数据快速生成，所以这样想，需求、场景都是有的，就尝试在BI里面集成这种鱼馆的效果，也算给BI的一种新的元素。</p><h1 id="技术选型"><a href="#技术选型" class="headerlink" title="技术选型"></a>技术选型</h1><p>​    技术点在动画选型上，后端不需要操作，这里我们推荐几种技术实现</p><ul><li><p>jQuery：之前就是用jQuery实现的，完全没有问题，就是代码量看上去比较繁琐</p></li><li><p>lufylengend：这是个h5的引擎，简单、功能强大，有兴趣可以了解一下，用于实现这个功能偏重，但是后续考虑增加一些特性会比较方便，功能没得说。</p></li><li><p>animate相关的npm包：</p><p>​    1、<a href="https://www.npmjs.com/package/animate" target="_blank" rel="noopener">animate-npm</a>：这个包有点像被抢注了，功能实在简单，简单到看上去就不是你想要的</p><p>​    2、<a href="https://github.com/bendc" target="_blank" rel="noopener">bendc</a>/<strong><a href="https://github.com/bendc/animate" target="_blank" rel="noopener">animate</a></strong>：这个是个封装的js文件，是6年前开发的了，完全够用，操作方便</p><p>​    3、<a href="https://github.com/bendc" target="_blank" rel="noopener">bendc</a>/<strong><a href="https://github.com/bendc/animateplus" target="_blank" rel="noopener">animateplus</a></strong>：这个包和上一个是一个作者，一看就是升级版，也已经开发有3年了，支持npm直接安装</p></li></ul><p>​    这里我们用的<a href="https://github.com/bendc" target="_blank" rel="noopener">bendc</a>/<strong><a href="https://github.com/bendc/animateplus" target="_blank" rel="noopener">animateplus</a></strong>，也可以尝试其它的，我们用到的动画只是简单的，不需要复杂的功能，更不需要复杂的算法。这里特别强调一下，这个本身就是开源的封装，没有完整的api，知识盲点会导致需要不断的尝试才行。</p><h1 id="功能点介绍"><a href="#功能点介绍" class="headerlink" title="功能点介绍"></a>功能点介绍</h1><table><thead><tr><th>序号</th><th>功能</th><th>备注</th></tr></thead><tbody><tr><td>1</td><td>数据模型</td><td>一个维度，一个指标，示例：用户和积分</td></tr><tr><td>2</td><td>主题</td><td>鱼馆背景可切换，海洋元素一些引入</td></tr><tr><td>3</td><td>速度</td><td>速度可设定</td></tr><tr><td>4</td><td>积分等级</td><td>目前固定，通过积分判断区间和对应的等级及动物</td></tr><tr><td>5</td><td>信息展示</td><td>默认展示维度信息，如用户及积分信息</td></tr></tbody></table><h1 id="背景切换"><a href="#背景切换" class="headerlink" title="背景切换"></a>背景切换</h1><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/07/seas-bj.gif" alt="seas-bj"></p><h1 id="速度切换"><a href="#速度切换" class="headerlink" title="速度切换"></a>速度切换</h1><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/07/seas-speed.gif" alt="seas-speed"></p><h1 id="显示指标"><a href="#显示指标" class="headerlink" title="显示指标"></a>显示指标</h1><p>单击显示指标信息，再次单击隐藏指标信息，我们也不提倡排名看分就隐藏</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/07/seas-xszb.gif" alt="seas-xszb"></p><h1 id="示例数据结构"><a href="#示例数据结构" class="headerlink" title="示例数据结构"></a>示例数据结构</h1><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/07/seas-data.jpg" alt="seas-data"></p><h1 id="积分等级处理"><a href="#积分等级处理" class="headerlink" title="积分等级处理"></a>积分等级处理</h1><p>​    这里效果图是随机取的动物，正常配置通过积分判断所处的等级和对应的动物，目前是静态的配置文件，后续也应该是可配置化。</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/07/seas-level.jpg" alt="seas-level"></p><h1 id="交流学习"><a href="#交流学习" class="headerlink" title="交流学习"></a>交流学习</h1><p>学习Metabase、Davinci等开源BI，群号：72569367，感兴趣的可以加一下。</p><p>备注：技术选型尝试多次，每个都有各自的优缺点，就会有所取舍，亦或者不能完全深入了解，这次BI里面加入这种非常规的东西也算是一种尝试，欢迎进群交流，留言和点赞。gif图片太大，进行了压缩，影响效果，由于素材牵扯版权的问题，暂时也不能提交代码，希望能制作素材的朋友联系。</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;​    忙于工作，停更很长时间了，最近继续开搞，先写此一篇。生活犹如演绎，写作算是解说，先看效果：&lt;/p&gt;
&lt;p&gt;​    &lt;img src=&quot;https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/07/seas_xgt01.gif&quot; alt=&quot;seas-xgt01&quot;&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="可视化工具" scheme="https://dumplingbao.github.io/categories/%E5%8F%AF%E8%A7%86%E5%8C%96%E5%B7%A5%E5%85%B7/"/>
    
      <category term="Davinci" scheme="https://dumplingbao.github.io/categories/Davinci/"/>
    
    
      <category term="BI" scheme="https://dumplingbao.github.io/tags/BI/"/>
    
      <category term="Davinci" scheme="https://dumplingbao.github.io/tags/Davinci/"/>
    
  </entry>
  
  <entry>
    <title>Davinci-二次开发系列06：导出excel合并单元格</title>
    <link href="https://dumplingbao.github.io/2020/05/14/davinci-dev-xsl/"/>
    <id>https://dumplingbao.github.io/2020/05/14/davinci-dev-xsl/</id>
    <published>2020-05-14T04:00:00.000Z</published>
    <updated>2021-11-26T18:18:19.596Z</updated>
    
    <content type="html"><![CDATA[<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>​    系统数据导出excel已经很具普遍性，不单单是BI有这需求，表单性质的数据大都希望直接导出excel，这个需求甚至比邮件接收更加突出。</p><p>​    Davinci导出excel有两种方式，都在dashboard页面</p><ol><li>单个widget导出</li><li>整个dashboard导出，多个sheet页，一个sheet页对应一个widget数据<a id="more"></a><h1 id="表格数据"><a href="#表格数据" class="headerlink" title="表格数据"></a>表格数据</h1></li></ol><p>​    Davinci透视驱动和图表驱动下都有表格的功能，表格中维度指标是自动合并的，效果如下：</p><h2 id="图表驱动"><a href="#图表驱动" class="headerlink" title="图表驱动"></a>图表驱动</h2><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/06/table-chart.jpg" alt="table-chart"></p><h2 id="透视驱动"><a href="#透视驱动" class="headerlink" title="透视驱动"></a>透视驱动</h2><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/06/table-pivot.jpg" alt="table-pivot"></p><h1 id="表格导出excel"><a href="#表格导出excel" class="headerlink" title="表格导出excel"></a>表格导出excel</h1><p>​    这里先不考虑图形效果的数据导出，表格数据更希望导出excel是相同的样式，也就是自动合并单元格，现有的表格数据导出效果如下：</p><h2 id="图表驱动-1"><a href="#图表驱动-1" class="headerlink" title="图表驱动"></a>图表驱动</h2><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/06/table-chart-old.jpg" alt="table-chart-old"></p><h2 id="透视驱动-1"><a href="#透视驱动-1" class="headerlink" title="透视驱动"></a>透视驱动</h2><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/06/talble-pivot-old.jpg" alt="table-pivot-old"></p><h1 id="图表驱动表格excel自动合并单元格"><a href="#图表驱动表格excel自动合并单元格" class="headerlink" title="图表驱动表格excel自动合并单元格"></a>图表驱动表格excel自动合并单元格</h1><h2 id="合并后效果图"><a href="#合并后效果图" class="headerlink" title="合并后效果图"></a>合并后效果图</h2><h3 id="图表驱动-2"><a href="#图表驱动-2" class="headerlink" title="图表驱动"></a>图表驱动</h3><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/06/table-chart-now.jpg" alt="table-chart-now"></p><h3 id="透视驱动-2"><a href="#透视驱动-2" class="headerlink" title="透视驱动"></a>透视驱动</h3><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/06/table-pivot-now.jpg" alt="table-pivot-now"></p><h2 id="了解现有逻辑"><a href="#了解现有逻辑" class="headerlink" title="了解现有逻辑"></a>了解现有逻辑</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&lt;dependency&gt;</span><br><span class="line">&lt;groupId&gt;org.apache.poi&lt;/groupId&gt;</span><br><span class="line">&lt;artifactId&gt;poi&lt;/artifactId&gt;</span><br><span class="line">&lt;version&gt;3.9&lt;/version&gt;</span><br><span class="line">&lt;/dependency&gt;</span><br></pre></td></tr></table></figure><p>通过代码和依赖可以看出采用的poi处理导出excel</p><h2 id="改造计划"><a href="#改造计划" class="headerlink" title="改造计划"></a>改造计划</h2><p>​    如果通过现有的方式加入合并单元格的逻辑改造有点麻烦，这里我们直接找较完善的poi合并单元格的方法来直接引用并调用，如果有更好的方式可以一起讨论交流，欢迎留言。</p><p>​    参考poi合并单元格：<a href="https://www.cnblogs.com/mr-wuxiansheng/p/7930378.html" target="_blank" rel="noopener">https://www.cnblogs.com/mr-wuxiansheng/p/7930378.html</a></p><h2 id="代码改造"><a href="#代码改造" class="headerlink" title="代码改造"></a>代码改造</h2><p>​    参考上面链接这里直接提供改造后端的代码</p><h3 id="一"><a href="#一" class="headerlink" title="一"></a>一</h3><p>新增PoiInfo实体类，严格意义上这应该是DO这样我们放的DTO下面</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">package edp.davinci.dto.poiDto;</span><br><span class="line">import lombok.Data;</span><br><span class="line">import java.io.Serializable;</span><br><span class="line">/**</span><br><span class="line"> * POI Excel报表导出，列合并实体&lt;br&gt;</span><br><span class="line"> */</span><br><span class="line">@Data</span><br><span class="line">public class PoiInfo implements Serializable&#123;</span><br><span class="line">    private static final long serialVersionUID = 1L;</span><br><span class="line">    private String content;</span><br><span class="line">    private String oldContent;</span><br><span class="line">    private int rowIndex;</span><br><span class="line">    private int cellIndex;</span><br><span class="line">    public PoiInfo() &#123;</span><br><span class="line">    &#125;</span><br><span class="line">    public PoiInfo(String content, String oldContent, int rowIndex,</span><br><span class="line">                   int cellIndex) &#123;</span><br><span class="line">        this.content = content;</span><br><span class="line">        this.oldContent = oldContent;</span><br><span class="line">        this.rowIndex = rowIndex;</span><br><span class="line">        this.cellIndex = cellIndex;</span><br><span class="line">    &#125;</span><br><span class="line">    @Override</span><br><span class="line">    public String toString() &#123;</span><br><span class="line">        return &quot;PoiInfo [content=&quot; + content + &quot;, oldContent=&quot; + oldContent</span><br><span class="line">                + &quot;, rowIndex=&quot; + rowIndex + &quot;, cellIndex=&quot; + cellIndex + &quot;]&quot;;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="二"><a href="#二" class="headerlink" title="二"></a>二</h3><p>废弃writeLine方法，新增createSheet方法</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">\server\src\main\java\edp\davinci\service\excel\AbstractSheetWriter.java</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line">    * @param queryColumns 标题集合 queryColumns的长度应该与list中的model的属性个数一致</span><br><span class="line">    * @param maps 内容集合</span><br><span class="line">    * @param mergeIndex 合并单元格的列</span><br><span class="line">    */</span><br><span class="line">   public Boolean createSheet(Sheet sheet,List&lt;QueryColumn&gt; queryColumns, Map&lt;String, List&lt;Map&lt;String, Object&gt;&gt;&gt; maps, int[] mergeIndex)&#123;</span><br><span class="line">       if (queryColumns.size()==0)&#123;</span><br><span class="line">           return false;</span><br><span class="line">       &#125;</span><br><span class="line">       int n = 0;</span><br><span class="line">       for(Map.Entry&lt;String, List&lt;Map&lt;String, Object&gt;&gt;&gt; entry : maps.entrySet())&#123;</span><br><span class="line">           /*初始化head，填值标题行（第一行）*/</span><br><span class="line">           Row row0 = sheet.createRow(0);</span><br><span class="line">           for(int i = 0; i&lt;queryColumns.size(); i++)&#123;</span><br><span class="line">               /*创建单元格，指定类型*/</span><br><span class="line">               Cell cell_1 = row0.createCell(i, Cell.CELL_TYPE_STRING);</span><br><span class="line">               cell_1.setCellValue(queryColumns.get(i).getName());</span><br><span class="line">           &#125;</span><br><span class="line">           /*得到当前sheet下的数据集合*/</span><br><span class="line">           List&lt;Map&lt;String, Object&gt;&gt; list = entry.getValue();</span><br><span class="line">           /*遍历该数据集合*/</span><br><span class="line">           List&lt;PoiInfo&gt; poiInfos = new ArrayList();</span><br><span class="line">           if(true)&#123;</span><br><span class="line">               Iterator iterator = list.iterator();</span><br><span class="line">               int index = 1;</span><br><span class="line">               while (iterator.hasNext())&#123;</span><br><span class="line">                   Row row = sheet.createRow(index);</span><br><span class="line">                   /*取得当前这行的map，该map中以key，value的形式存着这一行值*/</span><br><span class="line">                   Map&lt;String, String&gt; map = (Map&lt;String, String&gt;)iterator.next();</span><br><span class="line">                   /*循环列数，给当前行塞值*/</span><br><span class="line">                   for(int i = 0; i&lt;queryColumns.size(); i++)&#123;</span><br><span class="line">                       String old = &quot;&quot;;</span><br><span class="line">                       /*old存的是上一行统一位置的单元的值，第一行是最上一行了，所以从第二行开始记*/</span><br><span class="line">                       if(index &gt; 1)&#123;</span><br><span class="line">                           old = poiInfos.get(i)==null?&quot;&quot;: poiInfos.get(i).getContent();</span><br><span class="line">                       &#125;</span><br><span class="line">                       /*循环需要合并的列*/</span><br><span class="line">                       for(int j = 0; j &lt; mergeIndex.length; j++)&#123;</span><br><span class="line">                           if(index == 1)&#123;</span><br><span class="line">                               /*记录第一行的开始行和开始列*/</span><br><span class="line">                               PoiInfo poiInfo = new PoiInfo();</span><br><span class="line">                               poiInfo.setOldContent(String.valueOf(map.get(queryColumns.get(i).getName())));</span><br><span class="line">                               poiInfo.setContent(String.valueOf(map.get(queryColumns.get(i).getName())));</span><br><span class="line">                               poiInfo.setRowIndex(1);</span><br><span class="line">                               poiInfo.setCellIndex(i);</span><br><span class="line">                               poiInfos.add(poiInfo);</span><br><span class="line">                               break;</span><br><span class="line">                           &#125;else if(i &gt; 0 &amp;&amp; mergeIndex[j] == i)&#123;</span><br><span class="line">                               /*这边i&gt;0也是因为第一列已经是最前一列了，只能从第二列开始*/</span><br><span class="line">                               /*当前同一列的内容与上一行同一列不同时，把那以上的合并, 或者在当前元素一样的情况下，前一列的元素并不一样，这种情况也合并*/</span><br><span class="line">                               /*如果不需要考虑当前行与上一行内容相同，但是它们的前一列内容不一样则不合并的情况，把下面条件中</span><br><span class="line">　　　　　　　　　　　　　　　　　　||poiModels.get(i).getContent().equals(map.get(title[i])) &amp;&amp; !poiModels.get(i - 1).getOldContent().equals(map.get(title[i-1]))去掉就行*/</span><br><span class="line">                               if(!poiInfos.get(i).getContent().equals(String.valueOf(map.get(queryColumns.get(i).getName()))) || poiInfos.get(i).getContent().equals(String.valueOf(map.get(queryColumns.get(i).getName())))</span><br><span class="line">                                       &amp;&amp; !poiInfos.get(i - 1).getOldContent().equals(String.valueOf(map.get(queryColumns.get(i-1).getName()))))&#123;</span><br><span class="line">                                   /*当前行的当前列与上一行的当前列的内容不一致时，则把当前行以上的合并*/</span><br><span class="line">                                   CellRangeAddress cra=new CellRangeAddress(poiInfos.get(i).getRowIndex(), index - 1, poiInfos.get(i).getCellIndex(), poiInfos.get(i).getCellIndex());</span><br><span class="line">                                   //在sheet里增加合并单元格</span><br><span class="line">                                   sheet.addMergedRegion(cra);</span><br><span class="line">                                   /*重新记录该列的内容为当前内容，行标记改为当前行标记，列标记则为当前列*/</span><br><span class="line">                                   poiInfos.get(i).setContent(String.valueOf(map.get(queryColumns.get(i).getName())));</span><br><span class="line">                                   poiInfos.get(i).setRowIndex(index);</span><br><span class="line">                                   poiInfos.get(i).setCellIndex(i);</span><br><span class="line">                               &#125;</span><br><span class="line">                           &#125;</span><br><span class="line">                           /*处理第一列的情况*/</span><br><span class="line">                           if(mergeIndex[j] == i &amp;&amp; i == 0 &amp;&amp; !poiInfos.get(i).getContent().equals(String.valueOf(map.get(queryColumns.get(i).getName()))))&#123;</span><br><span class="line">                               /*当前行的当前列与上一行的当前列的内容不一致时，则把当前行以上的合并*/</span><br><span class="line">                               CellRangeAddress cra=new CellRangeAddress(poiInfos.get(i).getRowIndex(), index - 1, poiInfos.get(i).getCellIndex(), poiInfos.get(i).getCellIndex());</span><br><span class="line">                               //在sheet里增加合并单元格</span><br><span class="line">                               sheet.addMergedRegion(cra);</span><br><span class="line">                               /*重新记录该列的内容为当前内容，行标记改为当前行标记*/</span><br><span class="line">                               poiInfos.get(i).setContent(String.valueOf(map.get(queryColumns.get(i).getName())));</span><br><span class="line">                               poiInfos.get(i).setRowIndex(index);</span><br><span class="line">                               poiInfos.get(i).setCellIndex(i);</span><br><span class="line">                           &#125;</span><br><span class="line"></span><br><span class="line">                           /*最后一行没有后续的行与之比较，所有当到最后一行时则直接合并对应列的相同内容*/</span><br><span class="line">                           if(mergeIndex[j] == i &amp;&amp; index == list.size())&#123;</span><br><span class="line">                               CellRangeAddress cra=new CellRangeAddress(poiInfos.get(i).getRowIndex(), index, poiInfos.get(i).getCellIndex(), poiInfos.get(i).getCellIndex());</span><br><span class="line">                               //在sheet里增加合并单元格</span><br><span class="line">                               sheet.addMergedRegion(cra);</span><br><span class="line">                           &#125;</span><br><span class="line">                       &#125;</span><br><span class="line">                       Cell cell = row.createCell(i, Cell.CELL_TYPE_STRING);</span><br><span class="line">                       cell.setCellValue(String.valueOf(map.get(queryColumns.get(i).getName())));</span><br><span class="line">                       /*在每一个单元格处理完成后，把这个单元格内容设置为old内容*/</span><br><span class="line">                       poiInfos.get(i).setOldContent(old);</span><br><span class="line">                   &#125;</span><br><span class="line">                   index++;</span><br><span class="line">               &#125;</span><br><span class="line">           &#125;</span><br><span class="line">           n++;</span><br><span class="line">       &#125;</span><br><span class="line">       return true;</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure><h3 id="三"><a href="#三" class="headerlink" title="三"></a>三</h3><p>放弃原来template.query 使用lambda表达式的调用方式（注释部分），修改如下</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">\server\src\main\java\edp\davinci\service\excel\SheetWorker.java</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">//            template.query(sql, rs -&gt; &#123;</span><br><span class="line">//                Map&lt;String, Object&gt; dataMap = Maps.newHashMap();</span><br><span class="line">//                for (int i = 1; i &lt;= rs.getMetaData().getColumnCount(); i++) &#123;</span><br><span class="line">//                    dataMap.put(SqlUtils.getColumnLabel(queryFromsAndJoins, rs.getMetaData().getColumnLabel(i)), rs.getObject(rs.getMetaData().getColumnLabel(i)));</span><br><span class="line">//                &#125;</span><br><span class="line">//                writeLine(context, dataMap);</span><br><span class="line">//                count.incrementAndGet();</span><br><span class="line">//            &#125;);</span><br><span class="line"></span><br><span class="line">            List&lt;Map&lt;String, Object&gt;&gt; list = template.queryForList(sql);</span><br><span class="line">            // 获取合并列</span><br><span class="line">            List&lt;Integer&gt; listIt = new ArrayList&lt;Integer&gt;();</span><br><span class="line">            for (int j = 0; j &lt; context.getQueryColumns().size(); j++) &#123;</span><br><span class="line">                QueryColumn queryColumn = context.getQueryColumns().get(j);</span><br><span class="line">                if(!queryColumn.getType().equals(&quot;value&quot;))&#123;</span><br><span class="line">                    listIt.add(j);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            int[] mergeIndex = new int[listIt.size()];</span><br><span class="line">            int i = 0;</span><br><span class="line">            for(Integer it: listIt)&#123;</span><br><span class="line">                mergeIndex[i++] = it.intValue();</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            Map&lt;String, List&lt;Map&lt;String, Object&gt;&gt;&gt; map = new HashMap();</span><br><span class="line">            map.put(&quot;合并单元格数据&quot;, list);</span><br><span class="line">            createSheet(context.getSheet(),context.getQueryColumns(),map,mergeIndex);</span><br></pre></td></tr></table></figure><p>完成以上配置，效果就有了</p><h1 id="存在问题"><a href="#存在问题" class="headerlink" title="存在问题"></a>存在问题</h1><h2 id="透视驱动表头样式"><a href="#透视驱动表头样式" class="headerlink" title="透视驱动表头样式"></a>透视驱动表头样式</h2><p>​    目前无法做到透视驱动的表头样式，数据导出excel也仅仅和图表驱动类似的单元格数据的合并。</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/06/table-pivot2.jpg" alt="table-pivot2"></p><h2 id="表头样式进行分组合并影响导出"><a href="#表头样式进行分组合并影响导出" class="headerlink" title="表头样式进行分组合并影响导出"></a>表头样式进行分组合并影响导出</h2><p>​    表头样式进行分组合并设置，会影响导出，后续再进行处理。</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/06/table-merge.jpg" alt="table-merge"></p><h2 id="图表驱动表格合并存在不合理情形"><a href="#图表驱动表格合并存在不合理情形" class="headerlink" title="图表驱动表格合并存在不合理情形"></a>图表驱动表格合并存在不合理情形</h2><p>数据第一层维度数据不同，第二次数据相同合并，似乎不合理，excel做了处理，这样就不一致，如下情况：</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/06/table-issue.jpg" alt="table-issue"></p><h1 id="交流学习"><a href="#交流学习" class="headerlink" title="交流学习"></a>交流学习</h1><p>学习Metabase、Davinci等开源BI，群号：72569367，感兴趣的可以加一下。</p>]]></content>
    
    <summary type="html">
    
      &lt;h1 id=&quot;前言&quot;&gt;&lt;a href=&quot;#前言&quot; class=&quot;headerlink&quot; title=&quot;前言&quot;&gt;&lt;/a&gt;前言&lt;/h1&gt;&lt;p&gt;​    系统数据导出excel已经很具普遍性，不单单是BI有这需求，表单性质的数据大都希望直接导出excel，这个需求甚至比邮件接收更加突出。&lt;/p&gt;
&lt;p&gt;​    Davinci导出excel有两种方式，都在dashboard页面&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;单个widget导出&lt;/li&gt;
&lt;li&gt;整个dashboard导出，多个sheet页，一个sheet页对应一个widget数据
    
    </summary>
    
      <category term="可视化工具" scheme="https://dumplingbao.github.io/categories/%E5%8F%AF%E8%A7%86%E5%8C%96%E5%B7%A5%E5%85%B7/"/>
    
      <category term="Davinci" scheme="https://dumplingbao.github.io/categories/Davinci/"/>
    
    
      <category term="BI" scheme="https://dumplingbao.github.io/tags/BI/"/>
    
      <category term="Davinci" scheme="https://dumplingbao.github.io/tags/Davinci/"/>
    
  </entry>
  
  <entry>
    <title>Metabase-BI系列12：0.35版本表达式是真的香</title>
    <link href="https://dumplingbao.github.io/2020/04/12/metabase-bi-v035/"/>
    <id>https://dumplingbao.github.io/2020/04/12/metabase-bi-v035/</id>
    <published>2020-04-11T16:00:00.000Z</published>
    <updated>2021-11-26T18:18:19.597Z</updated>
    
    <content type="html"><![CDATA[<p>​    2020年3月30日，Metabase0.35版本真的来了，正如官方所说，0.35真的是一个重要的版本，最重磅的升级就是自定义表达式的升级，直接使Metabase的查询编辑器有了质的飞跃，对数据分析中自定义列、数据过滤器、数据聚合功能有了很大的提升。</p><a id="more"></a><p>​    这个重要的升级通俗讲：</p><ol><li>提升数据处理能力，不用写sql就能进行更多的数据转换</li><li>不同数据库，通用处理规则，提升用户体验</li><li>改为用<code>[]</code>方式获取字段，自动提示操作十分人性化</li></ol><h2 id="升级前后对比"><a href="#升级前后对比" class="headerlink" title="升级前后对比"></a>升级前后对比</h2><table><thead><tr><th>序号</th><th>功能</th><th>升级前</th><th>升级后（0.35之后）</th></tr></thead><tbody><tr><td>1</td><td>自定义列</td><td>只支持数字类型的<code>+</code>，<code>-</code>，<code>*</code>，<code>/</code></td><td>1、支持字符字段<br>2、新增字符和数字处理18个函数<code>abs</code>，<code>concat</code>等<br>3、支持升级前功能</td></tr><tr><td>2</td><td>过滤器</td><td>1、单个字段判断筛选<br>2、数字类型<code>是</code>，<code>不是</code>，<code>为空</code>，<code>不为空</code><br>3、字符类型除上面四个外，还有<code>包含</code>，<code>不包含</code>，<code>以..开始</code>，<code>以..结束</code><br>4、其它类型不再赘述，升级前后未变化</td><td>1、支持自定义表达式<br>2、新增函数支持<code>between</code>，<code>contains</code>，<code>ednWith</code>，<code>startWith</code>，<code>interval</code><br>3、扩展运算符：<code>AND</code>，<code>OR</code>，<code>NOT</code>，<code>&gt;</code>，<code>&gt;=</code>，<code>&lt;</code>，<code>&lt;=</code>，<code>=</code>，<code>!=</code><br>4、支持升级前功能</td></tr><tr><td>3</td><td>聚合</td><td>1、支持自定义表达式<br>2、原有聚合函数的<code>+</code>，<code>-</code>，<code>*</code>，<code>/</code></td><td>1、支持自定义表达式<br>2、新增了9中数字的处理函数<br>3、支持升级前功能</td></tr></tbody></table><p>过滤器：</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/Metabase/12/filter-expressions.gif" alt="filter-expressions"></p><p>聚合：</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/Metabase/12/first-expression.png" alt="first-expression"></p><h2 id="新增表达式介绍"><a href="#新增表达式介绍" class="headerlink" title="新增表达式介绍"></a>新增表达式介绍</h2><p>这次表达式确实扩展了很多，这里挑了几个常用的预览一下，也可以去Metabase官方查看全部表达式</p><table><thead><tr><th>名称</th><th>句法</th><th>备注</th><th>例</th></tr></thead><tbody><tr><td>Between</td><td>between(column, start, end)</td><td>1、日期范围内     2、数字区间内</td><td>between( [Rating], 3.75, 5 )</td></tr><tr><td>Case</td><td>case(condition, output,  condition, output …)</td><td>多情况判断，如枚举类型</td><td>case( [Weight] &gt; 200,  “Large”, [Weight] &gt; 150, “Medium”, “Small” )</td></tr><tr><td>返回非空值</td><td>coalesce( value1, value2, …)</td><td>按顺序查看每个参数中的值，并为每行返回第一个非空值。</td><td>coalesce( [Comments], [Notes],  “No comments” ）</td></tr><tr><td>字符串拼接</td><td>concat(value1, value2, …)</td><td>1、字符串或字段拼接     2、数值会转换字符拼接（已测试）</td><td>concat([Last Name] , “,  “, [First Name])</td></tr><tr><td>长度</td><td>length(text)</td><td>返回文本中的字符数</td><td>length([Comment])</td></tr><tr><td>小写转换</td><td>lower(text)</td><td>以小写形式返回文本字符串。</td><td>lower( [Status] )</td></tr><tr><td>去除左空格</td><td>ltrim(text)</td><td></td><td>ltrim( [Comment] )</td></tr><tr><td>正则表达式提取</td><td>regexextract(text,  regular_expression)</td><td>根据正则表达式提取匹配的子字符串</td><td>regexextract( [Address],  “[0-9]+” )</td></tr><tr><td>替换</td><td>replace(text, position, length,  new_text)</td><td></td><td>replace( [Order ID], 8, 3,  [Updated Part of ID] )</td></tr><tr><td>去除右空格</td><td>rtrim(text)</td><td></td><td>rtrim( [Comment] )</td></tr><tr><td>截取字符串</td><td>substring(text, position,  length)</td><td></td><td>substring( [Title], 0, 10 )</td></tr><tr><td>去除空格</td><td>trim(string)</td><td></td><td>trim( [Comment] )</td></tr><tr><td>大写转换</td><td>upper(text)</td><td></td><td>upper( [Status] )</td></tr></tbody></table><p>也可直接查看更多表达式连接（谷歌自动翻译）：<a href="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/Metabase/12/Metabase-bds.html" target="_blank" rel="noopener">https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/Metabase/12/Metabase-bds.html</a></p><h2 id="0-35其它说明"><a href="#0-35其它说明" class="headerlink" title="0.35其它说明"></a>0.35其它说明</h2><ul><li>新增表达式并不能兼容所有的数据库，因为数据库差异很大，做到这种程度已经很牛x了，表达式数据库兼容情况参加官方说明</li><li>此外0.35版本调整了查询结果缓存内存的策略，改为数据库流，调整了一些api，着眼性能提升</li><li>当然少不了的就是修复bug了，参加官方说明</li></ul><h2 id="交流学习"><a href="#交流学习" class="headerlink" title="交流学习"></a>交流学习</h2><p>刚建的群，学习Metabase、Davinci等开源BI，群号：72569367，感兴趣的可以加一下。</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;​    2020年3月30日，Metabase0.35版本真的来了，正如官方所说，0.35真的是一个重要的版本，最重磅的升级就是自定义表达式的升级，直接使Metabase的查询编辑器有了质的飞跃，对数据分析中自定义列、数据过滤器、数据聚合功能有了很大的提升。&lt;/p&gt;
    
    </summary>
    
      <category term="可视化工具" scheme="https://dumplingbao.github.io/categories/%E5%8F%AF%E8%A7%86%E5%8C%96%E5%B7%A5%E5%85%B7/"/>
    
      <category term="Metabase" scheme="https://dumplingbao.github.io/categories/Metabase/"/>
    
    
      <category term="BI" scheme="https://dumplingbao.github.io/tags/BI/"/>
    
      <category term="Metabase" scheme="https://dumplingbao.github.io/tags/Metabase/"/>
    
  </entry>
  
  <entry>
    <title>Davinci-二次开发系列05：echarts-gl map3D扩展</title>
    <link href="https://dumplingbao.github.io/2020/04/03/davinci-dev-egl/"/>
    <id>https://dumplingbao.github.io/2020/04/03/davinci-dev-egl/</id>
    <published>2020-04-03T15:00:00.000Z</published>
    <updated>2021-11-26T18:18:19.595Z</updated>
    
    <content type="html"><![CDATA[<h1 id="echarts-gl"><a href="#echarts-gl" class="headerlink" title="echarts-gl"></a>echarts-gl</h1><p>​    介绍一下<code>echarts-gl</code>，<code>charts-gl</code>专门为<code>echarts</code>补充了丰富三维可视化组件。这里的gl应该是global的意思，很多地方简写GL，不建议这样写，因为和真实的GL太冲突，更何况最近肖某的事情，和BL有着千丝万缕的关系，所以，就别和GL扯上关系，我们还是写全称<code>echarts-gl</code>。</p><a id="more"></a><h1 id="echarts-gl-map3D"><a href="#echarts-gl-map3D" class="headerlink" title="echarts-gl map3D"></a>echarts-gl map3D</h1><p>​    这次介绍<code>echarts-gl map3D</code>，就是用<code>echarts-gl</code>实现的地图的3D模式，也是在系列03的基础上进行的改造，开启3D，切换地图，效果如下：</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/05/echarts-gl.gif" alt="echarts-gl"></p><h2 id="echarts-gl安装"><a href="#echarts-gl安装" class="headerlink" title="echarts-gl安装"></a>echarts-gl安装</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cnpm install echarts-gl --save</span><br></pre></td></tr></table></figure><h2 id="页面引入"><a href="#页面引入" class="headerlink" title="页面引入"></a>页面引入</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">import &apos;echarts/dist/echarts-gl&apos;</span><br></pre></td></tr></table></figure><p>特别注意一下：如果集成了百度地图，这个引入不要放入到<code>app.tsx</code>里面，会出现一直加载不完的情况，所以最好放到<code>chart.tsx</code></p><h2 id="控制参数"><a href="#控制参数" class="headerlink" title="控制参数"></a>控制参数</h2><p>​    在样式里面，添加控制参数，开启3D</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/05/is3D.jpg" alt="is3D"></p><h2 id="render调整"><a href="#render调整" class="headerlink" title="render调整"></a>render调整</h2><p>​    在render下面的<code>map.ts</code>调整图形，主要是series的属性</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">map：&apos;&apos; // 注意与echarts.registerMap第一个参数保持一致</span><br><span class="line">type: &apos;map3D&apos; // 通过type指定必须是map3D，还有一种方式geo3D，见echarts官方实例</span><br></pre></td></tr></table></figure><p>完成以上配置，效果就有了</p><h2 id="echarts-gl事件存在问题"><a href="#echarts-gl事件存在问题" class="headerlink" title="echarts-gl事件存在问题"></a>echarts-gl事件存在问题</h2><p>​    <code>echarts-gl</code>图表事件一直存在问题，算是个坑，截止目前，我统计了一下官方issue关于事件目前一直open的最少四个，echarts-gl目前维护进度也较慢。</p><p>​    试了几个版本的<code>echarts-gl</code>，发现对于不同的版本：</p><ul><li>有版本需要加<code>getZr()</code>，有的版本不需要</li><li>有的事件需要加<code>getZr()</code>，有的事件不需要</li><li>有的版本获取不到区域名称，只能获取到坐标，有的版本能</li><li>有的版本区域域名加了<code>getZr()</code>能获取到，有的不加能获取到，有的都能，有的都不能</li></ul><p>​    我目前使用的版本<code>1.1.1</code>，单击事件不用加<code>getZr()</code>，右键事件需要加，但是右键事件获取不到区域名称，如果发现某个版本单击和右键事件都有，并能获取到取到区域名称，烦请留言告知，在此谢过。</p><p>​    就拿我们用的单击和右键事件来说：</p><p>​    单击事件实现方式：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">// 方式一</span><br><span class="line">myChart.on(&apos;click&apos;, function (params) &#123;</span><br><span class="line">   console.log(params);</span><br><span class="line">&#125;);</span><br><span class="line">// 方式二</span><br><span class="line">myChart.getZr().on(&apos;click&apos;, function (params) &#123;</span><br><span class="line">   console.log(params);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><p>​    右键事件</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">// 方式一</span><br><span class="line">myChart.on(&apos;contextmenu&apos;, function (params) &#123;</span><br><span class="line">   console.log(params);</span><br><span class="line">&#125;);</span><br><span class="line">// 方式二</span><br><span class="line">myChart.getZr().on(&apos;contextmenu&apos;, function (params) &#123;</span><br><span class="line">   console.log(params);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h1 id="几个推荐和注意"><a href="#几个推荐和注意" class="headerlink" title="几个推荐和注意"></a>几个推荐和注意</h1><h2 id="echarts-gl地图下钻"><a href="#echarts-gl地图下钻" class="headerlink" title="echarts-gl地图下钻"></a>echarts-gl地图下钻</h2><p>​    如果<code>echarts-gl</code> 地图下钻，一些类似边框、颜色等属性，需要在下钻事件里面重新调整，否则下钻到新的地图属性不能匹配。</p><h2 id="echarts-gl-map3D组合图形"><a href="#echarts-gl-map3D组合图形" class="headerlink" title="echarts-gl map3D组合图形"></a>echarts-gl map3D组合图形</h2><p>​    如果仅仅<code>echarts-gl map3D</code>效果没那么出众，一般都是配合其它图形，在地图上放柱形、雨滴等会更突出3D效果，所以可以进一步扩展。</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/05/demo-3D.jpg" alt="demo-3D"></p><h2 id="echarts-gl性能"><a href="#echarts-gl性能" class="headerlink" title="echarts-gl性能"></a>echarts-gl性能</h2><p>​    这里map3D较简单，性能未发现问题，echarts-gl有很多空间性很强的图形，这种图形渲染加载都会比2D慢，所以性能也是需要考虑的，其它3D图形用的维度指标较多，性能有待测试验证。</p><h2 id="geo3D和map3d区别"><a href="#geo3D和map3d区别" class="headerlink" title="geo3D和map3d区别"></a>geo3D和map3d区别</h2><p>geo3D不支持visualMap，显示3D地理，上面可以加柱状图，各省份数据无法展示。</p><p>map3d支持visualMap，可以显示区域数据，不能绘制柱状图，但是也有说可以隐藏一个geo3D来实现，所以待验证，大家可以尝试一下。</p><h1 id="交流学习"><a href="#交流学习" class="headerlink" title="交流学习"></a>交流学习</h1><p>刚建的群，学习Metabase、Davinci等开源BI，群号：72569367，感兴趣的可以加一下。</p>]]></content>
    
    <summary type="html">
    
      &lt;h1 id=&quot;echarts-gl&quot;&gt;&lt;a href=&quot;#echarts-gl&quot; class=&quot;headerlink&quot; title=&quot;echarts-gl&quot;&gt;&lt;/a&gt;echarts-gl&lt;/h1&gt;&lt;p&gt;​    介绍一下&lt;code&gt;echarts-gl&lt;/code&gt;，&lt;code&gt;charts-gl&lt;/code&gt;专门为&lt;code&gt;echarts&lt;/code&gt;补充了丰富三维可视化组件。这里的gl应该是global的意思，很多地方简写GL，不建议这样写，因为和真实的GL太冲突，更何况最近肖某的事情，和BL有着千丝万缕的关系，所以，就别和GL扯上关系，我们还是写全称&lt;code&gt;echarts-gl&lt;/code&gt;。&lt;/p&gt;
    
    </summary>
    
      <category term="可视化工具" scheme="https://dumplingbao.github.io/categories/%E5%8F%AF%E8%A7%86%E5%8C%96%E5%B7%A5%E5%85%B7/"/>
    
      <category term="Davinci" scheme="https://dumplingbao.github.io/categories/Davinci/"/>
    
    
      <category term="BI" scheme="https://dumplingbao.github.io/tags/BI/"/>
    
      <category term="Davinci" scheme="https://dumplingbao.github.io/tags/Davinci/"/>
    
  </entry>
  
  <entry>
    <title>Davinci-二次开发系列04：自定义水印扩展</title>
    <link href="https://dumplingbao.github.io/2020/04/03/davinci-dev-water/"/>
    <id>https://dumplingbao.github.io/2020/04/03/davinci-dev-water/</id>
    <published>2020-04-03T15:00:00.000Z</published>
    <updated>2021-11-26T18:18:19.596Z</updated>
    
    <content type="html"><![CDATA[<h1 id="水印（watermark）"><a href="#水印（watermark）" class="headerlink" title="水印（watermark）"></a>水印（watermark）</h1><p>​    目前来看，水印已经具有很高的附加价值了，钱币的水印能防伪，资料上的水印能宣传，甚至很多对外的产品软件都把去水印当成VIP的一项特殊功能，随着知识产权加强，知识付费的流行，水印也成了防止盗用的一种很重要的手段。</p><p>​    Davinci的水印我觉着官方迟早会出，但目前来看短时间出不来，出成什么样子也不确定，所以我们就先制瓜吃瓜。</p><a id="more"></a><p>​    效果：</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/04/watermark.gif" alt="watermark"></p><h1 id="水印制作"><a href="#水印制作" class="headerlink" title="水印制作"></a>水印制作</h1><h2 id="自定义水印位置"><a href="#自定义水印位置" class="headerlink" title="自定义水印位置"></a>自定义水印位置</h2><p>​    既然是自定义水印，自然也离不开用户和权限，为了先实现自定义，不考虑复杂因素，自定义水印根据项目划分，支持快捷显示项目名称等，不考虑用户自定义和项目自定义水印同时存在的情况。</p><p>​    在用户界面》》组织》》项目》》设置》》水印设置</p><h2 id="水印显示位置"><a href="#水印显示位置" class="headerlink" title="水印显示位置"></a>水印显示位置</h2><p>目前来看有这么几个位置：</p><ul><li>widget编辑区（编辑区理论不需要水印，观点不一）</li><li>dashboard看板</li><li>display大屏</li><li>widget分享面板（官方留了口子，但没有实现完善，暂不考虑）</li><li>dashboard分享面板</li><li>display分享面板</li></ul><h3 id="widget工作区："><a href="#widget工作区：" class="headerlink" title="widget工作区："></a>widget工作区：</h3><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/04/water-edit.jpg" alt="water-edit"></p><h3 id="dashboard页面："><a href="#dashboard页面：" class="headerlink" title="dashboard页面："></a>dashboard页面：</h3><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/04/water-dashboard.jpg" alt="water-dashboard"></p><h3 id="display页面："><a href="#display页面：" class="headerlink" title="display页面："></a>display页面：</h3><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/04/water-display.jpg" alt="water-display"></p><h2 id="水印属性"><a href="#水印属性" class="headerlink" title="水印属性"></a>水印属性</h2><ul><li><p>开启关闭</p></li><li><p>项目名称</p></li><li><p>用户名</p></li><li><p>水印文本（比如“内部资料，严禁外传”这类）</p></li><li><p>水印时间戳（支持多种日期格式）</p></li><li><p>水印颜色</p></li></ul><p>备注：未实现上传图片等格式的水印</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/04/data.jpg" alt="data"></p><h1 id="水印编码实现"><a href="#水印编码实现" class="headerlink" title="水印编码实现"></a>水印编码实现</h1><h2 id="用户信息获取"><a href="#用户信息获取" class="headerlink" title="用户信息获取"></a>用户信息获取</h2><p>​    登录用户信息获取目前有两种</p><p>​    方式一：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">const mapStateToProps = createStructuredSelector(&#123;</span><br><span class="line">  loginUser: makeSelectLoginUser(),</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure><p>​    方式二：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">const loginUser = localStorage.getItem(&apos;loginUser&apos;)</span><br></pre></td></tr></table></figure><h2 id="项目信息获取"><a href="#项目信息获取" class="headerlink" title="项目信息获取"></a>项目信息获取</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">const mapStateToProps = createStructuredSelector(&#123;</span><br><span class="line">  currentProject: makeSelectCurrentProject()</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure><h2 id="后台改造"><a href="#后台改造" class="headerlink" title="后台改造"></a>后台改造</h2><p>后台改造比较简单：</p><p>第一：project表增加config字段，类型text，注意和json的转换</p><p>第二：分享功能增加project信息，用于展示项目名称，因为分享不登录状态即可访问，所以无法显示用户名</p><h2 id="前端改造"><a href="#前端改造" class="headerlink" title="前端改造"></a>前端改造</h2><p>前端改造难点除代码语法外，</p><p>第一：重点还是在用户名称和项目名称获取上</p><p>第二：自定义水印在组织里面，项目的获取和值传递</p><p>第三：分享功能，项目信息传递</p><p>第四：水印组件引入可以放在多个位置，放到widget下面会比较省劲，尤其是要求多个地方都呈现水印</p><h1 id="几个推荐和注意"><a href="#几个推荐和注意" class="headerlink" title="几个推荐和注意"></a>几个推荐和注意</h1><h2 id="dashboard和display水印问题"><a href="#dashboard和display水印问题" class="headerlink" title="dashboard和display水印问题"></a>dashboard和display水印问题</h2><p>​    第一：看上面的效果图能明显看到水印是最终实在单个widget下面的，而不是在整个面板上的，整体效果就差一些</p><p>​    第二：尤其是大屏这种，可以考虑每个大屏自定义水印，因为大屏有自身特有的组件</p><h2 id="导出excel水印"><a href="#导出excel水印" class="headerlink" title="导出excel水印"></a>导出excel水印</h2><p>数据导出excel同样需要水印，推荐实现</p><h2 id="分享链接的水印"><a href="#分享链接的水印" class="headerlink" title="分享链接的水印"></a>分享链接的水印</h2><p>Davinci里面widget、dashboard、display都支持分享，widget不完善，分享不受权限控制，也不是我们正常进入到某个项目里面的操作，而我们的自定义水印是根据项目设定的，所以分享链接需要根据dashboard获取项目信息和水印的配置信息，并传递到widget组件里。</p><h2 id="定时任务邮件接收水印"><a href="#定时任务邮件接收水印" class="headerlink" title="定时任务邮件接收水印"></a>定时任务邮件接收水印</h2><p>邮件接收报表带水印是非常合理的，根据水印时间戳更是能够准确判断当前报表的出具时间。</p><h1 id="交流学习"><a href="#交流学习" class="headerlink" title="交流学习"></a>交流学习</h1><p>刚建的群，学习Metabase、Davinci等开源BI，群号：72569367，感兴趣的可以加一下。</p>]]></content>
    
    <summary type="html">
    
      &lt;h1 id=&quot;水印（watermark）&quot;&gt;&lt;a href=&quot;#水印（watermark）&quot; class=&quot;headerlink&quot; title=&quot;水印（watermark）&quot;&gt;&lt;/a&gt;水印（watermark）&lt;/h1&gt;&lt;p&gt;​    目前来看，水印已经具有很高的附加价值了，钱币的水印能防伪，资料上的水印能宣传，甚至很多对外的产品软件都把去水印当成VIP的一项特殊功能，随着知识产权加强，知识付费的流行，水印也成了防止盗用的一种很重要的手段。&lt;/p&gt;
&lt;p&gt;​    Davinci的水印我觉着官方迟早会出，但目前来看短时间出不来，出成什么样子也不确定，所以我们就先制瓜吃瓜。&lt;/p&gt;
    
    </summary>
    
      <category term="可视化工具" scheme="https://dumplingbao.github.io/categories/%E5%8F%AF%E8%A7%86%E5%8C%96%E5%B7%A5%E5%85%B7/"/>
    
      <category term="Davinci" scheme="https://dumplingbao.github.io/categories/Davinci/"/>
    
    
      <category term="BI" scheme="https://dumplingbao.github.io/tags/BI/"/>
    
      <category term="Davinci" scheme="https://dumplingbao.github.io/tags/Davinci/"/>
    
  </entry>
  
  <entry>
    <title>Davinci-二次开发系列03：区域地图下钻与选择</title>
    <link href="https://dumplingbao.github.io/2020/03/28/davinci-dev-map/"/>
    <id>https://dumplingbao.github.io/2020/03/28/davinci-dev-map/</id>
    <published>2020-03-28T04:00:00.000Z</published>
    <updated>2021-11-26T18:18:19.595Z</updated>
    
    <content type="html"><![CDATA[<h1 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h1><p>系列02中讲到百度地图扩展，地图应用场景多样，对于BI数据的呈现区域地图（非经纬度坐标）似乎应用更加广泛，这次说一下对于区域地图的几点改造。一个是下钻，一个是指定自定义的区域地图。</p><a id="more"></a><h2 id="地图下钻"><a href="#地图下钻" class="headerlink" title="地图下钻"></a>地图下钻</h2><p>层级下钻，没有具体的几级，可以一直下钻并返回，这里做了国家、省份、市、区县、街道的下钻。</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/03/drill.gif" alt="drill"></p><h2 id="指定地图"><a href="#指定地图" class="headerlink" title="指定地图"></a>指定地图</h2><p>指定需要展示的地图，并可以钻取和上卷。</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/03/switch.gif" alt="switch"></p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/03/switch%26drill.gif" alt="s&amp;d"></p><h1 id="吐槽一下Davinci地图"><a href="#吐槽一下Davinci地图" class="headerlink" title="吐槽一下Davinci地图"></a>吐槽一下Davinci地图</h1><p>Davinci 地图目前十分的不友好，不得不吐槽一下：</p><ul><li><p>不能很好的扩展地图</p></li><li><p>地图数据逻辑，通过地理类型和对照js文件去汇总，这种十分的不灵活</p></li><li><p>地图真实应用需求类似下钻不能满足</p></li></ul><h1 id="地图改造点"><a href="#地图改造点" class="headerlink" title="地图改造点"></a>地图改造点</h1><h2 id="去掉原有的地图类型"><a href="#去掉原有的地图类型" class="headerlink" title="去掉原有的地图类型"></a>去掉原有的地图类型</h2><p>​    原有地图类型：地图、气泡图、热力图、飞行图，</p><p>​    改造后：去掉地图类型</p><p>​    这些需求在区域地图上是有的，官方就是考虑这些类型的实现导致区域地图显得复杂，尤其是飞行图这种实际BI应用场景中较少，而且飞行图是要有起点的，默认指定的第一个为起始点，非配置化，略显鸡肋。我们已经在百度地图扩展里做了一些实现，这里直接去掉原有的地图类型，简化代码，更突出区域地图的功能。</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/03/style.jpg" alt="style"></p><h2 id="数据类型扩展"><a href="#数据类型扩展" class="headerlink" title="数据类型扩展"></a>数据类型扩展</h2><p>​    原类型：地理国家、地理省份、地理城市</p><p>​    扩展后：增加地理区县和地理街道</p><p>​    备注：实际改造了数据组装逻辑之后，类型仅仅是体现特殊性的地理维度，并不是严格的层级区分了，就是说改造之后实际指定的类型不影响数据展示。</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/03/dimtype.jpg" alt="dimtype"></p><h2 id="数据组装逻辑改造"><a href="#数据组装逻辑改造" class="headerlink" title="数据组装逻辑改造"></a>数据组装逻辑改造</h2><p>​    原逻辑：根据配置的地理类型，根据层级对照的js文件进行汇总计算。</p><p>​    改造后：根据实际数据进行自动汇总处理，与类型无关，即相同字段名称的汇总。</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/03/datastructure.jpg" alt="datastructure"></p><h2 id="增加单击下钻右键返回事件"><a href="#增加单击下钻右键返回事件" class="headerlink" title="增加单击下钻右键返回事件"></a>增加单击下钻右键返回事件</h2><p>​    添加单击和右键事件实现下钻返回。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">instance.off(&apos;click&apos;)</span><br><span class="line">instance.on(&apos;click&apos;, (params) =&gt; &#123;</span><br><span class="line">// 添加单击事件</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">instance.on(&apos;contextmenu&apos;, (params) =&gt; &#123;</span><br><span class="line">// 添加右键事件</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure><h2 id="地图json文件扩展"><a href="#地图json文件扩展" class="headerlink" title="地图json文件扩展"></a>地图json文件扩展</h2><p>​    既然能够指定区域地图，就要有地图的json文件，这里推荐两个免费的json地图地址。</p><p>​    阿里的：<a href="http://datav.aliyun.com/tools/atlas/#&amp;lat=33.54139466898275&amp;lng=104.2822265625&amp;zoom=4" target="_blank" rel="noopener">http://datav.aliyun.com/tools/atlas/#&amp;lat=33.54139466898275&amp;lng=104.2822265625&amp;zoom=4</a></p><p>​    个人的：<a href="https://gallery.echartsjs.com/editor.html?c=xr1IEt3r4Q" target="_blank" rel="noopener">https://gallery.echartsjs.com/editor.html?c=xr1IEt3r4Q</a>  更新很及时，行政区划调整比较及时。</p><p>​    中国闭源软件多，开源软件少，可能一个原因是付费的少，这些作者提供的json文件着实给力，所以建议大家使用之余，能力范围内打赏一下（非广告）。</p><p><img src="https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/davinci/03/json.jpg" alt="json"></p><h1 id="几个推荐和注意"><a href="#几个推荐和注意" class="headerlink" title="几个推荐和注意"></a>几个推荐和注意</h1><h2 id="json文件改造自定义上传"><a href="#json文件改造自定义上传" class="headerlink" title="json文件改造自定义上传"></a>json文件改造自定义上传</h2><p>​    可以改造json文件自定义上传，这样用户可以自己上传json文件然后从地图样式里面指定。</p><h2 id="json层级建立对照字典表"><a href="#json层级建立对照字典表" class="headerlink" title="json层级建立对照字典表"></a>json层级建立对照字典表</h2><p>​    对于自定义上传的json文件建立层级对照表，源码里面通过js文件对照的，不利于维护。</p><h2 id="普通图表下钻功能的影响"><a href="#普通图表下钻功能的影响" class="headerlink" title="普通图表下钻功能的影响"></a>普通图表下钻功能的影响</h2><p>​    Davinci dashboard有下钻的功能，并且图表的钻添加了右键事件，所以需要进一步验证是否存在冲突的问题。</p><h1 id="交流学习"><a href="#交流学习" class="headerlink" title="交流学习"></a>交流学习</h1><p>刚建的群，学习Metabase、Davinci等开源BI，群号：72569367，感兴趣的可以加一下。</p>]]></content>
    
    <summary type="html">
    
      &lt;h1 id=&quot;概述&quot;&gt;&lt;a href=&quot;#概述&quot; class=&quot;headerlink&quot; title=&quot;概述&quot;&gt;&lt;/a&gt;概述&lt;/h1&gt;&lt;p&gt;系列02中讲到百度地图扩展，地图应用场景多样，对于BI数据的呈现区域地图（非经纬度坐标）似乎应用更加广泛，这次说一下对于区域地图的几点改造。一个是下钻，一个是指定自定义的区域地图。&lt;/p&gt;
    
    </summary>
    
      <category term="可视化工具" scheme="https://dumplingbao.github.io/categories/%E5%8F%AF%E8%A7%86%E5%8C%96%E5%B7%A5%E5%85%B7/"/>
    
      <category term="Davinci" scheme="https://dumplingbao.github.io/categories/Davinci/"/>
    
    
      <category term="BI" scheme="https://dumplingbao.github.io/tags/BI/"/>
    
      <category term="Davinci" scheme="https://dumplingbao.github.io/tags/Davinci/"/>
    
  </entry>
  
</feed>
