mirror of https://github.com/jenkinsci/jenkins.git
				
				
				
			Integrated a newer timeline component.
git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@25557 71c3de6d-444a-0410-be80-ed276b4c234a
This commit is contained in:
		
							parent
							
								
									df0170ec87
								
							
						
					
					
						commit
						43791a1a35
					
				|  | @ -352,7 +352,7 @@ THE SOFTWARE. | |||
|     <dependency> | ||||
|       <groupId>org.kohsuke.stapler</groupId> | ||||
|       <artifactId>stapler-adjunct-timeline</artifactId> | ||||
|       <version>1.0</version> | ||||
|       <version>1.1</version> | ||||
|     </dependency> | ||||
|     <dependency><!-- this helps us see the source code of the control while we edit Hudson. --> | ||||
|       <groupId>org.kohsuke.stapler</groupId> | ||||
|  |  | |||
|  | @ -55,7 +55,6 @@ import hudson.util.ShiftedCategoryAxis; | |||
| import hudson.util.StackedAreaRenderer2; | ||||
| import hudson.util.TextFile; | ||||
| import hudson.util.Graph; | ||||
| import hudson.util.TimeUnit2; | ||||
| import hudson.widgets.HistoryWidget; | ||||
| import hudson.widgets.Widget; | ||||
| import hudson.widgets.HistoryWidget.Adapter; | ||||
|  | @ -68,15 +67,16 @@ import java.io.StringWriter; | |||
| import java.io.PrintWriter; | ||||
| import java.net.URLEncoder; | ||||
| import java.text.ParseException; | ||||
| import java.util.AbstractList; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collection; | ||||
| import java.util.Collections; | ||||
| import java.util.Comparator; | ||||
| import java.util.Date; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.SortedMap; | ||||
| import java.util.LinkedList; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| import javax.servlet.ServletException; | ||||
| import javax.xml.transform.Transformer; | ||||
|  | @ -85,7 +85,6 @@ import javax.xml.transform.TransformerFactory; | |||
| import javax.xml.transform.stream.StreamResult; | ||||
| import javax.xml.transform.stream.StreamSource; | ||||
| 
 | ||||
| import net.sf.json.JSONArray; | ||||
| import net.sf.json.JSONObject; | ||||
| import net.sf.json.JSONException; | ||||
| 
 | ||||
|  | @ -109,6 +108,8 @@ import org.kohsuke.stapler.WebMethod; | |||
| import org.kohsuke.stapler.export.Exported; | ||||
| import org.kohsuke.args4j.Argument; | ||||
| import org.kohsuke.args4j.CmdLineException; | ||||
| import org.koshuke.stapler.simile.timeline.Event; | ||||
| import org.koshuke.stapler.simile.timeline.TimelineEventList; | ||||
| 
 | ||||
| /** | ||||
|  * A job is an runnable entity under the monitoring of Hudson. | ||||
|  | @ -621,6 +622,38 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R | |||
|         return _getRuns().get(n); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Obtains a list of builds, in the descending order, that are within the specified time range [start,end). | ||||
|      * | ||||
|      * @return can be empty but never null. | ||||
|      */ | ||||
|     public List<RunT> getBuildsByTimestamp(long start, long end) { | ||||
|         final List<RunT> builds = getBuilds(); | ||||
|         AbstractList<Long> TIMESTAMP_ADAPTER = new AbstractList<Long>() { | ||||
|             public Long get(int index) { | ||||
|                 return builds.get(index).timestamp; | ||||
|             } | ||||
| 
 | ||||
|             public int size() { | ||||
|                 return builds.size(); | ||||
|             } | ||||
|         }; | ||||
|         Comparator<Long> DESCENDING_ORDER = new Comparator<Long>() { | ||||
|             public int compare(Long o1, Long o2) { | ||||
|                 if (o1 > o2) return -1; | ||||
|                 if (o1 < o2) return +1; | ||||
|                 return 0; | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         int s = Collections.binarySearch(TIMESTAMP_ADAPTER, start, DESCENDING_ORDER); | ||||
|         if (s<0)    s=-(s+1);   // min is inclusive | ||||
|         int e = Collections.binarySearch(TIMESTAMP_ADAPTER, end,   DESCENDING_ORDER); | ||||
|         if (e<0)    e=-(e+1);   else e++;   // max is exclusive, so the exact match should be excluded | ||||
| 
 | ||||
|         return builds.subList(e,s); | ||||
|     } | ||||
| 
 | ||||
|     @CLIResolver | ||||
|     public RunT getBuildForCLI(@Argument(required=true,metaVar="BUILD#",usage="Build number") String id) throws CmdLineException { | ||||
|         try { | ||||
|  | @ -1285,27 +1318,22 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R | |||
|         return Hudson.getInstance().getAuthorizationStrategy().getACL(this); | ||||
|     } | ||||
| 
 | ||||
|     public void doTimelineData(@QueryParameter long min, @QueryParameter long max, StaplerResponse rsp) throws IOException { | ||||
|         Date l = new Date(min); | ||||
|         Date h = new Date(max); | ||||
|         List<Event> result = new ArrayList<Event>(); | ||||
|         for (int i=0; i<10; i++) { | ||||
|     public TimelineEventList doTimelineData(StaplerRequest req, @QueryParameter long min, @QueryParameter long max) throws IOException { | ||||
|         TimelineEventList result = new TimelineEventList(); | ||||
|         for (RunT r : getBuildsByTimestamp(min,max)) { | ||||
|             Event e = new Event(); | ||||
|             e.start = new Date(min+ TimeUnit2.HOURS.toMillis(i)); | ||||
|             e.title = "Event "+i; | ||||
|             e.description = "Longish description of event "+i; | ||||
|             JSONObject.fromObject(e); | ||||
|             e.start = r.getTime(); | ||||
|             e.end   = new Date(r.timestamp+r.getDuration()); | ||||
|             e.title = r.getFullDisplayName(); | ||||
|             // what to put in the description? | ||||
|             // e.description = "Longish description of event "+r.getFullDisplayName(); | ||||
|             // e.durationEvent = true; | ||||
|             e.link = req.getContextPath()+'/'+r.getUrl(); | ||||
|             BallColor c = r.getIconColor(); | ||||
|             e.color = String.format("#%06X",c.getBaseColor().darker().getRGB()&0xFFFFFF); | ||||
|             e.classname = "event-"+c.noAnime().toString()+" " + (c.isAnimated()?"animated":""); | ||||
|             result.add(e); | ||||
|         } | ||||
|         JSONObject o = new JSONObject(); | ||||
|         o.put("events", JSONArray.fromObject(result)); | ||||
|         rsp.setContentType("application/javascript;charset=UTF-8"); | ||||
|         o.write(rsp.getWriter()); | ||||
|     } | ||||
| 
 | ||||
|     public static final class Event { | ||||
|         public Date start; | ||||
|         public Date end; | ||||
|         public String title, description; | ||||
|         return result; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -32,28 +32,6 @@ THE SOFTWARE. | |||
|       <div id="tl" style="height:500px; border:1px solid black;" /> | ||||
|       <div id="status" /> | ||||
|       <script><![CDATA[ | ||||
|         var timeline_data = {  // save as a global variable | ||||
|         'dateTimeFormat': 'iso8601', | ||||
| 
 | ||||
|         'events' : [ | ||||
|                 {'start': '1924', | ||||
|                 'title': 'Barfusserkirche', | ||||
|                 'description': 'by Lyonel Feininger, American/German Painter, 1871-1956', | ||||
|                 'image': 'http://images.allposters.com/images/AWI/NR096_b.jpg', | ||||
|                 'link': 'http://www.allposters.com/-sp/Barfusserkirche-1924-Posters_i1116895_.htm' | ||||
|                 }, | ||||
| 
 | ||||
| 
 | ||||
|                 {'start': '1900', | ||||
|                 'end': '1913', | ||||
|                 'title': 'Three Figures', | ||||
|                 'description': 'by Kasimir Malevich, Ukrainian Painter, 1878-1935', | ||||
|                 'image': 'http://images.allposters.com/images/BRGPOD/75857_b.jpg', | ||||
|                 'link': 'http://www.allposters.com/-sp/Three-Figures-1913-28-Posters_i1349989_.htm' | ||||
|                 } | ||||
|         ]}; | ||||
| 
 | ||||
|         var tl; | ||||
|         window.addEventListener('load', function() { | ||||
|             var tl_el = document.getElementById("tl"); | ||||
|             var eventSource1 = new Timeline.DefaultEventSource(); | ||||
|  | @ -61,6 +39,7 @@ THE SOFTWARE. | |||
|             var interval = 24*60*60*1000; | ||||
|             eventSource1.ensureVisible = function(band) { | ||||
|               // make sure all data are loaded for the portion visible in the band | ||||
|               // $('status').innerHTML = "min="+band.getMinDate()+" max="+band.getMaxDate(); | ||||
|               var min = Math.floor(band.getMinDate().getTime()/interval); | ||||
|               var max = Math.ceil(band.getMaxDate().getTime()/interval); | ||||
|               for (var i=min; i<=max; i++) { | ||||
|  | @ -70,7 +49,11 @@ THE SOFTWARE. | |||
|                       method:"POST", | ||||
|                       parameters: {min: i*interval, max:(i+1)*interval}, | ||||
|                       onSuccess: function(t) { | ||||
|                         eventSource1.loadJSON(eval(t.responseText)); | ||||
|                         try { | ||||
|                           eventSource1.loadJSON(eval('('+t.responseText+')'),'.'); | ||||
|                         } catch (e) { | ||||
|                           alert(e); | ||||
|                         } | ||||
|                       } | ||||
|                   }); | ||||
|                 } | ||||
|  | @ -82,10 +65,10 @@ THE SOFTWARE. | |||
| //            theme1.autoWidth = true; // Set the Timeline's "width" automatically. | ||||
|                                      // Set autoWidth on the Timeline's first band's theme, | ||||
|                                      // will affect all bands. | ||||
|             theme1.timeline_start = new Date(Date.UTC(1890, 0, 1)); | ||||
|             theme1.timeline_stop  = new Date(Date.UTC(2160, 0, 1)); | ||||
|             theme1.timeline_start = new Date(${it.firstBuild.timeInMillis-24*60*60*1000}); | ||||
|             theme1.timeline_stop  = new Date(${it.lastBuild.timeInMillis+24*60*60*1000}); | ||||
| 
 | ||||
|             var d = Timeline.DateTime.parseGregorianDateTime("1900") | ||||
|             var d = theme1.timeline_stop; | ||||
|             var bandInfos = [ | ||||
|                 // the bar that shows outline | ||||
|                 Timeline.createBandInfo({ | ||||
|  | @ -110,26 +93,24 @@ THE SOFTWARE. | |||
|             bandInfos[0].syncWith = 1; | ||||
| 
 | ||||
|             // create the Timeline | ||||
|             tl = Timeline.create(tl_el, bandInfos, Timeline.HORIZONTAL); | ||||
|             var tl = Timeline.create(tl_el, bandInfos, Timeline.HORIZONTAL); | ||||
| 
 | ||||
|             tl.getBand(1).addOnScrollListener(function(band) { | ||||
|             tl.getBand(0).addOnScrollListener(function(band) { | ||||
|                 eventSource1.ensureVisible(band); | ||||
|             }); | ||||
| 
 | ||||
|             var url = '.'; // The base url for image, icon and background image | ||||
|                            // references in the data | ||||
|             eventSource1.loadJSON(timeline_data, url); | ||||
|             tl.layout(); // display the Timeline | ||||
|         },false); | ||||
| 
 | ||||
|         var resizeTimerID = null; | ||||
|         window.addEventListener('resize',function() { | ||||
|             if (resizeTimerID == null) { | ||||
|                 resizeTimerID = window.setTimeout(function() { | ||||
|                     resizeTimerID = null; | ||||
|                     tl.layout(); | ||||
|                 }, 500); | ||||
|             } | ||||
|             // if resized, redo layout | ||||
|             var resizeTimerID = null; | ||||
|             window.addEventListener('resize',function() { | ||||
|                 if (resizeTimerID == null) { | ||||
|                     resizeTimerID = window.setTimeout(function() { | ||||
|                         resizeTimerID = null; | ||||
|                         tl.layout(); | ||||
|                     }, 500); | ||||
|                 } | ||||
|             },false); | ||||
|         },false); | ||||
|       ]]></script> | ||||
|     </l:main-panel> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue