182 2056 1552
新闻banner图
新闻资讯
tellhow news

Dazdata BI(Redash中文商业版)深度应用技术详解(第二期)

发布日期:2021-12-03 发布人: 

1.jpg

上一期,我们详细介绍了Dazdata BI(Redash中文商业版)部件联动、视图深入应用、取数函数使用的三个深入应用的内容,前期回顾链接地址:Dazdata BI(Redash中文商业版)深度应用技术详解

       本期,我们将详细讲解,Dazdata BI独有的自定义代码功能。

一、 自定义代码

Dazdata BI创造性提供了自定义代码视图功能,目前包括四类基础引擎(Plotly\ECharts\Three\Datatables.net),采用沙盒模式运行代码,同时把后台数据以内置对象的形式传进沙盒供调用,解决了传统BI产品充分依赖模板没有灵活性的问题。·············如下图所示,在视图类型中选择对应的自定义视图类型即可以自定义代码的方式设计图表。

2.jpg

(1)、内置对象:

1. x对象,此对象是在视图-->通用-->x轴选项中选择的字段的所有数据组成的数组。

2. ys对象,此对象是在视图-->通用-->y轴选项中选择的所有字段组成的json对象。例如ys.field1获取就是字段名为field1的所有数据组成的数组。

3. scheme对象,为样式对象,里面有当前报表的所有样式信息

o scheme.style 取当前报表的样式名

o scheme.bg 取报表背景样式

o scheme.back 取部件背景样式

o scheme.color 取部件文字颜色

o scheme.titleback 取部件标题栏背景样式

o scheme.titlecolor 取部件标题栏文字颜色

4. parameter对象,为url参数对象,里面有当前报表所有url参数的信息 例如,报表url为
http://demo.redash.cn//dashboards/342-test15?p_id1=1&p_id2=2

o parameter.p_id1 取url中p_id1的值

o parameter.p_id2 取url中p_id3的值

row对象,为Table视图中应用自定义代码视图列类型时,传入的行记录结果对象。默认在编辑态取table表格第0行的数据。

(2)、内置函数:

1、onclickhandler 为点击事件函数,参数为对象{key:value}。

若要再视图区域实现点击功能,需要调用改回调函数。能实现部件弹窗和传参。

2、onrefreshdashboardhandler、onrefreshwidgethandler 为强制刷新报表或部件数据函数。

3、onexpanddashboardhandler 以弹窗方式调用已发布报表函数。

(3)、ECharts视图参考手册

ECharts是纯Javascript的图表库,可以流畅的运行在PC和移动设备上,兼容当前绝大部分浏览器(IE6/7/8/9/10/11,chrome,firefox,Safari等),底层依赖轻量级的Canvas类库ZRender,提供直观,生动,可交互,可高度个性化定制的数据可视化图表。创新的拖拽重计算、数据视图、值域漫游等特性大大增强了用户体验,赋予了用户对数据进行挖掘、整合的能力。

Dazdata BI现已全面集成EChart全部图表组件,无需任何配置,自定义视图采用沙盒模式可实现增量渲染技术,配合各种细致的优化,能够展现千万级的数据量,并且在这个数据量级依然能够进行流畅的缩放平移等交互,两组数据之间的差异然后通过合适的动画去表现数据的变化,轻松实现动态数据。线数据,点数据等地理数据的可视化可增加特效,展示更多更强大绚丽的三维可视化,可以轻松的绘制出三维的地球,建筑群,人口分布的柱状图,画面渲染效果更加艺术性!

3.jpg

下面以折线图为例介绍如何自定义echarts视图(示例代码来源:https://echarts.apache.org/examples/zh/editor.html?c=line-simple)

1.静态数据

//选择自定义视图(ECharts),初始化对象,容器名称为chartDom

var myChart = echarts.init(chartDom);

//指定图表的配置项

var option;

option = {

xAxis: {

type: 'category',

data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']

},

yAxis: {

type: 'value'

},

series: [{

data: [150, 230, 224, 218, 135, 147, 260],

type: 'line'

}]

};

option && myChart.setOption(option);

图表展示效果:

4.jpg

下面以折线图为例介绍如何自定义echarts视图(示例代码来源:https://echarts.apache.org/examples/zh/editor.html?c=line-simple)

1.静态数据

//选择自定义视图(ECharts),初始化对象,容器名称为chartDom

var myChart = echarts.init(chartDom);

//指定图表的配置项

var option;

option = {

xAxis: {

type: 'category',

data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']

},

yAxis: {

type: 'value'

},

series: [{

data: [150, 230, 224, 218, 135, 147, 260],

type: 'line'

}]

};

option && myChart.setOption(option);

图表展示效果:

5.jpg

6.jpg

3.取数函数用法

query或querys查询id,数字,属于必填参数。当用querys时会立即加载,适用于非界面显示元素。

colName取数列名,字符串,必填参数。

rowNumber取数行号,可选参数。该参数为数字时:取指定行的值(从0开始);该参数不存在时:返回指定列全部行值数组

如:data:,表示取查询id为365的表中列名为alexa的数据。保存后效果如下:

7.jpg

更多图例请参考:
https://echarts.apache.org/examples/zh/index.html ECharts官网 和 https://www.makeapie.com/explore.html 更多资源

(4)、Three动画参考手册

Three.js(官网https://threejs.org/)是基于WebGL的Javascript开源框架,简言之,就是能够实现3D动画效果的JS库。3D动画可视化开发都是需要前端开发基础,目前市场两大three.js和babylon.js技术应用成熟且广泛。Dazdata BI内置Three.js引擎,可以方便的已自定义代码方式引入3D功能。

8.jpg

下面以Three.js官方示例little tokoya为例,用自定义代码实现3D视图:

loadJS("/static/three/examples/js/controls/OrbitControls.js", ()=>{

loadJS("/static/three/examples/js/environments/RoomEnvironment.js", ()=>{

loadJS("/static/three/examples/js/loaders/GLTFLoader.js", ()=>{

loadJS("/static/three/examples/js/loaders/DRACOLoader.js", ()=>{

init();

});

});

});

});


function init () {

let mixer;

const clock = new THREE.Clock();

const renderer = new THREE.WebGLRenderer( { antialias: true } );

renderer.setPixelRatio( window.devicePixelRatio );

renderer.setSize( window.innerWidth, window.innerHeight );

renderer.outputEncoding = THREE.sRGBEncoding;

container.appendChild( renderer.domElement );

const pmremGenerator = new THREE.PMREMGenerator( renderer );

const scene = new THREE.Scene();

scene.background = new THREE.Color( 0xbfe3dd );

scene.environment = pmremGenerator.fromScene( new THREE.RoomEnvironment(), 0.04 ).texture;

const camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 100 );

camera.position.set( 5, 2, 8 );

const controls = new THREE.OrbitControls( camera, renderer.domElement );

controls.target.set( 0, 0.5, 0 );

controls.update();

controls.enablePan = false;

controls.enableDamping = true;

const dracoLoader = new THREE.DRACOLoader();

dracoLoader.setDecoderPath( '/static/three/examples/js/libs/draco/gltf/' );

const loader = new THREE.GLTFLoader();

loader.setDRACOLoader( dracoLoader );

loader.load( '/static/three/tokyo.glb', function ( gltf ) {

const model = gltf.scene;

model.position.set( 1, 1, 0 );

model.scale.set( 0.01, 0.01, 0.01 );

scene.add( model );

mixer = new THREE.AnimationMixer( model );

mixer.clipAction( gltf.animations[ 0 ] ).play();

animate();

}, undefined, function ( e ) {

console.error( e );

} );

window.onresize = function () {

camera.aspect = window.innerWidth / window.innerHeight;

camera.updateProjectionMatrix();

renderer.setSize( window.innerWidth, window.innerHeight );

};

function animate() {

requestAnimationFrame( animate );

const delta = clock.getDelta();

mixer.update( delta );

controls.update();

renderer.render( scene, camera );

}


}

function loadJS( url, callback ) {

fn = callback || function(){};


if (document.getElementById(url)) {

fn();

return;

}

var script = document.createElement('script');

// script.type = 'module';

script.id = url;

//IE

if(script.readyState){

script.onreadystatechange = function(){

if( script.readyState == 'loaded' || script.readyState == 'complete' ) {

script.onreadystatechange = null;

fn();

}

};

}else{

//其他浏览器

script.onload = function(){

fn();

};

}

script.src = url;

document.getElementsByTagName('head')[0].appendChild(script);

}

若要实现3D标注并连接其它BI报表,需要用到自定义代码内置对象。

function onMouseClick(e){

//将html坐标系转化为webgl坐标系,并确定鼠标点击位置

mouse.x = e.clientX / renderer.domElement.clientWidth*2-1;

mouse.y = -(e.clientY / renderer.domElement.clientHeight*2)+1;

//以camera为z坐标,确定所点击物体的3D空间位置

raycaster.setFromCamera(mouse,camera);

//确定所点击位置上的物体数量

var intersects = raycaster.intersectObjects(scene.children,true);

//选中后进行的操作

for(var i=0;i<intersects.length;i++){

// console.log(intersects[i].object.name)

if(intersects[i].object.name === "House_World_ap_0"){

onexpanddashboardhandler(396);

// console.log("this is 1");

break;

}else if(intersects[i].object.name === "House_2_World_ap_0"){

onexpanddashboardhandler(356,true);

// console.log("this is 2");

break;

}else if(intersects[i].object.name === "House_3_World_ap_0"){

console.log("this is 3");

break;

}

};

// console.log(intersects)

}

var raycaster = new THREE.Raycaster();//光线投射,用于确定鼠标点击位置

var mouse = new THREE.Vector2();

container.addEventListener( 'click', onMouseClick, false );


7、Datatables.net表格参考手册

JQuery DataTables(官网https://datatables.net/)深受欢迎且功能强大,通过Dazdata BI的沙盒代码模式可以编程开发任意复杂报表。且支持带格式输出成Excel文件。Dazdata BI报表开发不再难。

9.jpg

var myhtml=`

<link href="https://cdn.datatables.net/1.10.25/css/jquery.dataTables.min.css" rel="stylesheet" type="text/css">

<style >

div.dataTables_length {

padding-left: 2em;

}

div.dataTables_length,

div.dataTables_filter {

padding-top: 0.55em;

}

.test{

width: 100%;

height: 100%;

overflow: auto;

float: left;

border: none;

}


.test-1::-webkit-scrollbar {/*滚动条整体样式*/

width: 10px; /*高宽分别对应横竖滚动条的尺寸*/

height: 1px;

}



.test-1::-webkit-scrollbar-thumb {/*滚动条里面小方块*/

border-radius: 10px;

-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);

background: #535353;

}


.test-1::-webkit-scrollbar-track {/*滚动条里面轨道*/

-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);

border-radius: 10px;

background: #EDEDED;

}

.odd .even .sorting_1{

background:transparent;

}

</style>

<div class="test test-1" >

<table id="example" class="display mytable" style="width:99%;background: transparent;">

<thead>

<tr>

<th rowspan="2">Name</th>

<th colspan="3">Info</th>

<th colspan="2">Count</th>

</tr>

<tr>

<th>Position</th>

<th>Office</th>

<th>Age</th>

<th>Start date</th>

<th>Salary</th>

</tr>

</thead>

<tbody style="background: transparent;">

<tr>

<td style="background: transparent;">Tiger Nixon</td>

<td>System Architect</td>

<td>Edinburgh</td>

<td>61</td>

<td>2011/04/25</td>

<td>$320,800</td>

</tr>

<tr style="background: transparent;">

<td>Garrett Winters</td>

<td>Accountant</td>

<td>Tokyo</td>

<td>63</td>

<td>2011/07/25</td>

<td>$170,750</td>

</tr>

<tr>

<td>Ashton Cox</td>

<td>Junior Technical Author</td>

<td>San Francisco</td>

<td>66</td>

<td>2009/01/12</td>

<td>$86,000</td>

</tr>

<tr>

<td>Cedric Kelly</td>

<td>Senior Javascript Developer</td>

<td>Edinburgh</td>

<td>22</td>

<td>2012/03/29</td>

<td>$433,060</td>

</tr>

<tr>

<td>Airi Satou</td>

<td>Accountant</td>

<td>Tokyo</td>

<td>33</td>

<td>2008/11/28</td>

<td>$162,700</td>

</tr>

<tr>

<td>Brielle Williamson</td>

<td>Integration Specialist</td>

<td>New York</td>

<td>61</td>

<td>2012/12/02</td>

<td>$372,000</td>

</tr>

<tr>

<td>Herrod Chandler</td>

<td>Sales Assistant</td>

<td>San Francisco</td>

<td>59</td>

<td>2012/08/06</td>

<td>$137,500</td>

</tr>

<tr>

<td>Rhona Davidson</td>

<td>Integration Specialist</td>

<td>Tokyo</td>

<td>55</td>

<td>2010/10/14</td>

<td>$327,900</td>

</tr>

<tr>

<td>Colleen Hurst</td>

<td>Javascript Developer</td>

<td>San Francisco</td>

<td>39</td>

<td>2009/09/15</td>

<td>$205,500</td>

</tr>

<tr>

<td>Sonya Frost</td>

<td>Software Engineer</td>

<td>Edinburgh</td>

<td>23</td>

<td>2008/12/13</td>

<td>$103,600</td>

</tr>

<tr>

<td>Jena Gaines</td>

<td>Office Manager</td>

<td>London</td>

<td>30</td>

<td>2008/12/19</td>

<td>$90,560</td>

</tr>

<tr>

<td>Quinn Flynn</td>

<td>Support Lead</td>

<td>Edinburgh</td>

<td>22</td>

<td>2013/03/03</td>

<td>$342,000</td>

</tr>

<tr>

<td>Charde Marshall</td>

<td>Regional Director</td>

<td>San Francisco</td>

<td>36</td>

<td>2008/10/16</td>

<td>$470,600</td>

</tr>

<tr>

<td>Haley Kennedy</td>

<td>Senior Marketing Designer</td>

<td>London</td>

<td>43</td>

<td>2012/12/18</td>

<td>$313,500</td>

</tr>

<tr>

<td>Tatyana Fitzpatrick</td>

<td>Regional Director</td>

<td>London</td>

<td>19</td>

<td>2010/03/17</td>

<td>$385,750</td>

</tr>

<tr>

<td>Michael Silva</td>

<td>Marketing Designer</td>

<td>London</td>

<td>66</td>

<td>2012/11/27</td>

<td>$198,500</td>

</tr>

<tr>

<td>Paul Byrd</td>

<td>Chief Financial Officer (CFO)</td>

<td>New York</td>

<td>64</td>

<td>2010/06/09</td>

<td>$725,000</td>

</tr>

<tr>

<td>Gloria Little</td>

<td>Systems Administrator</td>

<td>New York</td>

<td>59</td>

<td>2009/04/10</td>

<td>$237,500</td>

</tr>

<tr>

<td>Bradley Greer</td>

<td>Software Engineer</td>

<td>London</td>

<td>41</td>

<td>2012/10/13</td>

<td>$132,000</td>

</tr>

<tr>

<td>Dai Rios</td>

<td>Personnel Lead</td>

<td>Edinburgh</td>

<td>35</td>

<td>2012/09/26</td>

<td>$217,500</td>

</tr>

<tr>

<td>Jenette Caldwell</td>

<td>Development Lead</td>

<td>New York</td>

<td>30</td>

<td>2011/09/03</td>

<td>$345,000</td>

</tr>

<tr>

<td>Yuri Berry</td>

<td>Chief Marketing Officer (CMO)</td>

<td>New York</td>

<td>40</td>

<td>2009/06/25</td>

<td>$675,000</td>

</tr>

<tr>

<td>Caesar Vance</td>

<td>Pre-Sales Support</td>

<td>New York</td>

<td>21</td>

<td>2011/12/12</td>

<td>$106,450</td>

</tr>

<tr>

<td>Doris Wilder</td>

<td>Sales Assistant</td>

<td>Sydney</td>

<td>23</td>

<td>2010/09/20</td>

<td>$85,600</td>

</tr>

<tr>

<td>Angelica Ramos</td>

<td>Chief Executive Officer (CEO)</td>

<td>London</td>

<td>47</td>

<td>2009/10/09</td>

<td>$1,200,000</td>

</tr>

<tr>

<td>Gavin Joyce</td>

<td>Developer</td>

<td>Edinburgh</td>

<td>42</td>

<td>2010/12/22</td>

<td>$92,575</td>

</tr>

<tr>

<td>Jennifer Chang</td>

<td>Regional Director</td>

<td>Singapore</td>

<td>28</td>

<td>2010/11/14</td>

<td>$357,650</td>

</tr>

<tr>

<td>Brenden Wagner</td>

<td>Software Engineer</td>

<td>San Francisco</td>

<td>28</td>

<td>2011/06/07</td>

<td>$206,850</td>

</tr>

<tr>

<td>Fiona Green</td>

<td>Chief Operating Officer (COO)</td>

<td>San Francisco</td>

<td>48</td>

<td>2010/03/11</td>

<td>$850,000</td>

</tr>

<tr>

<td>Shou Itou</td>

<td>Regional Marketing</td>

<td>Tokyo</td>

<td>20</td>

<td>2011/08/14</td>

<td>$163,000</td>

</tr>

<tr>

<td>Michelle House</td>

<td>Integration Specialist</td>

<td>Sydney</td>

<td>37</td>

<td>2011/06/02</td>

<td>$95,400</td>

</tr>

<tr>

<td>Suki Burks</td>

<td>Developer</td>

<td>London</td>

<td>53</td>

<td>2009/10/22</td>

<td>$114,500</td>

</tr>

<tr>

<td>Prescott Bartlett</td>

<td>Technical Author</td>

<td>London</td>

<td>27</td>

<td>2011/05/07</td>

<td>$145,000</td>

</tr>

<tr>

<td>Gavin Cortez</td>

<td>Team Leader</td>

<td>San Francisco</td>

<td>22</td>

<td>2008/10/26</td>

<td>$235,500</td>

</tr>

<tr>

<td>Martena Mccray</td>

<td>Post-Sales support</td>

<td>Edinburgh</td>

<td>46</td>

<td>2011/03/09</td>

<td>$324,050</td>

</tr>

<tr>

<td>Unity Butler</td>

<td>Marketing Designer</td>

<td>San Francisco</td>

<td>47</td>

<td>2009/12/09</td>

<td>$85,675</td>

</tr>

<tr>

<td>Howard Hatfield</td>

<td>Office Manager</td>

<td>San Francisco</td>

<td>51</td>

<td>2008/12/16</td>

<td>$164,500</td>

</tr>

<tr>

<td>Hope Fuentes</td>

<td>Secretary</td>

<td>San Francisco</td>

<td>41</td>

<td>2010/02/12</td>

<td>$109,850</td>

</tr>

<tr>

<td>Vivian Harrell</td>

<td>Financial Controller</td>

<td>San Francisco</td>

<td>62</td>

<td>2009/02/14</td>

<td>$452,500</td>

</tr>

<tr>

<td>Timothy Mooney</td>

<td>Office Manager</td>

<td>London</td>

<td>37</td>

<td>2008/12/11</td>

<td>$136,200</td>

</tr>

<tr>

<td>Jackson Bradshaw</td>

<td>Director</td>

<td>New York</td>

<td>65</td>

<td>2008/09/26</td>

<td>$645,750</td>

</tr>

<tr>

<td>Olivia Liang</td>

<td>Support Engineer</td>

<td>Singapore</td>

<td>64</td>

<td>2011/02/03</td>

<td>$234,500</td>

</tr>

<tr>

<td>Bruno Nash</td>

<td>Software Engineer</td>

<td>London</td>

<td>38</td>

<td>2011/05/03</td>

<td>$163,500</td>

</tr>

<tr>

<td>Sakura Yamamoto</td>

<td>Support Engineer</td>

<td>Tokyo</td>

<td>37</td>

<td>2009/08/19</td>

<td>$139,575</td>

</tr>

<tr>

<td>Thor Walton</td>

<td>Developer</td>

<td>New York</td>

<td>61</td>

<td>2013/08/11</td>

<td>$98,540</td>

</tr>

<tr>

<td>Finn Camacho</td>

<td>Support Engineer</td>

<td>San Francisco</td>

<td>47</td>

<td>2009/07/07</td>

<td>$87,500</td>

</tr>

<tr>

<td>Serge Baldwin</td>

<td>Data Coordinator</td>

<td>Singapore</td>

<td>64</td>

<td>2012/04/09</td>

<td>$138,575</td>

</tr>

<tr>

<td>Zenaida Frank</td>

<td>Software Engineer</td>

<td>New York</td>

<td>63</td>

<td>2010/01/04</td>

<td>$125,250</td>

</tr>

<tr>

<td>Zorita Serrano</td>

<td>Software Engineer</td>

<td>San Francisco</td>

<td>56</td>

<td>2012/06/01</td>

<td>$115,000</td>

</tr>

<tr>

<td>Jennifer Acosta</td>

<td>Junior Javascript Developer</td>

<td>Edinburgh</td>

<td>43</td>

<td>2013/02/01</td>

<td>$75,650</td>

</tr>

<tr>

<td>Cara Stevens</td>

<td>Sales Assistant</td>

<td>New York</td>

<td>46</td>

<td>2011/12/06</td>

<td>$145,600</td>

</tr>

<tr>

<td>Hermione Butler</td>

<td>Regional Director</td>

<td>London</td>

<td>47</td>

<td>2011/03/21</td>

<td>$356,250</td>

</tr>

<tr>

<td>Lael Greer</td>

<td>Systems Administrator</td>

<td>London</td>

<td>21</td>

<td>2009/02/27</td>

<td>$103,500</td>

</tr>

<tr>

<td>Jonas Alexander</td>

<td>Developer</td>

<td>San Francisco</td>

<td>30</td>

<td>2010/07/14</td>

<td>$86,500</td>

</tr>

<tr>

<td>Shad Decker</td>

<td>Regional Director</td>

<td>Edinburgh</td>

<td>51</td>

<td>2008/11/13</td>

<td>$183,000</td>

</tr>

<tr>

<td>Michael Bruce</td>

<td>Javascript Developer</td>

<td>Singapore</td>

<td>29</td>

<td>2011/06/27</td>

<td>$183,000</td>

</tr>

<tr>

<td>Donna Snider</td>

<td>Customer Support</td>

<td>New York</td>

<td>27</td>

<td>2011/01/25</td>

<td>$112,000</td>

</tr>

</tbody>

<tfoot>

<tr>

<th>Name</th>

<th>Position</th>

<th>Office</th>

<th>Age</th>

<th>Start date</th>

<th>Salary</th>

</tr>

</tfoot>

</table>

</div>`;

options.dom='rt<"bottom"iflp<"clear">>';

// options.buttons:['excel'];

options.test1=123;

console.log(options);

container.innerHTML=myhtml;

$(document).ready(function() {

$('#example').DataTable( options );

} );