UNPKG

7.2 kBJavaScriptView Raw
1var util = require('vis-util');
2var DOMutil = require('../../DOMutil');
3var Component = require('./Component');
4
5/**
6 * Legend for Graph2d
7 *
8 * @param {vis.Graph2d.body} body
9 * @param {vis.Graph2d.options} options
10 * @param {number} side
11 * @param {vis.LineGraph.options} linegraphOptions
12 * @constructor Legend
13 * @extends Component
14 */
15function Legend(body, options, side, linegraphOptions) {
16 this.body = body;
17 this.defaultOptions = {
18 enabled: false,
19 icons: true,
20 iconSize: 20,
21 iconSpacing: 6,
22 left: {
23 visible: true,
24 position: 'top-left' // top/bottom - left,center,right
25 },
26 right: {
27 visible: true,
28 position: 'top-right' // top/bottom - left,center,right
29 }
30 };
31
32 this.side = side;
33 this.options = util.extend({}, this.defaultOptions);
34 this.linegraphOptions = linegraphOptions;
35
36 this.svgElements = {};
37 this.dom = {};
38 this.groups = {};
39 this.amountOfGroups = 0;
40 this._create();
41 this.framework = {svg: this.svg, svgElements: this.svgElements, options: this.options, groups: this.groups};
42
43 this.setOptions(options);
44}
45
46Legend.prototype = new Component();
47
48Legend.prototype.clear = function() {
49 this.groups = {};
50 this.amountOfGroups = 0;
51};
52
53Legend.prototype.addGroup = function(label, graphOptions) {
54
55 // Include a group only if the group option 'excludeFromLegend: false' is not set.
56 if (graphOptions.options.excludeFromLegend != true) {
57 if (!this.groups.hasOwnProperty(label)) {
58 this.groups[label] = graphOptions;
59 }
60 this.amountOfGroups += 1;
61 }
62};
63
64Legend.prototype.updateGroup = function(label, graphOptions) {
65 this.groups[label] = graphOptions;
66};
67
68Legend.prototype.removeGroup = function(label) {
69 if (this.groups.hasOwnProperty(label)) {
70 delete this.groups[label];
71 this.amountOfGroups -= 1;
72 }
73};
74
75Legend.prototype._create = function() {
76 this.dom.frame = document.createElement('div');
77 this.dom.frame.className = 'vis-legend';
78 this.dom.frame.style.position = "absolute";
79 this.dom.frame.style.top = "10px";
80 this.dom.frame.style.display = "block";
81
82 this.dom.textArea = document.createElement('div');
83 this.dom.textArea.className = 'vis-legend-text';
84 this.dom.textArea.style.position = "relative";
85 this.dom.textArea.style.top = "0px";
86
87 this.svg = document.createElementNS('http://www.w3.org/2000/svg',"svg");
88 this.svg.style.position = 'absolute';
89 this.svg.style.top = 0 +'px';
90 this.svg.style.width = this.options.iconSize + 5 + 'px';
91 this.svg.style.height = '100%';
92
93 this.dom.frame.appendChild(this.svg);
94 this.dom.frame.appendChild(this.dom.textArea);
95};
96
97/**
98 * Hide the component from the DOM
99 */
100Legend.prototype.hide = function() {
101 // remove the frame containing the items
102 if (this.dom.frame.parentNode) {
103 this.dom.frame.parentNode.removeChild(this.dom.frame);
104 }
105};
106
107/**
108 * Show the component in the DOM (when not already visible).
109 */
110Legend.prototype.show = function() {
111 // show frame containing the items
112 if (!this.dom.frame.parentNode) {
113 this.body.dom.center.appendChild(this.dom.frame);
114 }
115};
116
117Legend.prototype.setOptions = function(options) {
118 var fields = ['enabled','orientation','icons','left','right'];
119 util.selectiveDeepExtend(fields, this.options, options);
120};
121
122Legend.prototype.redraw = function() {
123 var activeGroups = 0;
124 var groupArray = Object.keys(this.groups);
125 groupArray.sort(function (a,b) {
126 return (a < b ? -1 : 1);
127 })
128
129 for (var i = 0; i < groupArray.length; i++) {
130 var groupId = groupArray[i];
131 if (this.groups[groupId].visible == true && (this.linegraphOptions.visibility[groupId] === undefined || this.linegraphOptions.visibility[groupId] == true)) {
132 activeGroups++;
133 }
134 }
135
136 if (this.options[this.side].visible == false || this.amountOfGroups == 0 || this.options.enabled == false || activeGroups == 0) {
137 this.hide();
138 }
139 else {
140 this.show();
141 if (this.options[this.side].position == 'top-left' || this.options[this.side].position == 'bottom-left') {
142 this.dom.frame.style.left = '4px';
143 this.dom.frame.style.textAlign = "left";
144 this.dom.textArea.style.textAlign = "left";
145 this.dom.textArea.style.left = (this.options.iconSize + 15) + 'px';
146 this.dom.textArea.style.right = '';
147 this.svg.style.left = 0 +'px';
148 this.svg.style.right = '';
149 }
150 else {
151 this.dom.frame.style.right = '4px';
152 this.dom.frame.style.textAlign = "right";
153 this.dom.textArea.style.textAlign = "right";
154 this.dom.textArea.style.right = (this.options.iconSize + 15) + 'px';
155 this.dom.textArea.style.left = '';
156 this.svg.style.right = 0 +'px';
157 this.svg.style.left = '';
158 }
159
160 if (this.options[this.side].position == 'top-left' || this.options[this.side].position == 'top-right') {
161 this.dom.frame.style.top = 4 - Number(this.body.dom.center.style.top.replace("px","")) + 'px';
162 this.dom.frame.style.bottom = '';
163 }
164 else {
165 var scrollableHeight = this.body.domProps.center.height - this.body.domProps.centerContainer.height;
166 this.dom.frame.style.bottom = 4 + scrollableHeight + Number(this.body.dom.center.style.top.replace("px","")) + 'px';
167 this.dom.frame.style.top = '';
168 }
169
170 if (this.options.icons == false) {
171 this.dom.frame.style.width = this.dom.textArea.offsetWidth + 10 + 'px';
172 this.dom.textArea.style.right = '';
173 this.dom.textArea.style.left = '';
174 this.svg.style.width = '0px';
175 }
176 else {
177 this.dom.frame.style.width = this.options.iconSize + 15 + this.dom.textArea.offsetWidth + 10 + 'px'
178 this.drawLegendIcons();
179 }
180
181 var content = '';
182 for (i = 0; i < groupArray.length; i++) {
183 groupId = groupArray[i];
184 if (this.groups[groupId].visible == true && (this.linegraphOptions.visibility[groupId] === undefined || this.linegraphOptions.visibility[groupId] == true)) {
185 content += this.groups[groupId].content + '<br />';
186 }
187 }
188 this.dom.textArea.innerHTML = content;
189 this.dom.textArea.style.lineHeight = ((0.75 * this.options.iconSize) + this.options.iconSpacing) + 'px';
190 }
191};
192
193Legend.prototype.drawLegendIcons = function() {
194 if (this.dom.frame.parentNode) {
195 var groupArray = Object.keys(this.groups);
196 groupArray.sort(function (a,b) {
197 return (a < b ? -1 : 1);
198 });
199
200 // this resets the elements so the order is maintained
201 DOMutil.resetElements(this.svgElements);
202
203 var padding = window.getComputedStyle(this.dom.frame).paddingTop;
204 var iconOffset = Number(padding.replace('px',''));
205 var x = iconOffset;
206 var iconWidth = this.options.iconSize;
207 var iconHeight = 0.75 * this.options.iconSize;
208 var y = iconOffset + 0.5 * iconHeight + 3;
209
210 this.svg.style.width = iconWidth + 5 + iconOffset + 'px';
211
212 for (var i = 0; i < groupArray.length; i++) {
213 var groupId = groupArray[i];
214 if (this.groups[groupId].visible == true && (this.linegraphOptions.visibility[groupId] === undefined || this.linegraphOptions.visibility[groupId] == true)) {
215 this.groups[groupId].getLegend(iconWidth, iconHeight, this.framework, x, y);
216 y += iconHeight + this.options.iconSpacing;
217 }
218 }
219 }
220};
221
222module.exports = Legend;