<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Keith's Blog &#187; JRuby</title>
	<atom:link href="http://kfahlgren.com/blog/category/jruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://kfahlgren.com/blog</link>
	<description>Keith on XML, Publishing, Ruby, Birds, &#038; San Francisco</description>
	<lastBuildDate>Fri, 09 Apr 2010 15:59:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>RubyConf 2007 Second Day Morning</title>
		<link>http://kfahlgren.com/blog/2007/11/03/rubyconf-2007-second-day-morning/</link>
		<comments>http://kfahlgren.com/blog/2007/11/03/rubyconf-2007-second-day-morning/#comments</comments>
		<pubDate>Sat, 03 Nov 2007 14:15:38 +0000</pubDate>
		<dc:creator>Keith</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Conferences]]></category>
		<category><![CDATA[JRuby]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[RubyConf2007]]></category>

		<guid isPermaLink="false">http://kfahlgren.com/blog/2007/11/03/rubyconf-2007-second-day-morning/</guid>
		<description><![CDATA[John Lam: State of IronRuby Photo by dwortlehock Who works on IronRuby? The core is: John Lam, Hiabo Luo, Tomas Matousek, &#38; John Messerly. Why did John move from Toronto to Seattle to start working at Microsoft on IronRuby? He was in love with RubyCLR and couldn&#8217;t turn down the opportunity to work on a [...]]]></description>
			<content:encoded><![CDATA[<h2>John Lam: State of IronRuby</h2>
<p><a href="http://flickr.com/photos/dwortlehock/1844335039/" title="John Lam"><img src="http://farm3.static.flickr.com/2355/1844335039_efcee0eb01.jpg" width="500" height="375" alt="John Lam" /></a></p>
<p><a href="http://flickr.com/photos/dwortlehock/1844335039/">Photo</a> by <a href="http://flickr.com/photos/dwortlehock/">dwortlehock</a></p>
<p>Who works on <a href="http://rubyforge.org/projects/ironruby">IronRuby</a>? The core is: John Lam, Hiabo Luo, Tomas Matousek, &amp; John Messerly.</p>
<p>Why did John move from Toronto to Seattle to start working at Microsoft on IronRuby? He was in love with RubyCLR and couldn&#8217;t turn down the opportunity to work on a &#8220;real&#8221; implementation. </p>
<h3>Goals</h3>
<p>John wants IronRuby to be a Ruby implementation but also in changing Microsoft&#8217;s approach to opensource (&#8220;change or die&#8221;), especially the &#8220;either or approach&#8221; to thinking about opensource. However, it&#8217;s really hard to change a company that&#8217;s doing pretty well. Unfortunately, after doing some announcements  about their intentions, the blogosphere decided that IronRuby was going to be the work of the devil. Today, the project is hosted on Rubyforge, has open SVN access, and has already recieved code contributions from the outside community.</p>
<p>Support Rails: it&#8217;s &#8220;the testbed&#8221; (dispite speculation about MS not wanting to threaten ASP.NET): it&#8217;s &#8220;the testbed&#8221; (dispite speculation about MS not wanting to threaten ASP.NET).</p>
<p>Run everywhere .NET runs (Mac, Linux, Windows). [John is doing the presentation on a Mac and does an irb demo (compiled on Windows) with CLR types (with nice integration between the CLR type's methods and pure Ruby methods) on Mono.]</p>
<h3>Under the covers</h3>
<p>[John runs the Rubinius spec suite in IronRuby in Windows on his Mac. A lot of things fail (373 failures of 1030 examples). He thanks the Rubinius team for all of their work.]</p>
<p>[John goes on to show a bunch of quick IronRuby demos, including some in-browser demos using IronRuby in Silverlight.] There&#8217;ll be more examples <a href="http://www.iunknown.com/">up later on his blog</a>.</p>
<p>If you&#8217;re interested in making a language on .NET, please come to the <a href="http://langnetsymposium.com">Lang.NET Symposium</a>.</p>
<h3>Q &amp; A</h3>
<p>Release schedule? Unlike &#8220;real projects&#8221;, IronRuby has a  &#8220;conference-driven schedule&#8221;. They want to do a push to have Rails working in IronRuby by RailsConf 2008.</p>
<p>Can the IronRuby developers look at other implementations source code? They have to be &#8220;extremely clean&#8221; on the DLR, but &#8220;IronRuby does not have the same restrictions&#8221; because it doesn&#8217;t ship with the OS. Explicitly, they can look at<br />
test and test frameworks.</p>
<h2>Charlie Nutter &amp; Tom Enebo: JRuby: Ruby for the JVM</h2>
<p><img src="http://kfahlgren.com/photos/logos/jruby_logo.jpg" alt="JRuby logo" /></p>
<p>Everyone in the audience knows already what JRuby is, so they won&#8217;t cover that. It&#8217;s a Java implementation of the Ruby 1.8 language. It&#8217;s available under a few opensource licenses, blah blah blah. They released 1.0.2 a couple of days ago (and 1.1b1 last night during Matz&#8217; questions).</p>
<p>[Tim Bray fairly incomprehensively announces that Sun has done a deal with University of Tokyo to work with ? on ? and give them "a bunch of money". Another implementation?]</p>
<h3>Design</h3>
<p>Installation: 1. unpack binary, 2. set PATH. Dependencies: Java 5+. <tt>jruby.jar</tt> contains the full runtime.</p>
<p>The lexer is a hand-written lexer ported from MRI. The parser is another port of the MIR YACC/Bison parser using Jay (Bison for Java). This parser is the key for the recent boom in IDE support for Ruby (like NetBeans). [Charlie does a little NetBeans demo showing auto-complete and variable renaming/highlighting, unused variable detection.] </p>
<p>The Core classes are all written in Java, and nearly all have a 1:1 correspondence (String is RubyString, Array is RubyArray, etc). </p>
<p>The interpreter is a &#8220;simple switch-based AST walker&#8221; that recurses for nesting. Code starts out interpreted but command-line scripts compile immediately. &#8220;<tt>eval</tt>&#8216;d code always interpreted (for now).&#8221;</p>
<p>JRuby 1.1 brings full bytecode compilation. &#8220;The compiler is basically done. This is the only complete 1.8 compiler in existence.&#8221; [Charlie shows a fib benchmark. Compiling makes it quite a bit bigger in filesize (oh well).  There's a _huge_ improvement when using <tt>java -server</tt>.] Typically, you want to use AOT mode, which avoids &#8220;JIT warmup time&#8221;. It may also use less memory in the future and perhaps start faster?</p>
<p><a href="http://flickr.com/photos/dwortlehock/1844321217/" title="Charlie and Tom"><img src="http://farm3.static.flickr.com/2178/1844321217_923a7dea5c.jpg" width="500" height="375" alt="Charlie and Tom" /></a></p>
<p><a href="http://flickr.com/photos/dwortlehock/1844321217/">Photo</a> by <a href="http://flickr.com/photos/dwortlehock/">dwortlehock</a></p>
<h3>Performance</h3>
<p>Performance optimizations are progressing in a few directions. The first is the obvious one of compilation. For real numbers, see <a href="ihttp://blog.nicksieger.com/articles/2007/10/25/jruby-on-rails-fast-enough">this blog post</a>. Comilation caches literals, uses Java local variables when possible, and uses &#8220;monomorphic inline method cache.&#8221; ObjectSpace is a more controversial<br />
optimization. ObjectSpace allows you to iterate all Objects in a system. This isn&#8217;t painful in MRI, but is not easy in the fully-concurrent JRuby (&#8220;it sucks 2-5 times as much&#8221;). Charlie asserts that it is almost never used (except for Test::Unit). It&#8217;s turned off by default but can be turned on with a flag. [Some in the audience believe that the reverse should be used.] Custom implementations of Array, String, and Hash (among others) have also boosted performance.</p>
<h3>Threading, Extensions, &amp; Integration</h3>
<p>JRuby supports only native OS threads but they&#8217;re parallel. They also emulate unsafe green thread operations (<tt>Thread#kill</tt>, <tt>Thread#raise</tt>, etc).</p>
<p>Ruby native (C) extensions are not supported. Some libraries may be accessible with JNA. If you&#8217;re looking for a good binding, consider a Java equivalent to the C. Most of the extensions that Rails uses have already been ported to Java/JRuby.</p>
<p>You can call Ruby from Java, you can call Java from Ruby. A popular integration is building GUIs with Swing. Ruby makes &#8220;Swing development fun&#8221; and is much less verbose than the Java version. Swing integration also brings a cross-platform GUI solution to Ruby (essentially for the first time). A direct approch:</p>
<pre>$ jirb
&gt;&gt; include Java
=&gt; Object
&gt;&gt; import javax.swing.JFrame
...
&gt;&gt; frame = JFrame.new("Hello")
&gt;&gt; frame.show
=&gt; nil
# there is a frame on the screen
&gt;&gt; frame.set_size(500, 500)
=&gt; nil </pre>
<p><a href="http://ihate.rubyforge.org/profligacy/">Profligacy</a> adds a new layout language to simply GUI creation. <a href="http://rubyforge.org/projects/monkeybars/">MonkeyBars</a> takes a GUI editor approach.</p>
<h3>Rails</h3>
<p>Rails works with JRuby. It uses a JDBC connector to ActiveRecord. It can generate .war files (via Warble). ActiveHibernate is coming soon, and provides a different persistence API. Ruvlets brings Servlets to JRuby.</p>
<h3>TDD/BDD</h3>
<p>You can use Test::Unit or RSpec for Java code. &#8220;It&#8217;s so much less code&#8221; that writing tests for Java directly.</p>
<h3>Takeaway</h3>
<ul>
<li>JRuby is ready</li>
<li>JRuby is more than just an implementation</li>
<li>JRuby needs your help</li>
</ul>
<h2>Evan Phoenix: Rubinius 1.0</h2>
<p><img alt="Rubinius logo"<br />
src="http://kfahlgren.com/photos/logos/3d_rubinius_logo.png" /></p>
<p><a href="http://rubini.us/">Rubinius</a>, like IronRuby and JRuby is aiming to bring &#8220;total world domination &#8230;. for Ruby!&#8221; It&#8217;s a Smalltalk-inspired VM: </p>
<pre>class Rubinius &lt; Smalltalk
  # form
  include Ruby::Syntax
  # function
  include Ruby::Behavior
  include Google.search("crazy cs papers")
end </pre>
<p>Rubinius debuted last year at RubyConf 2006. There&#8217;s been &#8220;enormous progress&#8221; over the course of the year.</p>
<p>A comparison of implementation langagues (slightly misleading):</p>
<pre>1.8
84,516 lines of C
     0 lines of Ruby

1.9
128,786 lines of C
     50 lines of Ruby

IronRuby
 48,282 of C#
      0 lines of Ruby

JRuby
113,508 lines of Java
  1,000 lines of Ruby

Rubinius
 25,398 lines of C
 13,946 lines of Ruby </pre>
<p><a href="http://flickr.com/photos/dwortlehock/1844312099/" title="Evan Phoenix"><img src="http://farm3.static.flickr.com/2242/1844312099_290461f2f2.jpg" width="500" height="375" alt="Evan Phoenix" /></a></p>
<p><a href="http://flickr.com/photos/dwortlehock/1844312099/">Photo</a> by <a href="http://flickr.com/photos/dwortlehock/">dwortlehock</a></p>
<p>Some &#8220;Junior High Analysis&#8221;:</p>
<ul>
<li>1.8 &amp; 1.9 is Ruby (core) for C programmers</li>
<li>JRuby is Ruby for Java programmers</li>
<li>IronRuby is Ruby for C# programmers</li>
<li>Rubinius is Ruby for Ruby programmers </li>
</ul>
<p>Rubinius finally allows Ruby programmers to &#8220;eat yummy dogfood.&#8221; It&#8217;s targeted at fellow Ruby programmers, not folks on the street. It also provides a much tighter feedback loop for language improvements &amp; clarification.</p>
<p>Following on that, they have 57 committers, with 17 of those with 20 or more commits (36 with 100+ lines changed). Commit bits have been &#8220;free flowing&#8221; and easy to get (if something you submit as a patch you get commit rights). </p>
<p>Props to EngineYard for funding Evan&#8217;s work on Rubinius.</p>
<p>Evan is shooting to have 1.0 out by ? (was: RubyConf 2007). Things change. Mistakes were made. They&#8217;re evolving.</p>
<h3>Q &amp; A</h3>
<p>Given the fact that Ola Bini and Avi Bryant should Rubinius replace MRI eventually? The chicken didn&#8217;t decide to replace the dinosaur [laughs], the environment did.   The ultimate goal (from the start) wasn&#8217;t &#8220;replace MRI&#8221;, it was &#8220;total world domination&#8221;.</p>
<p>Are you more interested in performance than conformance? Rubinius has some compiler flags to turn certain optimizations on and off.</p>
<p>How small do you think you can get the C? They&#8217;ll follow Squeak in that they&#8217;ll write a C generator. The final goal is hand-maintained lines of C==0.</p>
<p>Are you worried about incompatibilities? We&#8217;re all worried about that. We wouldn&#8217;t checking something that intentionally broke compatibility.</p>
<p>What are these specs you&#8217;re writing? Do you pass them? They&#8217;re as implementation-agnostic as possible and written for MiniRSpec<br />
(intended to sytnax-compatible with RSpec).  Compatibility is all centered on emulating MRI. We used to fail ~1100 specs a few weeks ago, today we&#8217;re closer to ~500. The improvement is all due to community involvement.</p>
<p>Have you made any enhancements? Yeah, we did some prettier backtraces andcapturing exceptions from C extension segfaults, for example.</p>
<p>Is Rubinius challenged by ObjectSpace, Continuations, &amp;Selector Namespaces? They have a problem with ObjectSpace like JRuby, continuations are &#8220;our shiny awesomeness&#8221; (thanks Smalltalk&#8217;s spaghetti stack) [shows continuation demo], and (no comment on SN). </p>
]]></content:encoded>
			<wfw:commentRss>http://kfahlgren.com/blog/2007/11/03/rubyconf-2007-second-day-morning/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stacked Bar Charts in JRuby using JFreeChart</title>
		<link>http://kfahlgren.com/blog/2007/07/12/stacked-bar-charts-in-jruby-using-jfreechart/</link>
		<comments>http://kfahlgren.com/blog/2007/07/12/stacked-bar-charts-in-jruby-using-jfreechart/#comments</comments>
		<pubDate>Thu, 12 Jul 2007 15:27:39 +0000</pubDate>
		<dc:creator>Keith</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[JRuby]]></category>

		<guid isPermaLink="false">http://kfahlgren.com/blog/2007/07/12/stacked-bar-charts-in-jruby-using-jfreechart/</guid>
		<description><![CDATA[I was getting some comments on a previous post asking about building stacked bar charts in JRuby using JFreeChart, so here&#8217;s another example: # Mostly inspired by # http://left.subtree.org/2007/01/15/creating-sparklines-with-jfreechart/ # have JFreeChart in your classpath, obviously, as well as jcommon.jar require 'java' module Graph class StackedBar include_class 'java.io.File' include_class 'org.jfree.chart.ChartUtilities' include_class 'org.jfree.chart.JFreeChart' include_class 'org.jfree.data.category.DefaultCategoryDataset' include_class [...]]]></description>
			<content:encoded><![CDATA[<p>I was getting some comments on a <a href="http://kfahlgren.com/blog/2007/04/13/jruby-jfreechart-sparklines/#comment-103">previous post</a> asking about building stacked bar charts in <a href="http://jruby.codehaus.org/">JRuby</a> using <a href="http://www.jfree.org/jfreechart/">JFreeChart</a>, so here&#8217;s another example:</p>
<pre>
<font color="#00ffff"><b># Mostly inspired by </b></font>
<font color="#00ffff"><b># <a href="http://left.subtree.org/2007/01/15/creating-sparklines-with-jfreechart/">http://left.subtree.org/2007/01/15/creating-sparklines-with-jfreechart/</a></b></font>
<font color="#00ffff"><b># have JFreeChart in your classpath, obviously, as well as jcommon.jar</b></font>
<font color="#8080ff"><b>require</b></font> <font color="#ff6060"><b>'</b></font><font color="#ff40ff"><b>java</b></font><span class="Special">'</span>

<font color="#8080ff"><b>module </b></font><font color="#00ff00"><b>Graph</b></font>
  <font color="#8080ff"><b>class </b></font><font color="#00ff00"><b>StackedBar</b></font>
    include_class <font color="#ff6060"><b>'</b></font><font color="#ff40ff"><b>java.io.File</b></font><span class="Special">'</span>
    include_class <font color="#ff6060"><b>'</b></font><font color="#ff40ff"><b>org.jfree.chart.ChartUtilities</b></font><span class="Special">'</span>
    include_class <font color="#ff6060"><b>'</b></font><font color="#ff40ff"><b>org.jfree.chart.JFreeChart</b></font><span class="Special">'</span>
    include_class <font color="#ff6060"><b>'</b></font><font color="#ff40ff"><b>org.jfree.data.category.DefaultCategoryDataset</b></font><span class="Special">'</span>
    include_class <font color="#ff6060"><b>'</b></font><font color="#ff40ff"><b>org.jfree.chart.ChartFactory</b></font><span class="Special">'</span>
    include_class <font color="#ff6060"><b>'</b></font><font color="#ff40ff"><b>org.jfree.chart.plot.PlotOrientation</b></font><span class="Special">'</span>

    <font color="#8080ff"><b>def </b></font><font color="#00ffff"><b>initialize</b></font><span class="rubyBlock">(width=</span><font color="#ff40ff"><b>600</b></font><span class="rubyBlock">, height=</span><span class="Constant">400</span><span class="rubyBlock">, data=[])</span>
      <font color="#00ffff"><b>@width</b></font><span class="rubyBlock"> = width</span>
      <font color="#00ffff"><b>@height</b></font><span class="rubyBlock"> = height</span>
      dataset = create_sample_data() <font color="#ffff00"><b>if</b></font><span class="rubyBlock"> data.empty?</span>
      <font color="#00ffff"><b>@chart</b></font><span class="rubyBlock"> = create_chart(dataset)</span>
    <font color="#8080ff"><b>end</b></font>

    <font color="#8080ff"><b>def </b></font><font color="#00ffff"><b>render_to_file</b></font><span class="rubyBlock">(filename, format=</span><font color="#ff6060"><b>&quot;</b></font><font color="#ff40ff"><b>png</b></font><span class="Special">&quot;</span><span class="rubyBlock">)</span>
      puts <font color="#ff6060"><b>&quot;</b></font><font color="#ff40ff"><b>Rendering graph to </b></font><span class="Special">#{filename}</span><span class="Special">&quot;</span>
      javafile = java.io.File.new(filename)
      ChartUtilities.saveChartAsPNG(javafile, <font color="#00ffff"><b>@chart</b></font><span class="rubyBlock">, </span><span class="Identifier">@width</span><span class="rubyBlock">, </span><span class="Identifier">@height</span><span class="rubyBlock">)</span>
    <font color="#8080ff"><b>end</b></font>

    <font color="#ffff00"><b>private</b></font>
    <font color="#8080ff"><b>def </b></font><font color="#00ffff"><b>create_sample_data</b></font>
      dataset = DefaultCategoryDataset.new
      dataset.addValue(<font color="#ff40ff"><b>1</b></font><span class="rubyBlock">, </span><font color="#ff6060"><b>&quot;</b></font><span class="Constant">Submitted</span><span class="Special">&quot;</span><span class="rubyBlock">, </span><span class="Special">&quot;</span><span class="Constant">A</span><span class="Special">&quot;</span><span class="rubyBlock">)</span>
      dataset.addValue(<font color="#ff40ff"><b>1</b></font><span class="rubyBlock">, </span><font color="#ff6060"><b>&quot;</b></font><span class="Constant">Assigned</span><span class="Special">&quot;</span><span class="rubyBlock">, </span><span class="Special">&quot;</span><span class="Constant">A</span><span class="Special">&quot;</span><span class="rubyBlock">)</span>
      dataset.addValue(<font color="#ff40ff"><b>3</b></font><span class="rubyBlock">, </span><font color="#ff6060"><b>&quot;</b></font><span class="Constant">In-work</span><span class="Special">&quot;</span><span class="rubyBlock">, </span><span class="Special">&quot;</span><span class="Constant">A</span><span class="Special">&quot;</span><span class="rubyBlock">)</span>
      dataset.addValue(<font color="#ff40ff"><b>1</b></font><span class="rubyBlock">, </span><font color="#ff6060"><b>&quot;</b></font><span class="Constant">InVerfication</span><span class="Special">&quot;</span><span class="rubyBlock">, </span><span class="Special">&quot;</span><span class="Constant">A</span><span class="Special">&quot;</span><span class="rubyBlock">)</span>
      dataset.addValue(<font color="#ff40ff"><b>2</b></font><span class="rubyBlock">, </span><font color="#ff6060"><b>&quot;</b></font><span class="Constant">Delivered</span><span class="Special">&quot;</span><span class="rubyBlock">, </span><span class="Special">&quot;</span><span class="Constant">A</span><span class="Special">&quot;</span><span class="rubyBlock">)</span>
      dataset.addValue(<font color="#ff40ff"><b>2</b></font><span class="rubyBlock">, </span><font color="#ff6060"><b>&quot;</b></font><span class="Constant">Submitted</span><span class="Special">&quot;</span><span class="rubyBlock">, </span><span class="Special">&quot;</span><span class="Constant">B</span><span class="Special">&quot;</span><span class="rubyBlock">)</span>
      dataset.addValue(<font color="#ff40ff"><b>1</b></font><span class="rubyBlock">, </span><font color="#ff6060"><b>&quot;</b></font><span class="Constant">Rejected</span><span class="Special">&quot;</span><span class="rubyBlock">, </span><span class="Special">&quot;</span><span class="Constant">B</span><span class="Special">&quot;</span><span class="rubyBlock">)</span>
      dataset.addValue(<font color="#ff40ff"><b>1</b></font><span class="rubyBlock">, </span><font color="#ff6060"><b>&quot;</b></font><span class="Constant">Closed</span><span class="Special">&quot;</span><span class="rubyBlock">, </span><span class="Special">&quot;</span><span class="Constant">B</span><span class="Special">&quot;</span><span class="rubyBlock">)</span>
      dataset.addValue(<font color="#ff40ff"><b>1</b></font><span class="rubyBlock">, </span><font color="#ff6060"><b>&quot;</b></font><span class="Constant">Submitted</span><span class="Special">&quot;</span><span class="rubyBlock">, </span><span class="Special">&quot;</span><span class="Constant">C</span><span class="Special">&quot;</span><span class="rubyBlock">)</span>
      dataset.addValue(<font color="#ff40ff"><b>1</b></font><span class="rubyBlock">, </span><font color="#ff6060"><b>&quot;</b></font><span class="Constant">Assigned</span><span class="Special">&quot;</span><span class="rubyBlock">, </span><span class="Special">&quot;</span><span class="Constant">C</span><span class="Special">&quot;</span><span class="rubyBlock">)</span>
      dataset.addValue(<font color="#ff40ff"><b>3</b></font><span class="rubyBlock">, </span><font color="#ff6060"><b>&quot;</b></font><span class="Constant">In-work</span><span class="Special">&quot;</span><span class="rubyBlock">, </span><span class="Special">&quot;</span><span class="Constant">C</span><span class="Special">&quot;</span><span class="rubyBlock">)</span>
      dataset.addValue(<font color="#ff40ff"><b>2</b></font><span class="rubyBlock">, </span><font color="#ff6060"><b>&quot;</b></font><span class="Constant">On-hold</span><span class="Special">&quot;</span><span class="rubyBlock">, </span><span class="Special">&quot;</span><span class="Constant">C</span><span class="Special">&quot;</span><span class="rubyBlock">)</span>

      <font color="#ffff00"><b>return</b></font><span class="rubyBlock"> dataset</span>
    <font color="#8080ff"><b>end</b></font>

    <font color="#8080ff"><b>def </b></font><font color="#00ffff"><b>create_chart</b></font><span class="rubyBlock">(dataset)</span>
      chart = ChartFactory.createStackedBarChart(<font color="#ff6060"><b>&quot;</b></font><font color="#ff40ff"><b>XYZ's Development Projects</b></font><span class="Special">&quot;</span><span class="rubyBlock">,</span>
                                                 <font color="#ff6060"><b>&quot;</b></font><font color="#ff40ff"><b>Project Name</b></font><span class="Special">&quot;</span><span class="rubyBlock">, </span>
                                                 <font color="#ff6060"><b>&quot;</b></font><font color="#ff40ff"><b>Hours</b></font><span class="Special">&quot;</span><span class="rubyBlock">, </span>
                                                 dataset,
                                                 <font color="#00ffff"><b>PlotOrientation</b></font><span class="rubyBlock">::</span><span class="Identifier">VERTICAL</span><span class="rubyBlock">, </span>
                                                 <font color="#ff40ff"><b>true</b></font><span class="rubyBlock">, </span>
                                                 <font color="#ff40ff"><b>true</b></font><span class="rubyBlock">, </span>
                                                 <font color="#ff40ff"><b>false</b></font><span class="rubyBlock">)</span>
      <font color="#ffff00"><b>return</b></font><span class="rubyBlock"> chart    </span>
    <font color="#8080ff"><b>end</b></font>
  <font color="#8080ff"><b>end</b></font><span class="rubyBlock"> </span><font color="#00ffff"><b># class StackedBar  </b></font>
<font color="#8080ff"><b>end</b></font> <font color="#00ffff"><b># class Graph</b></font>

sb = <font color="#00ffff"><b>Graph</b></font><span class="">::StackedBar.new</span>
sb.render_to_file(<font color="#ff6060"><b>&quot;</b></font><font color="#ff40ff"><b>stacked_bar.png</b></font><span class="Special">&quot;</span><span class="">)</span>
</pre>
<p>Here&#8217;s the output: </p>
<p><a href="http://kfahlgren.com/photos/work/stacked_bar.png"><img src="http://kfahlgren.com/photos/work/stacked_bar.png" alt="Stacked Bar chart example" /></a></p>
<p>Code here: <a href="http://kfahlgren.com/code/stacked_bar.jrb">http://kfahlgren.com/code/stacked_bar.jrb</a></p>
]]></content:encoded>
			<wfw:commentRss>http://kfahlgren.com/blog/2007/07/12/stacked-bar-charts-in-jruby-using-jfreechart/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>JRuby + Jetty</title>
		<link>http://kfahlgren.com/blog/2007/06/06/jruby-jetty/</link>
		<comments>http://kfahlgren.com/blog/2007/06/06/jruby-jetty/#comments</comments>
		<pubDate>Thu, 07 Jun 2007 00:32:51 +0000</pubDate>
		<dc:creator>Keith</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[JRuby]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://kfahlgren.com/blog/2007/06/06/jruby-jetty/</guid>
		<description><![CDATA[I finally figured out how to get JRuby to serve a Jetty servlet today (thanks to Charles). The key was flipping what I&#8217;d been trying to do for a while (getting Jetty to run JRuby). Here&#8217;s code that implements the AbstractHandler interface pretty trivially: $ cat jetty_example.jrb require 'java' include_class 'javax.servlet.ServletException' include_class 'javax.servlet.http.HttpServlet' include_class 'javax.servlet.http.HttpServletRequest' [...]]]></description>
			<content:encoded><![CDATA[<p>I finally figured out how to get JRuby to serve a Jetty servlet today (thanks to <a href="http://blog.earstu.org/">Charles</a>). The key was flipping what I&#8217;d been trying to do for a while (getting Jetty to run JRuby). Here&#8217;s code that implements the AbstractHandler interface pretty trivially:</p>
<pre>$ cat jetty_example.jrb
require 'java'
include_class 'javax.servlet.ServletException'
include_class 'javax.servlet.http.HttpServlet'
include_class 'javax.servlet.http.HttpServletRequest'
include_class 'javax.servlet.http.HttpServletResponse'

include_class 'org.mortbay.jetty.Server'
include_class 'org.mortbay.jetty.servlet.Context'
include_class 'org.mortbay.jetty.servlet.ServletHolder'
include_class 'org.mortbay.jetty.handler.AbstractHandler'

class SimpleHandler &lt; AbstractHandler
  def handle(target, request, response, dispatch)
    response.setContentType("text/html")
    response.setStatus(HttpServletResponse::SC_OK)
    response.getWriter().println("&lt;h1&gt;Goodbye, cruel monoglot world!&lt;/h1&gt;")
    request.setHandled(true)
  end
end

handler = SimpleHandler.new
server = Server.new(8080)
server.setHandler(handler)
server.start()
</pre>
<p>To run, add Jetty to your classpath:</p>
<pre>$ export CLASSPATH="/path/to/jetty-6.1.3.jar:/.../jetty-util-6.1.3.jar:/.../servlet-api-2.5-6.1.3.jar"</pre>
<p>Then it&#8217;s just a normal JRuby invocation:</p>
<p><code>$ jruby jetty_example.jrb</code></p>
<p>It&#8217;s trivial code at this point (and doesn&#8217;t handle concurrent requests, maxing out at 6.47r/s across my network), but at least it&#8217;s got me started.</p>
<p>[UPDATE: I can get the non-concurrent request handling way down with just a few simple tweaks (mainly running JRuby in SERVER mode) and running ab locally ;-)]</p>
]]></content:encoded>
			<wfw:commentRss>http://kfahlgren.com/blog/2007/06/06/jruby-jetty/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JRuby + JFreeChart = Sparklines</title>
		<link>http://kfahlgren.com/blog/2007/04/13/jruby-jfreechart-sparklines/</link>
		<comments>http://kfahlgren.com/blog/2007/04/13/jruby-jfreechart-sparklines/#comments</comments>
		<pubDate>Fri, 13 Apr 2007 22:43:31 +0000</pubDate>
		<dc:creator>Keith</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[JRuby]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://kfahlgren.com/blog/2007/04/13/jruby-jfreechart-sparklines/</guid>
		<description><![CDATA[Inspired by how easy it was to get JFreeChart working and some code from former colleague Andrew Bruno, I thought it&#8217;d be nice to write some JRuby to generate Edward Tufte&#8217;s Sparklines. Here&#8217;s some simple example code on a semi-random dataset: # Mostly inspired by # http://left.subtree.org/2007/01/15/creating-sparklines-with-jfreechart/ # have JFreeChart in your classpath, obviously, as [...]]]></description>
			<content:encoded><![CDATA[<p>Inspired by how easy it was to get <a href="http://www.jfree.org/jfreechart/">JFreeChart</a> working <a href="http://kfahlgren.com/blog/2007/04/12/more-jruby-play-jfreechart/"> and some code from former colleague </a><a href="http://left.subtree.org/2007/01/15/creating-sparklines-with-jfreechart/">Andrew Bruno</a>, I thought it&#8217;d be nice to write some JRuby to  generate Edward Tufte&#8217;s <a href="http://www.edwardtufte.com/bboard/q-and-a-fetch-msg?msg_id=0001OR&amp;topic_id=1">Sparklines</a>.</p>
<p>Here&#8217;s some simple example code on a semi-random dataset:</p>
<pre><span style="color: #00ffff;"><strong># Mostly inspired by
# <a href="http://left.subtree.org/2007/01/15/creating-sparklines-with-jfreechart/">http://left.subtree.org/2007/01/15/creating-sparklines-with-jfreechart/</a></strong></span>
<span style="color: #00ffff;"><strong># have JFreeChart in your classpath, obviously, as well as jcommon.jar</strong></span>
<span style="color: #8080ff;"><strong>require</strong></span> <span style="color: #ff6060;"><strong>'</strong></span><span style="color: #ff40ff;"><strong>java</strong></span><span style="color: #ff6060;"><strong>'</strong></span>

<span style="color: #8080ff;"><strong>module </strong></span><span style="color: #00ff00;"><strong>Graph</strong></span>
<span style="color: #8080ff;"><strong>  class </strong></span><span style="color: #00ff00;"><strong>Sparkline</strong></span>
    include_class <span style="color: #ff6060;"><strong>'</strong></span><span style="color: #ff40ff;"><strong>java.io.File</strong></span><span style="color: #ff6060;"><strong>'</strong></span>
    include_class <span style="color: #ff6060;"><strong>'</strong></span><span style="color: #ff40ff;"><strong>org.jfree.chart.ChartUtilities</strong></span><span style="color: #ff6060;"><strong>'</strong></span>
    include_class <span style="color: #ff6060;"><strong>'</strong></span><span style="color: #ff40ff;"><strong>org.jfree.chart.JFreeChart</strong></span><span style="color: #ff6060;"><strong>'</strong></span>
    include_class <span style="color: #ff6060;"><strong>'</strong></span><span style="color: #ff40ff;"><strong>org.jfree.chart.axis.NumberAxis</strong></span><span style="color: #ff6060;"><strong>'</strong></span>
    include_class <span style="color: #ff6060;"><strong>'</strong></span><span style="color: #ff40ff;"><strong>org.jfree.chart.plot.XYPlot</strong></span><span style="color: #ff6060;"><strong>'</strong></span>
    include_class <span style="color: #ff6060;"><strong>'</strong></span><span style="color: #ff40ff;"><strong>org.jfree.chart.renderer.xy.StandardXYItemRenderer</strong></span><span style="color: #ff6060;"><strong>'</strong></span>
    include_class <span style="color: #ff6060;"><strong>'</strong></span><span style="color: #ff40ff;"><strong>org.jfree.data.xy.XYSeries</strong></span><span style="color: #ff6060;"><strong>'</strong></span>
    include_class <span style="color: #ff6060;"><strong>'</strong></span><span style="color: #ff40ff;"><strong>org.jfree.data.xy.XYSeriesCollection</strong></span><span style="color: #ff6060;"><strong>'</strong></span>
    include_class <span style="color: #ff6060;"><strong>'</strong></span><span style="color: #ff40ff;"><strong>org.jfree.chart.plot.PlotOrientation</strong></span><span style="color: #ff6060;"><strong>'</strong></span>

<span style="color: #8080ff;"><strong>    def </strong></span><span style="color: #00ffff;"><strong>initialize</strong></span>(width=<span style="color: #ff40ff;"><strong>200</strong></span>, height=<span style="color: #ff40ff;"><strong>80</strong></span>, data=[])
      <span style="color: #00ffff;"><strong>@width</strong></span> = width
      <span style="color: #00ffff;"><strong>@height</strong></span> = height
      dataset = create_sample_data() <span style="color: #ffff00;"><strong>if</strong></span> data.empty?
      <span style="color: #00ffff;"><strong>@chart</strong></span> = create_chart(dataset)
    <span style="color: #8080ff;"><strong>end</strong></span>

<span style="color: #8080ff;"><strong>    def </strong></span><span style="color: #00ffff;"><strong>render_to_file</strong></span>(filename, format=<span style="color: #ff6060;"><strong>"</strong></span><span style="color: #ff40ff;"><strong>png</strong></span><span style="color: #ff6060;"><strong>"</strong></span>)
      javafile = java.io.<span style="color: #00ffff;"><strong>File</strong></span>.new(filename)
      <span style="color: #00ffff;"><strong>ChartUtilities</strong></span>.saveChartAsPNG(javafile, <span style="color: #00ffff;"><strong>@chart</strong></span>, <span style="color: #00ffff;"><strong>@width</strong></span>, <span style="color: #00ffff;"><strong>@height</strong></span>)
    <span style="color: #8080ff;"><strong>end</strong></span>

    private
<span style="color: #8080ff;"><strong>    def </strong></span><span style="color: #00ffff;"><strong>create_sample_data</strong></span>
       series = <span style="color: #00ffff;"><strong>XYSeries</strong></span>.new(<span style="color: #ff6060;"><strong>"</strong></span><span style="color: #ff40ff;"><strong>Sparkline</strong></span><span style="color: #ff6060;"><strong>"</strong></span>)
      data = [<span style="color: #ff40ff;"><strong>20</strong></span>]
      (<span style="color: #ff40ff;"><strong>1..99</strong></span>).each {<span style="color: #00ffff;"><strong>|x|</strong></span>
        y = (data.last + (rand(x) + <span style="color: #ff40ff;"><strong>1</strong></span>)) / <span style="color: #ff40ff;"><strong>2</strong></span>
        data &lt;&lt; y
        series.add(x, y)
      }

      dataset = <span style="color: #00ffff;"><strong>XYSeriesCollection</strong></span>.new
      dataset.addSeries(series)
      <span style="color: #ffff00;"><strong>return</strong></span> dataset
    <span style="color: #8080ff;"><strong>end</strong></span>

<span style="color: #8080ff;"><strong>    def </strong></span><span style="color: #00ffff;"><strong>create_chart</strong></span>(dataset)
      x = <span style="color: #00ffff;"><strong>NumberAxis</strong></span>.new
      x.setTickLabelsVisible(<span style="color: #ff40ff;"><strong>false</strong></span>)
      x.setTickMarksVisible(<span style="color: #ff40ff;"><strong>false</strong></span>)
      x.setAxisLineVisible(<span style="color: #ff40ff;"><strong>false</strong></span>)
      x.setNegativeArrowVisible(<span style="color: #ff40ff;"><strong>false</strong></span>)
      x.setPositiveArrowVisible(<span style="color: #ff40ff;"><strong>false</strong></span>)
      x.setVisible(<span style="color: #ff40ff;"><strong>false</strong></span>)

      y = <span style="color: #00ffff;"><strong>NumberAxis</strong></span>.new
      y.setTickLabelsVisible(<span style="color: #ff40ff;"><strong>false</strong></span>)
      y.setTickMarksVisible(<span style="color: #ff40ff;"><strong>false</strong></span>)
      y.setAxisLineVisible(<span style="color: #ff40ff;"><strong>false</strong></span>)
      y.setNegativeArrowVisible(<span style="color: #ff40ff;"><strong>false</strong></span>)
      y.setPositiveArrowVisible(<span style="color: #ff40ff;"><strong>false</strong></span>)
      y.setVisible(<span style="color: #ff40ff;"><strong>false</strong></span>)

      plot = <span style="color: #00ffff;"><strong>XYPlot</strong></span>.new
      plot.setDataset(dataset)
      plot.setDomainAxis(x)
      plot.setDomainGridlinesVisible(<span style="color: #ff40ff;"><strong>false</strong></span>)
      plot.setDomainCrosshairVisible(<span style="color: #ff40ff;"><strong>false</strong></span>)
      plot.setRangeGridlinesVisible(<span style="color: #ff40ff;"><strong>false</strong></span>)
      plot.setRangeCrosshairVisible(<span style="color: #ff40ff;"><strong>false</strong></span>)
      plot.setRangeAxis(y)
      plot.setOutlinePaint(<span style="color: #ff40ff;"><strong>nil</strong></span>)
      plot.setRenderer(<span style="color: #00ffff;"><strong>StandardXYItemRenderer</strong></span>.new(<span style="color: #00ffff;"><strong>StandardXYItemRenderer</strong></span>::<span style="color: #00ffff;"><strong>LINES</strong></span>))

      chart = <span style="color: #00ffff;"><strong>JFreeChart</strong></span>.new(<span style="color: #ff40ff;"><strong>nil</strong></span>, <span style="color: #00ffff;"><strong>JFreeChart</strong></span>::<span style="color: #00ffff;"><strong>DEFAULT_TITLE_FONT</strong></span>, plot, <span style="color: #ff40ff;"><strong>false</strong></span>)
      chart.setBorderVisible(<span style="color: #ff40ff;"><strong>false</strong></span>);
      <span style="color: #ffff00;"><strong>return</strong></span> chart
    <span style="color: #8080ff;"><strong>end</strong></span>

  <span style="color: #8080ff;"><strong>end</strong></span> <span style="color: #00ffff;"><strong># class Sparkline  </strong></span>
<span style="color: #8080ff;"><strong>end</strong></span> <span style="color: #00ffff;"><strong># class Graph</strong></span>

sp = <span style="color: #00ffff;"><strong>Graph</strong></span>::<span style="color: #00ffff;"><strong>Sparkline</strong></span>.new
puts <span style="color: #ff6060;"><strong>"</strong></span><span style="color: #ff40ff;"><strong>Rendering sparkline</strong></span><span style="color: #ff6060;"><strong>"</strong></span>
sp.render_to_file(<span style="color: #ff6060;"><strong>"</strong></span><span style="color: #ff40ff;"><strong>sparkline.png</strong></span><span style="color: #ff6060;"><strong>"</strong></span>)</pre>
<p>And the resulting sparkline chart:<br />
<img src="http://kfahlgren.com/photos/work/sparkline.png" alt="An Example Sparkline Chart" /></p>
<p>Code: <a href="http://kfahlgren.com/code/sparkline.jrb">http://kfahlgren.com/code/sparkline.jrb</a></p>
<p>UPDATE: Removed some of the useless sample generation code</p>
]]></content:encoded>
			<wfw:commentRss>http://kfahlgren.com/blog/2007/04/13/jruby-jfreechart-sparklines/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>More JRuby Play: JFreeChart</title>
		<link>http://kfahlgren.com/blog/2007/04/12/more-jruby-play-jfreechart/</link>
		<comments>http://kfahlgren.com/blog/2007/04/12/more-jruby-play-jfreechart/#comments</comments>
		<pubDate>Fri, 13 Apr 2007 01:30:12 +0000</pubDate>
		<dc:creator>Keith</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[JRuby]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Work]]></category>

		<guid isPermaLink="false">http://kfahlgren.com/blog/2007/04/12/more-jruby-play-jfreechart/</guid>
		<description><![CDATA[I&#8217;ve been messing around at work trying to make some automated scheduling charts (basically Gantt-like) in Ruby. I&#8217;ve implemented it a couple of times using SVG::Graph, which is close to what I need, but I end up having to rewrite a lot of methods whenever I really start using it. It occurred to me today [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been messing around at work trying to make some automated scheduling charts (basically Gantt-like) in Ruby. I&#8217;ve implemented it a couple of times using <a href="http://www.germane-software.com/software/SVG/SVG::Graph/">SVG::Graph</a>, which is close to what I need, but I end up having to rewrite a lot of methods whenever I really start using it. It occurred to me today that I might be able to co-opt a sexy Java library to do my dirty work. <a href="http://www.jfree.org/jfreechart/">JFreeChart</a> to the rescue!</p>
<p>As before, I&#8217;m generally amazed at how little work goes into integrating Java and <a href="http://jruby.codehaus.org/">JRuby</a> these days. It&#8217;s a testament to the JRuby team and to the wealth of well-written, well-documented Java libraries out there.</p>
<p>Here&#8217;s some toy code that makes a simple Gantt chart and saves it as a PNG to a file:</p>
<pre>
<font color="#8080ff"># have jfreechart.jar in your classpath, obviously, as well as jcommon.jar</font>
<font color="#8080ff"># and use a recent jruby</font>
<font color="#ff40ff">require</font> <font color="#ff40ff">'</font><font color="#ff6060">java</font><font color="#ff40ff">'</font>
<font color="#ff40ff">module </font><font color="#00ff00">Gantt</font>
<font color="#ff40ff">  class </font><font color="#00ff00">Simple</font>
    include_class <font color="#ff40ff">'</font><font color="#ff6060">org.jfree.chart.ChartFactory</font><font color="#ff40ff">'</font>
    include_class <font color="#ff40ff">'</font><font color="#ff6060">org.jfree.chart.ChartUtilities</font><font color="#ff40ff">'</font>
    include_class <font color="#ff40ff">'</font><font color="#ff6060">org.jfree.chart.JFreeChart</font><font color="#ff40ff">'</font>
    include_class <font color="#ff40ff">'</font><font color="#ff6060">org.jfree.data.gantt.Task</font><font color="#ff40ff">'</font>
    include_class <font color="#ff40ff">'</font><font color="#ff6060">org.jfree.data.gantt.TaskSeries</font><font color="#ff40ff">'</font>
    include_class <font color="#ff40ff">'</font><font color="#ff6060">org.jfree.data.gantt.TaskSeriesCollection</font><font color="#ff40ff">'</font>
    include_class <font color="#ff40ff">'</font><font color="#ff6060">org.jfree.data.time.SimpleTimePeriod</font><font color="#ff40ff">'</font>
    include_class <font color="#ff40ff">'</font><font color="#ff6060">java.lang.System</font><font color="#ff40ff">'</font>
    include_class <font color="#ff40ff">'</font><font color="#ff6060">java.io.File</font><font color="#ff40ff">'</font>

    <font color="#00ffff">MILLIS_IN_A_DAY</font> = <font color="#ff6060">86400000</font>

<font color="#ff40ff">    def </font><font color="#00ffff">initialize</font>(title=<font color="#ff40ff">&quot;</font><font color="#ff6060">Chunky Bacon</font><font color="#ff40ff">&quot;</font>, width=<font color="#ff6060">700</font>, height=<font color="#ff6060">400</font>, data=[])
      <font color="#00ffff">@width</font> = width
      <font color="#00ffff">@height</font> = height
      <font color="#00ffff">@title</font> = title
      dataset = create_sample_data() <font color="#ffff00">if</font> data.empty?
      <font color="#00ffff">@chart</font> = create_chart(dataset)
    <font color="#ff40ff">end</font>

<font color="#ff40ff">    def </font><font color="#00ffff">render_to_file</font>(filename, format=<font color="#ff40ff">&quot;</font><font color="#ff6060">png</font><font color="#ff40ff">&quot;</font>)
      javafile = java.io.<font color="#00ffff">File</font>.new(filename)
      <font color="#00ffff">ChartUtilities</font>.saveChartAsPNG(javafile, <font color="#00ffff">@chart</font>, <font color="#00ffff">@width</font>, <font color="#00ffff">@height</font>)
    <font color="#ff40ff">end</font>

    private
<font color="#ff40ff">    def </font><font color="#00ffff">create_sample_data</font>
      <font color="#8080ff"># dates as milliseconds seems the easiet</font>
      now = <font color="#00ffff">System</font>.currentTimeMillis
      tomorrow = now + (<font color="#00ffff">MILLIS_IN_A_DAY</font> * <font color="#ff6060">1</font>)
      day_after_tomorrow = now + (<font color="#00ffff">MILLIS_IN_A_DAY</font> * <font color="#ff6060">2</font>)
      week_from_today = now + (<font color="#00ffff">MILLIS_IN_A_DAY</font> * <font color="#ff6060">7</font>)

      s1 = <font color="#00ffff">TaskSeries</font>.new(<font color="#ff40ff">&quot;</font><font color="#ff6060">JRuby</font><font color="#ff40ff">&quot;</font>)
      s1.add(<font color="#00ffff">Task</font>.new(<font color="#ff40ff">&quot;</font><font color="#ff6060">Download JRuby</font><font color="#ff40ff">&quot;</font>,
                      <font color="#00ffff">SimpleTimePeriod</font>.new(now, tomorrow)))
      s1.add(<font color="#00ffff">Task</font>.new(<font color="#ff40ff">&quot;</font><font color="#ff6060">Write Code</font><font color="#ff40ff">&quot;</font>,
                      <font color="#00ffff">SimpleTimePeriod</font>.new(tomorrow, day_after_tomorrow)))
      s1.add(<font color="#00ffff">Task</font>.new(<font color="#ff40ff">&quot;</font><font color="#ff6060">Setup CLASSPATH</font><font color="#ff40ff">&quot;</font>,
                      <font color="#00ffff">SimpleTimePeriod</font>.new(day_after_tomorrow, week_from_today)))

      s2 = <font color="#00ffff">TaskSeries</font>.new(<font color="#ff40ff">&quot;</font><font color="#ff6060">Java</font><font color="#ff40ff">&quot;</font>)
      s2.add(<font color="#00ffff">Task</font>.new(<font color="#ff40ff">&quot;</font><font color="#ff6060">Read Comics</font><font color="#ff40ff">&quot;</font>,
                      <font color="#00ffff">SimpleTimePeriod</font>.new(now, tomorrow)))
      s2.add(<font color="#00ffff">Task</font>.new(<font color="#ff40ff">&quot;</font><font color="#ff6060">Write Code</font><font color="#ff40ff">&quot;</font>,
                      <font color="#00ffff">SimpleTimePeriod</font>.new(tomorrow, day_after_tomorrow)))
      s2.add(<font color="#00ffff">Task</font>.new(<font color="#ff40ff">&quot;</font><font color="#ff6060">Setup CLASSPATH</font><font color="#ff40ff">&quot;</font>,
                      <font color="#00ffff">SimpleTimePeriod</font>.new(day_after_tomorrow, week_from_today)))

      collection = <font color="#00ffff">TaskSeriesCollection</font>.new
      collection.add(s1)
      collection.add(s2)
      <font color="#ffff00">return</font> collection
    <font color="#ff40ff">end</font>

<font color="#ff40ff">    def </font><font color="#00ffff">create_chart</font>(dataset)
      opts = {
              <font color="#00ffff">:title</font> =&gt; <font color="#00ffff">@title</font>,
              <font color="#00ffff">:domain_axis_label</font> =&gt; <font color="#ff40ff">&quot;</font><font color="#ff6060">Task</font><font color="#ff40ff">&quot;</font>,
              <font color="#00ffff">:range_axis_label</font> =&gt; <font color="#ff40ff">&quot;</font><font color="#ff6060">Date</font><font color="#ff40ff">&quot;</font>,
              <font color="#00ffff">:data</font> =&gt; dataset,
              <font color="#00ffff">:include_legend</font> =&gt; <font color="#ff6060">true</font>,
              <font color="#00ffff">:tooltips</font> =&gt; <font color="#ff6060">false</font>,
              <font color="#00ffff">:urls</font> =&gt; <font color="#ff6060">false</font>
             }
      chart = <font color="#00ffff">ChartFactory</font>.createGanttChart(
                                              opts[<font color="#00ffff">:title</font>],
                                              opts[<font color="#00ffff">:domain_axis_label</font>],
                                              opts[<font color="#00ffff">:range_axis_label</font>],
                                              opts[<font color="#00ffff">:data</font>],
                                              opts[<font color="#00ffff">:include_legend</font>],
                                              opts[<font color="#00ffff">:tooltips</font>],
                                              opts[<font color="#00ffff">:urls</font>]
                                            )
      <font color="#ffff00">return</font> chart
    <font color="#ff40ff">end</font>

  <font color="#ff40ff">end</font> <font color="#8080ff"># class Simple</font>
<font color="#ff40ff">end</font> <font color="#8080ff"># module Gantt</font>

chart = <font color="#00ffff">Gantt</font>::<font color="#00ffff">Simple</font>.new(<font color="#ff40ff">&quot;</font><font color="#ff6060">Gantt Chart Demo</font><font color="#ff40ff">&quot;</font>)
puts <font color="#ff40ff">&quot;</font><font color="#ff6060">Rendering chart</font><font color="#ff40ff">&quot;</font>
chart.render_to_file(<font color="#ff40ff">&quot;</font><font color="#ff6060">simplegantt.png</font><font color="#ff40ff">&quot;</font>)
</pre>
<p>Example PNG:</p>
<p><a href="http://kfahlgren.com/photos/work/simplegantt.png"><img src="http://kfahlgren.com/photos/work/simplegantt.png" alt="A Simple Gantt Chart Example" /></a></p>
<p>Code: <a href="http://kfahlgren.com/code/simple_gantt.jrb">http://kfahlgren.com/code/simple_gantt.jrb</a></p>
]]></content:encoded>
			<wfw:commentRss>http://kfahlgren.com/blog/2007/04/12/more-jruby-play-jfreechart/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Borrowing Java&#8217;s XSLT Support for Ruby</title>
		<link>http://kfahlgren.com/blog/2007/03/02/borrowing-javas-xslt-support-for-ruby/</link>
		<comments>http://kfahlgren.com/blog/2007/03/02/borrowing-javas-xslt-support-for-ruby/#comments</comments>
		<pubDate>Fri, 02 Mar 2007 20:56:50 +0000</pubDate>
		<dc:creator>Keith</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[JRuby]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[XSLT]]></category>

		<guid isPermaLink="false">http://kfahlgren.com/blog/2007/03/02/borrowing-javas-xslt-support-for-ruby/</guid>
		<description><![CDATA[Well, I finally caught up with the crowd and got JRuby running on one of my dev boxes. The reason I&#8217;d been interested in it from the getgo was because Ruby lacks any support for internal XSLT processing. All those system()s were starting to get me down, especially as I&#8217;m trying to get a DocBook->PDF [...]]]></description>
			<content:encoded><![CDATA[<p>Well, I finally caught up with the crowd and got <a href="http://jruby.codehaus.org/">JRuby</a> running on one of my dev boxes. The reason I&#8217;d been interested in it from the getgo was because Ruby lacks any support for internal XSLT processing. All those <tt>system()</tt>s were starting to get me down, especially as I&#8217;m trying to get a DocBook->PDF rendering webservice to be a lot faster. Much to my surprise, I was able to get simple transforms working in almost no time (thanks in part to lots of help). Without further ado, here&#8217;s a simple library for XSLT transforms using either <a href="http://xml.apache.org/xalan-j/">Xalan-J</a> or <a href="http://sourceforge.net/projects/saxon/">Saxon</a> (make sure you have the <tt>jar</tt>s for both in your <tt>CLASSPATH</tt>):</p>
<pre>require 'java'
module JXslt
  include_class "javax.xml.transform.TransformerFactory"
  include_class "javax.xml.transform.Transformer"
  include_class "javax.xml.transform.stream.StreamSource"
  include_class "javax.xml.transform.stream.StreamResult"
  include_class "java.lang.System"

  class XsltProcessor
    def transform(xslt,infile,outfile)
      transformer = @tf.newTransformer(StreamSource.new(xslt))
      transformer.transform(StreamSource.new(infile), StreamResult.new(outfile))
    end
  end # XsltProcessor
  class Saxon < XsltProcessor
    TRANSFORMER_FACTORY_IMPL = "net.sf.saxon.TransformerFactoryImpl"
    def initialize
      System.setProperty("javax.xml.transform.TransformerFactory", TRANSFORMER_FACTORY_IMPL)
      @tf = TransformerFactory.newInstance
    end
  end
  class Xalan < XsltProcessor
    TRANSFORMER_FACTORY_IMPL = "org.apache.xalan.processor.TransformerFactoryImpl"
    def initialize
      System.setProperty("javax.xml.transform.TransformerFactory", TRANSFORMER_FACTORY_IMPL)
      @tf = TransformerFactory.newInstance
    end
  end
end 

# if you wanted to run this from the command line, do something like
# $ jruby lib/jxslt.rb a.xsl in.xml out.xml
xalan = JXslt::Xalan.new
xalan.transform(*ARGV)
#saxon = JXslt::Saxon.new
#saxon.transform(*ARGV)
</pre>
<p>Big props to <a href="http://blog.earstu.org/">Charles</a> for helping me get going and writing the first version of the above.</p>
<p><tt>darcs get http://kfahlgren.com/code/lib/jxslt/</tt> or <a href="http://kfahlgren.com/code/lib/jxslt/jxslt.rb">jxslt.rb</a></pre>
]]></content:encoded>
			<wfw:commentRss>http://kfahlgren.com/blog/2007/03/02/borrowing-javas-xslt-support-for-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

