purechart 0.0.3 → 0.0.5
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 +4 -4
- data/app/views/_lollipop.html.erb +51 -0
- data/app/views/_pie.html.erb +91 -0
- data/app/views/_styles.html.erb +152 -0
- data/lib/purechart/chart_helper.rb +58 -0
- data/lib/purechart/styles/default.yml +18 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 72182144697d37343ce85634ec4089b8e3f490b7856d7368644663b9782e4580
|
4
|
+
data.tar.gz: 6f58dbcbc9b04f3fdc5c563e1fc5a0421e6170c74a18b9ca6f859591fd7a6f44
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ca861faea0eeb11ebc21764fbdab5798015c72ec92f31e2e61bafa43464613f2eec9124cdd9dff60cf3752e2c77aa9c7276cfe722586cc4ad2aea61986c36c4a
|
7
|
+
data.tar.gz: 34b108389320aa960504e3f9399b2f54275a94664cd5b32a7e530d0e54a9e63e53402879f2b63ad15cd31db7a23c01bdf9613813f0e9f8ea44f1470de26e3097
|
@@ -0,0 +1,51 @@
|
|
1
|
+
<div class="chart-flex-container">
|
2
|
+
<div class="chart" style="border-left: <%= style['axes']['style'] %>; border-bottom: <%= style['axes']['style'] %>">
|
3
|
+
<div class="chart-elements">
|
4
|
+
<%- data.each do |object| %>
|
5
|
+
<div class="bar" style="width: <%= object[:width] %>%; background-color: <%= object[:color] %>;">
|
6
|
+
<p class="bar-title" style="font-family: <%= style['labels']['font'] %>; font-weight: <%= style['labels']['weight'] %>; color: <%= style['labels']['color'] %>"><%= object[:name] %></p>
|
7
|
+
<div class="lollipop-end" style="background-color: <%= object[:color] %>;">
|
8
|
+
<div class="tooltip">
|
9
|
+
<p style="color: <%= object[:color] %>;"><%= object[:name] %></p>
|
10
|
+
<p><%= configuration[:symbol] ? configuration[:symbol] : ''%><%= object[:value] %></p>
|
11
|
+
</div>
|
12
|
+
</div>
|
13
|
+
</div>
|
14
|
+
<% end %>
|
15
|
+
</div>
|
16
|
+
<div class="gridlines">
|
17
|
+
<div style="width: 10%; border-right: <%= style['gridlines']['style'] %>">
|
18
|
+
</div>
|
19
|
+
<div style="width: 10%; border-right: <%= style['gridlines']['style'] %>">
|
20
|
+
</div>
|
21
|
+
<div style="width: 10%; border-right: <%= style['gridlines']['style'] %>">
|
22
|
+
</div>
|
23
|
+
<div style="width: 10%; border-right: <%= style['gridlines']['style'] %>">
|
24
|
+
</div>
|
25
|
+
<div style="width: 10%; border-right: <%= style['gridlines']['style'] %>">
|
26
|
+
</div>
|
27
|
+
<div style="width: 10%; border-right: <%= style['gridlines']['style'] %>">
|
28
|
+
</div>
|
29
|
+
<div style="width: 10%; border-right: <%= style['gridlines']['style'] %>">
|
30
|
+
</div>
|
31
|
+
<div style="width: 10%; border-right: <%= style['gridlines']['style'] %>">
|
32
|
+
</div>
|
33
|
+
<div style="width: 10%; border-right: <%= style['gridlines']['style'] %>">
|
34
|
+
</div>
|
35
|
+
<div style="width: 10%; border-right: <%= style['gridlines']['style'] %>">
|
36
|
+
</div>
|
37
|
+
</div>
|
38
|
+
</div>
|
39
|
+
<div class="gridlines-ticks">
|
40
|
+
<%- (1..10).each do |index| %>
|
41
|
+
<div class="tick" style="width: 10%; border-right: <%= style['gridlines']['style'] %>">
|
42
|
+
<p style="margin-right: 4px; font-family: <%= style['ticks']['font'] %>; font-weight: <%= style['ticks']['weight'] %>; color: <%= style['ticks']['color'] %>"><%= index * 120 %></p>
|
43
|
+
</div>
|
44
|
+
<% end %>
|
45
|
+
</div>
|
46
|
+
<div style="margin-left: 96px">
|
47
|
+
<h4 class="purechart" style="text-align: center; font-family: <%= style['labels']['font'] %>; font-weight: <%= style['labels']['weight'] %>; color: <%= style['labels']['color'] %>"><%= configuration[:axes][:horizontal] %><%= configuration[:symbol] ? " (" + configuration[:symbol] + ")" : ''%></h4>
|
48
|
+
</div>
|
49
|
+
</div>
|
50
|
+
|
51
|
+
<%= render :partial => '/styles' %>
|
@@ -0,0 +1,91 @@
|
|
1
|
+
<div class="pieContainer">
|
2
|
+
<div class="pieBackground"></div>
|
3
|
+
<div id="pie-slice-1" class="hold"><div class="pie"></div></div>
|
4
|
+
<div id="pie-slice-2" class="hold"><div class="pie"></div></div>
|
5
|
+
<div id="pie-slice-3" class="hold"><div class="pie"></div></div>
|
6
|
+
<div id="pie-slice-4" class="hold"><div class="pie"></div></div>
|
7
|
+
<div id="pie-slice-5" class="hold"><div class="pie"></div></div>
|
8
|
+
<div id="pie-slice-6" class="hold"><div class="pie"></div></div>
|
9
|
+
</div>
|
10
|
+
|
11
|
+
<style>
|
12
|
+
.pieContainer {
|
13
|
+
height: 250px;
|
14
|
+
width: 250px;
|
15
|
+
position: relative;
|
16
|
+
}
|
17
|
+
|
18
|
+
.pieBackground {
|
19
|
+
position: absolute;
|
20
|
+
width: 250px;
|
21
|
+
height: 250px;
|
22
|
+
border-radius: 100%;
|
23
|
+
}
|
24
|
+
|
25
|
+
.pie {
|
26
|
+
transition: all 1s;
|
27
|
+
position: absolute;
|
28
|
+
width: 250px;
|
29
|
+
height: 250px;
|
30
|
+
border-radius: 100%;
|
31
|
+
clip: rect(0px, 125px, 250px, 0px);
|
32
|
+
}
|
33
|
+
|
34
|
+
.hold {
|
35
|
+
position: absolute;
|
36
|
+
width: 250px;
|
37
|
+
height: 250px;
|
38
|
+
border-radius: 100%;
|
39
|
+
clip: rect(0px, 250px, 250px, 125px);
|
40
|
+
}
|
41
|
+
|
42
|
+
#pie-slice-1 .pie {
|
43
|
+
background-color: #2ed573;
|
44
|
+
transform:rotate(30deg);
|
45
|
+
}
|
46
|
+
|
47
|
+
#pie-slice-2 {
|
48
|
+
transform: rotate(30deg);
|
49
|
+
}
|
50
|
+
|
51
|
+
#pie-slice-2 .pie {
|
52
|
+
background-color: #ffa502;
|
53
|
+
transform: rotate(60deg);
|
54
|
+
}
|
55
|
+
|
56
|
+
#pie-slice-3 {
|
57
|
+
transform: rotate(90deg);
|
58
|
+
}
|
59
|
+
|
60
|
+
#pie-slice-3 .pie {
|
61
|
+
background-color: #5352ed;
|
62
|
+
transform: rotate(120deg);
|
63
|
+
}
|
64
|
+
|
65
|
+
#pie-slice-4 {
|
66
|
+
transform: rotate(210deg);
|
67
|
+
}
|
68
|
+
|
69
|
+
#pie-slice-4 .pie {
|
70
|
+
background-color: #ff4757;
|
71
|
+
transform: rotate(10deg);
|
72
|
+
}
|
73
|
+
|
74
|
+
#pie-slice-5 {
|
75
|
+
transform: rotate(220deg);
|
76
|
+
}
|
77
|
+
|
78
|
+
#pie-slice-5 .pie {
|
79
|
+
background-color: #1e90ff;
|
80
|
+
transform: rotate(70deg);
|
81
|
+
}
|
82
|
+
|
83
|
+
#pie-slice-6 {
|
84
|
+
transform: rotate(290deg);
|
85
|
+
}
|
86
|
+
|
87
|
+
#pie-slice-6 .pie {
|
88
|
+
background-color: #ff7f50;
|
89
|
+
transform: rotate(70deg);
|
90
|
+
}
|
91
|
+
</style>
|
@@ -0,0 +1,152 @@
|
|
1
|
+
<style>
|
2
|
+
@import url('https://fonts.googleapis.com/css2?family=Inter+Tight:wght@400;600&display=swap');
|
3
|
+
|
4
|
+
h4.purechart {
|
5
|
+
margin: 0;
|
6
|
+
margin-top: 16px;
|
7
|
+
font-family: 'Inter Tight', sans-serif;
|
8
|
+
}
|
9
|
+
|
10
|
+
.chart {
|
11
|
+
width: 500px;
|
12
|
+
height: 400px;
|
13
|
+
|
14
|
+
margin-left: 96px;
|
15
|
+
padding-top: 32px;
|
16
|
+
padding-bottom: 32px;
|
17
|
+
|
18
|
+
position: relative;
|
19
|
+
|
20
|
+
border-left: 2px solid black;
|
21
|
+
border-bottom: 2px solid black;
|
22
|
+
}
|
23
|
+
|
24
|
+
.chart-elements {
|
25
|
+
width: 100%;
|
26
|
+
height: 100%;
|
27
|
+
|
28
|
+
display: flex;
|
29
|
+
flex-direction: column;
|
30
|
+
align-items: baseline;
|
31
|
+
justify-content: space-around;
|
32
|
+
}
|
33
|
+
|
34
|
+
.bar {
|
35
|
+
height: 4px;
|
36
|
+
background-color: #476D54;
|
37
|
+
|
38
|
+
margin-bottom: 32px;
|
39
|
+
position: relative;
|
40
|
+
|
41
|
+
cursor: pointer;
|
42
|
+
z-index: 1;
|
43
|
+
}
|
44
|
+
|
45
|
+
.lollipop-end {
|
46
|
+
width: 16px;
|
47
|
+
height: 16px;
|
48
|
+
background-color: #476D54;
|
49
|
+
border-radius: 100px;
|
50
|
+
position: absolute;
|
51
|
+
top: 50%;
|
52
|
+
right: -8px;
|
53
|
+
transform: translateY(-50%);
|
54
|
+
}
|
55
|
+
|
56
|
+
.bar-title {
|
57
|
+
position: absolute;
|
58
|
+
top: -12px;
|
59
|
+
margin: 0;
|
60
|
+
right: 100%;
|
61
|
+
height: 24px;
|
62
|
+
width: 96px;
|
63
|
+
line-height: 24px;
|
64
|
+
font-family: 'Inter Tight', sans-serif;
|
65
|
+
font-weight: 700;
|
66
|
+
|
67
|
+
white-space: nowrap;
|
68
|
+
text-overflow: ellipsis;
|
69
|
+
overflow: hidden;
|
70
|
+
padding-right: 8px;
|
71
|
+
}
|
72
|
+
|
73
|
+
.tooltip {
|
74
|
+
position: absolute;
|
75
|
+
top: 50%;
|
76
|
+
left: 50%;
|
77
|
+
|
78
|
+
padding: 8px;
|
79
|
+
|
80
|
+
background-color: #fff;
|
81
|
+
border-radius: 8px;
|
82
|
+
box-shadow: rgba(0, 0, 0, 0.25) 0px 10px 36px 0px, rgba(0, 0, 0, 0.15) 0px 0px 0px 1px;
|
83
|
+
|
84
|
+
opacity: 0;
|
85
|
+
transform: translateX(-50%) translateY(-50%);
|
86
|
+
|
87
|
+
transition: 0.25s all ease;
|
88
|
+
}
|
89
|
+
|
90
|
+
.tooltip p {
|
91
|
+
margin: 0px;
|
92
|
+
font-family: 'Inter Tight';
|
93
|
+
font-weight: 700;
|
94
|
+
color: black;
|
95
|
+
}
|
96
|
+
|
97
|
+
.gridlines {
|
98
|
+
position: absolute;
|
99
|
+
top: 0;
|
100
|
+
right: 0;
|
101
|
+
left: 0;
|
102
|
+
bottom: 0;
|
103
|
+
|
104
|
+
display: flex;
|
105
|
+
}
|
106
|
+
|
107
|
+
.gridlines div {
|
108
|
+
height: 100%;
|
109
|
+
border-right: 2px solid #00000033;
|
110
|
+
|
111
|
+
display: flex;
|
112
|
+
flex-direction: column;
|
113
|
+
justify-content: end;
|
114
|
+
}
|
115
|
+
|
116
|
+
.gridlines div p {
|
117
|
+
margin: 0;
|
118
|
+
font-family: 'Inter Tight';
|
119
|
+
}
|
120
|
+
|
121
|
+
/* TICKS */
|
122
|
+
.gridlines-ticks {
|
123
|
+
margin-left: 96px;
|
124
|
+
width: 500px;
|
125
|
+
display: flex;
|
126
|
+
border-bottom: 2px solid #00000000;
|
127
|
+
padding-left: 2px;
|
128
|
+
text-align: right;
|
129
|
+
}
|
130
|
+
|
131
|
+
.gridlines-ticks div {
|
132
|
+
border-right: 2px solid #0003;
|
133
|
+
display: flex;
|
134
|
+
flex-direction: column;
|
135
|
+
justify-content: end;
|
136
|
+
position: relative;
|
137
|
+
}
|
138
|
+
|
139
|
+
.gridlines-ticks div p {
|
140
|
+
margin: 0;
|
141
|
+
font-family: 'Inter Tight';
|
142
|
+
}
|
143
|
+
|
144
|
+
.bar:hover .tooltip {
|
145
|
+
opacity: 1;
|
146
|
+
transform: translateX(-50%) translateY(calc(-50% - 32px));
|
147
|
+
}
|
148
|
+
|
149
|
+
* {
|
150
|
+
box-sizing: border-box;
|
151
|
+
}
|
152
|
+
</style>
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module PureChart
|
2
|
+
module ChartHelpers
|
3
|
+
def lollipop_chart(data, configuration = { axes: { horizontal: "Value" } }, path = "")
|
4
|
+
# Set default configuration file path
|
5
|
+
default_config_path = File.join( File.dirname(__FILE__), 'styles/default.yml' )
|
6
|
+
|
7
|
+
default_config_hash = YAML.load(File.read(default_config_path))
|
8
|
+
user_config_hash = {}
|
9
|
+
|
10
|
+
if path != ""
|
11
|
+
# TODO - Implement better logic
|
12
|
+
if File.file?("app/purechart/" + path + ".yml")
|
13
|
+
user_config_hash = YAML.load(File.read("app/purechart/" + path + ".yml"))
|
14
|
+
elsif File.file?("app/purechart/" + path + ".yaml")
|
15
|
+
user_config_hash = YAML.load(File.read("app/purechart/" + path + ".yaml"))
|
16
|
+
elsif File.file?("app/purechart/" + path + ".json")
|
17
|
+
user_config_hash = JSON.load(File.read("app/purechart/" + path + ".json"))
|
18
|
+
else
|
19
|
+
raise "(PureChart) ERROR - Could not locate configuration file '" + path + ".[YML, YAML, JSON]'. Make sure this file exists in your 'app/purechart' directory."
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Merge user's configuration with default
|
24
|
+
style_config = default_config_hash.merge(user_config_hash)
|
25
|
+
|
26
|
+
# Format data for chart generation
|
27
|
+
largest_value = (data.map { |object| object[:value] }).max()
|
28
|
+
|
29
|
+
data.each do |object|
|
30
|
+
object[:width] = (Float(object[:value]) / largest_value) * 100
|
31
|
+
end
|
32
|
+
|
33
|
+
gridlines = {
|
34
|
+
vertical_lines: 10,
|
35
|
+
vertical_increment: (Float(largest_value) / 10).ceil
|
36
|
+
}
|
37
|
+
|
38
|
+
ActionController::Base.render partial: '/lollipop', locals: {
|
39
|
+
data: data,
|
40
|
+
gridlines: gridlines,
|
41
|
+
configuration: configuration,
|
42
|
+
style: style_config
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
def bar_chart
|
47
|
+
"<div>Bar chart will be rendered here.</div>".html_safe
|
48
|
+
end
|
49
|
+
|
50
|
+
def column_chart
|
51
|
+
"<div>Column chart will be rendered here.</div>".html_safe
|
52
|
+
end
|
53
|
+
|
54
|
+
def pie_chart
|
55
|
+
ActionController::Base.render partial: '/pie'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
---
|
2
|
+
title:
|
3
|
+
font: Inter Tight
|
4
|
+
weight: 700
|
5
|
+
color: "#000000"
|
6
|
+
labels:
|
7
|
+
font: Inter Tight
|
8
|
+
weight: 700
|
9
|
+
color: "#000000"
|
10
|
+
ticks:
|
11
|
+
font: Inter Tight
|
12
|
+
weight: 400
|
13
|
+
color: "#000000"
|
14
|
+
axes:
|
15
|
+
style: "2px solid #000000"
|
16
|
+
gridlines:
|
17
|
+
style: "2px dashed #00000033"
|
18
|
+
...
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: purechart
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- George Berdovskiy
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-03-15 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Pure HTML/CSS charts for Ruby on Rails.
|
14
14
|
email:
|
@@ -16,7 +16,12 @@ executables: []
|
|
16
16
|
extensions: []
|
17
17
|
extra_rdoc_files: []
|
18
18
|
files:
|
19
|
+
- app/views/_lollipop.html.erb
|
20
|
+
- app/views/_pie.html.erb
|
21
|
+
- app/views/_styles.html.erb
|
19
22
|
- lib/purechart.rb
|
23
|
+
- lib/purechart/chart_helper.rb
|
24
|
+
- lib/purechart/styles/default.yml
|
20
25
|
homepage:
|
21
26
|
licenses:
|
22
27
|
- MIT
|