1 // Copyright (c) 2011 Google, Inc.
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:
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
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
22 * @fileoverview Multiple Dygraphs palettes, grouped by global, series, etc..
24 * @author konigsberg@google.com (Robert Konigsberg)
27 function MultiPalette() {
30 this.filterBar
= null;
31 // This is meant to be overridden by a palette host.
32 this.activePalette
= null;
33 this.onchange
= function() {};
36 MultiPalette
.optionSetValues
= {
43 MultiPalette
.prototype.create
= function(parentElement
) {
46 this.root
= $("<div>").addClass("palette").appendTo(parentElement
);
47 var header
= $("<div>").addClass("header").appendTo(this.root
);
48 // Selector for series and axes.
49 var selectorRow
= $("<div>").appendTo(header
);
50 this.optionSelector
= $("<select>")
52 self
.activate(self
.optionSelector
.val());
56 .append($("<span>").text("Option Set:"))
57 .append(this.optionSelector
)
62 .css("float", "right")
63 .css("padding-right", "8px")
64 .click(function() { self
.showHash(); })));
66 var filter
= function() {
67 $.each(self
.palettes
, function(key
, value
) {
68 value
.filter(self
.filterBar
.val());
72 this.filterBar
= $("<input>", { type
: "search" })
76 header
.append($("<div>")
77 .append($("<span>").text("Filter:"))
78 .append($("<span>").append(this.filterBar
))
83 .css("float", "right")
84 .css("padding-right", "8px")
85 .click(function() { self
.onchange(); }))));
87 $.each(MultiPalette
.optionSetValues
, function(key
, value
) {
88 self
.createPalette_(key
, key
, value
);
91 this.activate("global");
94 MultiPalette
.prototype.createPalette_
= function(key
, scope
, value
) {
96 .append($("<option></option>")
99 var palette
= new Palette(scope
);
100 palette
.create(this.root
);
103 palette
.onchange
= function() {
106 this.palettes
[key
] = palette
;
109 MultiPalette
.prototype.setSeries
= function(labels
) {
110 for (var idx
= 1; idx
< labels
.length
; idx
++) {
111 this.conditionallyAddSingleSeries_(labels
[idx
]);
115 MultiPalette
.prototype.conditionallyAddSingleSeries_
= function(series
) {
116 var key
= "series:" + series
;
117 if (!this.palettes
.hasOwnProperty(key
)) {
118 this.createPalette_(key
, "series", series
+ " (series)");
122 MultiPalette
.prototype.activate
= function(key
) {
123 if (this.activePalette
) {
124 this.activePalette
.root
.hide();
126 this.activePalette
= this.palettes
[key
];
127 this.activePalette
.root
.show();
130 MultiPalette
.prototype.showHash
= function() {
131 var hash
= this.read();
132 var textarea
= new TextArea();
134 var hashToString
= function(hash
) {
136 * JSON.stringify isn't built to be nice to functions. The following fixes
139 * First, val.toString only does part of the work, turning it into
140 * "function () {\n alert(\"p-click!\");\n}",
142 * {start,end}Marker make the surrounding quotes easy to find, and then
143 * remove them. It also converts the instances of \n and \" so the
149 var startMarker
= "<~%!<";
150 var endMarker
= ">!%~>";
151 var replacer
= function(key
, val
) {
152 if (typeof val
=== 'function') {
153 return startMarker
+ val
.toString() + endMarker
;
157 var text
= JSON
.stringify(hash
, replacer
, 2);
159 var start
= text
.indexOf(startMarker
);
160 var end
= text
.indexOf(endMarker
);
164 var substring
= text
.substring(start
+ startMarker
.length
, end
);
165 while(substring
.indexOf("\\n") >= 0) {
166 substring
= substring
.replace("\\n", "\n");
168 while(substring
.indexOf("\\\"") >= 0) {
169 substring
= substring
.replace("\\\"", "\"");
171 text
= text
.substring(0, start
- 1)
173 + text
.substring(end
+ endMarker
.length
+ 1);
178 var text
= hashToString(hash
);
180 textarea
.show("options", text
);
181 textarea
.okCallback
= function(value
) {
184 eval("newHash = " + value
+ ";");
194 MultiPalette
.prototype.read
= function() {
195 var results
= this.palettes
.global
.read();
198 var clearIfEmpty
= function(hash
, key
) {
200 if ($.isEmptyObject(val
)) {
204 var clearEmptyChildren
= function(hash
) {
205 for (var key
in hash
) {
206 if (hash
.hasOwnProperty(key
)) {
207 clearIfEmpty(hash
, key
);
212 results
.axes
.x
= this.palettes
.x
.read();
213 results
.axes
.y
= this.palettes
.y
.read();
214 results
.axes
.y2
= this.palettes
.y2
.read();
216 clearEmptyChildren(results
.axes
);
217 clearIfEmpty(results
, "axes");
219 for (var key
in this.palettes
) {
220 if (key
.indexOf("series:") == 0) {
221 var series
= key
.substring("series:".length
);
222 results
.series
[series
] = this.palettes
[key
].read();
226 clearEmptyChildren(results
.series
);
227 clearIfEmpty(results
, "series");
233 * Write to palette from hash.
235 MultiPalette
.prototype.write
= function(hash
) {
236 this.palettes
.global
.write(hash
);
237 if (hash
.hasOwnProperty("axes")) {
238 var axes
= hash
.axes
;
239 this.palettes
.x
.write(axes
["x"]);
240 this.palettes
.y
.write(axes
["y"]);
241 this.palettes
.y2
.write(axes
["y2"]);
244 if (hash
.hasOwnProperty("series")) {
245 for (var key
in hash
.series
) {
246 if (hash
.series
.hasOwnProperty(key
)) {
247 this.conditionallyAddSingleSeries_(key
);
248 this.palettes
["series:" + key
].write(hash
.series
[key
]);