Hiding "copy".
[dygraphs.git] / experimental / palette / palette.js
CommitLineData
20590000
RK
1// Copyright (c) 2011 Google, Inc.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19// THE SOFTWARE.
20
21/**
22 * @fileoverview Dygraphs options palette.
23 *
24 * @author konigsberg@google.com (Robert Konigsberg)
25 */
26"use strict";
27
28function Palette() {
29 this.model = {};
30 this.onchange = function() {};
31 this.filterBar = null;
32}
33
59a80f4a
RK
34Palette.createChild = function(type, parentElement) {
35 var element = document.createElement(type);
36 parentElement.appendChild(element);
37 return element;
38};
39
20590000
RK
40Palette.prototype.create = function(document, parentElement) {
41 var palette = this;
20590000 42
59a80f4a
RK
43 var table = Palette.createChild("div", parentElement);
44 table.className = "palette";
45 table.width="300px";
20590000 46
59a80f4a 47 this.tooltip = new Tooltip();
20590000 48
59a80f4a
RK
49 var row = Palette.createChild("div", table);
50 row.style.visibility = "visible";
51 row.className = "header";
52
53 Palette.createChild("span", row).innerText = "Filter:";
54 this.filterBar = Palette.createChild("input", Palette.createChild("span", row));
2d9dee16 55 this.filterBar.type = "search";
20590000
RK
56 this.filterBar.onkeyup = function() {
57 palette.filter(palette.filterBar.value)
58 };
2d9dee16 59 this.filterBar.onclick = this.filterBar.onkeyup;
d95dc014 60 var go = Palette.createChild("button", Palette.createChild("span", row));
20590000
RK
61 go.innerText = "Redraw"
62 go.onclick = function() {
63 palette.onchange();
64 };
65
ce50b6e8 66 // CURRENTLY HIDDEN.
d95dc014
RK
67 var tmp = Palette.createChild("button", Palette.createChild("span", row));
68 tmp.innerText = "Copy"
69 tmp.onclick = function() {
70 var textarea = new TextArea();
ce50b6e8 71 textarea.show("header", "Now is the time for all good men\nto come to the aid of their country");
d95dc014 72 };
ce50b6e8 73 tmp.style.display = "none";
d95dc014 74
20590000
RK
75 for (var opt in opts) {
76 try {
77 if (opts.hasOwnProperty(opt)) {
78 var type = opts[opt].type;
79 var isFunction = type.indexOf("function(") == 0;
59a80f4a
RK
80 var row = Palette.createChild("div", table);
81 row.onmouseover = function(source, title, type, body, e) {
82 return function(e) {
83 palette.tooltip.show(source, e, title, type, body);
84 };
85 } (row, opt, type, Dygraph.OPTIONS_REFERENCE[opt].description);
86 row.onmouseout = function() { palette.tooltip.hide(); };
87
88 var div = Palette.createChild("span", row);
89 div.innerText = opt;
90 div.className = "name";
91
92 var value = Palette.createChild("span", row);
93 value.className = "option";
20590000
RK
94
95 if (isFunction) {
59a80f4a 96 var input = Palette.createChild("button", value);
20590000
RK
97 input.onclick = function(opt, palette) {
98 return function(event) {
99 var entry = palette.model[opt];
100 var inputValue = entry.functionString;
101 if (inputValue == null || inputValue.length == 0) {
d95dc014 102 inputValue = opts[opt].type + "{\n\n}";
20590000 103 }
d95dc014 104 var textarea = new TextArea();
3faa59c9 105 textarea.show("Function for " + opt, inputValue);
d95dc014 106 textarea.okCallback = function(value) {
20590000
RK
107 if (value != inputValue) {
108 entry.functionString = value;
109 entry.input.innerText = value ? "defined" : "not defined";
110 palette.onchange();
111 }
112 }
113 }
114 }(opt, this);
115 } else {
59a80f4a 116 var input = Palette.createChild("input", value);
20590000
RK
117 input.onkeypress = function(event) {
118 var keycode = event.which;
119 if (keycode == 13 || keycode == 8) {
120 palette.onchange();
121 }
122 }
123
124 input.type="text";
125 }
126 this.model[opt] = { input: input, row: row };
127 }
128 } catch(err) {
129 throw "For option " + opt + ":" + err;
130 }
131 }
132 this.filter("");
133}
134
135// TODO: replace semicolon parsing with comma parsing, and supporting quotes.
136Palette.parseStringArray = function(value) {
137 if (value == null || value.length == 0) {
138 return null;
139 }
140 return value.split(";");
141}
142
143Palette.parseBooleanArray = function(value) {
144 if (value == null || value.length == 0) {
145 return null;
146 }
147 return value.split(',').map(function(x) { return x.trim() == "true"; });
148}
149
150Palette.parseFloatArray = function(value) {
151 if (value == null || value.length == 0) {
152 return null;
153 }
154 return value.split(',').map(function(x) { return parseFloat(x); });
155}
156
157Palette.parseIntArray = function(value) {
158 if (value == null || value.length == 0) {
159 return null;
160 }
161 return value.split(',').map(function(x) { return parseInt(x); });
162}
163
164Palette.prototype.read = function() {
165 var results = {};
166 for (var opt in this.model) {
167 if (this.model.hasOwnProperty(opt)) {
168 var type = opts[opt].type;
169 var isFunction = type.indexOf("function(") == 0;
170 var input = this.model[opt].input;
171 var value = isFunction ? this.model[opt].functionString : input.value;
172 if (value && value.length != 0) {
173 if (type == "boolean") {
174 results[opt] = value == "true";
175 } else if (type == "int") {
176 results[opt] = parseInt(value);
177 } else if (type == "float") {
178 results[opt] = parseFloat(value);
179 } else if (type == "array<string>") {
180 results[opt] = Palette.parseStringArray(value);
181 } else if (type == "array<float>") {
182 results[opt] = Palette.parseFloatArray(value);
183 } else if (type == "array<boolean>") {
184 results[opt] = Palette.parseBooleanArray(value);
185 } else if (type == "array<Date>") {
186 results[opt] = Palette.parseIntArray(value);
187 } else if (isFunction) {
188 var localVariable = null;
189 eval("localVariable = " + value);
190 results[opt] = localVariable;
191 } else {
192 results[opt] = value;
193 }
194 }
195 }
196 }
197 return results;
198}
199
200/**
201 * Write to input elements.
202 */
203Palette.prototype.write = function(hash) {
204 var results = {};
205 for (var opt in this.model) {
206 // && hash.hasOwnProperty(opt)
207 if (this.model.hasOwnProperty(opt)) {
208 var input = this.model[opt].input;
209 var type = opts[opt].type;
210 var value = hash[opt];
211 if (type == "array<string>") {
212 if (value) {
213 input.value = value.join("; ");
214 }
215 } else if (type.indexOf("array") == 0) {
216 if (value) {
217 input.value = value.join(", ");
218 }
219 } else if (type.indexOf("function(") == 0) {
220 input.innerText = value ? "defined" : "not defined";
221 this.model[opt].functionString = value ? value.toString() : null;
222 } else {
223 if (value) {
224 input.value = value;
225 }
226 }
227 }
228 }
229}
230
231Palette.prototype.filter = function(pattern) {
232 pattern = pattern.toLowerCase();
59a80f4a 233 var even = true;
20590000
RK
234 for (var opt in this.model) {
235 if (this.model.hasOwnProperty(opt)) {
236 var row = this.model[opt].row;
59a80f4a
RK
237 var matches = opt.toLowerCase().indexOf(pattern) >= 0;
238 row.style.display = matches ? "block" : "none";
239 if (matches) {
240 row.className = even ? "even" : "odd";
241 even = !even;
242 }
20590000
RK
243 }
244 }
245}