asciidoctor-chart 1.0.0.alpha.1
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 +7 -0
- data/LICENSE.adoc +22 -0
- data/README.adoc +19 -0
- data/asciidoctor-chart.gemspec +38 -0
- data/lib/asciidoctor-chart.rb +3 -0
- data/lib/asciidoctor/chart.rb +20 -0
- data/lib/asciidoctor/chart/backend.rb +58 -0
- data/lib/asciidoctor/chart/block_macro_processor.rb +22 -0
- data/lib/asciidoctor/chart/block_processor.rb +20 -0
- data/lib/asciidoctor/chart/c3js/chart_builder.rb +226 -0
- data/lib/asciidoctor/chart/chartist/chart_builder.rb +88 -0
- data/lib/asciidoctor/chart/chartjs/chart_builder.rb +66 -0
- data/lib/asciidoctor/chart/docinfo_processor.rb +32 -0
- data/lib/asciidoctor/chart/plain_ruby_csv.rb +25 -0
- data/lib/asciidoctor/chart/plain_ruby_random.rb +11 -0
- data/lib/asciidoctor/chart/version.rb +7 -0
- metadata +103 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f04e36b08cd8bcd45da1387e52efb5f982f92aceb1b14912130158eb4c7f34a1
|
4
|
+
data.tar.gz: fc325aa365a1b8ccf11fcc3e10cb6efd52fb0a447280e72c37d8db77eb412f94
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: dba17ce4d883a862ad885833dbe8785fbc9d3d334a35fc97a31fb0d05bf11442a2cb086cd80a23a43b15be9031d6e96dce0f48e5042c035f365dd0b1a7102d5a
|
7
|
+
data.tar.gz: d55676125f54e5898e966fe0f4241c01dc24bc7bb8cfdf0a8f72601eba1999e8f69080d61efbe19dac9b7a966e658609162f9cf1fdeeede3882aae9e68b3e35b
|
data/LICENSE.adoc
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
.The MIT License
|
2
|
+
....
|
3
|
+
Copyright (C) 2014-2020 Guillaume Grossetie
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
22
|
+
....
|
data/README.adoc
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
= Asciidoctor Chart
|
2
|
+
// Settings:
|
3
|
+
:idprefix:
|
4
|
+
:idseparator: -
|
5
|
+
|
6
|
+
image:https://github.com/asciidoctor/asciidoctor-chart/workflows/Ruby/badge.svg[link=https://github.com/asciidoctor/asciidoctor-chart/actions?query=workflow%3ARuby]
|
7
|
+
|
8
|
+
A set of Asciidoctor extensions that adds a chart block and block macro for including charts powered by powered by c3js, chartist, or chartjs in your AsciiDoc document.
|
9
|
+
|
10
|
+
== Authors
|
11
|
+
|
12
|
+
Asciidoctor Chart was written by https://github.com/mogztter/[Guillaume Grossetie].
|
13
|
+
|
14
|
+
== Copyright
|
15
|
+
|
16
|
+
Copyright (C) 2014-2020 Guillaume Grossetie
|
17
|
+
Free use of this software is granted under the terms of the MIT License.
|
18
|
+
|
19
|
+
For the full text of the license, see the <<LICENSE.adoc#,LICENSE>> file.
|
@@ -0,0 +1,38 @@
|
|
1
|
+
begin
|
2
|
+
require_relative 'lib/asciidoctor/chart/version'
|
3
|
+
rescue LoadError
|
4
|
+
require 'asciidoctor/chart/version'
|
5
|
+
end
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = 'asciidoctor-chart'
|
9
|
+
s.version = Asciidoctor::Chart::VERSION
|
10
|
+
s.summary = 'Adds a chart block and block macro to AsciiDoc'
|
11
|
+
s.description = 'A set of Asciidoctor extensions that add a chart block and block macro to AsciiDoc for including charts in your AsciiDoc document.'
|
12
|
+
s.authors = ['Guillaume Grossetie']
|
13
|
+
s.email = 'ggrossetie@gmail.com'
|
14
|
+
s.homepage = 'https://asciidoctor.org'
|
15
|
+
s.license = 'MIT'
|
16
|
+
# NOTE required ruby version is informational only; it's not enforced since it can't be overridden and can cause builds to break
|
17
|
+
#s.required_ruby_version = '>= 2.5.0'
|
18
|
+
s.metadata = {
|
19
|
+
'bug_tracker_uri' => 'https://github.com/asciidoctor/asciidoctor-chart/issues',
|
20
|
+
#'changelog_uri' => 'https://github.com/asciidoctor/asciidoctor-chart/blob/master/CHANGELOG.adoc',
|
21
|
+
'mailing_list_uri' => 'http://discuss.asciidoctor.org',
|
22
|
+
'source_code_uri' => 'https://github.com/asciidoctor/asciidoctor-chart'
|
23
|
+
}
|
24
|
+
|
25
|
+
# NOTE the logic to build the list of files is designed to produce a usable package even when the git command is not available
|
26
|
+
begin
|
27
|
+
files = (result = `git ls-files -z`.split ?\0).empty? ? Dir['**/*'] : result
|
28
|
+
rescue
|
29
|
+
files = Dir['**/*']
|
30
|
+
end
|
31
|
+
s.files = files.grep %r/^(?:(?:data|lib)\/.+|(?:CHANGELOG|LICENSE|NOTICE|README)\.adoc|\.yardopts|#{s.name}\.gemspec)$/
|
32
|
+
s.executables = (files.grep %r/^bin\//).map {|f| File.basename f }
|
33
|
+
s.require_paths = ['lib']
|
34
|
+
|
35
|
+
s.add_runtime_dependency 'asciidoctor', '~> 2.0'
|
36
|
+
s.add_development_dependency 'rake', '~> 13.0.0'
|
37
|
+
s.add_development_dependency 'rspec', '~> 3.9.0'
|
38
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'asciidoctor/extensions'
|
4
|
+
require_relative 'chart/block_macro_processor'
|
5
|
+
require_relative 'chart/block_processor'
|
6
|
+
require_relative 'chart/docinfo_processor'
|
7
|
+
require_relative 'chart/backend'
|
8
|
+
require_relative 'chart/plain_ruby_csv'
|
9
|
+
require_relative 'chart/plain_ruby_random'
|
10
|
+
require_relative 'chart/c3js/chart_builder'
|
11
|
+
require_relative 'chart/chartjs/chart_builder'
|
12
|
+
require_relative 'chart/chartist/chart_builder'
|
13
|
+
|
14
|
+
Asciidoctor::Extensions.register do
|
15
|
+
return unless document.basebackend? 'html'
|
16
|
+
|
17
|
+
block_macro Asciidoctor::Chart::BlockMacroProcessor
|
18
|
+
block Asciidoctor::Chart::BlockProcessor
|
19
|
+
docinfo_processor Asciidoctor::Chart::DocinfoProcessor
|
20
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Asciidoctor
|
4
|
+
module Chart
|
5
|
+
class Backend
|
6
|
+
def self.resolve_engine attrs, document
|
7
|
+
if attrs.key? 'engine'
|
8
|
+
attrs['engine'].downcase
|
9
|
+
elsif document.attributes.key? 'chart-engine'
|
10
|
+
document.attributes['chart-engine'].downcase
|
11
|
+
else
|
12
|
+
'c3js'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.process engine, attrs, raw_data
|
17
|
+
# TODO: Check that the engine can process the required type (bar, line, step...)
|
18
|
+
type = attrs['type']
|
19
|
+
case engine
|
20
|
+
when 'c3js'
|
21
|
+
if type == 'pie'
|
22
|
+
C3js::ChartBuilder.pie raw_data, attrs
|
23
|
+
else
|
24
|
+
data, labels = C3js::ChartBuilder.prepare_data raw_data
|
25
|
+
case type
|
26
|
+
when 'bar'
|
27
|
+
C3js::ChartBuilder.bar data, labels, attrs
|
28
|
+
when 'line'
|
29
|
+
C3js::ChartBuilder.line data, labels, attrs
|
30
|
+
when 'step'
|
31
|
+
C3js::ChartBuilder.step data, labels, attrs
|
32
|
+
when 'spline'
|
33
|
+
C3js::ChartBuilder.spline data, labels, attrs
|
34
|
+
else
|
35
|
+
# By default chart line
|
36
|
+
C3js::ChartBuilder.line data, labels, attrs
|
37
|
+
end
|
38
|
+
end
|
39
|
+
when 'chartist'
|
40
|
+
data, labels = Chartist::ChartBuilder.prepare_data raw_data
|
41
|
+
case type
|
42
|
+
when 'bar'
|
43
|
+
Chartist::ChartBuilder.bar data, labels, attrs
|
44
|
+
when 'line'
|
45
|
+
Chartist::ChartBuilder.line data, labels, attrs
|
46
|
+
else
|
47
|
+
# By default chart line
|
48
|
+
Chartist::ChartBuilder.line data, labels, attrs
|
49
|
+
end
|
50
|
+
when 'chartjs'
|
51
|
+
data, labels = Chartjs::ChartBuilder.prepare_data raw_data
|
52
|
+
# By default chart line
|
53
|
+
Chartjs::ChartBuilder.line data, labels, attrs
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Asciidoctor
|
4
|
+
module Chart
|
5
|
+
class BlockMacroProcessor < ::Asciidoctor::Extensions::BlockMacroProcessor
|
6
|
+
use_dsl
|
7
|
+
named :chart
|
8
|
+
name_positional_attributes 'type', 'width', 'height', 'axis-x-label', 'axis-y-label', 'data-names'
|
9
|
+
|
10
|
+
def process parent, target, attrs
|
11
|
+
data_path = parent.normalize_asset_path target, 'target'
|
12
|
+
read_data = parent.read_asset data_path, warn_on_failure: true, normalize: true
|
13
|
+
return if read_data.nil? || read_data.empty?
|
14
|
+
|
15
|
+
engine = Backend.resolve_engine attrs, parent.document
|
16
|
+
raw_data = PlainRubyCSV.parse read_data
|
17
|
+
html = Backend.process engine, attrs, raw_data
|
18
|
+
create_pass_block parent, html, attrs, subs: nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Asciidoctor
|
4
|
+
module Chart
|
5
|
+
class BlockProcessor < ::Asciidoctor::Extensions::BlockProcessor
|
6
|
+
use_dsl
|
7
|
+
named :chart
|
8
|
+
on_context :literal
|
9
|
+
name_positional_attributes 'type', 'width', 'height', 'axis-x-label', 'axis-y-label', 'data-names'
|
10
|
+
parse_content_as :raw
|
11
|
+
|
12
|
+
def process parent, reader, attrs
|
13
|
+
engine = Backend.resolve_engine attrs, parent.document
|
14
|
+
raw_data = PlainRubyCSV.parse reader.source
|
15
|
+
html = Backend.process engine, attrs, raw_data
|
16
|
+
create_pass_block parent, html, attrs, subs: nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,226 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Asciidoctor
|
4
|
+
module Chart
|
5
|
+
module C3js
|
6
|
+
class ChartBuilder
|
7
|
+
def self.bar data, labels, attrs
|
8
|
+
chart_id = get_chart_id attrs
|
9
|
+
chart_div = create_chart_div chart_id
|
10
|
+
chart_generate_script = chart_bar_script chart_id, data, labels, attrs
|
11
|
+
to_html chart_div, chart_generate_script
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.line data, labels, attrs
|
15
|
+
chart_id = get_chart_id attrs
|
16
|
+
chart_div = create_chart_div chart_id
|
17
|
+
chart_generate_script = chart_line_script chart_id, data, labels, attrs
|
18
|
+
to_html chart_div, chart_generate_script
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.step data, labels, attrs
|
22
|
+
chart_id = get_chart_id attrs
|
23
|
+
chart_div = create_chart_div chart_id
|
24
|
+
chart_generate_script = chart_step_script chart_id, data, labels, attrs
|
25
|
+
to_html chart_div, chart_generate_script
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.spline data, labels, attrs
|
29
|
+
chart_id = get_chart_id attrs
|
30
|
+
chart_div = create_chart_div chart_id
|
31
|
+
chart_generate_script = chart_spline_script chart_id, data, labels, attrs
|
32
|
+
to_html chart_div, chart_generate_script
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.pie raw_data, attrs
|
36
|
+
chart_id = get_chart_id attrs
|
37
|
+
chart_div = create_chart_div chart_id
|
38
|
+
chart_generate_script = chart_pie_script chart_id, raw_data, attrs
|
39
|
+
to_html chart_div, chart_generate_script
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.create_chart_div chart_id
|
43
|
+
%(<div id="#{chart_id}"></div>)
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.get_chart_id attrs
|
47
|
+
attrs.fetch('id', 'chart' + PlainRubyRandom.uuid)
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.prepare_data raw_data
|
51
|
+
labels = raw_data[0]
|
52
|
+
raw_data.shift
|
53
|
+
raw_data.map.with_index {|row, index| row.unshift index.to_s }
|
54
|
+
[raw_data, labels]
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.chart_bar_script chart_id, data, labels, attrs
|
58
|
+
chart_height = get_chart_height attrs
|
59
|
+
chart_width = get_chart_width attrs
|
60
|
+
axis_x_label = get_axis_x_label attrs
|
61
|
+
axis_y_label = get_axis_y_label attrs
|
62
|
+
data_names = get_data_names attrs
|
63
|
+
<<~EOS
|
64
|
+
<script>
|
65
|
+
c3.generate({
|
66
|
+
bindto: '##{chart_id}',
|
67
|
+
size: { height: #{chart_height}, width: #{chart_width} },
|
68
|
+
data: {
|
69
|
+
columns: #{data.to_s},
|
70
|
+
type: 'bar',
|
71
|
+
names: #{data_names.to_s}
|
72
|
+
},
|
73
|
+
axis: {
|
74
|
+
x: {
|
75
|
+
type: 'category',
|
76
|
+
categories: #{labels.to_s},
|
77
|
+
label: '#{axis_x_label}'
|
78
|
+
},
|
79
|
+
y: {
|
80
|
+
label: '#{axis_y_label}'
|
81
|
+
}
|
82
|
+
}
|
83
|
+
});
|
84
|
+
</script>
|
85
|
+
EOS
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.chart_line_script chart_id, data, labels, attrs
|
89
|
+
chart_height = get_chart_height attrs
|
90
|
+
chart_width = get_chart_width attrs
|
91
|
+
axis_x_label = get_axis_x_label attrs
|
92
|
+
axis_y_label = get_axis_y_label attrs
|
93
|
+
data_names = get_data_names attrs
|
94
|
+
<<~EOS
|
95
|
+
<script>
|
96
|
+
c3.generate({
|
97
|
+
bindto: '##{chart_id}',
|
98
|
+
size: { height: #{chart_height}, width: #{chart_width} },
|
99
|
+
data: {
|
100
|
+
columns: #{data.to_s},
|
101
|
+
names: #{data_names.to_s}
|
102
|
+
},
|
103
|
+
axis: {
|
104
|
+
x: {
|
105
|
+
type: 'category',
|
106
|
+
categories: #{labels.to_s},
|
107
|
+
label: '#{axis_x_label}'
|
108
|
+
},
|
109
|
+
y: {
|
110
|
+
label: '#{axis_y_label}'
|
111
|
+
}
|
112
|
+
}
|
113
|
+
});
|
114
|
+
</script>
|
115
|
+
EOS
|
116
|
+
end
|
117
|
+
|
118
|
+
def self.chart_step_script chart_id, data, labels, attrs
|
119
|
+
chart_height = get_chart_height attrs
|
120
|
+
chart_width = get_chart_width attrs
|
121
|
+
axis_x_label = get_axis_x_label attrs
|
122
|
+
axis_y_label = get_axis_y_label attrs
|
123
|
+
data_names = get_data_names attrs
|
124
|
+
<<~EOS
|
125
|
+
<script>
|
126
|
+
c3.generate({
|
127
|
+
bindto: '##{chart_id}',
|
128
|
+
size: { height: #{chart_height}, width: #{chart_width} },
|
129
|
+
data: {
|
130
|
+
columns: #{data.to_s},
|
131
|
+
type: 'step',
|
132
|
+
names: #{data_names.to_s}
|
133
|
+
},
|
134
|
+
axis: {
|
135
|
+
x: {
|
136
|
+
type: 'category',
|
137
|
+
categories: #{labels.to_s},
|
138
|
+
label: '#{axis_x_label}'
|
139
|
+
},
|
140
|
+
y: {
|
141
|
+
label: '#{axis_y_label}'
|
142
|
+
}
|
143
|
+
}
|
144
|
+
});
|
145
|
+
</script>
|
146
|
+
EOS
|
147
|
+
end
|
148
|
+
|
149
|
+
def self.chart_spline_script chart_id, data, labels, attrs
|
150
|
+
chart_height = get_chart_height attrs
|
151
|
+
chart_width = get_chart_width attrs
|
152
|
+
axis_x_label = get_axis_x_label attrs
|
153
|
+
axis_y_label = get_axis_y_label attrs
|
154
|
+
data_names = get_data_names attrs
|
155
|
+
<<~EOS
|
156
|
+
<script>
|
157
|
+
c3.generate({
|
158
|
+
bindto: '##{chart_id}',
|
159
|
+
size: { height: #{chart_height}, width: #{chart_width} },
|
160
|
+
data: {
|
161
|
+
columns: #{data.to_s},
|
162
|
+
type: 'spline',
|
163
|
+
names: #{data_names.to_s}
|
164
|
+
},
|
165
|
+
axis: {
|
166
|
+
x: {
|
167
|
+
type: 'category',
|
168
|
+
categories: #{labels.to_s},
|
169
|
+
label: '#{axis_x_label}'
|
170
|
+
},
|
171
|
+
y: {
|
172
|
+
label: '#{axis_y_label}'
|
173
|
+
}
|
174
|
+
}
|
175
|
+
});
|
176
|
+
</script>
|
177
|
+
EOS
|
178
|
+
end
|
179
|
+
|
180
|
+
def self.chart_pie_script chart_id, raw_data, attrs
|
181
|
+
chart_height = get_chart_height attrs
|
182
|
+
chart_width = get_chart_width attrs
|
183
|
+
<<~EOS
|
184
|
+
<script>
|
185
|
+
c3.generate({
|
186
|
+
bindto: '##{chart_id}',
|
187
|
+
size: { height: #{chart_height}, width: #{chart_width} },
|
188
|
+
data: {
|
189
|
+
columns: #{raw_data.to_s},
|
190
|
+
type: 'pie'
|
191
|
+
}
|
192
|
+
});
|
193
|
+
</script>
|
194
|
+
EOS
|
195
|
+
end
|
196
|
+
|
197
|
+
def self.to_html chart_div, chart_script
|
198
|
+
<<~EOS
|
199
|
+
#{chart_div}
|
200
|
+
#{chart_script}
|
201
|
+
EOS
|
202
|
+
end
|
203
|
+
|
204
|
+
def self.get_chart_height attrs
|
205
|
+
attrs.fetch 'height', '400'
|
206
|
+
end
|
207
|
+
|
208
|
+
def self.get_chart_width attrs
|
209
|
+
attrs.fetch 'width', '600'
|
210
|
+
end
|
211
|
+
|
212
|
+
def self.get_axis_x_label attrs
|
213
|
+
attrs.key?('axis-x-label') ? CGI.unescapeHTML(attrs['axis-x-label']) : ''
|
214
|
+
end
|
215
|
+
|
216
|
+
def self.get_axis_y_label attrs
|
217
|
+
attrs.key?('axis-y-label') ? CGI.unescapeHTML(attrs['axis-y-label']) : ''
|
218
|
+
end
|
219
|
+
|
220
|
+
def self.get_data_names attrs
|
221
|
+
attrs.key?('data-names') ? CGI.unescapeHTML(attrs['data-names']) : '{}'
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Asciidoctor
|
4
|
+
module Chart
|
5
|
+
module Chartist
|
6
|
+
class ChartBuilder
|
7
|
+
def self.bar data, labels, attrs
|
8
|
+
chart_id = get_chart_id attrs
|
9
|
+
chart_div = create_chart_div chart_id
|
10
|
+
chart_generate_script = chart_bar_script chart_id, data, labels, attrs
|
11
|
+
to_html chart_div, chart_generate_script
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.line data, labels, attrs
|
15
|
+
chart_id = get_chart_id attrs
|
16
|
+
chart_div = create_chart_div chart_id
|
17
|
+
chart_generate_script = chart_line_script chart_id, data, labels, attrs
|
18
|
+
to_html chart_div, chart_generate_script
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.create_chart_div chart_id
|
22
|
+
%(<div id="#{chart_id}"class="ct-chart"></div>)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.get_chart_id attrs
|
26
|
+
attrs.fetch('id', 'chart' + PlainRubyRandom.uuid)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.prepare_data raw_data
|
30
|
+
labels = raw_data[0]
|
31
|
+
raw_data.shift
|
32
|
+
[raw_data, labels]
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.chart_bar_script chart_id, data, labels, attrs
|
36
|
+
chart_height = get_chart_height attrs
|
37
|
+
<<~EOS
|
38
|
+
<script>
|
39
|
+
var options = {
|
40
|
+
height: '#{chart_height}',
|
41
|
+
colors: ["#72B3CC", "#8EB33B"]
|
42
|
+
};
|
43
|
+
var data = {
|
44
|
+
labels: #{labels.to_s},
|
45
|
+
series: #{data.to_s}
|
46
|
+
};
|
47
|
+
new Chartist.Bar('##{chart_id}', data, options);
|
48
|
+
</script>
|
49
|
+
EOS
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.chart_line_script chart_id, data, labels, attrs
|
53
|
+
chart_height = get_chart_height attrs
|
54
|
+
chart_width = get_chart_width attrs
|
55
|
+
<<~EOS
|
56
|
+
<script>
|
57
|
+
var options = {
|
58
|
+
height: '#{chart_height}',
|
59
|
+
width: '#{chart_width}',
|
60
|
+
colors: ["#72B3CC", "#8EB33B"]
|
61
|
+
};
|
62
|
+
var data = {
|
63
|
+
labels: #{labels.to_s},
|
64
|
+
series: #{data.to_s}
|
65
|
+
};
|
66
|
+
new Chartist.Line('##{chart_id}', data, options);
|
67
|
+
</script>
|
68
|
+
EOS
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.to_html chart_div, chart_script
|
72
|
+
<<~EOS
|
73
|
+
#{chart_div}
|
74
|
+
#{chart_script}
|
75
|
+
EOS
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.get_chart_height attrs
|
79
|
+
attrs.fetch 'height', '400'
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.get_chart_width attrs
|
83
|
+
attrs.fetch 'width', '600'
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Asciidoctor
|
4
|
+
module Chart
|
5
|
+
module Chartjs
|
6
|
+
class ChartBuilder
|
7
|
+
def self.line data, labels, attrs
|
8
|
+
default_colors = [{ r: 220, g: 220, b: 220 }, { r: 151, g: 187, b: 205 }]
|
9
|
+
datasets = data.map do |set|
|
10
|
+
color = default_colors[data.index(set) % 2]
|
11
|
+
color_rgba = "rgba(#{color[:r]},#{color[:g]},#{color[:b]},1.0)"
|
12
|
+
<<~EOS
|
13
|
+
{
|
14
|
+
fillColor: "#{color_rgba.gsub('1.0', '0.2')}",
|
15
|
+
strokeColor: "#{color_rgba}",
|
16
|
+
pointColor: "#{color_rgba}",
|
17
|
+
pointHighlightStroke: "#{color_rgba}",
|
18
|
+
pointStrokeColor: "#fff",
|
19
|
+
pointHighlightFill: "#fff",
|
20
|
+
data: #{set.to_s}
|
21
|
+
}
|
22
|
+
EOS
|
23
|
+
end.join ','
|
24
|
+
chart_id = attrs.fetch('id', 'chart' + PlainRubyRandom.uuid)
|
25
|
+
chart_height = get_chart_height attrs
|
26
|
+
chart_width = get_chart_width attrs
|
27
|
+
chart_canvas = %(<div style="width:#{chart_width}px; height:#{chart_height}px"><canvas id="#{chart_id}"></canvas></div>) # rubocop:disable Layout/LineLength
|
28
|
+
chart_init_ctx_script = %(var ctx = document.getElementById("#{chart_id}").getContext("2d");)
|
29
|
+
chart_init_data_script = <<~EOS
|
30
|
+
var data = {
|
31
|
+
labels: #{labels.to_s},
|
32
|
+
datasets: [
|
33
|
+
#{datasets}
|
34
|
+
]
|
35
|
+
};
|
36
|
+
EOS
|
37
|
+
chart_init_script = 'var chart = new Chart(ctx).Line(data, {responsive : true});'
|
38
|
+
<<~EOS
|
39
|
+
#{chart_canvas}
|
40
|
+
<script>
|
41
|
+
window.onload = function() {
|
42
|
+
#{chart_init_ctx_script}
|
43
|
+
#{chart_init_data_script}
|
44
|
+
#{chart_init_script}
|
45
|
+
}
|
46
|
+
</script>
|
47
|
+
EOS
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.prepare_data raw_data
|
51
|
+
labels = raw_data[0]
|
52
|
+
raw_data.shift
|
53
|
+
[raw_data, labels]
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.get_chart_height attrs
|
57
|
+
attrs.fetch 'height', '400'
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.get_chart_width attrs
|
61
|
+
attrs.fetch 'width', '600'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Asciidoctor
|
4
|
+
module Chart
|
5
|
+
class DocinfoProcessor < ::Asciidoctor::Extensions::DocinfoProcessor
|
6
|
+
use_dsl
|
7
|
+
# at_location :head
|
8
|
+
|
9
|
+
C3JS_STYLESHEET = '<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/c3/0.3.0/c3.min.css">'
|
10
|
+
D3JS_SCRIPT = '<script src="http://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js" charset="utf-8"></script>'
|
11
|
+
C3JS_SCRIPT = '<script src="http://cdnjs.cloudflare.com/ajax/libs/c3/0.3.0/c3.min.js"></script>'
|
12
|
+
|
13
|
+
CHARTIST_STYLESHEET = '<link rel="stylesheet" href="http://cdn.jsdelivr.net/chartist.js/latest/chartist.min.css">'
|
14
|
+
CHARTIST_SCRIPT = '<script src="http://cdn.jsdelivr.net/chartist.js/latest/chartist.min.js"></script>'
|
15
|
+
|
16
|
+
CHARTJS_SCRIPT = '<script src="http://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js"></script>'
|
17
|
+
|
18
|
+
def process _doc
|
19
|
+
# TODO: Import only the required engines
|
20
|
+
# TODO: Honor linkcss and copycss
|
21
|
+
<<~EOS
|
22
|
+
#{C3JS_STYLESHEET}
|
23
|
+
#{D3JS_SCRIPT}
|
24
|
+
#{C3JS_SCRIPT}
|
25
|
+
#{CHARTIST_STYLESHEET}
|
26
|
+
#{CHARTIST_SCRIPT}
|
27
|
+
#{CHARTJS_SCRIPT})
|
28
|
+
EOS
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Asciidoctor
|
4
|
+
module Chart
|
5
|
+
class PlainRubyCSV
|
6
|
+
def self.parse data
|
7
|
+
result = []
|
8
|
+
data.each_line do |line|
|
9
|
+
line_chomp = line.chomp
|
10
|
+
result.push line_chomp.split ','
|
11
|
+
end
|
12
|
+
result
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.read(filename)
|
16
|
+
result = []
|
17
|
+
(File.open filename).each do |line|
|
18
|
+
line_chomp = line.chomp
|
19
|
+
result.push line_chomp.split ','
|
20
|
+
end
|
21
|
+
result
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: asciidoctor-chart
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0.alpha.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Guillaume Grossetie
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-08-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: asciidoctor
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 13.0.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 13.0.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.9.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.9.0
|
55
|
+
description: A set of Asciidoctor extensions that add a chart block and block macro
|
56
|
+
to AsciiDoc for including charts in your AsciiDoc document.
|
57
|
+
email: ggrossetie@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- LICENSE.adoc
|
63
|
+
- README.adoc
|
64
|
+
- asciidoctor-chart.gemspec
|
65
|
+
- lib/asciidoctor-chart.rb
|
66
|
+
- lib/asciidoctor/chart.rb
|
67
|
+
- lib/asciidoctor/chart/backend.rb
|
68
|
+
- lib/asciidoctor/chart/block_macro_processor.rb
|
69
|
+
- lib/asciidoctor/chart/block_processor.rb
|
70
|
+
- lib/asciidoctor/chart/c3js/chart_builder.rb
|
71
|
+
- lib/asciidoctor/chart/chartist/chart_builder.rb
|
72
|
+
- lib/asciidoctor/chart/chartjs/chart_builder.rb
|
73
|
+
- lib/asciidoctor/chart/docinfo_processor.rb
|
74
|
+
- lib/asciidoctor/chart/plain_ruby_csv.rb
|
75
|
+
- lib/asciidoctor/chart/plain_ruby_random.rb
|
76
|
+
- lib/asciidoctor/chart/version.rb
|
77
|
+
homepage: https://asciidoctor.org
|
78
|
+
licenses:
|
79
|
+
- MIT
|
80
|
+
metadata:
|
81
|
+
bug_tracker_uri: https://github.com/asciidoctor/asciidoctor-chart/issues
|
82
|
+
mailing_list_uri: http://discuss.asciidoctor.org
|
83
|
+
source_code_uri: https://github.com/asciidoctor/asciidoctor-chart
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: 1.3.1
|
98
|
+
requirements: []
|
99
|
+
rubygems_version: 3.0.3
|
100
|
+
signing_key:
|
101
|
+
specification_version: 4
|
102
|
+
summary: Adds a chart block and block macro to AsciiDoc
|
103
|
+
test_files: []
|