Packery+ngDraggable+Grafana+iframe 实现自定义可视化数据展示

前段时间做的项目,整理一下,大致的功能就是系统需要呈现很多监控图,这些图我们想让用户来自定义数量,大小以及怎么摆放。用户把我们准备好的动态概览图的缩略图拖拽到画布上,并且在画布上任意摆放,摆放完毕后,我们就能给用户呈现自定义的动态概览图了。

原理就是:通过ngDraggable来实现组件拖拽,Packery来实现页面布局,通过iframe嵌套Grafana来实现展示,从而实现用户的个性化需求。

出发点就是摒弃传统图表的排版格式,让用户可以自定义图表的大小和位置,用户可以自定义多套概览模式。

先介绍下用到的各项技术:

Packery:  JavaScript布局的一个装箱算法库。Packery布局可以智能排序,元素可以拖动到适合一个理想的地点,很容易创建不同类型的动态网格布局.使用之前需要下载相关类库文件,下载地址:https://download.csdn.net/download/qq_34527715/10320870,也可以去官网下载,官网:https://packery.metafizzy.co/。

另附一个packery的小程序:http://wow.techbrood.com/fiddle/35696

ngDraggable:可以实现元素的拖动,在菜鸟发现一个小例子:http://www.runoob.com/try/try.php?filename=jqueryui-example-droppable-photo-manager。同样使用需要引入相关JS文件,也需要在代码中加入ngDraggable模块。

Grafana:只要用到了仪表盘展示功能,grafana可以提供一个链接,在HTML中用iframe嵌入便可访问。如下:

<iframe src="仪表盘链接地址" frameborder="0" scrolling="no"></iframe>

下面介绍具体代码:

1.拖拽模块

 <li ng-drag="true" class="samplechart"  ng-drag-data="chart" ng-repeat="chart in charts">
            <div class="dashboard-corner-label" ng-click="delDashboardRes($index)"><i class="fa fa-trash"></i></div>
            <img ng-src="{{ picUrl + chart.demoPicture}}"
                 class="checkboximg ui-draggable" style="position: relative;">
        </li>
<div id="canvas" class="grid" ng-drop="true" ng-drop-success="dropComplete($index,$data,$event)">
        <div class="grid-item" ng-repeat="item in viewLists" title="双击删除图片"
             style="position: absolute; height:{{item.style.height}};width:{{item.style.width}};
         left:{{item.style.left}};top:{{item.style.top}};" id="{{item.url}}">
            <img ng-src="{{item.style.src}}" style="width: 100%; height: 100%;">
        </div>
    </div>
 $scope.dropComplete = function (index, obj) {

           .....
        };

可拖动元素,ng-drag="true" ng-drag-data。 可放置元素:ng-daop="true",放置后出发方法dropComplete.

2.Packery的使用:

首先初始化packery模块:

$scope.grid = document.querySelector('.grid');
        $scope.pckry = new Packery('.grid', {
            itemSelector: '.grid-item',
            gutter: 7,
            columnWidth: 7
        });

上面这段代码意思是,凡是在.grid内,class为grid-item的元素,都会添加packery属性。然后我们在元素拖拽完成后,给后来添加的元素赋上packery属性:

function getItemElement(obj) {
            var itemElem = document.createElement('div');
            var img = new Image();
            img.src = $scope.picUrl + obj.demoPicture;
            img.style.width = "100%";
            img.style.height = "100%";
            itemElem.append(img);
            itemElem.id = obj.url;
            itemElem.title = "双击删除图片";
            itemElem.className = 'grid-item ';
            itemElem.style.width = obj.width + "%";
            itemElem.style.height = obj.height + "%";
            return itemElem;
        }

function makeItemDraggable(itemElem) {
            var draggie = new Draggabilly(itemElem);
            $scope.pckry.bindDraggabillyEvents(draggie);
        }

$scope.dropComplete = function (index, obj) {
            $scope.grid = document.querySelector('.grid');
            var itemElems = [
                getItemElement(obj);//这个方法是给图片添加样式和对应的grafanaURL 
            ];
            // append to grid via document fragment
            var fragment = document.createDocumentFragment();
            itemElems.forEach(function (itemElem) {
                fragment.appendChild(itemElem)
            });
            $scope.grid.appendChild(fragment);
            // add to packery & make draggable
            $scope.pckry.appended(itemElems);
            itemElems.forEach(makeItemDraggable);
        };

3.最后我们通过iframe来嵌套grafana.把动态图展现出来:

<iframe width="100%" height="100%" src="{{item.url | trustAsResourceUrl}}" frameborder="0" scrolling="no"></iframe>

4.还有些图grafana做的不是很完美,我们可以借助hignCharts或者eCharts来画。


猜你喜欢

转载自blog.csdn.net/qq_34527715/article/details/79776937
今日推荐