ChartDirector 6.0 (Ruby Edition)

Multi-Stacked Bar Chart




This example demonstrates combining multi-bar style with stacked bar style. It also demonstrates drawing horizontal bar charts, using icons in axis labels with CDML, customizing legend and bar labels, controlling bar widths and centering legend box.

A multi-stacked bar chart combines the multi-bar style with the stacked bar style by allowing each bar in a multi-bar chart to be a stacked bar. This provides two levels of data grouping. The data from the data sets are clusters based on their index position. Within each cluster, the data are grouped again to form stack bars.

The standard multi-bar chart provides the first level of grouping. The Layer.addDataGroup method is used to provide the second level of grouping.

The key features demonstrated in this example are:

Source Code Listing

[Ruby On Rails Version - Controller] app/controllers/multistackbar_controller.rb
require("chartdirector")

class MultistackbarController < ApplicationController

    def index()
        @title = "Multi-Stacked Bar Chart"
        @ctrl_file = File.expand_path(__FILE__)
        @noOfCharts = 1
        render :template => "templates/chartview"
    end

    #
    # Render and deliver the chart
    #
    def getchart()
        # The data for the bar chart
        data0 = [44, 55, 100]
        data1 = [97, 87, 167]
        data2 = [156, 78, 147]
        data3 = [125, 118, 211]

        # The labels for the bar chart. The labels contains embedded images as icons.
        labels = ["<*img=service.png*><*br*>Service", "<*img=software.png*><*br*>Software",
            "<*img=computer.png*><*br*>Hardware"]

        # Create a XYChart object of size 600 x 350 pixels, using 0xe0e0ff as the background color,
        # 0xccccff as the border color, with 1 pixel 3D border effect.
        c = ChartDirector::XYChart.new(600, 350, 0xe0e0ff, 0xccccff, 1)

        # Set directory for loading images to current script directory
        c.setSearchPath(File.dirname(__FILE__))

        # Add a title to the chart using 14 points Times Bold Itatic font and light blue (0x9999ff)
        # as the background color
        c.addTitle("Business Results 2001 vs 2002", "timesbi.ttf", 14).setBackground(0x9999ff)

        # Set the plotarea at (60, 45) and of size 500 x 210 pixels, using white (0xffffff) as the
        # background
        c.setPlotArea(60, 45, 500, 210, 0xffffff)

        # Swap the x and y axes to create a horizontal bar chart
        c.swapXY()

        # Add a title to the y axis using 11 pt Times Bold Italic as font
        c.yAxis().setTitle("Revenue (millions)", "timesbi.ttf", 11)

        # Set the labels on the x axis
        c.xAxis().setLabels(labels)

        # Disable x-axis ticks by setting the tick length to 0
        c.xAxis().setTickLength(0)

        # Add a stacked bar layer to the chart
        layer = c.addBarLayer2(ChartDirector::Stack)

        # Add the first two data sets to the chart as a stacked bar group
        layer.addDataGroup("2001")
        layer.addDataSet(data0, 0xaaaaff, "Local")
        layer.addDataSet(data1, 0x6666ff, "International")

        # Add the remaining data sets to the chart as another stacked bar group
        layer.addDataGroup("2002")
        layer.addDataSet(data2, 0xffaaaa, "Local")
        layer.addDataSet(data3, 0xff6666, "International")

        # Set the sub-bar gap to 0, so there is no gap between stacked bars with a group
        layer.setBarGap(0.2, 0)

        # Set the bar border to transparent
        layer.setBorderColor(ChartDirector::Transparent)

        # Set the aggregate label format
        layer.setAggregateLabelFormat("Year {dataGroupName}\n{value} millions")

        # Set the aggregate label font to 8 point Arial Bold Italic
        layer.setAggregateLabelStyle("arialbi.ttf", 8)

        # Reverse 20% space at the right during auto-scaling to allow space for the aggregate bar
        # labels
        c.yAxis().setAutoScale(0.2)

        # Add a legend box at (310, 300) using TopCenter alignment, with 2 column grid layout, and
        # use 8pt Arial Bold Italic as font
        legendBox = c.addLegend2(310, 300, 2, "arialbi.ttf", 8)
        legendBox.setAlignment(ChartDirector::TopCenter)

        # Set the format of the text displayed in the legend box
        legendBox.setText("Year {dataGroupName} {dataSetName} Revenue")

        # Set the background and border of the legend box to transparent
        legendBox.setBackground(ChartDirector::Transparent, ChartDirector::Transparent)

        # Output the chart
        send_data(c.makeChart2(ChartDirector::PNG), :type => "image/png", :disposition => "inline")

    end

end

[Ruby On Rails Version - View] app/views/templates/chartview.html.erb
<html>
<body style="margin:5px 0px 0px 5px">

<!-- Title -->
<div style="font-size:18pt; font-family:verdana; font-weight:bold">
    <%= @title %>
</div>
<hr style="border:solid 1px #000080" />

<!-- Source Code Listing Link -->
<div style="font-size:9pt; font-family:verdana; margin-bottom:1.5em">
    <%= link_to "Source Code Listing", 
        :controller => "cddemo", :action => "viewsource",
        :ctrl_file => @ctrl_file, :view_file => File.expand_path(__FILE__) %>
</div>

<!-- Create one or more IMG tags to display the demo chart(s) -->
<% 0.upto(@noOfCharts - 1) do |i| %>
    <img src="<%= url_for(:action => "getchart", :img => i) %>">
<% end %>

</body>
</html>

[Command Line Version] rubydemo/multistackbar.rb
#!/usr/bin/env ruby
require("chartdirector")

# The data for the bar chart
data0 = [44, 55, 100]
data1 = [97, 87, 167]
data2 = [156, 78, 147]
data3 = [125, 118, 211]

# The labels for the bar chart. The labels contains embedded images as icons.
labels = ["<*img=service.png*><*br*>Service", "<*img=software.png*><*br*>Software",
    "<*img=computer.png*><*br*>Hardware"]

# Create a XYChart object of size 600 x 350 pixels, using 0xe0e0ff as the background color, 0xccccff
# as the border color, with 1 pixel 3D border effect.
c = ChartDirector::XYChart.new(600, 350, 0xe0e0ff, 0xccccff, 1)

# Add a title to the chart using 14 points Times Bold Itatic font and light blue (0x9999ff) as the
# background color
c.addTitle("Business Results 2001 vs 2002", "timesbi.ttf", 14).setBackground(0x9999ff)

# Set the plotarea at (60, 45) and of size 500 x 210 pixels, using white (0xffffff) as the
# background
c.setPlotArea(60, 45, 500, 210, 0xffffff)

# Swap the x and y axes to create a horizontal bar chart
c.swapXY()

# Add a title to the y axis using 11 pt Times Bold Italic as font
c.yAxis().setTitle("Revenue (millions)", "timesbi.ttf", 11)

# Set the labels on the x axis
c.xAxis().setLabels(labels)

# Disable x-axis ticks by setting the tick length to 0
c.xAxis().setTickLength(0)

# Add a stacked bar layer to the chart
layer = c.addBarLayer2(ChartDirector::Stack)

# Add the first two data sets to the chart as a stacked bar group
layer.addDataGroup("2001")
layer.addDataSet(data0, 0xaaaaff, "Local")
layer.addDataSet(data1, 0x6666ff, "International")

# Add the remaining data sets to the chart as another stacked bar group
layer.addDataGroup("2002")
layer.addDataSet(data2, 0xffaaaa, "Local")
layer.addDataSet(data3, 0xff6666, "International")

# Set the sub-bar gap to 0, so there is no gap between stacked bars with a group
layer.setBarGap(0.2, 0)

# Set the bar border to transparent
layer.setBorderColor(ChartDirector::Transparent)

# Set the aggregate label format
layer.setAggregateLabelFormat("Year {dataGroupName}\n{value} millions")

# Set the aggregate label font to 8 point Arial Bold Italic
layer.setAggregateLabelStyle("arialbi.ttf", 8)

# Reverse 20% space at the right during auto-scaling to allow space for the aggregate bar labels
c.yAxis().setAutoScale(0.2)

# Add a legend box at (310, 300) using TopCenter alignment, with 2 column grid layout, and use 8pt
# Arial Bold Italic as font
legendBox = c.addLegend2(310, 300, 2, "arialbi.ttf", 8)
legendBox.setAlignment(ChartDirector::TopCenter)

# Set the format of the text displayed in the legend box
legendBox.setText("Year {dataGroupName} {dataSetName} Revenue")

# Set the background and border of the legend box to transparent
legendBox.setBackground(ChartDirector::Transparent, ChartDirector::Transparent)

# Output the chart
c.makeChart("multistackbar.png")