Project

General

Profile

Feature #1432 » issueRelationFollows_r2924.patch

Adds "follows" issue relation type - Anonymous, 2009-10-14 17:11

View differences:

app/models/issue_relation.rb (kopia robocza)
23 23
  TYPE_DUPLICATES   = "duplicates"
24 24
  TYPE_BLOCKS       = "blocks"
25 25
  TYPE_PRECEDES     = "precedes"
26
  TYPE_FOLLOWS      = "follows"
26 27
  
27 28
  TYPES = { TYPE_RELATES =>     { :name => :label_relates_to, :sym_name => :label_relates_to, :order => 1 },
28
            TYPE_DUPLICATES =>  { :name => :label_duplicates, :sym_name => :label_duplicated_by, :order => 2 },
29
            TYPE_BLOCKS =>      { :name => :label_blocks, :sym_name => :label_blocked_by, :order => 3 },
30
            TYPE_PRECEDES =>    { :name => :label_precedes, :sym_name => :label_follows, :order => 4 },
31
          }.freeze
32
  
29
    TYPE_DUPLICATES =>  { :name => :label_duplicates, :sym_name => :label_duplicated_by, :order => 2 },
30
    TYPE_BLOCKS =>      { :name => :label_blocks, :sym_name => :label_blocked_by, :order => 3 },
31
    TYPE_PRECEDES =>    { :name => :label_precedes, :sym_name => :label_follows, :order => 4 },
32
    TYPE_FOLLOWS =>    { :name => :label_follows, :sym_name => :label_precedes, :order => 5 },
33
  }.freeze
34

  
33 35
  validates_presence_of :issue_from, :issue_to, :relation_type
34 36
  validates_inclusion_of :relation_type, :in => TYPES.keys
35 37
  validates_numericality_of :delay, :allow_nil => true
36 38
  validates_uniqueness_of :issue_to_id, :scope => :issue_from_id
37
  
39

  
38 40
  attr_protected :issue_from_id, :issue_to_id
39
  
41

  
42
  def before_validation
43
    convert_to_precedes if TYPE_FOLLOWS == relation_type
44
  end
45

  
40 46
  def validate
41 47
    if issue_from && issue_to
42 48
      errors.add :issue_to_id, :invalid if issue_from_id == issue_to_id
......
78 84
  def <=>(relation)
79 85
    TYPES[self.relation_type][:order] <=> TYPES[relation.relation_type][:order]
80 86
  end
87

  
88
  private
89

  
90
  def convert_to_precedes
91
    if (TYPE_FOLLOWS == self.relation_type)
92
      issue_tmp = self.issue_to
93
      self.issue_to = self.issue_from
94
      self.issue_from = issue_tmp
95
      self.relation_type = TYPE_PRECEDES
96
    end
97
  end
98

  
81 99
end
db/migrate/001_setup.rb (kopia robocza)
21 21
  # model removed
22 22
  class Permission < ActiveRecord::Base; end
23 23
  
24
  def self.up
25
    create_table "attachments", :force => true do |t|
26
      t.column "container_id", :integer, :default => 0, :null => false
27
      t.column "container_type", :string, :limit => 30, :default => "", :null => false
28
      t.column "filename", :string, :default => "", :null => false
29
      t.column "disk_filename", :string, :default => "", :null => false
30
      t.column "filesize", :integer, :default => 0, :null => false
31
      t.column "content_type", :string, :limit => 60, :default => ""
32
      t.column "digest", :string, :limit => 40, :default => "", :null => false
33
      t.column "downloads", :integer, :default => 0, :null => false
34
      t.column "author_id", :integer, :default => 0, :null => false
35
      t.column "created_on", :timestamp
36
    end
24
  def self.up
25
    create_table "attachments", :force => true do |t|
26
      t.column "container_id", :integer, :default => 0, :null => false
27
      t.column "container_type", :string, :limit => 30, :default => "", :null => false
28
      t.column "filename", :string, :default => "", :null => false
29
      t.column "disk_filename", :string, :default => "", :null => false
30
      t.column "filesize", :integer, :default => 0, :null => false
31
      t.column "content_type", :string, :limit => 60, :default => ""
32
      t.column "digest", :string, :limit => 40, :default => "", :null => false
33
      t.column "downloads", :integer, :default => 0, :null => false
34
      t.column "author_id", :integer, :default => 0, :null => false
35
      t.column "created_on", :timestamp
36
    end
37 37

  
38 38
    create_table "auth_sources", :force => true do |t|
39 39
      t.column "type", :string, :limit => 30, :default => "", :null => false
......
49 49
      t.column "attr_mail", :string, :limit => 30
50 50
      t.column "onthefly_register", :boolean, :default => false, :null => false
51 51
    end
52
    
52
    
53 53
    create_table "custom_fields", :force => true do |t|
54
      t.column "type", :string, :limit => 30, :default => "", :null => false
55
      t.column "name", :string, :limit => 30, :default => "", :null => false
56
      t.column "field_format", :string, :limit => 30, :default => "", :null => false
57
      t.column "possible_values", :text
58
      t.column "regexp", :string, :default => ""
59
      t.column "min_length", :integer, :default => 0, :null => false
60
      t.column "max_length", :integer, :default => 0, :null => false
54
      t.column "type", :string, :limit => 30, :default => "", :null => false
55
      t.column "name", :string, :limit => 30, :default => "", :null => false
56
      t.column "field_format", :string, :limit => 30, :default => "", :null => false
57
      t.column "possible_values", :text
58
      t.column "regexp", :string, :default => ""
59
      t.column "min_length", :integer, :default => 0, :null => false
60
      t.column "max_length", :integer, :default => 0, :null => false
61 61
      t.column "is_required", :boolean, :default => false, :null => false
62 62
      t.column "is_for_all", :boolean, :default => false, :null => false
63
    end
64
  
65
    create_table "custom_fields_projects", :id => false, :force => true do |t|
66
      t.column "custom_field_id", :integer, :default => 0, :null => false
67
      t.column "project_id", :integer, :default => 0, :null => false
68
    end
63
    end
64
  
65
    create_table "custom_fields_projects", :id => false, :force => true do |t|
66
      t.column "custom_field_id", :integer, :default => 0, :null => false
67
      t.column "project_id", :integer, :default => 0, :null => false
68
    end
69 69

  
70 70
    create_table "custom_fields_trackers", :id => false, :force => true do |t|
71 71
      t.column "custom_field_id", :integer, :default => 0, :null => false
72 72
      t.column "tracker_id", :integer, :default => 0, :null => false
73 73
    end
74

  
75
    create_table "custom_values", :force => true do |t|
74

  
75
    create_table "custom_values", :force => true do |t|
76 76
      t.column "customized_type", :string, :limit => 30, :default => "", :null => false
77 77
      t.column "customized_id", :integer, :default => 0, :null => false
78
      t.column "custom_field_id", :integer, :default => 0, :null => false
79
      t.column "value", :text
80
    end
81
  
82
    create_table "documents", :force => true do |t|
83
      t.column "project_id", :integer, :default => 0, :null => false
84
      t.column "category_id", :integer, :default => 0, :null => false
85
      t.column "title", :string, :limit => 60, :default => "", :null => false
86
      t.column "description", :text
87
      t.column "created_on", :timestamp
78
      t.column "custom_field_id", :integer, :default => 0, :null => false
79
      t.column "value", :text
88 80
    end
81
  
82
    create_table "documents", :force => true do |t|
83
      t.column "project_id", :integer, :default => 0, :null => false
84
      t.column "category_id", :integer, :default => 0, :null => false
85
      t.column "title", :string, :limit => 60, :default => "", :null => false
86
      t.column "description", :text
87
      t.column "created_on", :timestamp
88
    end
89 89
    
90
    add_index "documents", ["project_id"], :name => "documents_project_id"
91
  
92
    create_table "enumerations", :force => true do |t|
93
      t.column "opt", :string, :limit => 4, :default => "", :null => false
94
      t.column "name", :string, :limit => 30, :default => "", :null => false
95
    end
96
  
97
    create_table "issue_categories", :force => true do |t|
98
      t.column "project_id", :integer, :default => 0, :null => false
99
      t.column "name", :string, :limit => 30, :default => "", :null => false
90
    add_index "documents", ["project_id"], :name => "documents_project_id"
91
  
92
    create_table "enumerations", :force => true do |t|
93
      t.column "opt", :string, :limit => 4, :default => "", :null => false
94
      t.column "name", :string, :limit => 30, :default => "", :null => false
100 95
    end
96
  
97
    create_table "issue_categories", :force => true do |t|
98
      t.column "project_id", :integer, :default => 0, :null => false
99
      t.column "name", :string, :limit => 30, :default => "", :null => false
100
    end
101 101
    
102
    add_index "issue_categories", ["project_id"], :name => "issue_categories_project_id"
103
  
104
    create_table "issue_histories", :force => true do |t|
105
      t.column "issue_id", :integer, :default => 0, :null => false
106
      t.column "status_id", :integer, :default => 0, :null => false
107
      t.column "author_id", :integer, :default => 0, :null => false
108
      t.column "notes", :text
109
      t.column "created_on", :timestamp
110
    end
111
  
112
    add_index "issue_histories", ["issue_id"], :name => "issue_histories_issue_id"
113

  
114
    create_table "issue_statuses", :force => true do |t|
115
      t.column "name", :string, :limit => 30, :default => "", :null => false
116
      t.column "is_closed", :boolean, :default => false, :null => false
117
      t.column "is_default", :boolean, :default => false, :null => false
118
      t.column "html_color", :string, :limit => 6, :default => "FFFFFF", :null => false
119
    end
120
  
121
    create_table "issues", :force => true do |t|
122
      t.column "tracker_id", :integer, :default => 0, :null => false
123
      t.column "project_id", :integer, :default => 0, :null => false
124
      t.column "subject", :string, :default => "", :null => false
102
    add_index "issue_categories", ["project_id"], :name => "issue_categories_project_id"
103
  
104
    create_table "issue_histories", :force => true do |t|
105
      t.column "issue_id", :integer, :default => 0, :null => false
106
      t.column "status_id", :integer, :default => 0, :null => false
107
      t.column "author_id", :integer, :default => 0, :null => false
108
      t.column "notes", :text
109
      t.column "created_on", :timestamp
110
    end
111
  
112
    add_index "issue_histories", ["issue_id"], :name => "issue_histories_issue_id"
113

  
114
    create_table "issue_statuses", :force => true do |t|
115
      t.column "name", :string, :limit => 30, :default => "", :null => false
116
      t.column "is_closed", :boolean, :default => false, :null => false
117
      t.column "is_default", :boolean, :default => false, :null => false
118
      t.column "html_color", :string, :limit => 6, :default => "FFFFFF", :null => false
119
    end
120
  
121
    create_table "issues", :force => true do |t|
122
      t.column "tracker_id", :integer, :default => 0, :null => false
123
      t.column "project_id", :integer, :default => 0, :null => false
124
      t.column "subject", :string, :default => "", :null => false
125 125
      t.column "description", :text
126
      t.column "due_date", :date
127
      t.column "category_id", :integer
128
      t.column "status_id", :integer, :default => 0, :null => false
129
      t.column "assigned_to_id", :integer
130
      t.column "priority_id", :integer, :default => 0, :null => false
131
      t.column "fixed_version_id", :integer
126
      t.column "due_date", :date
127
      t.column "category_id", :integer
128
      t.column "status_id", :integer, :default => 0, :null => false
129
      t.column "assigned_to_id", :integer
130
      t.column "priority_id", :integer, :default => 0, :null => false
131
      t.column "fixed_version_id", :integer
132 132
      t.column "author_id", :integer, :default => 0, :null => false
133
      t.column "lock_version", :integer, :default => 0, :null => false
134
      t.column "created_on", :timestamp
135
      t.column "updated_on", :timestamp
136
    end
137
  
138
    add_index "issues", ["project_id"], :name => "issues_project_id"
139
  
140
    create_table "members", :force => true do |t|
141
      t.column "user_id", :integer, :default => 0, :null => false
142
      t.column "project_id", :integer, :default => 0, :null => false
143
      t.column "role_id", :integer, :default => 0, :null => false
144
      t.column "created_on", :timestamp
145
    end
146
  
147
    create_table "news", :force => true do |t|
148
      t.column "project_id", :integer
149
      t.column "title", :string, :limit => 60, :default => "", :null => false
150
      t.column "summary", :string, :limit => 255, :default => ""
151
      t.column "description", :text
152
      t.column "author_id", :integer, :default => 0, :null => false
153
      t.column "created_on", :timestamp
133
      t.column "lock_version", :integer, :default => 0, :null => false
134
      t.column "created_on", :timestamp
135
      t.column "updated_on", :timestamp
154 136
    end
137
  
138
    add_index "issues", ["project_id"], :name => "issues_project_id"
139
  
140
    create_table "members", :force => true do |t|
141
      t.column "user_id", :integer, :default => 0, :null => false
142
      t.column "project_id", :integer, :default => 0, :null => false
143
      t.column "role_id", :integer, :default => 0, :null => false
144
      t.column "created_on", :timestamp
145
    end
146
  
147
    create_table "news", :force => true do |t|
148
      t.column "project_id", :integer
149
      t.column "title", :string, :limit => 60, :default => "", :null => false
150
      t.column "summary", :string, :limit => 255, :default => ""
151
      t.column "description", :text
152
      t.column "author_id", :integer, :default => 0, :null => false
153
      t.column "created_on", :timestamp
154
    end
155 155
    
156
    add_index "news", ["project_id"], :name => "news_project_id"
157
  
158
    create_table "permissions", :force => true do |t|
159
      t.column "controller", :string, :limit => 30, :default => "", :null => false
160
      t.column "action", :string, :limit => 30, :default => "", :null => false
161
      t.column "description", :string, :limit => 60, :default => "", :null => false
162
      t.column "is_public", :boolean, :default => false, :null => false
163
      t.column "sort", :integer, :default => 0, :null => false
164
      t.column "mail_option", :boolean, :default => false, :null => false
165
      t.column "mail_enabled", :boolean, :default => false, :null => false
166
    end
167
  
168
    create_table "permissions_roles", :id => false, :force => true do |t|
169
      t.column "permission_id", :integer, :default => 0, :null => false
170
      t.column "role_id", :integer, :default => 0, :null => false
171
    end
172
  
173
    add_index "permissions_roles", ["role_id"], :name => "permissions_roles_role_id"
174
  
175
    create_table "projects", :force => true do |t|
176
      t.column "name", :string, :limit => 30, :default => "", :null => false
177
      t.column "description", :string, :default => "", :null => false
178
      t.column "homepage", :string, :limit => 60, :default => ""
156
    add_index "news", ["project_id"], :name => "news_project_id"
157
  
158
    create_table "permissions", :force => true do |t|
159
      t.column "controller", :string, :limit => 30, :default => "", :null => false
160
      t.column "action", :string, :limit => 30, :default => "", :null => false
161
      t.column "description", :string, :limit => 60, :default => "", :null => false
162
      t.column "is_public", :boolean, :default => false, :null => false
163
      t.column "sort", :integer, :default => 0, :null => false
164
      t.column "mail_option", :boolean, :default => false, :null => false
165
      t.column "mail_enabled", :boolean, :default => false, :null => false
166
    end
167
  
168
    create_table "permissions_roles", :id => false, :force => true do |t|
169
      t.column "permission_id", :integer, :default => 0, :null => false
170
      t.column "role_id", :integer, :default => 0, :null => false
171
    end
172
  
173
    add_index "permissions_roles", ["role_id"], :name => "permissions_roles_role_id"
174
  
175
    create_table "projects", :force => true do |t|
176
      t.column "name", :string, :limit => 30, :default => "", :null => false
177
      t.column "description", :string, :default => "", :null => false
178
      t.column "homepage", :string, :limit => 60, :default => ""
179 179
      t.column "is_public", :boolean, :default => true, :null => false
180 180
      t.column "parent_id", :integer
181
      t.column "projects_count", :integer, :default => 0
182
      t.column "created_on", :timestamp
183
      t.column "updated_on", :timestamp
184
    end
185
  
186
    create_table "roles", :force => true do |t|
187
      t.column "name", :string, :limit => 30, :default => "", :null => false
188
    end
181
      t.column "projects_count", :integer, :default => 0
182
      t.column "created_on", :timestamp
183
      t.column "updated_on", :timestamp
184
    end
185
  
186
    create_table "roles", :force => true do |t|
187
      t.column "name", :string, :limit => 30, :default => "", :null => false
188
    end
189 189

  
190 190
    create_table "tokens", :force => true do |t|
191 191
      t.column "user_id", :integer, :default => 0, :null => false
......
193 193
      t.column "value", :string, :limit => 40, :default => "", :null => false
194 194
      t.column "created_on", :datetime, :null => false
195 195
    end
196
  
197
    create_table "trackers", :force => true do |t|
198
      t.column "name", :string, :limit => 30, :default => "", :null => false
199
      t.column "is_in_chlog", :boolean, :default => false, :null => false
200
    end
201
  
202
    create_table "users", :force => true do |t|
203
      t.column "login", :string, :limit => 30, :default => "", :null => false
204
      t.column "hashed_password", :string, :limit => 40, :default => "", :null => false
205
      t.column "firstname", :string, :limit => 30, :default => "", :null => false
206
      t.column "lastname", :string, :limit => 30, :default => "", :null => false
207
      t.column "mail", :string, :limit => 60, :default => "", :null => false
208
      t.column "mail_notification", :boolean, :default => true, :null => false
209
      t.column "admin", :boolean, :default => false, :null => false
210
      t.column "status", :integer, :default => 1, :null => false
211
      t.column "last_login_on", :datetime
196
  
197
    create_table "trackers", :force => true do |t|
198
      t.column "name", :string, :limit => 30, :default => "", :null => false
199
      t.column "is_in_chlog", :boolean, :default => false, :null => false
200
    end
201
  
202
    create_table "users", :force => true do |t|
203
      t.column "login", :string, :limit => 30, :default => "", :null => false
204
      t.column "hashed_password", :string, :limit => 40, :default => "", :null => false
205
      t.column "firstname", :string, :limit => 30, :default => "", :null => false
206
      t.column "lastname", :string, :limit => 30, :default => "", :null => false
207
      t.column "mail", :string, :limit => 60, :default => "", :null => false
208
      t.column "mail_notification", :boolean, :default => true, :null => false
209
      t.column "admin", :boolean, :default => false, :null => false
210
      t.column "status", :integer, :default => 1, :null => false
211
      t.column "last_login_on", :datetime
212 212
      t.column "language", :string, :limit => 2, :default => ""
213
      t.column "auth_source_id", :integer
214
      t.column "created_on", :timestamp
215
      t.column "updated_on", :timestamp
216
    end
217
  
218
    create_table "versions", :force => true do |t|
219
      t.column "project_id", :integer, :default => 0, :null => false
220
      t.column "name", :string, :limit => 30, :default => "", :null => false
221
      t.column "description", :string, :default => ""
222
      t.column "effective_date", :date
223
      t.column "created_on", :timestamp
224
      t.column "updated_on", :timestamp
213
      t.column "auth_source_id", :integer
214
      t.column "created_on", :timestamp
215
      t.column "updated_on", :timestamp
225 216
    end
217
  
218
    create_table "versions", :force => true do |t|
219
      t.column "project_id", :integer, :default => 0, :null => false
220
      t.column "name", :string, :limit => 30, :default => "", :null => false
221
      t.column "description", :string, :default => ""
222
      t.column "effective_date", :date
223
      t.column "created_on", :timestamp
224
      t.column "updated_on", :timestamp
225
    end
226 226
    
227
    add_index "versions", ["project_id"], :name => "versions_project_id"
228
  
229
    create_table "workflows", :force => true do |t|
230
      t.column "tracker_id", :integer, :default => 0, :null => false
231
      t.column "old_status_id", :integer, :default => 0, :null => false
232
      t.column "new_status_id", :integer, :default => 0, :null => false
233
      t.column "role_id", :integer, :default => 0, :null => false
234
    end
235
  
236
    # project
237
    Permission.create :controller => "projects", :action => "show", :description => "label_overview", :sort => 100, :is_public => true
238
    Permission.create :controller => "projects", :action => "changelog", :description => "label_change_log", :sort => 105, :is_public => true
239
    Permission.create :controller => "reports", :action => "issue_report", :description => "label_report_plural", :sort => 110, :is_public => true
240
    Permission.create :controller => "projects", :action => "settings", :description => "label_settings", :sort => 150
241
    Permission.create :controller => "projects", :action => "edit", :description => "button_edit", :sort => 151
242
    # members
243
    Permission.create :controller => "projects", :action => "list_members", :description => "button_list", :sort => 200, :is_public => true
244
    Permission.create :controller => "projects", :action => "add_member", :description => "button_add", :sort => 220
245
    Permission.create :controller => "members", :action => "edit", :description => "button_edit", :sort => 221
246
    Permission.create :controller => "members", :action => "destroy", :description => "button_delete", :sort => 222
247
    # versions
248
    Permission.create :controller => "projects", :action => "add_version", :description => "button_add", :sort => 320
249
    Permission.create :controller => "versions", :action => "edit", :description => "button_edit", :sort => 321
250
    Permission.create :controller => "versions", :action => "destroy", :description => "button_delete", :sort => 322
251
    # issue categories
252
    Permission.create :controller => "projects", :action => "add_issue_category", :description => "button_add", :sort => 420
253
    Permission.create :controller => "issue_categories", :action => "edit", :description => "button_edit", :sort => 421
254
    Permission.create :controller => "issue_categories", :action => "destroy", :description => "button_delete", :sort => 422
255
    # issues
256
    Permission.create :controller => "projects", :action => "list_issues", :description => "button_list", :sort => 1000, :is_public => true
227
    add_index "versions", ["project_id"], :name => "versions_project_id"
228
  
229
    create_table "workflows", :force => true do |t|
230
      t.column "tracker_id", :integer, :default => 0, :null => false
231
      t.column "old_status_id", :integer, :default => 0, :null => false
232
      t.column "new_status_id", :integer, :default => 0, :null => false
233
      t.column "role_id", :integer, :default => 0, :null => false
234
    end
235
  
236
    # project
237
    Permission.create :controller => "projects", :action => "show", :description => "label_overview", :sort => 100, :is_public => true
238
    Permission.create :controller => "projects", :action => "changelog", :description => "label_change_log", :sort => 105, :is_public => true
239
    Permission.create :controller => "reports", :action => "issue_report", :description => "label_report_plural", :sort => 110, :is_public => true
240
    Permission.create :controller => "projects", :action => "settings", :description => "label_settings", :sort => 150
241
    Permission.create :controller => "projects", :action => "edit", :description => "button_edit", :sort => 151
242
    # members
243
    Permission.create :controller => "projects", :action => "list_members", :description => "button_list", :sort => 200, :is_public => true
244
    Permission.create :controller => "projects", :action => "add_member", :description => "button_add", :sort => 220
245
    Permission.create :controller => "members", :action => "edit", :description => "button_edit", :sort => 221
246
    Permission.create :controller => "members", :action => "destroy", :description => "button_delete", :sort => 222
247
    # versions
248
    Permission.create :controller => "projects", :action => "add_version", :description => "button_add", :sort => 320
249
    Permission.create :controller => "versions", :action => "edit", :description => "button_edit", :sort => 321
250
    Permission.create :controller => "versions", :action => "destroy", :description => "button_delete", :sort => 322
251
    # issue categories
252
    Permission.create :controller => "projects", :action => "add_issue_category", :description => "button_add", :sort => 420
253
    Permission.create :controller => "issue_categories", :action => "edit", :description => "button_edit", :sort => 421
254
    Permission.create :controller => "issue_categories", :action => "destroy", :description => "button_delete", :sort => 422
255
    # issues
256
    Permission.create :controller => "projects", :action => "list_issues", :description => "button_list", :sort => 1000, :is_public => true
257 257
    Permission.create :controller => "projects", :action => "export_issues_csv", :description => "label_export_csv", :sort => 1001, :is_public => true
258
    Permission.create :controller => "issues", :action => "show", :description => "button_view", :sort => 1005, :is_public => true
259
    Permission.create :controller => "issues", :action => "download", :description => "button_download", :sort => 1010, :is_public => true
260
    Permission.create :controller => "projects", :action => "add_issue", :description => "button_add", :sort => 1050, :mail_option => 1, :mail_enabled => 1
261
    Permission.create :controller => "issues", :action => "edit", :description => "button_edit", :sort => 1055
262
    Permission.create :controller => "issues", :action => "change_status", :description => "label_change_status", :sort => 1060, :mail_option => 1, :mail_enabled => 1
263
    Permission.create :controller => "issues", :action => "destroy", :description => "button_delete", :sort => 1065
264
    Permission.create :controller => "issues", :action => "add_attachment", :description => "label_attachment_new", :sort => 1070
265
    Permission.create :controller => "issues", :action => "destroy_attachment", :description => "label_attachment_delete", :sort => 1075
266
    # news
267
    Permission.create :controller => "projects", :action => "list_news", :description => "button_list", :sort => 1100, :is_public => true
268
    Permission.create :controller => "news", :action => "show", :description => "button_view", :sort => 1101, :is_public => true
269
    Permission.create :controller => "projects", :action => "add_news", :description => "button_add", :sort => 1120
270
    Permission.create :controller => "news", :action => "edit", :description => "button_edit", :sort => 1121
271
    Permission.create :controller => "news", :action => "destroy", :description => "button_delete", :sort => 1122
258
    Permission.create :controller => "issues", :action => "show", :description => "button_view", :sort => 1005, :is_public => true
259
    Permission.create :controller => "issues", :action => "download", :description => "button_download", :sort => 1010, :is_public => true
260
    Permission.create :controller => "projects", :action => "add_issue", :description => "button_add", :sort => 1050, :mail_option => 1, :mail_enabled => 1
261
    Permission.create :controller => "issues", :action => "edit", :description => "button_edit", :sort => 1055
262
    Permission.create :controller => "issues", :action => "change_status", :description => "label_change_status", :sort => 1060, :mail_option => 1, :mail_enabled => 1
263
    Permission.create :controller => "issues", :action => "destroy", :description => "button_delete", :sort => 1065
264
    Permission.create :controller => "issues", :action => "add_attachment", :description => "label_attachment_new", :sort => 1070
265
    Permission.create :controller => "issues", :action => "destroy_attachment", :description => "label_attachment_delete", :sort => 1075
266
    # news
267
    Permission.create :controller => "projects", :action => "list_news", :description => "button_list", :sort => 1100, :is_public => true
268
    Permission.create :controller => "news", :action => "show", :description => "button_view", :sort => 1101, :is_public => true
269
    Permission.create :controller => "projects", :action => "add_news", :description => "button_add", :sort => 1120
270
    Permission.create :controller => "news", :action => "edit", :description => "button_edit", :sort => 1121
271
    Permission.create :controller => "news", :action => "destroy", :description => "button_delete", :sort => 1122
272 272
    # documents
273
    Permission.create :controller => "projects", :action => "list_documents", :description => "button_list", :sort => 1200, :is_public => true
274
    Permission.create :controller => "documents", :action => "show", :description => "button_view", :sort => 1201, :is_public => true
275
    Permission.create :controller => "documents", :action => "download", :description => "button_download", :sort => 1202, :is_public => true
276
    Permission.create :controller => "projects", :action => "add_document", :description => "button_add", :sort => 1220
277
    Permission.create :controller => "documents", :action => "edit", :description => "button_edit", :sort => 1221
278
    Permission.create :controller => "documents", :action => "destroy", :description => "button_delete", :sort => 1222
279
    Permission.create :controller => "documents", :action => "add_attachment", :description => "label_attachment_new", :sort => 1223
280
    Permission.create :controller => "documents", :action => "destroy_attachment", :description => "label_attachment_delete", :sort => 1224
281
    # files
282
    Permission.create :controller => "projects", :action => "list_files", :description => "button_list", :sort => 1300, :is_public => true
283
    Permission.create :controller => "versions", :action => "download", :description => "button_download", :sort => 1301, :is_public => true
284
    Permission.create :controller => "projects", :action => "add_file", :description => "button_add", :sort => 1320
285
    Permission.create :controller => "versions", :action => "destroy_file", :description => "button_delete", :sort => 1322
286
    
287
    # create default administrator account
273
    Permission.create :controller => "projects", :action => "list_documents", :description => "button_list", :sort => 1200, :is_public => true
274
    Permission.create :controller => "documents", :action => "show", :description => "button_view", :sort => 1201, :is_public => true
275
    Permission.create :controller => "documents", :action => "download", :description => "button_download", :sort => 1202, :is_public => true
276
    Permission.create :controller => "projects", :action => "add_document", :description => "button_add", :sort => 1220
277
    Permission.create :controller => "documents", :action => "edit", :description => "button_edit", :sort => 1221
278
    Permission.create :controller => "documents", :action => "destroy", :description => "button_delete", :sort => 1222
279
    Permission.create :controller => "documents", :action => "add_attachment", :description => "label_attachment_new", :sort => 1223
280
    Permission.create :controller => "documents", :action => "destroy_attachment", :description => "label_attachment_delete", :sort => 1224
281
    # files
282
    Permission.create :controller => "projects", :action => "list_files", :description => "button_list", :sort => 1300, :is_public => true
283
    Permission.create :controller => "versions", :action => "download", :description => "button_download", :sort => 1301, :is_public => true
284
    Permission.create :controller => "projects", :action => "add_file", :description => "button_add", :sort => 1320
285
    Permission.create :controller => "versions", :action => "destroy_file", :description => "button_delete", :sort => 1322
286
    
287
    # create default administrator account
288 288
    user = User.create :login => "admin",
289 289
                       :hashed_password => "d033e22ae348aeb5660fc2140aec35850c4da997",
290 290
                       :admin => true,
......
296 296
                       :status => 1
297 297
  end
298 298

  
299
  def self.down
299
  def self.down
300 300
    drop_table :attachments
301
    drop_table :auth_sources
302
    drop_table :custom_fields
301
    drop_table :auth_sources
302
    drop_table :custom_fields
303 303
    drop_table :custom_fields_projects
304
    drop_table :custom_fields_trackers
305
    drop_table :custom_values
306
    drop_table :documents
307
    drop_table :enumerations
308
    drop_table :issue_categories
309
    drop_table :issue_histories
310
    drop_table :issue_statuses
311
    drop_table :issues
312
    drop_table :members
313
    drop_table :news
314
    drop_table :permissions
315
    drop_table :permissions_roles
316
    drop_table :projects
317
    drop_table :roles
318
    drop_table :trackers
304
    drop_table :custom_fields_trackers
305
    drop_table :custom_values
306
    drop_table :documents
307
    drop_table :enumerations
308
    drop_table :issue_categories
309
    drop_table :issue_histories
310
    drop_table :issue_statuses
311
    drop_table :issues
312
    drop_table :members
313
    drop_table :news
314
    drop_table :permissions
315
    drop_table :permissions_roles
316
    drop_table :projects
317
    drop_table :roles
318
    drop_table :trackers
319 319
    drop_table :tokens
320
    drop_table :users
321
    drop_table :versions
320
    drop_table :users
321
    drop_table :versions
322 322
    drop_table :workflows
323 323
  end
324 324
end
lib/SVG/Graph/Pie.rb (kopia robocza)
1
require 'SVG/Graph/Graph'
2

  
3
module SVG
4
  module Graph
5
    # === Create presentation quality SVG pie graphs easily
6
    # 
7
    # == Synopsis
8
    # 
9
    #   require 'SVG/Graph/Pie'
10
    # 
11
    #   fields = %w(Jan Feb Mar)
12
    #   data_sales_02 = [12, 45, 21]
13
    #   
14
    #   graph = SVG::Graph::Pie.new({
15
    #   	:height => 500,
16
    # 	  :width  => 300,
17
    # 	  :fields => fields,
18
    #   })
19
    #   
20
    #   graph.add_data({
21
    #   	:data => data_sales_02,
22
    # 	  :title => 'Sales 2002',
23
    #   })
24
    #   
25
    #   print "Content-type: image/svg+xml\r\n\r\n"
26
    #   print graph.burn();
27
    # 
28
    # == Description
29
    # 
30
    # This object aims to allow you to easily create high quality
31
    # SVG pie graphs. You can either use the default style sheet
32
    # or supply your own. Either way there are many options which can
33
    # be configured to give you control over how the graph is
34
    # generated - with or without a key, display percent on pie chart,
35
    # title, subtitle etc.
36
    #
37
    # = Examples
38
    # 
39
    # http://www.germane-software/repositories/public/SVG/test/single.rb
40
    # 
41
    # == See also
42
    #
43
    # * SVG::Graph::Graph
44
    # * SVG::Graph::BarHorizontal
45
    # * SVG::Graph::Bar
46
    # * SVG::Graph::Line
47
    # * SVG::Graph::Plot
48
    # * SVG::Graph::TimeSeries
49
    #
50
    # == Author
51
    #
52
    # Sean E. Russell <serATgermaneHYPHENsoftwareDOTcom>
53
    #
54
    # Copyright 2004 Sean E. Russell
55
    # This software is available under the Ruby license[LICENSE.txt]
56
    #
57
    class Pie < Graph
58
      # Defaults are those set by Graph::initialize, and
59
      # [show_shadow] true
60
      # [shadow_offset] 10
61
      # [show_data_labels] false
62
      # [show_actual_values] false
63
      # [show_percent] true
64
      # [show_key_data_labels] true
65
      # [show_key_actual_values] true
66
      # [show_key_percent] false
67
      # [expanded] false
68
      # [expand_greatest] false
69
      # [expand_gap] 10
70
      # [show_x_labels] false
71
      # [show_y_labels] false
72
      # [datapoint_font_size] 12
73
      def set_defaults
74
        init_with(
75
          :show_shadow		        => true,
76
          :shadow_offset	        => 10, 
77
          
78
          :show_data_labels	      => false,
79
          :show_actual_values     => false,
80
          :show_percent		        => true,
81

  
82
          :show_key_data_labels	  => true,
83
          :show_key_actual_values => true,
84
          :show_key_percent		    => false,
85
          
86
          :expanded				        => false,
87
          :expand_greatest		    => false,
88
          :expand_gap             => 10,
89
          
90
          :show_x_labels          => false,
91
          :show_y_labels          => false,
92
          :datapoint_font_size    => 12
93
        )
94
        @data = []
95
      end
96

  
97
      # Adds a data set to the graph.
98
      #
99
      #   graph.add_data( { :data => [1,2,3,4] } )
100
      #
101
      # Note that the :title is not necessary.  If multiple
102
      # data sets are added to the graph, the pie chart will
103
      # display the +sums+ of the data.  EG:
104
      #
105
      #   graph.add_data( { :data => [1,2,3,4] } )
106
      #   graph.add_data( { :data => [2,3,5,9] } )
107
      #
108
      # is the same as:
109
      #
110
      #   graph.add_data( { :data => [3,5,8,13] } )
111
      def add_data arg
112
        arg[:data].each_index {|idx|
113
          @data[idx] = 0 unless @data[idx]
114
          @data[idx] += arg[:data][idx]
115
        }
116
      end
117

  
118
      # If true, displays a drop shadow for the chart
119
      attr_accessor :show_shadow 
120
      # Sets the offset of the shadow from the pie chart
121
      attr_accessor :shadow_offset
122
      # If true, display the data labels on the chart
123
      attr_accessor :show_data_labels 
124
      # If true, display the actual field values in the data labels
125
      attr_accessor :show_actual_values 
126
      # If true, display the percentage value of each pie wedge in the data
127
      # labels
128
      attr_accessor :show_percent
129
      # If true, display the labels in the key
130
      attr_accessor :show_key_data_labels 
131
      # If true, display the actual value of the field in the key
132
      attr_accessor :show_key_actual_values 
133
      # If true, display the percentage value of the wedges in the key
134
      attr_accessor :show_key_percent
135
      # If true, "explode" the pie (put space between the wedges)
136
      attr_accessor :expanded 
137
      # If true, expand the largest pie wedge
138
      attr_accessor :expand_greatest 
139
      # The amount of space between expanded wedges
140
      attr_accessor :expand_gap 
141
      # The font size of the data point labels
142
      attr_accessor :datapoint_font_size
143

  
144

  
145
      protected
146

  
147
      def add_defs defs
148
        gradient = defs.add_element( "filter", {
149
          "id"=>"dropshadow",
150
          "width" => "1.2",
151
          "height" => "1.2",
152
        } )
153
        gradient.add_element( "feGaussianBlur", {
154
          "stdDeviation" => "4",
155
          "result" => "blur"
156
        })
157
      end
158

  
159
      # We don't need the graph
160
      def draw_graph
161
      end
162

  
163
      def get_y_labels
164
        [""]
165
      end
166

  
167
      def get_x_labels
168
        [""]
169
      end
170

  
171
      def keys
172
        total = 0
173
        max_value = 0
174
        @data.each {|x| total += x }
175
        percent_scale = 100.0 / total
176
        count = -1
177
        a = @config[:fields].collect{ |x|
178
          count += 1
179
          v = @data[count]
180
          perc = show_key_percent ? " "+(v * percent_scale).round.to_s+"%" : ""
181
          x + " [" + v.to_s + "]" + perc
182
        }
183
      end
184

  
185
      RADIANS = Math::PI/180
186

  
187
      def draw_data
188
        @graph = @root.add_element( "g" )
189
        background = @graph.add_element("g")
190
        midground = @graph.add_element("g")
191

  
192
        diameter = @graph_height > @graph_width ? @graph_width : @graph_height
193
        diameter -= expand_gap if expanded or expand_greatest
194
        diameter -= datapoint_font_size if show_data_labels
195
        diameter -= 10 if show_shadow
196
        radius = diameter / 2.0
197

  
198
        xoff = (width - diameter) / 2
199
        yoff = (height - @border_bottom - diameter)
200
        yoff -= 10 if show_shadow
201
        @graph.attributes['transform'] = "translate( #{xoff} #{yoff} )"
202

  
203
        wedge_text_pad = 5
204
        wedge_text_pad = 20 if show_percent and show_data_labels
205

  
206
        total = 0
207
        max_value = 0
208
        @data.each {|x| 
209
          max_value = max_value < x ? x : max_value
210
          total += x 
211
        }
212
        percent_scale = 100.0 / total
213

  
214
        prev_percent = 0
215
        rad_mult = 3.6 * RADIANS
216
        @config[:fields].each_index { |count|
217
          value = @data[count]
218
          percent = percent_scale * value
219

  
220
          radians = prev_percent * rad_mult
221
          x_start = radius+(Math.sin(radians) * radius)
222
          y_start = radius-(Math.cos(radians) * radius)
223
          radians = (prev_percent+percent) * rad_mult
224
          x_end = radius+(Math.sin(radians) * radius)
225
          x_end -= 0.00001 if @data.length == 1
226
          y_end = radius-(Math.cos(radians) * radius)
227
          path = "M#{radius},#{radius} L#{x_start},#{y_start} "+
228
            "A#{radius},#{radius} "+
229
            "0, #{percent >= 50 ? '1' : '0'},1, "+
230
            "#{x_end} #{y_end} Z"
231

  
232

  
233
          wedge = @foreground.add_element( "path", {
234
            "d" => path,
235
            "class" => "fill#{count+1}"
236
          })
237

  
238
          translate = nil
239
          tx = 0
240
          ty = 0
241
          half_percent = prev_percent + percent / 2
242
          radians = half_percent * rad_mult
243

  
244
          if show_shadow
245
            shadow = background.add_element( "path", {
246
              "d" => path,
247
              "filter" => "url(#dropshadow)",
248
              "style" => "fill: #ccc; stroke: none;"
249
            })
250
            clear = midground.add_element( "path", {
251
              "d" => path,
252
              "style" => "fill: #fff; stroke: none;"
253
            })
254
          end
255

  
256
          if expanded or (expand_greatest && value == max_value)
257
            tx = (Math.sin(radians) * expand_gap)
258
            ty = -(Math.cos(radians) * expand_gap)
259
            translate = "translate( #{tx} #{ty} )"
260
            wedge.attributes["transform"] = translate
261
            clear.attributes["transform"] = translate if clear
262
          end
263

  
264
          if show_shadow
265
            shadow.attributes["transform"] = 
266
              "translate( #{tx+shadow_offset} #{ty+shadow_offset} )"
267
          end
268
          
269
          if show_data_labels and value != 0
270
            label = ""
271
            label += @config[:fields][count] if show_key_data_labels
272
            label += " ["+value.to_s+"]" if show_actual_values
273
            label += " "+percent.round.to_s+"%" if show_percent
274

  
275
            msr = Math.sin(radians)
276
            mcr = Math.cos(radians)
277
            tx = radius + (msr * radius)
278
            ty = radius -(mcr * radius)
279

  
280
            if expanded or (expand_greatest && value == max_value)
281
              tx += (msr * expand_gap)
282
              ty -= (mcr * expand_gap)
283
            end
284
            @foreground.add_element( "text", {
285
              "x" => tx.to_s,
286
              "y" => ty.to_s,
287
              "class" => "dataPointLabel",
288
              "style" => "stroke: #fff; stroke-width: 2;"
289
            }).text = label.to_s
290
            @foreground.add_element( "text", {
291
              "x" => tx.to_s,
292
              "y" => ty.to_s,
293
              "class" => "dataPointLabel",
294
            }).text = label.to_s
295
          end
296

  
297
          prev_percent += percent
298
        }
299
      end
300
      
301

  
302
      def round val, to
303
        up = 10**to.to_f
304
        (val * up).to_i / up
305
      end
306

  
307

  
308
      def get_css
309
        return <<EOL
310
.dataPointLabel{
311
	fill: #000000;
312
	text-anchor:middle;
313
	font-size: #{datapoint_font_size}px;
314
	font-family: "Arial", sans-serif;
315
	font-weight: normal;
316
}
317

  
318
/* key - MUST match fill styles */
319
.key1,.fill1{
320
	fill: #ff0000;
321
	fill-opacity: 0.7;
322
	stroke: none;
323
	stroke-width: 1px;	
324
}
325
.key2,.fill2{
326
	fill: #0000ff;
327
	fill-opacity: 0.7;
328
	stroke: none;
329
	stroke-width: 1px;	
330
}
331
.key3,.fill3{
332
	fill-opacity: 0.7;
333
	fill: #00ff00;
334
	stroke: none;
335
	stroke-width: 1px;	
336
}
337
.key4,.fill4{
338
	fill-opacity: 0.7;
339
	fill: #ffcc00;
340
	stroke: none;
341
	stroke-width: 1px;	
342
}
343
.key5,.fill5{
344
	fill-opacity: 0.7;
345
	fill: #00ccff;
346
	stroke: none;
347
	stroke-width: 1px;	
348
}
349
.key6,.fill6{
350
	fill-opacity: 0.7;
351
	fill: #ff00ff;
352
	stroke: none;
353
	stroke-width: 1px;	
354
}
355
.key7,.fill7{
356
	fill-opacity: 0.7;
357
	fill: #00ff99;
358
	stroke: none;
359
	stroke-width: 1px;	
360
}
361
.key8,.fill8{
362
	fill-opacity: 0.7;
363
	fill: #ffff00;
364
	stroke: none;
365
	stroke-width: 1px;	
366
}
367
.key9,.fill9{
368
	fill-opacity: 0.7;
369
	fill: #cc6666;
370
	stroke: none;
371
	stroke-width: 1px;	
372
}
373
.key10,.fill10{
374
	fill-opacity: 0.7;
375
	fill: #663399;
376
	stroke: none;
377
	stroke-width: 1px;	
378
}
379
.key11,.fill11{
380
	fill-opacity: 0.7;
381
	fill: #339900;
382
	stroke: none;
383
	stroke-width: 1px;	
384
}
385
.key12,.fill12{
386
	fill-opacity: 0.7;
387
	fill: #9966FF;
388
	stroke: none;
389
	stroke-width: 1px;	
390
}
391
EOL
392
      end
393
    end
394
  end
395
end
1
require 'SVG/Graph/Graph'
2

  
3
module SVG
4
  module Graph
5
    # === Create presentation quality SVG pie graphs easily
6
    # 
7
    # == Synopsis
8
    # 
9
    #   require 'SVG/Graph/Pie'
10
    # 
11
    #   fields = %w(Jan Feb Mar)
12
    #   data_sales_02 = [12, 45, 21]
13
    #   
14
    #   graph = SVG::Graph::Pie.new({
15
    #   	:height => 500,
16
    # 	  :width  => 300,
17
    # 	  :fields => fields,
18
    #   })
19
    #   
20
    #   graph.add_data({
21
    #   	:data => data_sales_02,
22
    # 	  :title => 'Sales 2002',
23
    #   })
24
    #   
25
    #   print "Content-type: image/svg+xml\r\n\r\n"
26
    #   print graph.burn();
27
    # 
28
    # == Description
29
    # 
30
    # This object aims to allow you to easily create high quality
31
    # SVG pie graphs. You can either use the default style sheet
32
    # or supply your own. Either way there are many options which can
33
    # be configured to give you control over how the graph is
34
    # generated - with or without a key, display percent on pie chart,
35
    # title, subtitle etc.
36
    #
37
    # = Examples
38
    # 
39
    # http://www.germane-software/repositories/public/SVG/test/single.rb
40
    # 
41
    # == See also
42
    #
43
    # * SVG::Graph::Graph
44
    # * SVG::Graph::BarHorizontal
45
    # * SVG::Graph::Bar
46
    # * SVG::Graph::Line
47
    # * SVG::Graph::Plot
48
    # * SVG::Graph::TimeSeries
49
    #
50
    # == Author
51
    #
52
    # Sean E. Russell <serATgermaneHYPHENsoftwareDOTcom>
53
    #
54
    # Copyright 2004 Sean E. Russell
55
    # This software is available under the Ruby license[LICENSE.txt]
56
    #
57
    class Pie < Graph
58
      # Defaults are those set by Graph::initialize, and
59
      # [show_shadow] true
60
      # [shadow_offset] 10
61
      # [show_data_labels] false
62
      # [show_actual_values] false
63
      # [show_percent] true
64
      # [show_key_data_labels] true
65
      # [show_key_actual_values] true
66
      # [show_key_percent] false
67
      # [expanded] false
68
      # [expand_greatest] false
69
      # [expand_gap] 10
70
      # [show_x_labels] false
71
      # [show_y_labels] false
72
      # [datapoint_font_size] 12
73
      def set_defaults
74
        init_with(
75
          :show_shadow		        => true,
76
          :shadow_offset	        => 10, 
77
          
78
          :show_data_labels	      => false,
79
          :show_actual_values     => false,
80
          :show_percent		        => true,
81

  
82
          :show_key_data_labels	  => true,
83
          :show_key_actual_values => true,
84
          :show_key_percent		    => false,
85
          
86
          :expanded				        => false,
87
          :expand_greatest		    => false,
88
          :expand_gap             => 10,
89
          
90
          :show_x_labels          => false,
91
          :show_y_labels          => false,
92
          :datapoint_font_size    => 12
93
        )
94
        @data = []
95
      end
96

  
97
      # Adds a data set to the graph.
98
      #
99
      #   graph.add_data( { :data => [1,2,3,4] } )
100
      #
101
      # Note that the :title is not necessary.  If multiple
102
      # data sets are added to the graph, the pie chart will
103
      # display the +sums+ of the data.  EG:
104
      #
105
      #   graph.add_data( { :data => [1,2,3,4] } )
106
      #   graph.add_data( { :data => [2,3,5,9] } )
107
      #
108
      # is the same as:
109
      #
110
      #   graph.add_data( { :data => [3,5,8,13] } )
111
      def add_data arg
112
        arg[:data].each_index {|idx|
113
          @data[idx] = 0 unless @data[idx]
114
          @data[idx] += arg[:data][idx]
115
        }
116
      end
117

  
118
      # If true, displays a drop shadow for the chart
119
      attr_accessor :show_shadow 
120
      # Sets the offset of the shadow from the pie chart
121
      attr_accessor :shadow_offset
122
      # If true, display the data labels on the chart
123
      attr_accessor :show_data_labels 
124
      # If true, display the actual field values in the data labels
125
      attr_accessor :show_actual_values 
126
      # If true, display the percentage value of each pie wedge in the data
127
      # labels
128
      attr_accessor :show_percent
129
      # If true, display the labels in the key
130
      attr_accessor :show_key_data_labels 
131
      # If true, display the actual value of the field in the key
132
      attr_accessor :show_key_actual_values 
133
      # If true, display the percentage value of the wedges in the key
134
      attr_accessor :show_key_percent
135
      # If true, "explode" the pie (put space between the wedges)
136
      attr_accessor :expanded 
137
      # If true, expand the largest pie wedge
138
      attr_accessor :expand_greatest 
139
      # The amount of space between expanded wedges
140
      attr_accessor :expand_gap 
141
      # The font size of the data point labels
142
      attr_accessor :datapoint_font_size
143

  
144

  
145
      protected
146

  
147
      def add_defs defs
148
        gradient = defs.add_element( "filter", {
149
          "id"=>"dropshadow",
150
          "width" => "1.2",
151
          "height" => "1.2",
152
        } )
153
        gradient.add_element( "feGaussianBlur", {
154
          "stdDeviation" => "4",
155
          "result" => "blur"
156
        })
157
      end
158

  
159
      # We don't need the graph
160
      def draw_graph
161
      end
162

  
163
      def get_y_labels
164
        [""]
165
      end
166

  
167
      def get_x_labels
168
        [""]
169
      end
170

  
171
      def keys
172
        total = 0
173
        max_value = 0
174
        @data.each {|x| total += x }
175
        percent_scale = 100.0 / total
176
        count = -1
177
        a = @config[:fields].collect{ |x|
178
          count += 1
179
          v = @data[count]
180
          perc = show_key_percent ? " "+(v * percent_scale).round.to_s+"%" : ""
181
          x + " [" + v.to_s + "]" + perc
182
        }
183
      end
184

  
185
      RADIANS = Math::PI/180
186

  
187
      def draw_data
188
        @graph = @root.add_element( "g" )
189
        background = @graph.add_element("g")
190
        midground = @graph.add_element("g")
191

  
192
        diameter = @graph_height > @graph_width ? @graph_width : @graph_height
193
        diameter -= expand_gap if expanded or expand_greatest
194
        diameter -= datapoint_font_size if show_data_labels
195
        diameter -= 10 if show_shadow
196
        radius = diameter / 2.0
197

  
198
        xoff = (width - diameter) / 2
199
        yoff = (height - @border_bottom - diameter)
200
        yoff -= 10 if show_shadow
201
        @graph.attributes['transform'] = "translate( #{xoff} #{yoff} )"
202

  
203
        wedge_text_pad = 5
204
        wedge_text_pad = 20 if show_percent and show_data_labels
205

  
206
        total = 0
207
        max_value = 0
208
        @data.each {|x| 
209
          max_value = max_value < x ? x : max_value
210
          total += x 
211
        }
212
        percent_scale = 100.0 / total
213

  
214
        prev_percent = 0
215
        rad_mult = 3.6 * RADIANS
216
        @config[:fields].each_index { |count|
217
          value = @data[count]
218
          percent = percent_scale * value
219

  
220
          radians = prev_percent * rad_mult
221
          x_start = radius+(Math.sin(radians) * radius)
222
          y_start = radius-(Math.cos(radians) * radius)
223
          radians = (prev_percent+percent) * rad_mult
224
          x_end = radius+(Math.sin(radians) * radius)
225
          x_end -= 0.00001 if @data.length == 1
226
          y_end = radius-(Math.cos(radians) * radius)
227
          path = "M#{radius},#{radius} L#{x_start},#{y_start} "+
228
            "A#{radius},#{radius} "+
229
            "0, #{percent >= 50 ? '1' : '0'},1, "+
230
            "#{x_end} #{y_end} Z"
231

  
232

  
233
          wedge = @foreground.add_element( "path", {
234
            "d" => path,
235
            "class" => "fill#{count+1}"
236
          })
237

  
238
          translate = nil
239
          tx = 0
240
          ty = 0
241
          half_percent = prev_percent + percent / 2
242
          radians = half_percent * rad_mult
243

  
244
          if show_shadow
245
            shadow = background.add_element( "path", {
246
              "d" => path,
247
              "filter" => "url(#dropshadow)",
248
              "style" => "fill: #ccc; stroke: none;"
249
            })
250
            clear = midground.add_element( "path", {
251
              "d" => path,
252
              "style" => "fill: #fff; stroke: none;"
253
            })
254
          end
255

  
256
          if expanded or (expand_greatest && value == max_value)
257
            tx = (Math.sin(radians) * expand_gap)
258
            ty = -(Math.cos(radians) * expand_gap)
259
            translate = "translate( #{tx} #{ty} )"
260
            wedge.attributes["transform"] = translate
261
            clear.attributes["transform"] = translate if clear
262
          end
263

  
264
          if show_shadow
265
            shadow.attributes["transform"] = 
266
              "translate( #{tx+shadow_offset} #{ty+shadow_offset} )"
267
          end
268
          
269
          if show_data_labels and value != 0
270
            label = ""
271
            label += @config[:fields][count] if show_key_data_labels
272
            label += " ["+value.to_s+"]" if show_actual_values
273
            label += " "+percent.round.to_s+"%" if show_percent
274

  
275
            msr = Math.sin(radians)
276
            mcr = Math.cos(radians)
277
            tx = radius + (msr * radius)
278
            ty = radius -(mcr * radius)
279

  
280
            if expanded or (expand_greatest && value == max_value)
281
              tx += (msr * expand_gap)
282
              ty -= (mcr * expand_gap)
283
            end
284
            @foreground.add_element( "text", {
285
              "x" => tx.to_s,
286
              "y" => ty.to_s,
287
              "class" => "dataPointLabel",
288
              "style" => "stroke: #fff; stroke-width: 2;"
289
            }).text = label.to_s
290
            @foreground.add_element( "text", {
291
              "x" => tx.to_s,
292
              "y" => ty.to_s,
293
              "class" => "dataPointLabel",
294
            }).text = label.to_s
295
          end
296

  
297
          prev_percent += percent
298
        }
299
      end
300
      
301

  
302
      def round val, to
303
        up = 10**to.to_f
304
        (val * up).to_i / up
305
      end
306

  
307

  
308
      def get_css
309
        return <<EOL
310
.dataPointLabel{
311
	fill: #000000;
312
	text-anchor:middle;
313
	font-size: #{datapoint_font_size}px;
314
	font-family: "Arial", sans-serif;
315
	font-weight: normal;
316
}
317

  
318
/* key - MUST match fill styles */
319
.key1,.fill1{
320
	fill: #ff0000;
321
	fill-opacity: 0.7;
322
	stroke: none;
323
	stroke-width: 1px;	
324
}
325
.key2,.fill2{
326
	fill: #0000ff;
327
	fill-opacity: 0.7;
328
	stroke: none;
329
	stroke-width: 1px;	
330
}
331
.key3,.fill3{
332
	fill-opacity: 0.7;
333
	fill: #00ff00;
334
	stroke: none;
335
	stroke-width: 1px;	
336
}
337
.key4,.fill4{
338
	fill-opacity: 0.7;
339
	fill: #ffcc00;
340
	stroke: none;
341
	stroke-width: 1px;	
342
}
343
.key5,.fill5{
344
	fill-opacity: 0.7;
345
	fill: #00ccff;
346
	stroke: none;
347
	stroke-width: 1px;	
348
}
349
.key6,.fill6{
350
	fill-opacity: 0.7;
351
	fill: #ff00ff;
352
	stroke: none;
353
	stroke-width: 1px;	
354
}
355
.key7,.fill7{
356
	fill-opacity: 0.7;
357
	fill: #00ff99;
358
	stroke: none;
359
	stroke-width: 1px;	
360
}
361
.key8,.fill8{
362
	fill-opacity: 0.7;
363
	fill: #ffff00;
364
	stroke: none;
365
	stroke-width: 1px;	
366
}
367
.key9,.fill9{
368
	fill-opacity: 0.7;
369
	fill: #cc6666;
370
	stroke: none;
371
	stroke-width: 1px;	
372
}
373
.key10,.fill10{
374
	fill-opacity: 0.7;
375
	fill: #663399;
376
	stroke: none;
377
	stroke-width: 1px;	
378
}
379
.key11,.fill11{
380
	fill-opacity: 0.7;
381
	fill: #339900;
382
	stroke: none;
383
	stroke-width: 1px;	
384
}
385
.key12,.fill12{
386
	fill-opacity: 0.7;
387
	fill: #9966FF;
388
	stroke: none;
389
	stroke-width: 1px;	
390
}
391
EOL
392
      end
393
    end
394
  end
395
end
lib/SVG/Graph/BarHorizontal.rb (kopia robocza)
1
require 'rexml/document'
2
require 'SVG/Graph/BarBase'
3

  
4
module SVG
5
  module Graph
6
    # === Create presentation quality SVG horitonzal bar graphs easily
7
    # 
8
    # = Synopsis
9
    # 
10
    #   require 'SVG/Graph/BarHorizontal'
11
    #   
12
    #   fields = %w(Jan Feb Mar)
13
    #   data_sales_02 = [12, 45, 21]
14
    #   
15
    #   graph = SVG::Graph::BarHorizontal.new({
16
    #     :height => 500,
17
    #     :width => 300,
18
    #     :fields => fields,
19
    #   })
20
    #   
21
    #   graph.add_data({
22
    #     :data => data_sales_02,
23
    #     :title => 'Sales 2002',
24
    #   })
25
    #   
26
    #   print "Content-type: image/svg+xml\r\n\r\n"
27
    #   print graph.burn
28
    # 
29
    # = Description
30
    # 
31
    # This object aims to allow you to easily create high quality
32
    # SVG horitonzal bar graphs. You can either use the default style sheet
33
    # or supply your own. Either way there are many options which can
34
    # be configured to give you control over how the graph is
35
    # generated - with or without a key, data elements at each point,
36
    # title, subtitle etc.
37
    # 
38
    # = Examples
39
    # 
40
    # * http://germane-software.com/repositories/public/SVG/test/test.rb
41
    # 
42
    # = See also
43
    # 
44
    # * SVG::Graph::Graph
45
    # * SVG::Graph::Bar
46
    # * SVG::Graph::Line
47
    # * SVG::Graph::Pie
48
    # * SVG::Graph::Plot
49
    # * SVG::Graph::TimeSeries
50
    #
51
    # == Author
52
    #
53
    # Sean E. Russell <serATgermaneHYPHENsoftwareDOTcom>
54
    #
55
    # Copyright 2004 Sean E. Russell
56
    # This software is available under the Ruby license[LICENSE.txt]
57
    #
58
    class BarHorizontal < BarBase
59
      # In addition to the defaults set in BarBase::set_defaults, sets
60
      # [rotate_y_labels] true
61
      # [show_x_guidelines] true
62
      # [show_y_guidelines] false
63
      def set_defaults
64
        super
65
        init_with( 
66
          :rotate_y_labels    => true,
67
          :show_x_guidelines  => true,
68
          :show_y_guidelines  => false
69
        )
70
        self.right_align = self.right_font = 1
71
      end
72
  
73
      protected
74

  
75
      def get_x_labels
76
        maxvalue = max_value
77
        minvalue = min_value
78
        range = maxvalue - minvalue
79
        top_pad = range == 0 ? 10 : range / 20.0
80
        scale_range = (maxvalue + top_pad) - minvalue
81

  
82
        scale_division = scale_divisions || (scale_range / 10.0)
83

  
84
        if scale_integers
85
          scale_division = scale_division < 1 ? 1 : scale_division.round
86
        end
87

  
88
        rv = []
89
        maxvalue = maxvalue%scale_division == 0 ? 
90
          maxvalue : maxvalue + scale_division
91
        minvalue.step( maxvalue, scale_division ) {|v| rv << v}
92
        return rv
93
      end
94

  
95
      def get_y_labels
96
        @config[:fields]
97
      end
98

  
99
      def y_label_offset( height )
100
        height / -2.0
101
      end
102

  
103
      def draw_data
104
        minvalue = min_value
105
        fieldheight = field_height
106

  
107
        unit_size = (@graph_width.to_f - font_size*2*right_font ) /
108
                        (get_x_labels.max - get_x_labels.min )
109
        bargap = bar_gap ? (fieldheight < 10 ? fieldheight / 2 : 10) : 0
110

  
111
        bar_height = fieldheight - bargap
112
        bar_height /= @data.length if stack == :side
... This diff was truncated because it exceeds the maximum size that can be displayed.
(1-1/2)