preface

In this era of big data, data is king, and it is particularly important for the system to display all kinds of data in real time, so the dashboard becomes the standard configuration of every system.

background

We all know that most front-end frameworks offer a rich variety of dashboards, but there are a few things that don’t meet our needs

  1. It’s not easy to drag
  2. It is not convenient to add them dynamically
  3. Dashboards that are not compatible with multiple front-end frameworks
  4. It is not easy to unify the front-end framework
  5. Limitations more

Therefore, this time we use iframe with div to achieve a general dashboard framework.

The selection

Let’s first find a draggable div. The draggable event of H5 is not used here, and the main problem is not secondary encapsulation, such as dashboard size and sorting.

Preview the address

The above is most of the functional style of the renderer, and comes with a serialized JSON file, which also saves us too much code to modify.

Secondary reconstruction

Our general solution is to use serialization version, add iframe to div, control URL, add drag button, zoom button, add new button, save button.

increaseurlthesrcfield

Let’s transform the JSON file first

[{"x":0,"y":0,"width":3,"height":4,"src":"demo.html"},{"x":3,"y":0,"width":4,"height":4,"src":"client.html"}]
Copy the code

Transform div

this.load_grid = function() {
	this.grid.remove_all();
	var items = GridStackUI.Utils.sort(this.serialized_data);
	_.each(items, function(node, i) {
		this.grid.add_widget($('
      
+ node.src + '" width="100%" height="100%" marginwidth="0" marginheight="0" vspace="0" hspace="0" frameborder="0" allowtransparency="true" scrolling="no" allowfullscreen="true" > + i + '" class="delete">x</div></div><div/>'), node.x, node.y, node.width, node.height); }, this); }.bind(this); Copy the code

Insert

Save the logical

this.save_grid = function() {
		this.serialized_data = _.map($('.grid-stack > .grid-stack-item:visible'), function(el, i) {
			el = $(el);
			var node = el.data('_gridstack_node');
			var src = $(".mainIframe")[i].src;
          var host = window.location.host;
          if(src.indexOf(host)>0){
              src=src.substring(src.indexOf(host)+host.length , src.length);
			}
			return {
				x: node.x,
				y: node.y,
				width: node.width,
				height: node.height,
				src: src
			};
		}, this);
      $.ajax({
          type: "PUT",
          url: "dashboard",
			data:JSON.stringify({"v":JSON.stringify(this.serialized_data)}),
          dataType: "json",
          contentType: "application/json",
          success: function(data) {
              alert("Saved successfully");
          },
          error:function (data) {
              alert("Save failed");
          },
          complete:function(XMLHttpRequest,textStatus){
          }
      });

	}.bind(this);

Copy the code

Control the drag

$(document).on("mouseover".".grid-stack-item".function() {
					$(this).find(".drog").show();
				});
				$(document).on("mouseleave".".grid-stack-item".function() {
					$(this).find(".drog").hide();
				});

Copy the code

Redraw after changing the window

	window.onresize = function(obj) {
				$(".mainIframe").each(function(i) {
					try {
						$(".mainIframe")[i].contentWindow.resizeWorldMapContainer();
						$(".mainIframe")[i].contentWindow.myChart.resize();
					} catch(e) {}
				});
			}

Copy the code

delete

	$(document).on("click".".delete".function(el) {
						el = $(this).closest('.grid-stack-item');
						self.grid.remove_widget(el);
					});

Copy the code

Drag logic

If the drag-and-drop div is not hidden, the mouse event will be received in iframe, which will lead to drag-and-drop failure. Moreover, the performance loss caused by the page transformation and redrawing is great, so the code was invaded and the drag-and-drop logic was modified.

        var on_start_moving = function (event, ui) {
            var o = $(this);
            try{
                var controls=document.getElementsByName("iframe");
                for(var i=0; i<controls.length; i++) { controls[i].style.visibility="hidden";
                }
            } catch(err){}
            self.grid.clean_nodes();
            self.grid.begin_update(node);
            cell_width = Math.ceil(o.outerWidth() / o.attr('data-gs-width'));
            cell_height = self.opts.cell_height + self.opts.vertical_margin;
            self.placeholder
                .attr('data-gs-x', o.attr('data-gs-x'))
                .attr('data-gs-y', o.attr('data-gs-y'))
                .attr('data-gs-width', o.attr('data-gs-width'))
                .attr('data-gs-height', o.attr('data-gs-height'))
                .show();
            node.el = self.placeholder;

            el.resizable('option'.'minWidth', cell_width * (node.min_width || 1));
            el.resizable('option'.'minHeight', self.opts.cell_height * (node.min_height || 1));
        };
        
         var on_end_moving = function (event, ui) {
            var o = $(this);
            try{
                var controls=document.getElementsByName("ifame");
                for(var i=0; i<controls.length; i++) { controls[i].style.visibility="visible";
                }
            } catch(err){}

            node.el = o;
            self.placeholder.hide();
            o
                .attr('data-gs-x', node.x)
                .attr('data-gs-y', node.y)
                .attr('data-gs-width', node.width)
                .attr('data-gs-height', node.height)
                .removeAttr('style');
            self._update_container_height();
            self.container.trigger('change', [self.grid.get_dirty_nodes()]);

            self.grid.end_update();
        };
Copy the code

The main code

 var controls=document.getElementsByName("iframe");
 for(var i=0; i<controls.length; i++) { controls[i].style.visibility="hidden";
 }
  
var controls=document.getElementsByName("iframe");
for(var i=0; i<controls.length; i++) { controls[i].style.visibility="visible";
}              
                
Copy the code

CSS styles

.drog {
	width: 20px;
	height: 20px;
	position: absolute;
	top: 5px;
	left: 5px;
	display: none;
	cursor: pointer;
}

Copy the code

The iframe instrument

Finally, we need to prepare a few diagrams, which can be used by echarts or any other framework diagram.

Since each chart is independent in iframe, it does not interfere with each other, which allows us to integrate all the charts in the system into this dashboard.

conclusion

The dashboard design is a simple version of the idea, a lot of code has a better way to achieve, here only to provide a design idea, do not like spray.