Harry Seldon's blog

Psychohistory on Rails

Read

Tutorial Rails/OFC/Ajax : Alter the chart using Javascript

Posted by Harry Seldon on September 28, 2008

In a first example I showed how to load a chart using javascript. Here I will show you how to dynamically alter an OFC chart without recreating it. This example is a raw adaptation of this Teethgrinder’s example. The chart is hard coded in ajax code so it is not loaded by OFC rails plugin, this will be done in a next example. Indeed, the aim of all this is at some point to be able to create a chart and then modify it to hide one signal or to zoom in or to change the legend, or etc.

The controller code is simple. Well OK it is even void (as I said the graph is hard coded in the javascript, it gives you opportunity to see how an OFC graph is serialized in json):

class TestItController < ApplicationController
def index_js_4
end
end

Everything happens in the view (index_js_4.html.erb) through ajax code and OFC code. I assume you have installed OFC rails plugin. You need 2 more things: the json2 library available here and the ajax code from Teethgrinder available here. Put these 2 js files in your public/javascripts folder.

The view:

<html>
    <head>
        <%#= javascript_include_tag :defaults, 'swfobject' %>
        <script type="text/javascript" src="/javascripts/swfobject.js">
        </script>
        <script type="text/javascript" src="/javascripts/json2.js">
        </script>
        <script type="text/javascript" src="/javascripts/tutorial-js.js">
        </script>
        <script type="text/javascript">

            function ofc_ready(){
                alert('ofc_ready');
            }

            function open_flash_chart_data(){
                // alert( 'reading data' );
                return JSON.stringify(data);
            }

            function findSWF(movieName){
                if (navigator.appName.indexOf("Microsoft") != -1) {
                    return window[movieName];
                }
                else {
                    return document[movieName];
                }
            }

            var data = {
                "elements": [{
                    "type": "hbar",
                    "values": [{
                        "left": 0,
                        "right": 5
                    }, {
                        "left": 0,
                        "right": 3
                    }, {
                        "left": 4,
                        "right": 8
                    }, {
                        "left": 4,
                        "right": 8
                    }, {
                        "left": 4,
                        "right": 8
                    }],
                    "colour": "#AF99DF"
                }],
                "title": {
                    "text": "Sat Sep 27 2008"
                },
                "y_axis": {
                    "labels": ["Job 1", "Job 2", "Job 3", "Job 4", "Job 5"]
                },
                "x_axis": {
                    "offset": false,
                    "min": 0,
                    "max": 10
                }
            };
        </script>
        <script type="text/javascript">
            swfobject.embedSWF("/open-flash-chart.swf", "my_chart", "550", "350", "9.0.0");
        </script>
    </head>
    <body>
    Here is the chart:
    </p>
    <div id="my_chart"></div>
    <p>
        <a href="javascript:update(data)">Update</a>, <a href="javascript:save(data)">Save</a>
    </p>
    <br/><br/>
    </body>
</html>

To understand this example have a look at the js file tutorial-js.js. It contains the update and save functions. It is understandable even by someone like me who does not speak javascript fluently. You can see the live example here.

Posted in | no comments |

A Rails/OFC/Ajax raw example

Posted by Harry Seldon on September 27, 2008

Here is a simple exercise to use Rails, OFC, OFC rails plugin and ajax together. The idea is just to follow the example given here in php. At first I did not manage to get this working. That is why I asked some help to Pullmonkey. He did a great job to make this working in this nice post . Moreover, he came up with nice improvements on OFC to render a chart using ajax and using Rails helper to keep a pretty code (you need to update OFC plugin to make his example work). However I want to show you here the translation in Rails of Teethgrinder’s tutorial with minimum code (no need to update OFC plugin).

Controller code (test_it_controller.rb), notice it has the original php code from teethgrinder in it.

class TestItController < ApplicationController
def tuto_5
    title = Title.new("tuto_5")
    #$title = new title( date("D M d Y") );
    #$chart = new open_flash_chart();
    @chart = OpenFlashChart.new
    #$bar = new bar();
    bar = BarGlass.new
    #$bar->set_values( array(9,8,7,6,5,4,3,2,1) );
    bar.set_values([1,2,3,4,5,6,7,8,9])
    #$chart->set_title( $title );
    @chart.set_title(title)
    #$chart->add_element( $bar );
    @chart.add_element(bar)
end
end

Then I had directly coded the view code (tuto5.html.erb) without helpers (and quite ugly) :

<head>
<script type="text/javascript" src="/javascripts/json2.js"></script>
<script type="text/javascript" src="/javascripts/swfobject.js"></script>
</head>

<body>
<script type="text/javascript">
swfobject.embedSWF("/open-flash-chart.swf", "my_chart", "350", "200", "9.0.0");
</script>
<script type="text/javascript">

function ofc_ready()
{
    alert('ofc_ready');
}

function open_flash_chart_data()
{
    alert( 'reading data' );
    return JSON.stringify(data);
}

function findSWF(movieName) {
  if (navigator.appName.indexOf("Microsoft")!= -1) {
    return window[movieName];
  } else {
    return document[movieName];
  }
}

var data = <%= @chart.to_s %>;
</script>

<p>Hello World</p>
<div id="my_chart"></div>
</body>

In this example you need the json2.js library that you can find here. However notice that Pullmonkey uses directly the json capabilities of Rails which is a much better way.
This code works, you can check it out here.

Thanks to Pullmonkey ! H

Posted in | no comments |

A Rails/OFC/Ajax example

Posted by Harry Seldon on September 27, 2008

Following this nice work from Pullmonkey, here is a small example on how to use OFCII to dynamically load a chart. We will display a line chart and then dynamically add one more line.

Controller code (test_it_controller.rb):

class TestItController < ApplicationController
def index_js_3_line
   title = Title.new("Multiple Lines")

    data1 = [5, 3, 4, 1, 3, 2, 5, 4, 3, 3]
    data2 = [12, 9, 9, 7, 8, 8, 9, 9, 8, 9]
    data3 = [16, 14, 17, 18, 14, 15, 16, 18, 15, 15]

    line_dot = LineDot.new
    line_dot.text = "Line Dot"
    line_dot.width = 4
    line_dot.colour = '#DFC329'
    line_dot.dot_size = 5
    line_dot.values = data1

    line_hollow = LineHollow.new
    line_hollow.text = "Line Hollow"
    line_hollow.width = 1
    line_hollow.colour = '#6363AC'
    line_hollow.dot_size = 5
    line_hollow.values = data2

    line = Line.new
    line.text = "Line"
    line.width = 1
    line.colour = '#5E4725'
    line.dot_size = 5
    line.values = data3

    y = YAxis.new
    y.set_range(0,20,5)

    x_legend = XLegend.new("MY X Legend")
    x_legend.set_style('{font-size: 20px; color: #778877}')

    y_legend = YLegend.new("MY Y Legend")
    y_legend.set_style('{font-size: 20px; color: #770077}')

    chart = OpenFlashChart.new
    chart.set_title(title)
    chart.set_x_legend(x_legend)
    chart.set_y_legend(y_legend)
    chart.y_axis = y

    chart.add_element(line_dot)
    chart.add_element(line_hollow)
    @chart = chart
  end

  def some_server_data_line
    title = Title.new("Multiple Lines")

    data1 = [5, 3, 4, 1, 3, 2, 5, 4, 3, 3]
    data2 = [12, 9, 9, 7, 8, 8, 9, 9, 8, 9]
    data3 = [16, 14, 17, 18, 14, 15, 16, 18, 15, 15]

    line_dot = LineDot.new
    line_dot.text = "Line Dot"
    line_dot.width = 4
    line_dot.colour = '#DFC329'
    line_dot.dot_size = 5
    line_dot.values = data1

    line_hollow = LineHollow.new
    line_hollow.text = "Line Hollow"
    line_hollow.width = 1
    line_hollow.colour = '#6363AC'
    line_hollow.dot_size = 5
    line_hollow.values = data2

    line = Line.new
    line.text = "Line"
    line.width = 1
    line.colour = '#5E4725'
    line.dot_size = 5
    line.values = data3

    y = YAxis.new
    y.set_range(0,20,5)

    x_legend = XLegend.new("MY X Legend")
    x_legend.set_style('{font-size: 20px; color: #778877}')

    y_legend = YLegend.new("MY Y Legend")
    y_legend.set_style('{font-size: 20px; color: #770077}')

    chart =OpenFlashChart.new
    chart.set_title(title)
    chart.set_x_legend(x_legend)
    chart.set_y_legend(y_legend)
    chart.y_axis = y

    chart.add_element(line_dot)
    chart.add_element(line_hollow)
    chart.add_element(line)

    render :text => chart.to_s
  end
end

And in the view (index_js_3_line.html.erb):

<html>
  <head>
    <%= javascript_include_tag :defaults, 'swfobject' %>
  </head>
  <body>
    <%= @chart.js_open_flash_chart_object("my_chart_js_1", 550,300) %>
    <br/><br/>
    <%= @chart.link_to_ofc_load("Load Original Chart", "my_chart_js_1") %> ||
    <%= @chart.link_to_remote_ofc_load("Load Chart from server data", "my_chart_js_1", "/test_it/some_server_data_line") %>
  </body>
</html>

You can see this example in live here : http://www.thinkosphere.com/test_it/index_js_3_line.

Actually there is some “cheating” involved. Indeed we simply load a first chart and then reload a new chart identical with one more line. Next step is to load once the whole graph and to dynamically modify the JSON Data to display one line or another.

H

Posted in | no comments |

Search