Skip to content
This repository was archived by the owner on Mar 4, 2022. It is now read-only.

Commit f028ed8

Browse files
committed
Support layouts in layouts
Create a Panel class to handle all layout Move view creation into its own file Dynamically convert all configs into panels
1 parent fd3b84b commit f028ed8

File tree

6 files changed

+467
-386
lines changed

6 files changed

+467
-386
lines changed

lib/dashboard.js

Lines changed: 17 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
var _ = require("lodash");
44
var blessed = require("blessed");
5-
65
var HelpView = require("./views/help");
76
var generateLayouts = require("./generate-layouts");
87
var LogProvider = require("./providers/log-provider");
@@ -14,8 +13,7 @@ var THROTTLE_TIMEOUT = 150;
1413

1514
var Dashboard = function Dashboard(options) {
1615
this.options = options || {};
17-
this.views = {};
18-
this.settings = options.settings;
16+
this.settings = this.options.settings;
1917

2018
this.screen = blessed.screen({
2119
smartCSR: true,
@@ -32,21 +30,19 @@ var Dashboard = function Dashboard(options) {
3230

3331
Dashboard.prototype._createViews = function () {
3432
this.layouts = generateLayouts(this.options.layoutsFile);
35-
this.views = [];
3633

3734
// container prevents stream view scrolling from interfering with side views
3835
this.container = blessed.box();
3936
this.screen.append(this.container);
40-
41-
this.helpView = new HelpView({
42-
parent: this.container
43-
});
44-
45-
this.gotoTimeView = new GotoTimeView({
46-
metricsProvider: this.metricsProvider,
37+
this.viewOptions = {
38+
screen: this.screen,
4739
parent: this.container,
48-
screen: this.screen
49-
});
40+
logProvider: this.logProvider,
41+
metricsProvider: this.metricsProvider
42+
};
43+
44+
this.helpView = new HelpView(this.viewOptions);
45+
this.gotoTimeView = new GotoTimeView(this.viewOptions);
5046

5147
this._showLayout(0);
5248
};
@@ -126,31 +122,15 @@ Dashboard.prototype._showLayout = function (id) {
126122
if (this.currentLayout === id) {
127123
return;
128124
}
129-
_.each(this.views, function (view) {
130-
view.destroy();
131-
});
132125

133-
this.views = [];
134-
135-
_.each(this.layouts[id], function (layoutConfig) {
136-
var View = views.getConstructor(layoutConfig.view);
137-
138-
if (View) {
139-
if (this.settings[layoutConfig.view.type]) {
140-
layoutConfig = _.merge(layoutConfig, {
141-
view: this.settings[layoutConfig.view.type]
142-
});
143-
}
144-
var view = new View({
145-
parent: this.container,
146-
logProvider: this.logProvider,
147-
metricsProvider: this.metricsProvider,
148-
layoutConfig: layoutConfig
149-
});
150-
151-
this.views.push(view);
152-
}
153-
}.bind(this));
126+
// Remove current layout
127+
if (this.panel) {
128+
this.panel.destroy();
129+
delete this.panel;
130+
}
131+
132+
// create new layout
133+
this.panel = views.create(this.layouts[id], this.viewOptions, this.settings);
154134

155135
this.currentLayout = id;
156136
this.helpView.node.setFront();

lib/generate-layouts.js

Lines changed: 10 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,112 +1,11 @@
11
"use strict";
2+
23
var _ = require("lodash");
34
var assert = require("assert");
45
var path = require("path");
56
var defaultLayoutConfig = require("./default-layout-config");
67
var validate = require("jsonschema").validate;
78
var layoutConfigSchema = require("./layout-config-schema.json");
8-
/* eslint-disable no-magic-numbers */
9-
10-
// Each layout consists of vertical panels, that contains its position and horizontal views.
11-
// Flex-like positions of panels and views defined by 'grow' and 'size' parameters.
12-
// View or panel with 'size' has exactly <size> height or width respectively.
13-
// View or panel with 'grow' fills <grow> part of the residuary space (it works like flex-grow).
14-
// By default, position = { grow: 1 }
15-
16-
var normalizePosition = function (position) {
17-
if (!_.has(position, "grow") && !_.has(position, "size")) {
18-
position = { grow: 1 };
19-
}
20-
21-
return position;
22-
};
23-
24-
var concatPosition = function (position1, position2) {
25-
position1 = normalizePosition(position1);
26-
position2 = normalizePosition(position2);
27-
28-
return {
29-
grow: (position1.grow || 0) + (position2.grow || 0),
30-
size: (position1.size || 0) + (position2.size || 0)
31-
};
32-
};
33-
34-
var getSummaryPosition = function (items) {
35-
return items.map(function (item) { return item.position; })
36-
.reduce(concatPosition, { grow: 0, size: 0 });
37-
};
38-
39-
var getSize = function (parentSize, itemPosition) {
40-
var position = normalizePosition(itemPosition.position);
41-
if (_.has(position, "size")) {
42-
return position.size;
43-
}
44-
45-
// Prevent last growing view from overflowing screen
46-
var round = itemPosition.offset.grow + position.grow === itemPosition.summary.grow ?
47-
Math.floor : Math.ceil;
48-
49-
return round(
50-
(parentSize - itemPosition.summary.size) * position.grow / itemPosition.summary.grow
51-
);
52-
};
53-
54-
var getOffset = function (parentSize, itemPosition) {
55-
return itemPosition.summary.grow ? Math.ceil(
56-
itemPosition.offset.size +
57-
(parentSize - itemPosition.summary.size) * itemPosition.offset.grow / itemPosition.summary.grow
58-
) : 0;
59-
};
60-
61-
var createViewLayout = function (view, viewPosition, panelPosition) {
62-
return {
63-
view: view,
64-
getPosition: function (parent) {
65-
return {
66-
width: getSize(parent.width, panelPosition),
67-
height: getSize(parent.height, viewPosition),
68-
left: getOffset(parent.width, panelPosition),
69-
top: getOffset(parent.height, viewPosition)
70-
};
71-
}
72-
};
73-
};
74-
75-
var createPanelLayout = function (panelPosition, views) {
76-
var viewSummaryPosition = getSummaryPosition(views);
77-
var offsetPosition = { size: 0, grow: 0 };
78-
79-
return views.map(function (view) {
80-
var viewPosition = {
81-
summary: viewSummaryPosition,
82-
offset: offsetPosition,
83-
position: view.position
84-
};
85-
86-
offsetPosition = concatPosition(view.position, offsetPosition);
87-
88-
return createViewLayout(view, viewPosition, panelPosition);
89-
});
90-
};
91-
92-
var createLayout = function (panelsConfig) {
93-
var panelSummaryPosition = getSummaryPosition(panelsConfig);
94-
var offsetPosition = { size: 0, grow: 0 };
95-
96-
return panelsConfig.reduce(function (layouts, panelConfig) {
97-
var panelPosition = {
98-
summary: panelSummaryPosition,
99-
offset: offsetPosition,
100-
position: panelConfig.position
101-
};
102-
103-
var viewLayouts = createPanelLayout(panelPosition, panelConfig.views);
104-
105-
offsetPosition = concatPosition(panelConfig.position, offsetPosition);
106-
107-
return layouts.concat(viewLayouts);
108-
}, []);
109-
};
1109

11110
module.exports = function generateLayouts(layoutsFile) {
11211
var layoutConfig = defaultLayoutConfig;
@@ -125,5 +24,13 @@ module.exports = function generateLayouts(layoutsFile) {
12524
);
12625
}
12726

128-
return layoutConfig.map(createLayout);
27+
return layoutConfig.map(function (layouts) {
28+
return {
29+
view: {
30+
type: "panel",
31+
views: layouts.map(function (config) { return _.merge(config, { type: "panel" }); })
32+
},
33+
getPosition: _.identity
34+
};
35+
});
12936
};

lib/views/index.js

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,34 @@
11
"use strict";
22

3+
var _ = require("lodash");
34
var StreamView = require("./stream-view");
45
var EventLoopView = require("./eventloop-view");
56
var MemoryGaugeView = require("./memory-gauge-view");
67
var MemoryGraphView = require("./memory-graph-view");
78
var CpuView = require("./cpu-view");
89
var BaseView = require("./base-view");
10+
var Panel = require("./panel");
911

1012
var VIEW_MAP = {
1113
log: StreamView,
1214
cpu: CpuView,
1315
memory: MemoryGaugeView,
1416
memoryGraph: MemoryGraphView,
15-
eventLoop: EventLoopView
17+
eventLoop: EventLoopView,
18+
panel: Panel
19+
};
20+
21+
// Customize view types based on a settings class
22+
var applyCustomizations = function (customizations, layoutConfig) {
23+
var customization = customizations[layoutConfig.view.type];
24+
if (!customization) {
25+
return layoutConfig;
26+
}
27+
return _.merge(layoutConfig, { view: customization });
1628
};
1729

1830
var getConstructor = function (options) {
31+
options = options || {};
1932
if (VIEW_MAP[options.type]) {
2033
return VIEW_MAP[options.type];
2134
} else if (options.module) {
@@ -25,6 +38,23 @@ var getConstructor = function (options) {
2538
return null;
2639
};
2740

28-
module.exports = {
29-
getConstructor: getConstructor
41+
/**
42+
* Creates a view
43+
*
44+
* @param {Object} layoutConfig raw layout { type, views, position }
45+
* @param {Object} options startup options for views
46+
* @param {Object} customizations view type customiztaions
47+
*
48+
* @returns {Object} created view oject
49+
*/
50+
module.exports.create = function create(layoutConfig, options, customizations) {
51+
var customized = applyCustomizations(customizations, layoutConfig);
52+
var viewOptions = Object.assign({}, options, {
53+
layoutConfig: customized,
54+
creator: function (layout) {
55+
return create(layout, options, customizations);
56+
}
57+
});
58+
var View = getConstructor(customized.view);
59+
return View ? new View(viewOptions) : null;
3060
};

0 commit comments

Comments
 (0)