rukbat 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9e1adcf1d5362c707d385caf7e0035b9aa358286bc45752d67abe012606a9961
4
- data.tar.gz: ec59e5a8ac486e57bded8e8f3a54129ac7514321722132edbae4181aabcefc4f
3
+ metadata.gz: fbd7509f4fe7e264acc4fe9dc0f51fedfc0c953a15f115046c4dd54557540263
4
+ data.tar.gz: 750029435921d213b829a14a87ece225e926c9d0aa4d876138071f01405b09ef
5
5
  SHA512:
6
- metadata.gz: 207d10683c00d7ce74ac3c101f0facd2c8e39385ee186f09e2c38dbbb15e19e7ee603e3b9f6a0ff528a5d46006a52693e12511ebc36981324e6c469d61bea5ef
7
- data.tar.gz: f2ee8e18a439ae0fc7a7ad271aa44ea783250504b1362afe82cae72af1461c3f5304861bd3334e1bec3880fe1689d9b52d7f2451b1deda883609b61e8f58f2e9
6
+ metadata.gz: 6659e6022995046877f65163bea1ecd7412181591b69376d0b369013832c2507e75576c038914a33b86a3871fabdf86390bd32840eca70c647daa9b955b3f085
7
+ data.tar.gz: 489ff8a98679c21b4d7f70481ad161cae366e94e7b0b9acec22d82a02f8c45b4d6df37229e6860faebe5fefd681544c9c532e5e315ae7f4052d72c9641b35b04
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.0 — 2026-09-24
4
+
5
+ - Add donut, scatter, area, stacked-area, and stacked-bar chart options.
6
+
3
7
  ## 0.1.0 — 2026-09-23
4
8
 
5
9
  - Initial release.
data/README.md CHANGED
@@ -7,9 +7,9 @@ Furud formula engine.
7
7
  The current implementation includes a virtualized million-row grid, formula
8
8
  editing and completion, multi-sheet formulas, range summaries, undo/redo,
9
9
  structural row/column edits, formatting, sorting, filtering, duplicate removal,
10
- find/replace, comments, named ranges, conditional formatting, line/bar/pie
11
- charts, CSV/TSV import/export, and searchable PDF export. The application is
12
- still under development and has not been released as `0.1.0`. On arm64 macOS
10
+ find/replace, comments, named ranges, conditional formatting, line/bar/pie,
11
+ donut/scatter/area/stacked charts, CSV/TSV import/export, and searchable PDF
12
+ export. On arm64 macOS
13
13
  with Ruby 4.0.6, the million-row integrated scroll benchmark measured 11.383 ms
14
14
  against a 16.67 ms budget, and the 100,000-cell edit/recalculation benchmark
15
15
  measured 1.773 s against a 3 s budget. Formula compatibility, public CI, and
@@ -69,7 +69,8 @@ count, numeric count, sum, and average appear in the status bar.
69
69
 
70
70
  The toolbar provides common number, font, alignment, fill, and border formats;
71
71
  sorting, filtering, duplicate removal, search/replace, comments, named ranges,
72
- positive-value highlighting, freeze/unfreeze panes, print areas, and line/bar/pie charts.
72
+ positive-value highlighting, freeze/unfreeze panes, print areas, and line, bar,
73
+ pie, donut, scatter, area, stacked-area, and stacked-bar charts.
73
74
  Freeze panes are kept per sheet and restored by undo/redo; the selected cell and
74
75
  the row/column headers before it stay visible while scrolling. **Unfreeze** removes
75
76
  all frozen rows and columns. Clear highlights removes conditional formatting
@@ -37,9 +37,8 @@ module Rukbat
37
37
  @freeze_button = UI::Button.new("Freeze", size: :sm, variant: :ghost).on_click { freeze_panes }
38
38
  @unfreeze_button = UI::Button.new("Unfreeze", size: :sm, variant: :ghost).on_click { unfreeze_panes }
39
39
  @clear_conditional_button = UI::Button.new("Clear highlights", size: :sm, variant: :ghost).on_click { clear_highlights }
40
- @line_chart_button = UI::Button.new("Line", size: :sm, variant: :ghost).on_click { show_chart(:line) }
41
- @bar_chart_button = UI::Button.new("Bar", size: :sm, variant: :ghost).on_click { show_chart(:bar) }
42
- @pie_chart_button = UI::Button.new("Pie", size: :sm, variant: :ghost).on_click { show_chart(:pie) }
40
+ @chart_dropdown = UI::Dropdown.new("Chart", items: %w[Line Bar Pie Donut Scatter Area Stacked\ area Stacked\ bar])
41
+ .on_change { |name, *_| show_chart(name.downcase.tr(" ", "_").to_sym) }
43
42
  @font_down_button = UI::Button.new("A−", size: :sm, variant: :ghost).on_click { change_font_size(-1) }
44
43
  @font_up_button = UI::Button.new("A+", size: :sm, variant: :ghost).on_click { change_font_size(1) }
45
44
  @align_button = UI::Button.new("Align", size: :sm, variant: :ghost).on_click { cycle_alignment }
@@ -118,7 +117,7 @@ module Rukbat
118
117
  .child(@undo_button).child(@redo_button).child(@save_button).child(@add_sheet_button)
119
118
  .child(@number_button).child(@percent_button).child(@bold_button).child(@fill_button)
120
119
  .child(@freeze_button).child(@unfreeze_button).child(@clear_conditional_button)
121
- .child(@line_chart_button).child(@bar_chart_button).child(@pie_chart_button)
120
+ .child(@chart_dropdown)
122
121
  format_toolbar = Zaniah::Div.new.flex_row.items_center.gap(cx.theme.spacing[1])
123
122
  .child(@font_down_button).child(@font_up_button).child(@align_button)
124
123
  .child(@text_color_button).child(@border_button)
@@ -750,14 +749,19 @@ module Rukbat
750
749
  request_frame
751
750
  return false
752
751
  end
753
- series = chart_series(top, left, bottom, right)
752
+ series = chart_series(top, left, bottom, right) unless type == :scatter
754
753
  @chart_component = case type
755
754
  when :line then UI::LineChart.new(series, width: 480, height: 180)
756
755
  when :bar then UI::BarChart.new(series, width: 480, height: 180)
757
756
  when :pie then UI::PieChart.new(pie_values(top, left, bottom, right), width: 320, height: 180)
757
+ when :donut then UI::DonutChart.new(pie_values(top, left, bottom, right), width: 320, height: 180)
758
+ when :scatter then UI::ScatterChart.new(scatter_series(top, left, bottom, right), width: 480, height: 180)
759
+ when :area then UI::AreaChart.new(series, width: 480, height: 180)
760
+ when :stacked_area then UI::AreaChart.new(series, width: 480, height: 180, stacked: true)
761
+ when :stacked_bar then UI::StackedBarChart.new(series, width: 480, height: 180)
758
762
  else raise ArgumentError, "unsupported chart type"
759
763
  end
760
- @status = "#{type.to_s.capitalize} chart"
764
+ @status = "#{type.to_s.tr("_", " ").capitalize} chart"
761
765
  request_frame
762
766
  true
763
767
  rescue ArgumentError, Rukbat::Error => error
@@ -782,16 +786,37 @@ module Rukbat
782
786
  columns.to_h do |column|
783
787
  name = @workbook.input_at(top, column).to_s
784
788
  name = "Series #{column_name(column)}" if name.empty?
785
- values = ((top + 1)..bottom).map do |row|
786
- value = @workbook[row, column]
787
- value.nil? ? 0 : Float(value)
788
- rescue ArgumentError, TypeError
789
- 0
790
- end
789
+ values = ((top + 1)..bottom).map { |row| chart_value(row, column) }
791
790
  [name, values]
792
791
  end
793
792
  end
794
793
 
794
+ def scatter_series(top, left, bottom, right)
795
+ columns = (left..right).to_a
796
+ first_column_is_labels = ((top + 1)..bottom).none? do |row|
797
+ Float(@workbook[row, left])
798
+ true
799
+ rescue ArgumentError, TypeError
800
+ false
801
+ end
802
+ columns.shift if first_column_is_labels
803
+ raise ArgumentError, "select X and at least one Y column for a scatter chart" if columns.length < 2
804
+
805
+ x_values = ((top + 1)..bottom).map { |row| chart_value(row, columns.first) }
806
+ columns.drop(1).to_h do |column|
807
+ name = @workbook.input_at(top, column).to_s
808
+ name = "Series #{column_name(column)}" if name.empty?
809
+ [name, ((top + 1)..bottom).map { |row| [x_values[row - top - 1], chart_value(row, column)] }]
810
+ end
811
+ end
812
+
813
+ def chart_value(row, column)
814
+ value = @workbook[row, column]
815
+ value.nil? ? 0 : Float(value)
816
+ rescue ArgumentError, TypeError
817
+ 0
818
+ end
819
+
795
820
  def pie_values(top, left, bottom, right)
796
821
  column = right > left ? left + 1 : left
797
822
  (top + 1..bottom).to_h do |row|
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rukbat
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rukbat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yudai Takada
8
+ autorequire:
8
9
  bindir: exe
9
10
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
11
+ date: 2026-09-24 00:00:00.000000000 Z
11
12
  dependencies:
12
13
  - !ruby/object:Gem::Dependency
13
14
  name: denebola
@@ -181,6 +182,7 @@ metadata:
181
182
  source_code_uri: https://github.com/noxdea/rukbat/tree/main
182
183
  changelog_uri: https://github.com/noxdea/rukbat/blob/main/CHANGELOG.md
183
184
  rubygems_mfa_required: 'true'
185
+ post_install_message:
184
186
  rdoc_options: []
185
187
  require_paths:
186
188
  - lib
@@ -195,7 +197,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
195
197
  - !ruby/object:Gem::Version
196
198
  version: '0'
197
199
  requirements: []
198
- rubygems_version: 4.0.16
200
+ rubygems_version: 3.4.19
201
+ signing_key:
199
202
  specification_version: 4
200
203
  summary: Spreadsheet application with sparse storage and incremental formulas
201
204
  test_files: []