1 // ==========================================================================
  2 // Papercube.PaperGraphView
  3 //
  4 // License:  PaperCube is open source software released under 
  5 //           the MIT License (see license.js)
  6 // ==========================================================================
  7 
  8 require('core');
  9 require('controllers/canvas');
 10 require('controllers/papergraph');
 11 
 12 /** @class
 13 
 14   This is the paper graph view. It will show all the refs/citations for a paper
 15   and also show all references/citations for it. Strong relationships will be shown
 16   with thicker and darker lines. This view uses SVG.
 17 
 18   @extends NodeGraph.NodeGraphView
 19   @author Peter Bergstrom
 20   @version 1.0
 21   @copyright 2008-2009 Peter Bergström.
 22 */
 23 
 24 Papercube.PaperGraphView = NodeGraph.NodeGraphView.extend(
 25 /** @scope Papercube.PaperGraphView.prototype */ {
 26 
 27   /**
 28     The delegate is the paperGraphController
 29   */
 30   delegate: Papercube.paperGraphController,
 31 
 32   /**
 33     Bind the display properties from the canvasController.
 34 
 35     @property {Array}
 36     @binding "Papercube.canvasController.displayProperties"
 37   */
 38   displayPropertiesBinding: "Papercube.canvasController.displayProperties",
 39 
 40   /**
 41     Bind the depth. Don't show items beyond this depth.
 42   
 43     @property {Integer}
 44     @binding "Papercube.paperGraphController.depth"
 45   */
 46   depthBinding: "Papercube.paperGraphController.depth",
 47   
 48   /**
 49     Bind the ref threshold binding. Don't show papers with less refs. 
 50 
 51     @property {Integer}
 52     @binding "Papercube.paperGraphController.refThreshold"
 53   */
 54   linkThresholdBinding: "Papercube.paperGraphController.refThreshold",
 55 
 56   /**
 57     Bind the cite threshold binding. Don't show papers with less cites. 
 58   
 59     @property {Integer}
 60     @binding "Papercube.paperGraphController.citeThreshold"
 61   */
 62   citeThresholdBinding: "Papercube.paperGraphController.citeThreshold",
 63 
 64   /**
 65     Bind the view direction from the viewController.
 66 
 67     @property {String}
 68     @binding "Papercube.viewController.viewDirection"
 69   */
 70   viewDirectionBinding: "Papercube.viewController.viewDirection",
 71 
 72   /**
 73     Cite threshold cached value.  
 74     
 75     @property {Integer}
 76     @default 1
 77   */
 78   _cached_citeThreshold: 1,
 79 
 80   /**
 81     The name of the view. 
 82     
 83     'papergraph'
 84 
 85     @property {String}
 86   */
 87   viewName: 'papergraph',
 88   
 89   /**
 90     The type of content being displayed.
 91     
 92     'Paper'
 93 
 94     @property {String}
 95   */
 96   contentTypeViewing: 'Paper',
 97 
 98   // Cached view direction.
 99   _cached_viewDirection: null,
100 
101   /** 
102     The key for the default title display.
103 
104     'title'
105 
106     @property {String}
107   */
108   defaultTitleKey: 'title',
109 
110   /**
111     The nodeTextRatio allows the font size for the node to the calculated. The font size is calculated as radius/nodeTextRatio.
112 
113     @property {Integer}
114     @default is 3
115   */
116   nodeTextRatio: 3,
117 
118   nodeXYRatio: 1.7,
119 
120   /**
121     A value of 0.1 would puts the edge label close to start node. 0.5 would put it in the middle of the edge. 
122     0.9 would put it close to the end node.
123 
124     @property {Float}
125     @default 0.4
126   */
127   edgeTextPosOffset: 0.4, 
128 
129   /**
130     Node background color.
131     
132     @property {String}
133     @config
134     @default '#F3D15C'
135   */
136   nodeColor: '#F3D15C',
137 
138   /**
139     Selected node background color.
140     
141     @property {String}
142     @config
143     @default 'FFF594'
144   */
145   nodeColorSel: '#FFF594',
146 
147   /**
148     Node border color.
149     
150     @property {String}
151     @config
152     @default '#DF7E05'
153   */
154   nodeBorderColor: '#DF7E05',
155 
156   /**
157     Selected node border color.
158     
159     @property {String}
160     @config
161     @default '#FFB60B'
162   */
163   nodeBorderColorSel: '#FFB60B',
164 
165   /**
166     Node text color.
167     
168     @property {String}
169     @config
170     @default '#6D3D03'
171   */
172   nodeTextColor: '#6D3D03',
173   
174   /** 
175     Get the details of a given item.
176   
177     @param guids {Array} The array of guids.
178     @param callBack {Function} The callBack function is called when the request is successful.
179   */
180   performCustomRequest: function(guids, callBack)
181   {
182     Papercube.adaptor.getPaperDetails(guids, callBack);
183   },
184     
185   /** 
186     Generate custom metadata for item.
187     
188     @param guid {string} The guid for content object to be shown in the meta data view.
189 
190     @returns {Boolean} Returns NO if there is an error.
191   */
192   generateCustomMetaData: function(guid)
193   {
194     // Get the uathor content.
195     var content = Papercube.Paper.find(guid);
196 
197     if(!content) return;
198 
199     // Set the title
200     this.metaDataView.childNodes[0].innerHTML = content.get("title");
201 
202     // Set the authors
203     var authors = content.get('authorNames').join(', ');
204     var authLen = authors.length;
205     this.metaDataView.childNodes[1].innerHTML = (authLen > 150) ? (authors.substr(0,150)+"…") : authors;
206     this.metaDataView.childNodes[2].innerHTML = (content.get('publisher')) ? content.get('publisher') : '';
207 
208     // Set the date
209     this.metaDataView.childNodes[3].innerHTML = "<strong>Publication Date: </strong> " + content.get("year");
210 
211     this.metaDataView.childNodes[4].innerHTML = Papercube.pluralizeString(" reference", content.get('refCount'));
212     this.metaDataView.childNodes[5].innerHTML = Papercube.pluralizeString(" citation", content.get('citeCount'));
213   },
214 
215     
216   /** 
217     Generate custom metadata for item.
218   
219     @param guid {string} The guid for content object that is found in the SC Store.
220 
221     @returns {array|SC.Record} Returns the found content object.
222   */
223   findCustomObject: function(guid)
224   {
225     return Papercube.Paper.find(guid);
226   },
227 
228   /** 
229     Find Custom Object Relation Attribute.
230 
231     @param object {Record} The content object.
232 
233     @returns {Array} Returns the found relation attribute array.
234   */
235   findCustomObjectAttr: function(object)
236   {
237     if(object) 
238     {
239       if(this._displayRefs)
240         return object._attributes.references;
241       return object._attributes.citations;
242     }
243     else
244     {
245       return null;
246     }
247   },
248 
249   /**
250     Given relation object, return guid for it.
251 
252     @param rel {Object} The relation object or array.
253 
254     @returns {String} Returns the guid for the relation object.
255   */
256   getGuidForRelation: function(rel)
257   {
258     if(rel) return rel;
259   },
260   
261   /**
262     Given relation object, return weight for it.
263 
264     @param rel {Object} The relation object or array.
265 
266     @returns {Integer} Returns the calculated weight for the relation object.
267   */
268   calcRelationWeight: function(rel)
269   {
270     var paper = Papercube.Paper.find(rel);
271     if(paper)
272     {
273       if(this._displayRefs)
274         return paper.get('citeCount');
275       return paper.get('refCount');
276     }
277     return 1;
278   },
279 
280   /**
281     Given an object, return its label.
282 
283     @param object {Object} The content object.
284 
285     @returns {String} Returns a title string for display.
286   */
287   findCustomObjectLabel: function(object)
288   {
289     if(object)
290     {
291       return object._attributes.title.substr(0,20);
292       // var title = object.get('title');
293       // if(title.length > 40)
294       // {
295       //   return [title.substr(0,20), title.substr(20, 40)];
296       // }
297       // return title.substr(0,20);
298     }
299     return '?';
300   },
301     
302   /**
303     Revert bindings to default.
304   */
305   setBindingDefaults: function()
306   {
307     Papercube.paperGraphController.setDefaults();
308   },
309   
310   // Redraw of view direction change.
311   viewDirectionDidChange: function()
312   {
313     var content = this.get('content');
314     // If there is no content or if you're not visible, bail.
315 
316     if(!this.get("isVisible") || !content) return;
317     
318     var direction = this.get('viewDirection');
319     
320     // Render if needed.
321     if(direction != this._cached_viewDirection)
322     {
323       this._cached_viewDirection = direction;
324       this._displayRefs = (direction == "References");
325       this._render();
326     }
327   }.observes('viewDirection'),
328     
329   /**
330     Custom threshold calculation for complex link threshold calculations.
331 
332     @param rel {Object} The relation's guid.
333 
334     @returns {String} Returns if the item is accepted by the threshold(s). Returns NO otherwise.
335   */
336   relationMeetsCustomThreshold: function(rel)
337   {
338     if(this._cached_linkThreshold == 0 && this._cached_citeThreshold == 0) return YES;
339     
340     var paper = Papercube.Paper.find(rel);
341     if(paper)
342     {
343       return (paper.get('refCount') >= this._cached_linkThreshold &&
344               paper.get('citeCount') >= this._cached_citeThreshold);
345     }
346     return NO;
347   },
348   
349   /**
350     Redraw if citeThreshold change.
351 
352     @observes citeThreshold
353   */
354   citeThresholdDidChange: function()
355   {
356     var content = this.get('content');
357     // If there is no content or if you're not visible, bail.
358 
359     if(!this.get("isVisible") || !content) return;
360     
361     var threshold = this.get('citeThreshold');
362     
363     // Render if needed.
364     if(threshold != this._cached_citeThreshold)
365     {
366       this._hideExistingLines();
367       this._cached_citeThreshold = threshold;
368       this._render();
369     }
370   }.observes('citeThreshold')
371 }) ;
372