Commit | Line | Data |
---|---|---|
58a18b02 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 Multiple Dygraphs palettes, grouped by global, series, etc.. | |
23 | * | |
24 | * @author konigsberg@google.com (Robert Konigsberg) | |
25 | */ | |
26 | ||
27 | function MultiPalette() { | |
28 | this.palettes = {}; | |
29 | this.root = null; | |
30 | this.filterBar = null; | |
31 | // This is meant to be overridden by a palette host. | |
32 | this.activePalette = null; | |
33 | this.onchange = function() {}; | |
34 | } | |
35 | ||
36 | ||
37 | MultiPalette.optionSetValues = { | |
38 | "global": "global", | |
39 | "x": "x axis", | |
40 | "y": "y axis", | |
41 | "y2": "y2 axis", | |
42 | }; | |
43 | ||
44 | MultiPalette.prototype.create = function(parentElement) { | |
45 | var self = this; | |
46 | ||
47 | this.root = $("<div>").addClass("palette").appendTo(parentElement); | |
48 | var header = $("<div>").addClass("header").appendTo(this.root); | |
49 | // Selector for series and axes. | |
50 | var selectorRow = $("<div>").appendTo(header); | |
51 | var optionSelector = $("<select>") | |
52 | .change(function(x) { | |
53 | self.activate(optionSelector.val()); | |
54 | }); | |
55 | ||
56 | selectorRow | |
57 | .append($("<span>").text("Option Set:")) | |
cd1d97d8 RK |
58 | .append(optionSelector) |
59 | .append($("<span>") | |
60 | .append($("<a>") | |
61 | .addClass("link") | |
62 | .text("to hash") | |
63 | .css("float", "right") | |
64 | .css("padding-right", "8px") | |
65 | .click(function() { self.showHash(); }))); | |
58a18b02 RK |
66 | |
67 | var filter = function() { | |
68 | $.each(self.palettes, function(key, value) { | |
69 | value.filter(self.filterBar.val()); | |
70 | }); | |
71 | } | |
72 | ||
73 | this.filterBar = $("<input>", { type : "search" }) | |
74 | .keyup(filter) | |
75 | .click(filter); | |
76 | ||
77 | header.append($("<div>") | |
78 | .append($("<span>").text("Filter:")) | |
79 | .append($("<span>").append(this.filterBar)) | |
80 | .append($("<span>") | |
81 | .append($("<a>") | |
58a18b02 RK |
82 | .addClass("link") |
83 | .text("Redraw") | |
84 | .css("float", "right") | |
85 | .css("padding-right", "8px") | |
86 | .click(function() { self.onchange(); })))); | |
87 | ||
88 | $.each(MultiPalette.optionSetValues, function(key, value) { | |
89 | $(optionSelector) | |
90 | .append($("<option></option>") | |
91 | .attr("value", key) | |
92 | .text(value)); | |
93 | var palette = new Palette(key); | |
94 | palette.create(self.root); | |
95 | palette.root.style.display = "none"; | |
96 | palette.onchange = function() { | |
97 | self.onchange(); | |
98 | }; | |
99 | self.palettes[key] = palette; | |
100 | }); | |
101 | ||
102 | this.activate("global"); | |
103 | } | |
104 | ||
105 | MultiPalette.prototype.activate = function(key) { | |
106 | if (this.activePalette) { | |
107 | this.activePalette.root.style.display = "none"; | |
108 | } | |
109 | this.activePalette = this.palettes[key]; | |
110 | this.activePalette.root.style.display = "block"; | |
111 | } | |
112 | ||
cd1d97d8 RK |
113 | MultiPalette.prototype.showHash = function() { |
114 | var hash = this.read(); | |
115 | var textarea = new TextArea(); | |
116 | textarea.cancel.style.display = "none"; | |
117 | ||
118 | /* | |
119 | * JSON.stringify isn't built to be nice to functions. The following fixes | |
120 | * this. | |
121 | * | |
122 | * First, val.toString only does part of the work, turning it into | |
123 | * "function () {\n alert(\"p-click!\");\n}", | |
124 | * | |
125 | * {start,end}Marker make the surrounding quotes easy to find, and then | |
126 | * remove them. It also converts the instances of \n and \" so the | |
127 | * result looks like: | |
128 | * function () { | |
129 | * alert("p-click!"); | |
130 | * }", | |
131 | */ | |
132 | var startMarker = "<~%!<"; | |
133 | var endMarker = ">!%~>"; | |
134 | var replacer = function(key, val) { | |
135 | if (typeof val === 'function') { | |
136 | return startMarker + val.toString() + endMarker; | |
137 | } | |
138 | return val; | |
139 | } | |
140 | var text = JSON.stringify(hash, replacer, 2); | |
141 | console.log(text); | |
142 | while(true) { | |
143 | var start = text.indexOf(startMarker); | |
144 | var end = text.indexOf(endMarker); | |
145 | if (start == -1) { | |
146 | break; | |
147 | } | |
148 | var substring = text.substring(start + startMarker.length, end); | |
149 | while(substring.indexOf("\\n") >= 0) { | |
150 | substring = substring.replace("\\n", "\n"); | |
151 | } | |
152 | while(substring.indexOf("\\\"") >= 0) { | |
153 | substring = substring.replace("\\\"", "\""); | |
154 | } | |
155 | text = text.substring(0, start - 1) | |
156 | + substring | |
157 | + text.substring(end + endMarker.length + 1); | |
158 | } | |
159 | textarea.show("options", text); | |
160 | } | |
161 | ||
58a18b02 RK |
162 | /** |
163 | * Read from palette | |
164 | */ | |
165 | MultiPalette.prototype.read = function() { | |
166 | var results = this.palettes.global.read(); | |
167 | results.axes = {}; | |
168 | var clearIfEmpty = function(hash, key) { | |
169 | var val = hash[key]; | |
170 | if ($.isEmptyObject(val)) { | |
171 | delete hash[key]; | |
172 | } | |
173 | } | |
174 | results.axes.x = this.palettes.x.read(); | |
175 | results.axes.y = this.palettes.y.read(); | |
176 | results.axes.y2 = this.palettes.y2.read(); | |
177 | clearIfEmpty(results.axes, "x"); | |
178 | clearIfEmpty(results.axes, "y"); | |
179 | clearIfEmpty(results.axes, "y2"); | |
180 | clearIfEmpty(results, "axes"); | |
181 | return results; | |
182 | } | |
183 | ||
184 | /** | |
185 | * Write to palette from hash. | |
186 | */ | |
187 | MultiPalette.prototype.write = function(hash) { | |
188 | this.palettes.global.write(hash); | |
189 | if (hash.hasOwnProperty("axes")) { | |
190 | var axes = hash.axes; | |
191 | this.palettes.x.write(axes["x"]); | |
192 | this.palettes.y.write(axes["y"]); | |
193 | this.palettes.y2.write(axes["y2"]); | |
194 | } | |
195 | } |