mirror of
				https://github.com/redmine/redmine.git
				synced 2025-11-03 20:06:24 +01:00 
			
		
		
		
	
		
			
	
	
		
			395 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
		
		
			
		
	
	
			395 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| 
								 | 
							
								require 'SVG/Graph/Graph'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module SVG
							 | 
						||
| 
								 | 
							
								  module Graph
							 | 
						||
| 
								 | 
							
								    # === Create presentation quality SVG pie graphs easily
							 | 
						||
| 
								 | 
							
								    # 
							 | 
						||
| 
								 | 
							
								    # == Synopsis
							 | 
						||
| 
								 | 
							
								    # 
							 | 
						||
| 
								 | 
							
								    #   require 'SVG/Graph/Pie'
							 | 
						||
| 
								 | 
							
								    # 
							 | 
						||
| 
								 | 
							
								    #   fields = %w(Jan Feb Mar)
							 | 
						||
| 
								 | 
							
								    #   data_sales_02 = [12, 45, 21]
							 | 
						||
| 
								 | 
							
								    #   
							 | 
						||
| 
								 | 
							
								    #   graph = SVG::Graph::Pie.new({
							 | 
						||
| 
								 | 
							
								    #   	:height => 500,
							 | 
						||
| 
								 | 
							
								    # 	  :width  => 300,
							 | 
						||
| 
								 | 
							
								    # 	  :fields => fields,
							 | 
						||
| 
								 | 
							
								    #   })
							 | 
						||
| 
								 | 
							
								    #   
							 | 
						||
| 
								 | 
							
								    #   graph.add_data({
							 | 
						||
| 
								 | 
							
								    #   	:data => data_sales_02,
							 | 
						||
| 
								 | 
							
								    # 	  :title => 'Sales 2002',
							 | 
						||
| 
								 | 
							
								    #   })
							 | 
						||
| 
								 | 
							
								    #   
							 | 
						||
| 
								 | 
							
								    #   print "Content-type: image/svg+xml\r\n\r\n"
							 | 
						||
| 
								 | 
							
								    #   print graph.burn();
							 | 
						||
| 
								 | 
							
								    # 
							 | 
						||
| 
								 | 
							
								    # == Description
							 | 
						||
| 
								 | 
							
								    # 
							 | 
						||
| 
								 | 
							
								    # This object aims to allow you to easily create high quality
							 | 
						||
| 
								 | 
							
								    # SVG pie graphs. You can either use the default style sheet
							 | 
						||
| 
								 | 
							
								    # or supply your own. Either way there are many options which can
							 | 
						||
| 
								 | 
							
								    # be configured to give you control over how the graph is
							 | 
						||
| 
								 | 
							
								    # generated - with or without a key, display percent on pie chart,
							 | 
						||
| 
								 | 
							
								    # title, subtitle etc.
							 | 
						||
| 
								 | 
							
								    #
							 | 
						||
| 
								 | 
							
								    # = Examples
							 | 
						||
| 
								 | 
							
								    # 
							 | 
						||
| 
								 | 
							
								    # http://www.germane-software/repositories/public/SVG/test/single.rb
							 | 
						||
| 
								 | 
							
								    # 
							 | 
						||
| 
								 | 
							
								    # == See also
							 | 
						||
| 
								 | 
							
								    #
							 | 
						||
| 
								 | 
							
								    # * SVG::Graph::Graph
							 | 
						||
| 
								 | 
							
								    # * SVG::Graph::BarHorizontal
							 | 
						||
| 
								 | 
							
								    # * SVG::Graph::Bar
							 | 
						||
| 
								 | 
							
								    # * SVG::Graph::Line
							 | 
						||
| 
								 | 
							
								    # * SVG::Graph::Plot
							 | 
						||
| 
								 | 
							
								    # * SVG::Graph::TimeSeries
							 | 
						||
| 
								 | 
							
								    #
							 | 
						||
| 
								 | 
							
								    # == Author
							 | 
						||
| 
								 | 
							
								    #
							 | 
						||
| 
								 | 
							
								    # Sean E. Russell <serATgermaneHYPHENsoftwareDOTcom>
							 | 
						||
| 
								 | 
							
								    #
							 | 
						||
| 
								 | 
							
								    # Copyright 2004 Sean E. Russell
							 | 
						||
| 
								 | 
							
								    # This software is available under the Ruby license[LICENSE.txt]
							 | 
						||
| 
								 | 
							
								    #
							 | 
						||
| 
								 | 
							
								    class Pie < Graph
							 | 
						||
| 
								 | 
							
								      # Defaults are those set by Graph::initialize, and
							 | 
						||
| 
								 | 
							
								      # [show_shadow] true
							 | 
						||
| 
								 | 
							
								      # [shadow_offset] 10
							 | 
						||
| 
								 | 
							
								      # [show_data_labels] false
							 | 
						||
| 
								 | 
							
								      # [show_actual_values] false
							 | 
						||
| 
								 | 
							
								      # [show_percent] true
							 | 
						||
| 
								 | 
							
								      # [show_key_data_labels] true
							 | 
						||
| 
								 | 
							
								      # [show_key_actual_values] true
							 | 
						||
| 
								 | 
							
								      # [show_key_percent] false
							 | 
						||
| 
								 | 
							
								      # [expanded] false
							 | 
						||
| 
								 | 
							
								      # [expand_greatest] false
							 | 
						||
| 
								 | 
							
								      # [expand_gap] 10
							 | 
						||
| 
								 | 
							
								      # [show_x_labels] false
							 | 
						||
| 
								 | 
							
								      # [show_y_labels] false
							 | 
						||
| 
								 | 
							
								      # [datapoint_font_size] 12
							 | 
						||
| 
								 | 
							
								      def set_defaults
							 | 
						||
| 
								 | 
							
								        init_with(
							 | 
						||
| 
								 | 
							
								          :show_shadow		        => true,
							 | 
						||
| 
								 | 
							
								          :shadow_offset	        => 10, 
							 | 
						||
| 
								 | 
							
								          
							 | 
						||
| 
								 | 
							
								          :show_data_labels	      => false,
							 | 
						||
| 
								 | 
							
								          :show_actual_values     => false,
							 | 
						||
| 
								 | 
							
								          :show_percent		        => true,
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          :show_key_data_labels	  => true,
							 | 
						||
| 
								 | 
							
								          :show_key_actual_values => true,
							 | 
						||
| 
								 | 
							
								          :show_key_percent		    => false,
							 | 
						||
| 
								 | 
							
								          
							 | 
						||
| 
								 | 
							
								          :expanded				        => false,
							 | 
						||
| 
								 | 
							
								          :expand_greatest		    => false,
							 | 
						||
| 
								 | 
							
								          :expand_gap             => 10,
							 | 
						||
| 
								 | 
							
								          
							 | 
						||
| 
								 | 
							
								          :show_x_labels          => false,
							 | 
						||
| 
								 | 
							
								          :show_y_labels          => false,
							 | 
						||
| 
								 | 
							
								          :datapoint_font_size    => 12
							 | 
						||
| 
								 | 
							
								        )
							 | 
						||
| 
								 | 
							
								        @data = []
							 | 
						||
| 
								 | 
							
								      end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      # Adds a data set to the graph.
							 | 
						||
| 
								 | 
							
								      #
							 | 
						||
| 
								 | 
							
								      #   graph.add_data( { :data => [1,2,3,4] } )
							 | 
						||
| 
								 | 
							
								      #
							 | 
						||
| 
								 | 
							
								      # Note that the :title is not necessary.  If multiple
							 | 
						||
| 
								 | 
							
								      # data sets are added to the graph, the pie chart will
							 | 
						||
| 
								 | 
							
								      # display the +sums+ of the data.  EG:
							 | 
						||
| 
								 | 
							
								      #
							 | 
						||
| 
								 | 
							
								      #   graph.add_data( { :data => [1,2,3,4] } )
							 | 
						||
| 
								 | 
							
								      #   graph.add_data( { :data => [2,3,5,9] } )
							 | 
						||
| 
								 | 
							
								      #
							 | 
						||
| 
								 | 
							
								      # is the same as:
							 | 
						||
| 
								 | 
							
								      #
							 | 
						||
| 
								 | 
							
								      #   graph.add_data( { :data => [3,5,8,13] } )
							 | 
						||
| 
								 | 
							
								      def add_data arg
							 | 
						||
| 
								 | 
							
								        arg[:data].each_index {|idx|
							 | 
						||
| 
								 | 
							
								          @data[idx] = 0 unless @data[idx]
							 | 
						||
| 
								 | 
							
								          @data[idx] += arg[:data][idx]
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      # If true, displays a drop shadow for the chart
							 | 
						||
| 
								 | 
							
								      attr_accessor :show_shadow 
							 | 
						||
| 
								 | 
							
								      # Sets the offset of the shadow from the pie chart
							 | 
						||
| 
								 | 
							
								      attr_accessor :shadow_offset
							 | 
						||
| 
								 | 
							
								      # If true, display the data labels on the chart
							 | 
						||
| 
								 | 
							
								      attr_accessor :show_data_labels 
							 | 
						||
| 
								 | 
							
								      # If true, display the actual field values in the data labels
							 | 
						||
| 
								 | 
							
								      attr_accessor :show_actual_values 
							 | 
						||
| 
								 | 
							
								      # If true, display the percentage value of each pie wedge in the data
							 | 
						||
| 
								 | 
							
								      # labels
							 | 
						||
| 
								 | 
							
								      attr_accessor :show_percent
							 | 
						||
| 
								 | 
							
								      # If true, display the labels in the key
							 | 
						||
| 
								 | 
							
								      attr_accessor :show_key_data_labels 
							 | 
						||
| 
								 | 
							
								      # If true, display the actual value of the field in the key
							 | 
						||
| 
								 | 
							
								      attr_accessor :show_key_actual_values 
							 | 
						||
| 
								 | 
							
								      # If true, display the percentage value of the wedges in the key
							 | 
						||
| 
								 | 
							
								      attr_accessor :show_key_percent
							 | 
						||
| 
								 | 
							
								      # If true, "explode" the pie (put space between the wedges)
							 | 
						||
| 
								 | 
							
								      attr_accessor :expanded 
							 | 
						||
| 
								 | 
							
								      # If true, expand the largest pie wedge
							 | 
						||
| 
								 | 
							
								      attr_accessor :expand_greatest 
							 | 
						||
| 
								 | 
							
								      # The amount of space between expanded wedges
							 | 
						||
| 
								 | 
							
								      attr_accessor :expand_gap 
							 | 
						||
| 
								 | 
							
								      # The font size of the data point labels
							 | 
						||
| 
								 | 
							
								      attr_accessor :datapoint_font_size
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      protected
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      def add_defs defs
							 | 
						||
| 
								 | 
							
								        gradient = defs.add_element( "filter", {
							 | 
						||
| 
								 | 
							
								          "id"=>"dropshadow",
							 | 
						||
| 
								 | 
							
								          "width" => "1.2",
							 | 
						||
| 
								 | 
							
								          "height" => "1.2",
							 | 
						||
| 
								 | 
							
								        } )
							 | 
						||
| 
								 | 
							
								        gradient.add_element( "feGaussianBlur", {
							 | 
						||
| 
								 | 
							
								          "stdDeviation" => "4",
							 | 
						||
| 
								 | 
							
								          "result" => "blur"
							 | 
						||
| 
								 | 
							
								        })
							 | 
						||
| 
								 | 
							
								      end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      # We don't need the graph
							 | 
						||
| 
								 | 
							
								      def draw_graph
							 | 
						||
| 
								 | 
							
								      end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      def get_y_labels
							 | 
						||
| 
								 | 
							
								        [""]
							 | 
						||
| 
								 | 
							
								      end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      def get_x_labels
							 | 
						||
| 
								 | 
							
								        [""]
							 | 
						||
| 
								 | 
							
								      end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      def keys
							 | 
						||
| 
								 | 
							
								        total = 0
							 | 
						||
| 
								 | 
							
								        max_value = 0
							 | 
						||
| 
								 | 
							
								        @data.each {|x| total += x }
							 | 
						||
| 
								 | 
							
								        percent_scale = 100.0 / total
							 | 
						||
| 
								 | 
							
								        count = -1
							 | 
						||
| 
								 | 
							
								        a = @config[:fields].collect{ |x|
							 | 
						||
| 
								 | 
							
								          count += 1
							 | 
						||
| 
								 | 
							
								          v = @data[count]
							 | 
						||
| 
								 | 
							
								          perc = show_key_percent ? " "+(v * percent_scale).round.to_s+"%" : ""
							 | 
						||
| 
								 | 
							
								          x + " [" + v.to_s + "]" + perc
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      RADIANS = Math::PI/180
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      def draw_data
							 | 
						||
| 
								 | 
							
								        @graph = @root.add_element( "g" )
							 | 
						||
| 
								 | 
							
								        background = @graph.add_element("g")
							 | 
						||
| 
								 | 
							
								        midground = @graph.add_element("g")
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        diameter = @graph_height > @graph_width ? @graph_width : @graph_height
							 | 
						||
| 
								 | 
							
								        diameter -= expand_gap if expanded or expand_greatest
							 | 
						||
| 
								 | 
							
								        diameter -= datapoint_font_size if show_data_labels
							 | 
						||
| 
								 | 
							
								        diameter -= 10 if show_shadow
							 | 
						||
| 
								 | 
							
								        radius = diameter / 2.0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        xoff = (width - diameter) / 2
							 | 
						||
| 
								 | 
							
								        yoff = (height - @border_bottom - diameter)
							 | 
						||
| 
								 | 
							
								        yoff -= 10 if show_shadow
							 | 
						||
| 
								 | 
							
								        @graph.attributes['transform'] = "translate( #{xoff} #{yoff} )"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        wedge_text_pad = 5
							 | 
						||
| 
								 | 
							
								        wedge_text_pad = 20 if show_percent and show_data_labels
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        total = 0
							 | 
						||
| 
								 | 
							
								        max_value = 0
							 | 
						||
| 
								 | 
							
								        @data.each {|x| 
							 | 
						||
| 
								 | 
							
								          max_value = max_value < x ? x : max_value
							 | 
						||
| 
								 | 
							
								          total += x 
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        percent_scale = 100.0 / total
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        prev_percent = 0
							 | 
						||
| 
								 | 
							
								        rad_mult = 3.6 * RADIANS
							 | 
						||
| 
								 | 
							
								        @config[:fields].each_index { |count|
							 | 
						||
| 
								 | 
							
								          value = @data[count]
							 | 
						||
| 
								 | 
							
								          percent = percent_scale * value
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          radians = prev_percent * rad_mult
							 | 
						||
| 
								 | 
							
								          x_start = radius+(Math.sin(radians) * radius)
							 | 
						||
| 
								 | 
							
								          y_start = radius-(Math.cos(radians) * radius)
							 | 
						||
| 
								 | 
							
								          radians = (prev_percent+percent) * rad_mult
							 | 
						||
| 
								 | 
							
								          x_end = radius+(Math.sin(radians) * radius)
							 | 
						||
| 
								 | 
							
								          y_end = radius-(Math.cos(radians) * radius)
							 | 
						||
| 
								 | 
							
								          path = "M#{radius},#{radius} L#{x_start},#{y_start} "+
							 | 
						||
| 
								 | 
							
								            "A#{radius},#{radius} "+
							 | 
						||
| 
								 | 
							
								            "0, #{percent >= 50 ? '1' : '0'},1, "+
							 | 
						||
| 
								 | 
							
								            "#{x_end} #{y_end} Z"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          wedge = @foreground.add_element( "path", {
							 | 
						||
| 
								 | 
							
								            "d" => path,
							 | 
						||
| 
								 | 
							
								            "class" => "fill#{count+1}"
							 | 
						||
| 
								 | 
							
								          })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          translate = nil
							 | 
						||
| 
								 | 
							
								          tx = 0
							 | 
						||
| 
								 | 
							
								          ty = 0
							 | 
						||
| 
								 | 
							
								          half_percent = prev_percent + percent / 2
							 | 
						||
| 
								 | 
							
								          radians = half_percent * rad_mult
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          if show_shadow
							 | 
						||
| 
								 | 
							
								            shadow = background.add_element( "path", {
							 | 
						||
| 
								 | 
							
								              "d" => path,
							 | 
						||
| 
								 | 
							
								              "filter" => "url(#dropshadow)",
							 | 
						||
| 
								 | 
							
								              "style" => "fill: #ccc; stroke: none;"
							 | 
						||
| 
								 | 
							
								            })
							 | 
						||
| 
								 | 
							
								            clear = midground.add_element( "path", {
							 | 
						||
| 
								 | 
							
								              "d" => path,
							 | 
						||
| 
								 | 
							
								              "style" => "fill: #fff; stroke: none;"
							 | 
						||
| 
								 | 
							
								            })
							 | 
						||
| 
								 | 
							
								          end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          if expanded or (expand_greatest && value == max_value)
							 | 
						||
| 
								 | 
							
								            tx = (Math.sin(radians) * expand_gap)
							 | 
						||
| 
								 | 
							
								            ty = -(Math.cos(radians) * expand_gap)
							 | 
						||
| 
								 | 
							
								            translate = "translate( #{tx} #{ty} )"
							 | 
						||
| 
								 | 
							
								            wedge.attributes["transform"] = translate
							 | 
						||
| 
								 | 
							
								            clear.attributes["transform"] = translate
							 | 
						||
| 
								 | 
							
								          end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          if show_shadow
							 | 
						||
| 
								 | 
							
								            shadow.attributes["transform"] = 
							 | 
						||
| 
								 | 
							
								              "translate( #{tx+shadow_offset} #{ty+shadow_offset} )"
							 | 
						||
| 
								 | 
							
								          end
							 | 
						||
| 
								 | 
							
								          
							 | 
						||
| 
								 | 
							
								          if show_data_labels and value != 0
							 | 
						||
| 
								 | 
							
								            label = ""
							 | 
						||
| 
								 | 
							
								            label += @config[:fields][count] if show_key_data_labels
							 | 
						||
| 
								 | 
							
								            label += " ["+value.to_s+"]" if show_actual_values
							 | 
						||
| 
								 | 
							
								            label += " "+percent.round.to_s+"%" if show_percent
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            msr = Math.sin(radians)
							 | 
						||
| 
								 | 
							
								            mcr = Math.cos(radians)
							 | 
						||
| 
								 | 
							
								            tx = radius + (msr * radius)
							 | 
						||
| 
								 | 
							
								            ty = radius -(mcr * radius)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if expanded or (expand_greatest && value == max_value)
							 | 
						||
| 
								 | 
							
								              tx += (msr * expand_gap)
							 | 
						||
| 
								 | 
							
								              ty -= (mcr * expand_gap)
							 | 
						||
| 
								 | 
							
								            end
							 | 
						||
| 
								 | 
							
								            @foreground.add_element( "text", {
							 | 
						||
| 
								 | 
							
								              "x" => tx.to_s,
							 | 
						||
| 
								 | 
							
								              "y" => ty.to_s,
							 | 
						||
| 
								 | 
							
								              "class" => "dataPointLabel",
							 | 
						||
| 
								 | 
							
								              "style" => "stroke: #fff; stroke-width: 2;"
							 | 
						||
| 
								 | 
							
								            }).text = label.to_s
							 | 
						||
| 
								 | 
							
								            @foreground.add_element( "text", {
							 | 
						||
| 
								 | 
							
								              "x" => tx.to_s,
							 | 
						||
| 
								 | 
							
								              "y" => ty.to_s,
							 | 
						||
| 
								 | 
							
								              "class" => "dataPointLabel",
							 | 
						||
| 
								 | 
							
								            }).text = label.to_s
							 | 
						||
| 
								 | 
							
								          end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          prev_percent += percent
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      end
							 | 
						||
| 
								 | 
							
								      
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      def round val, to
							 | 
						||
| 
								 | 
							
								        up = 10**to.to_f
							 | 
						||
| 
								 | 
							
								        (val * up).to_i / up
							 | 
						||
| 
								 | 
							
								      end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      def get_css
							 | 
						||
| 
								 | 
							
								        return <<EOL
							 | 
						||
| 
								 | 
							
								.dataPointLabel{
							 | 
						||
| 
								 | 
							
									fill: #000000;
							 | 
						||
| 
								 | 
							
									text-anchor:middle;
							 | 
						||
| 
								 | 
							
									font-size: #{datapoint_font_size}px;
							 | 
						||
| 
								 | 
							
									font-family: "Arial", sans-serif;
							 | 
						||
| 
								 | 
							
									font-weight: normal;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* key - MUST match fill styles */
							 | 
						||
| 
								 | 
							
								.key1,.fill1{
							 | 
						||
| 
								 | 
							
									fill: #ff0000;
							 | 
						||
| 
								 | 
							
									fill-opacity: 0.7;
							 | 
						||
| 
								 | 
							
									stroke: none;
							 | 
						||
| 
								 | 
							
									stroke-width: 1px;	
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								.key2,.fill2{
							 | 
						||
| 
								 | 
							
									fill: #0000ff;
							 | 
						||
| 
								 | 
							
									fill-opacity: 0.7;
							 | 
						||
| 
								 | 
							
									stroke: none;
							 | 
						||
| 
								 | 
							
									stroke-width: 1px;	
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								.key3,.fill3{
							 | 
						||
| 
								 | 
							
									fill-opacity: 0.7;
							 | 
						||
| 
								 | 
							
									fill: #00ff00;
							 | 
						||
| 
								 | 
							
									stroke: none;
							 | 
						||
| 
								 | 
							
									stroke-width: 1px;	
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								.key4,.fill4{
							 | 
						||
| 
								 | 
							
									fill-opacity: 0.7;
							 | 
						||
| 
								 | 
							
									fill: #ffcc00;
							 | 
						||
| 
								 | 
							
									stroke: none;
							 | 
						||
| 
								 | 
							
									stroke-width: 1px;	
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								.key5,.fill5{
							 | 
						||
| 
								 | 
							
									fill-opacity: 0.7;
							 | 
						||
| 
								 | 
							
									fill: #00ccff;
							 | 
						||
| 
								 | 
							
									stroke: none;
							 | 
						||
| 
								 | 
							
									stroke-width: 1px;	
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								.key6,.fill6{
							 | 
						||
| 
								 | 
							
									fill-opacity: 0.7;
							 | 
						||
| 
								 | 
							
									fill: #ff00ff;
							 | 
						||
| 
								 | 
							
									stroke: none;
							 | 
						||
| 
								 | 
							
									stroke-width: 1px;	
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								.key7,.fill7{
							 | 
						||
| 
								 | 
							
									fill-opacity: 0.7;
							 | 
						||
| 
								 | 
							
									fill: #00ff99;
							 | 
						||
| 
								 | 
							
									stroke: none;
							 | 
						||
| 
								 | 
							
									stroke-width: 1px;	
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								.key8,.fill8{
							 | 
						||
| 
								 | 
							
									fill-opacity: 0.7;
							 | 
						||
| 
								 | 
							
									fill: #ffff00;
							 | 
						||
| 
								 | 
							
									stroke: none;
							 | 
						||
| 
								 | 
							
									stroke-width: 1px;	
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								.key9,.fill9{
							 | 
						||
| 
								 | 
							
									fill-opacity: 0.7;
							 | 
						||
| 
								 | 
							
									fill: #cc6666;
							 | 
						||
| 
								 | 
							
									stroke: none;
							 | 
						||
| 
								 | 
							
									stroke-width: 1px;	
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								.key10,.fill10{
							 | 
						||
| 
								 | 
							
									fill-opacity: 0.7;
							 | 
						||
| 
								 | 
							
									fill: #663399;
							 | 
						||
| 
								 | 
							
									stroke: none;
							 | 
						||
| 
								 | 
							
									stroke-width: 1px;	
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								.key11,.fill11{
							 | 
						||
| 
								 | 
							
									fill-opacity: 0.7;
							 | 
						||
| 
								 | 
							
									fill: #339900;
							 | 
						||
| 
								 | 
							
									stroke: none;
							 | 
						||
| 
								 | 
							
									stroke-width: 1px;	
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								.key12,.fill12{
							 | 
						||
| 
								 | 
							
									fill-opacity: 0.7;
							 | 
						||
| 
								 | 
							
									fill: #9966FF;
							 | 
						||
| 
								 | 
							
									stroke: none;
							 | 
						||
| 
								 | 
							
									stroke-width: 1px;	
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								EOL
							 | 
						||
| 
								 | 
							
								      end
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								  end
							 | 
						||
| 
								 | 
							
								end
							 |