gen_svg (SVG::Graph::Bar)

    # File temp/Graph/Bar.rb, line 216
          def gen_svg
            d = Document.new
            d << XMLDecl.new
            d << DocType.new( %{svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"} )
            if style_sheet && style_sheet != ''
              d << ProcessingInstruction.new( "xml-stylesheet",
                %{href="#{style_sheet}" type="text/css"} )
            end
            root = d.add_element( "svg", {
              "width" => width,
              "height" => height,
              "viewBox" => "0 0 #{width} #{height}",
              "xmlns" => "http://www.w3.org/2000/svg",
              "xmlns:xlink" => "http://www.w3.org/1999/xlink"
            })
            root << Comment.new( " "+"\\"*66 )
            root << Comment.new( " Created with SVG::Graph " )
            root << Comment.new( " Sean Russell " )
            root << Comment.new( " Based on SVG::TT::Graph for Perl by"+
            " Leo Lapworth & Stephan Morgan " )
            root << Comment.new( " "+"/"*66 )

            if not(style_sheet && style_sheet != '')
              root << Comment.new(" include default stylesheet if none specified ")
              defs = root.add_element( "defs" )
              style = defs.add_element( "style", {"type"=>"text/css"} )
              style << CData.new( CSS )
            end

            root << Comment.new( "SVG Background" )
            root.add_element( "rect", {
              "width" => width,
              "height" => height,
              "x" => "0",
              "y" => "0",
              "class" => "svgBackground"
            })

            # Calculate graph area and boundries
            x = 0
            y = 0
            char_width = 9
            half_char_height = 2.5

            min_value = 9e20
            max_value = 0
            max_key_size = 0
            max_x_label_size = @config[:fields].max{ |a,b|
              a.length <=> b.length
            }.length

            for data in @data
              dataset = data[:data]
              title = data[:title]

              dm = dataset.min
              min_value = dm < min_value ? dm : min_value
              dm = dataset.max
              max_value = dm > max_value ? dm : max_value
              max_key_size = title.length if title.length > max_key_size
            end

            h = height
            w = width
            h -= 20 if show_x_labels
            max_x_label_length = 0
            if rotate_x_labels
              max_x_label_length = max_x_label_size * char_width
              h -= max_x_label_length
            end

            stagger = 0
            if stagger_x_labels
              stagger = 17
              h -= stagger
            end

            h = h - 25 - stagger if show_x_title

            if show_y_labels
              h -= 10
              y += 10
            end

            if show_graph_title
              h -= 25
              y += 25
            end

            if show_graph_subtitle
              h -= 10
              y += 10
            end

            key_box_size = 12
            key_padding = 5

            if key && key_position == :right
              w = w - (max_key_size * (char_width - 1)) - (key_box_size * 3 )
            elsif key && key_position == :bottom
              if data.size > 4
                h -= (data.size + 1) * (key_box_size + key_padding)
              else
                h -= 4 * (key_box_size + key_padding)
              end
            end

            minvalue = min_value
            minvalue = min_scale_value if min_scale_value

            base_line = h + y

            temp = max_value - minvalue
            top_pad = temp == 0 ? 10 : temp / 20.0

            scale_range = (max_value + top_pad) - minvalue

            scale_division = scale_divisions || (scale_range / 10.0)

            if scale_integers
              scale_division = scale_division < 1 ? 1 : scale_division.round
            end

            dx = @config[:fields].size
            data_widths_x = w / dx
            dw = data_widths_x

            half_label_width = @config[:fields][0].length/2 * char_width

            space_b4_y_axis = 0
            if half_label_width > (dw / 2)
              space_b4_y_axis = half_label_width - (dw / 2)
              if key && key_position == :right
                w = w - space_b4_y_axis
              else
                w = w - (space_b4_y_axis * 2)
              end
              x = x + space_b4_y_axis
            end

            max_value_length = max_value.to_s.length

            max_value_length_px = max_value_length * char_width

            if show_y_labels && space_b4_y_axis < max_value_length_px
              if max_value_length < 2
                w = w - (max_value_length * (char_width * 2)) - char_width
                x = x + (max_value_length * (char_width * 2)) + char_width
              else
                w = w - max_value_length_px + char_width
                x = x + max_value_length_px + char_width
              end
            end

            if show_y_title && space_b4_y_axis < max_value_length_px
              w = w - 25
              x = x + 25
            end

            # Background
            root.add_element( "rect", {
              "x" => x,
              "y" => y,
              "width" => w,
              "height" => h,
              "class" => "graphBackground"
            })

            # Axis
            root.add_element( "path", {
              "d" => "M #{x} #{y} v#{h}",
              "class" => "axis",
              "id" => "xAxis"
            })
            root.add_element( "path", {
              "d" => "M #{x} #{base_line} h#{w}",
              "class" => "axis",
              "id" => "yAxis"
            })

            dx = @config[:fields].size

            data_widths_x = w / dx

            dw = (data_widths_x*100).truncate / 100.0

            i = dw
            count = 0

            if bar_gap
              bargap = 10
              bargap = dw / 2 if dw < bargap
            else
              bargap = 0
            end

            stagger_count = 0
            if show_x_labels
              for field in @config[:fields]
                text = root.add_element( "text" )
                text.attributes["class"] = "xAxisLabels"
                text.text = field

                tx = x + (dw / 2) - (bargap / 2)
                ty = base_line + 15
                tt = x + ( dw / 2 ) - ( bargap / 2 ) - half_char_height

                if count == 0
                  i -= dw
                else
                  tx += i
                  tt += i
                  if stagger_count == 2
                    stagger_count = 0
                  else
                    ty += stagger
                    root.add_element( "path", {
                      "d" => "M#{tx} #{base_line}, v#{stagger}",
                      "class" => "staggerGuideLine"
                    })
                  end
                end

                text.attributes["x"] = tx
                text.attributes["y"] = ty
                if rotate_x_labels
                  text.attributes["transform"] = "rotate( 90 #{tt} #{ty} )"
                  text.attributes["style"] = "text-anchor: start"
                end

                i += dw
                count += 1
                stagger_count += 1
              end
            end

            dy = scale_range / scale_division
            y_marker_height = h.to_f / dy
            dy = y_marker_height.to_i
            count = 0
            y_value = min_scale_value
            if show_y_labels
              while (dy * count) < h
                root.add_element( "text", {
                  "x" => x - 5,
                  "y" => base_line - (dy * count),
                  "class" => "yAxisLabels"
                }).text = y_value
                if count != 0
                  root.add_element( "path", {
                    "d" => "M#{x} #{base_line - (dy * count)} h#{w}",
                    "class" => "guideLines"
                  })
                end
                y_value = y_value + scale_division
                count += 1
              end
            end

            if show_x_title
              y_xtitle = show_x_labels ? 35 : 15
              root.add_element( "text", {
                "x" => (w / 2) + x,
                "y" => h + y + y_xtitle + stagger + max_x_label_length,
                "class" => "xAxisTitle"
              }).text = x_title
            end

            if show_y_title
              text = root.add_element( "text", { "class" => "yAxisTitle" } )
              text.text = y_title
              if y_title_text_direction == :tb
                text.attributes["x"] = 12
                text.attributes["y"] = (h / 2) + y
                text.attributes["style"] = "writing-mode: tb;"
              else
                text.attributes["transform"]="translate(15, #{(h/2)+y}) rotate(270)"
              end
            end

            bar_width = dw - bargap
            divider = dy / scale_division

            xcount = 0

            subbar_width = bar_width
            subbar_width /= @data.length if stack == :side
            @config[:fields].each_index { |i|
              dcount = 1
              for dataset in @data
                # X1
                p1 = (dw * xcount) + x
                # Y1
                p2 = base_line
                # to Y2
                p3 = base_line - (dataset[:data][i] * divider)
                # to X2
                p4 = subbar_width
                case stack
                when :side
                  p1 += (dcount-1) * subbar_width
                when :top
                else
                end
                root.add_element( "path", {
                  "class" => "fill#{dcount}",
                  "d" => "M#{p1} #{p2} V#{p3} h#{p4} V#{p2} Z"
                })
                if show_data_values
                  root.add_element( "text", {
                    "x" => p1 + ((dw-bargap)/2)-(stack==:side ? subbar_width/2 : 0),
                    "y" => p3 - 6,
                    "class" => "dataPointLabel"
                  } ).text = dataset[:data][i].to_s
                end
                dcount += 1
              end
              xcount += 1
            }

            key_count = 1
            key_padding = 5
            if key && key_position == :right
              for dataset in @data
                yval = y + (key_box_size * key_count) + (key_count * key_padding)
                root.add_element( "rect", {
                  "x" => x + w + 20,
                  "y" => yval,
                  "width" => key_box_size,
                  "height" => key_box_size,
                  "class" => "key#{key_count}"
                })
                root.add_element( "text", {
                  "x" => x + w + 20 + key_box_size + key_padding,
                  "y" => yval + key_box_size,
                  "class" => "keyText"
                }).text = dataset[:title]
                key_count += 1
              end
            elsif key && key_position == :bottom
              y_key = base_line
              y_key += 25 if show_x_title
              if rotate_x_labels && show_x_labels
                y_key = y_key + max_x_label_length
              elsif show_x_labels && stagger < 1
                y_key = y_key + 20
              end

              y_key_start = y_key
              x_key = x
              for dataset in @data
                if key_count == 4 || key_count == 7 || key_count == 10
                  x_key += 200
                  y_key -= (key_box_size * 4) - 2
                end
                wh = key_box_size
                bs = y_key + (key_box_size * key_count) +
                (key_count * key_padding) + stagger
                cl = "key#{key_count}"
                root.add_element( "rect", {
                  "x" => x_key,
                  "y" => bs,
                  "width" => wh,
                  "height" => wh,
                  "class" => cl
                })
                root.add_element( "text", {
                  "x" => x_key + key_box_size + key_padding,
                  "y" => bs + key_box_size,
                  "width" => wh,
                  "height" => wh,
                  "class" => cl
                }).text = dataset[:title]
                key_count += 1
              end
            end

            if show_graph_title
              root.add_element( "text", {
                "x" => width / 2,
                "y" => "15",
                "class" => "mainTitle"
              }).text = graph_title
            end

            if show_graph_subtitle
              y_subtitle = show_graph_title ? 30 : 15
              root.add_element("text", {
                "x" => width / 2,
                "y" => y_subtitle,
                "class" => "subTitle"
              }).text = graph_subtitle
            end

            return d
          end