Can run all tests in one fell swoop.
[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
34Palette.prototype.create = function(document, parentElement) {
35 var palette = this;
36 var createChild = function(type, parentElement) {
37 var element = document.createElement(type);
38 parentElement.appendChild(element);
39 return element;
40 };
41
42 var table = createChild("table", parentElement);
43 table.class = "palette";
44
45 var row = createChild("tr", table);
46 row.style.display = "block";
47
48 createChild("td", row).innerText = "Filter:";
49 this.filterBar = createChild("input", createChild("td", row));
50 this.filterBar.onkeyup = function() {
51 palette.filter(palette.filterBar.value)
52 };
53 var go = document.createElement("button");
54 createChild("td", row).appendChild(go);
55 go.innerText = "Redraw"
56 go.onclick = function() {
57 palette.onchange();
58 };
59
60 for (var opt in opts) {
61 try {
62 if (opts.hasOwnProperty(opt)) {
63 var type = opts[opt].type;
64 var isFunction = type.indexOf("function(") == 0;
65 var row = createChild("tr", table);
66 var div = createChild("div", createChild("td", row));
67 var a = createChild("a", div);
68 a.innerText = opt;
69 a.href = "http://dygraphs.com/options.html#" + opt;
70 a.title = Dygraph.OPTIONS_REFERENCE[opt].description;
71 a.target="_blank";
72
73 if (isFunction) {
74 var input = createChild("button", createChild("td", row));
75 input.onclick = function(opt, palette) {
76 return function(event) {
77 var entry = palette.model[opt];
78 var inputValue = entry.functionString;
79 if (inputValue == null || inputValue.length == 0) {
f3fe39ed 80 inputValue = opts[opt].type + "{ }";
20590000
RK
81 }
82 var value = prompt("enter function", inputValue);
83 if (value != null) {
84 if (value.length == 0) {
85 value = null;
86 }
87 if (value != inputValue) {
88 entry.functionString = value;
89 entry.input.innerText = value ? "defined" : "not defined";
90 palette.onchange();
91 }
92 }
93 }
94 }(opt, this);
95 } else {
96 var input = createChild("input", createChild("td", row));
97 input.onkeypress = function(event) {
98 var keycode = event.which;
99 if (keycode == 13 || keycode == 8) {
100 palette.onchange();
101 }
102 }
103
104 input.type="text";
105 }
106 this.model[opt] = { input: input, row: row };
107 }
108 } catch(err) {
109 throw "For option " + opt + ":" + err;
110 }
111 }
112 this.filter("");
113}
114
115// TODO: replace semicolon parsing with comma parsing, and supporting quotes.
116Palette.parseStringArray = function(value) {
117 if (value == null || value.length == 0) {
118 return null;
119 }
120 return value.split(";");
121}
122
123Palette.parseBooleanArray = function(value) {
124 if (value == null || value.length == 0) {
125 return null;
126 }
127 return value.split(',').map(function(x) { return x.trim() == "true"; });
128}
129
130Palette.parseFloatArray = function(value) {
131 if (value == null || value.length == 0) {
132 return null;
133 }
134 return value.split(',').map(function(x) { return parseFloat(x); });
135}
136
137Palette.parseIntArray = function(value) {
138 if (value == null || value.length == 0) {
139 return null;
140 }
141 return value.split(',').map(function(x) { return parseInt(x); });
142}
143
144Palette.prototype.read = function() {
145 var results = {};
146 for (var opt in this.model) {
147 if (this.model.hasOwnProperty(opt)) {
148 var type = opts[opt].type;
149 var isFunction = type.indexOf("function(") == 0;
150 var input = this.model[opt].input;
151 var value = isFunction ? this.model[opt].functionString : input.value;
152 if (value && value.length != 0) {
153 if (type == "boolean") {
154 results[opt] = value == "true";
155 } else if (type == "int") {
156 results[opt] = parseInt(value);
157 } else if (type == "float") {
158 results[opt] = parseFloat(value);
159 } else if (type == "array<string>") {
160 results[opt] = Palette.parseStringArray(value);
161 } else if (type == "array<float>") {
162 results[opt] = Palette.parseFloatArray(value);
163 } else if (type == "array<boolean>") {
164 results[opt] = Palette.parseBooleanArray(value);
165 } else if (type == "array<Date>") {
166 results[opt] = Palette.parseIntArray(value);
167 } else if (isFunction) {
168 var localVariable = null;
169 eval("localVariable = " + value);
170 results[opt] = localVariable;
171 } else {
172 results[opt] = value;
173 }
174 }
175 }
176 }
177 return results;
178}
179
180/**
181 * Write to input elements.
182 */
183Palette.prototype.write = function(hash) {
184 var results = {};
185 for (var opt in this.model) {
186 // && hash.hasOwnProperty(opt)
187 if (this.model.hasOwnProperty(opt)) {
188 var input = this.model[opt].input;
189 var type = opts[opt].type;
190 var value = hash[opt];
191 if (type == "array<string>") {
192 if (value) {
193 input.value = value.join("; ");
194 }
195 } else if (type.indexOf("array") == 0) {
196 if (value) {
197 input.value = value.join(", ");
198 }
199 } else if (type.indexOf("function(") == 0) {
200 input.innerText = value ? "defined" : "not defined";
201 this.model[opt].functionString = value ? value.toString() : null;
202 } else {
203 if (value) {
204 input.value = value;
205 }
206 }
207 }
208 }
209}
210
211Palette.prototype.filter = function(pattern) {
212 pattern = pattern.toLowerCase();
213 for (var opt in this.model) {
214 if (this.model.hasOwnProperty(opt)) {
215 var row = this.model[opt].row;
216 row.style.display = (opt.toLowerCase().indexOf(pattern) >= 0) ? "block" : "none";
217 }
218 }
219}