apexcharts 0.1.5 → 0.1.6
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/README.md +227 -16
- data/lib/apexcharts/charts.rb +1 -0
- data/lib/apexcharts/charts/range_bar.rb +9 -0
- data/lib/apexcharts/colors.rb +28 -0
- data/lib/apexcharts/helper.rb +14 -0
- data/lib/apexcharts/options/root.rb +2 -0
- data/lib/apexcharts/options_builder.rb +12 -6
- data/lib/apexcharts/theme.rb +61 -0
- data/lib/apexcharts/utils/date_time.rb +2 -2
- data/lib/apexcharts/version.rb +1 -1
- data/vendor/assets/javascripts/apexcharts.js +2 -2
- metadata +7 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 691f5a61767a709faa0a664940bd1c3fd151ce3704bc4e8d611e0be89b24867b
|
|
4
|
+
data.tar.gz: e7a6816de1ad3ac93511aee84f0b2217f98f9ebf1c57e5c4e00bf51b21c4ee73
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2cc56083d7c1a92157f27836ffdeec621951f67c4cc979850f4482a028a1433983f18d6fcd80a2ab847e1af34033c78b8a43fb32aff9a9bdefd4f0b7aa0305f2
|
|
7
|
+
data.tar.gz: 79363b03e25c694ddba264375ca41a08853510fd27ef5d7533c73c99442cdd8d3aab68015016d5dfe597938189354493ecdb9ad44f582098b6add1197a913e9d
|
data/README.md
CHANGED
|
@@ -1,19 +1,80 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="images/
|
|
2
|
+
<img src="images/placeholder.png" height="120">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
|
-
<a href="https://
|
|
6
|
+
<a href="https://rubygems.org/gems/apexcharts"><img src="https://img.shields.io/gem/v/apexcharts.svg?label=apexcharts" alt="Gem Version" /></a>
|
|
7
7
|
<a href="https://travis-ci.org/styd/apexcharts.rb"><img src="https://travis-ci.org/styd/apexcharts.rb.svg?branch=master" alt="Build Status" /></a>
|
|
8
|
-
<a href="https://rubygems.org/gems/apexcharts"><img src="https://
|
|
8
|
+
<a href="https://rubygems.org/gems/apexcharts"><img alt="Downloads" src="https://img.shields.io/gem/dt/apexcharts"></a>
|
|
9
|
+
<img src="https://img.shields.io/github/commit-activity/m/styd/apexcharts.rb.svg?label=commits" alt="Commits" />
|
|
10
|
+
<a href="https://github.com/styd/apexcharts.rb/blob/master/LICENSE"><img src="https://img.shields.io/badge/License-MIT-brightgreen.svg" alt="License"></a>
|
|
11
|
+
<a href="https://codeclimate.com/github/styd/apexcharts.rb/maintainability"><img src="https://api.codeclimate.com/v1/badges/07a4f59e67abfeae21cb/maintainability" /></a>
|
|
12
|
+
<a href='https://coveralls.io/github/styd/apexcharts.rb?branch=master'><img src='https://coveralls.io/repos/github/styd/apexcharts.rb/badge.svg?branch=master' alt='Coverage Status' /></a>
|
|
9
13
|
</p>
|
|
10
14
|
|
|
11
15
|
|
|
12
16
|
## What is this?
|
|
13
17
|
|
|
14
|
-
ApexCharts.
|
|
15
|
-
[
|
|
16
|
-
|
|
18
|
+
ApexCharts.RB is a ruby gem that wraps a JavaScript charting library called with the same name,
|
|
19
|
+
[ApexCharts.JS](https://github.com/apexcharts/apexcharts.js), that's going to give you
|
|
20
|
+
beautiful, interactive, and responsive charts for your ruby app.
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
## README Versions
|
|
24
|
+
|
|
25
|
+
This README might not be for the version you use.
|
|
26
|
+
Choose the right README:
|
|
27
|
+
|
|
28
|
+
- [v0.1.6](https://github.com/styd/apexcharts.rb/blob/v0.1.6/README.md)
|
|
29
|
+
- [v0.1.5](https://github.com/styd/apexcharts.rb/blob/v0.1.5/README.md)
|
|
30
|
+
- [v0.1.4](https://github.com/styd/apexcharts.rb/blob/v0.1.4/README.md)
|
|
31
|
+
- [v0.1.3](https://github.com/styd/apexcharts.rb/blob/v0.1.3/README.md)
|
|
32
|
+
- [v0.1.2](https://github.com/styd/apexcharts.rb/blob/v0.1.2/README.md)
|
|
33
|
+
- [v0.1.1](https://github.com/styd/apexcharts.rb/blob/v0.1.1/README.md)
|
|
34
|
+
|
|
35
|
+
## Table of Contents
|
|
36
|
+
|
|
37
|
+
- [Usage](#usage)
|
|
38
|
+
- [Cartesian Charts](#cartesian-charts)
|
|
39
|
+
- [Line Chart](#line-chart)
|
|
40
|
+
- [Stepline Chart](#stepline-chart)
|
|
41
|
+
- [Area Chart](#area-chart)
|
|
42
|
+
- [Column Chart](#column-chart)
|
|
43
|
+
- [Bar Chart](#bar-chart)
|
|
44
|
+
- [Range Bar Chart](#range-bar-chart)
|
|
45
|
+
- [Scatter Chart](#scatter-chart)
|
|
46
|
+
- [Candlestick Chart](#candlestick-chart)
|
|
47
|
+
- [Mixed Charts](#mixed-charts)
|
|
48
|
+
- [Syncing Charts](#syncing-charts)
|
|
49
|
+
- [Brush Chart](#brush-chart)
|
|
50
|
+
- [Annotations](#annotations)
|
|
51
|
+
- [Heatmap Chart](#heatmap-chart)
|
|
52
|
+
- [Radar Chart](#radar-chart)
|
|
53
|
+
- [Bubble Chart](#bubble-chart)
|
|
54
|
+
- [Polar Charts](#polar-charts)
|
|
55
|
+
- [Pie Chart](#pie-chart)
|
|
56
|
+
- [Donut Chart](#donut-chart)
|
|
57
|
+
- [Radial Bar Chart](#radial-bar-chart)
|
|
58
|
+
- [Data Formats](#data-formats)
|
|
59
|
+
- [Cartesian Charts](#cartesian-charts-1)
|
|
60
|
+
- [Candlestick Chart](#candlestick-chart-1)
|
|
61
|
+
- [Heatmap Chart](#heatmap-chart-1)
|
|
62
|
+
- [Radar Chart](#radar-chart-1)
|
|
63
|
+
- [Bubble Chart](#bubble-chart-1)
|
|
64
|
+
- [Polar Charts](#polar-charts-1)
|
|
65
|
+
- [Options](#options)
|
|
66
|
+
- [Global Options](#global-options)
|
|
67
|
+
- [Installation](#installation)
|
|
68
|
+
- [Reusable Custom Palette](#reusable-custom-palette)
|
|
69
|
+
- [Global Palette](#global-palette)
|
|
70
|
+
- [Local Palette](#local-palette)
|
|
71
|
+
- [Web Support](#web-support)
|
|
72
|
+
- [Rails](#rails)
|
|
73
|
+
- [Plain HTML+ERB (Without Framework)](#plain-htmlerb-without-framework)
|
|
74
|
+
- [Roadmap](#roadmap)
|
|
75
|
+
- [Contributing](#contributing)
|
|
76
|
+
- [License](#license)
|
|
77
|
+
- [Like the charts?](#like-the-charts)
|
|
17
78
|
|
|
18
79
|
|
|
19
80
|
## Usage
|
|
@@ -101,6 +162,33 @@ Example options used for cartesian charts:
|
|
|
101
162
|

|
|
102
163
|
|
|
103
164
|
|
|
165
|
+
#### Range Bar Chart
|
|
166
|
+
|
|
167
|
+
```erb
|
|
168
|
+
<% range_bar_series = [{
|
|
169
|
+
name: "Series A",
|
|
170
|
+
data: {
|
|
171
|
+
'A' => [1, 5],
|
|
172
|
+
'B' => [4, 6],
|
|
173
|
+
'C' => [5, 8],
|
|
174
|
+
'D' => [3, 11]
|
|
175
|
+
}
|
|
176
|
+
}, {
|
|
177
|
+
name: "Series B",
|
|
178
|
+
data: {
|
|
179
|
+
'A' => [2, 6],
|
|
180
|
+
'B' => [1, 3],
|
|
181
|
+
'C' => [7, 8],
|
|
182
|
+
'D' => [5, 9]
|
|
183
|
+
}
|
|
184
|
+
}]
|
|
185
|
+
%>
|
|
186
|
+
|
|
187
|
+
<%= range_bar_chart(range_bar_series, theme: 'palette3') %>
|
|
188
|
+
```
|
|
189
|
+

|
|
190
|
+
|
|
191
|
+
|
|
104
192
|
#### Scatter Chart
|
|
105
193
|
|
|
106
194
|
```erb
|
|
@@ -110,6 +198,7 @@ Example options used for cartesian charts:
|
|
|
110
198
|
|
|
111
199
|
|
|
112
200
|
#### Candlestick Chart
|
|
201
|
+
|
|
113
202
|
Candlestick chart is typically used to illustrate movements in the price of a
|
|
114
203
|
financial instrument over time. This chart is also popular by the name "ohlc chart".
|
|
115
204
|
That's why you can call it with `ohlc_chart` too.
|
|
@@ -309,6 +398,7 @@ Also called `circle_chart`.
|
|
|
309
398
|
## Data Formats
|
|
310
399
|
|
|
311
400
|
### Cartesian Charts
|
|
401
|
+
|
|
312
402
|
The data format for line, stepline, area, column, bar, and scatter
|
|
313
403
|
charts should be in following format **per-series**:
|
|
314
404
|
|
|
@@ -331,6 +421,7 @@ or this:
|
|
|
331
421
|
```
|
|
332
422
|
|
|
333
423
|
#### Candlestick Chart
|
|
424
|
+
|
|
334
425
|
Candlestick chart is just like other cartesian charts, only the y value is
|
|
335
426
|
an array of 4 members which called the OHLC (Open-High-Low-Close):
|
|
336
427
|
|
|
@@ -353,6 +444,7 @@ or this:
|
|
|
353
444
|
```
|
|
354
445
|
|
|
355
446
|
### Heatmap Chart
|
|
447
|
+
|
|
356
448
|
The data format for heatmap chart **per-series** is similar to cartesian
|
|
357
449
|
charts. But instead of y values they are heat values. The series names will
|
|
358
450
|
be the y values.
|
|
@@ -376,6 +468,7 @@ or this:
|
|
|
376
468
|
```
|
|
377
469
|
|
|
378
470
|
### Radar Chart
|
|
471
|
+
|
|
379
472
|
The data format for radar chart **per-series** is also similar but instead
|
|
380
473
|
of x values they are variables and instead of y values they are the only
|
|
381
474
|
values for the variables with type of Numeric.
|
|
@@ -400,6 +493,7 @@ or this:
|
|
|
400
493
|
|
|
401
494
|
|
|
402
495
|
### Bubble Chart
|
|
496
|
+
|
|
403
497
|
Bubble chart is similar to scatter chart, only they have one more value
|
|
404
498
|
for bubble size:
|
|
405
499
|
|
|
@@ -412,10 +506,58 @@ for bubble size:
|
|
|
412
506
|
```
|
|
413
507
|
|
|
414
508
|
### Polar Charts
|
|
509
|
+
|
|
415
510
|
The data format for donut, pie, and radial bar are the simplest. They are
|
|
416
511
|
just any single value of type Numeric.
|
|
417
512
|
|
|
418
513
|
|
|
514
|
+
## Options
|
|
515
|
+
|
|
516
|
+
ApexCharts.RB supports [all options from apexcharts.js](https://apexcharts.com/docs/options/), but instead of camelCase, you can write them in snake_case.
|
|
517
|
+
|
|
518
|
+
ApexCharts.RB also provides shortcuts to some ApexCharts.js options, such as `title`. In ApexCharts.js you would have to write `title: { text: "Some title" }`. In ApexCharts.rb you can write `title: "Some title"` if you just want to add the text.
|
|
519
|
+
`xtitle` and `ytitle` are even greater shortcuts. Instead of `xaxis: { title: { text: "x title" } }` you can write `xtitle: "x title"`."
|
|
520
|
+
|
|
521
|
+
```ruby
|
|
522
|
+
options = {
|
|
523
|
+
animations: false, # Shortcut for chart: { animations: { enabled: false } }
|
|
524
|
+
chart: {
|
|
525
|
+
fontFamily: "Helvetica, Arial, sans-serif",
|
|
526
|
+
toolbar: {
|
|
527
|
+
show: false
|
|
528
|
+
}
|
|
529
|
+
},
|
|
530
|
+
curve: "straight", # Shortcut for stroke: { curve: "straight" }
|
|
531
|
+
markers: {
|
|
532
|
+
size: 5,
|
|
533
|
+
},
|
|
534
|
+
tooltip: false, # Shortcut for tooltip: { enabled: false }
|
|
535
|
+
xtitle: "Boars per capita"
|
|
536
|
+
}
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
These options can be passed to any chart helper like `<%= line_chart(series, options) %>`.
|
|
540
|
+
|
|
541
|
+
### Global Options
|
|
542
|
+
|
|
543
|
+
To change options globally, you can manipulate the `Apex` JavaScript object directly:
|
|
544
|
+
|
|
545
|
+
```javascript
|
|
546
|
+
require("apexcharts")
|
|
547
|
+
|
|
548
|
+
const apexGlobalOptions = {
|
|
549
|
+
chart: {
|
|
550
|
+
…
|
|
551
|
+
},
|
|
552
|
+
…
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
Object.assign(Apex, apexGlobalOptions)
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
All charts will then be created with these global options, which can be overwritten individually by any ApexCharts.RB helper method.
|
|
559
|
+
|
|
560
|
+
|
|
419
561
|
## Installation
|
|
420
562
|
Add this line to your application's Gemfile:
|
|
421
563
|
|
|
@@ -430,55 +572,124 @@ $ bundle
|
|
|
430
572
|
```
|
|
431
573
|
|
|
432
574
|
|
|
575
|
+
## Reusable Custom Palette
|
|
576
|
+
|
|
577
|
+
You can create custom palette that works globally or locally.
|
|
578
|
+
|
|
579
|
+
### Global Palette
|
|
580
|
+
|
|
581
|
+
To create global palettes to be used anywhere on your any parts of your app, you can use
|
|
582
|
+
`ApexCharts::Theme.create`.
|
|
583
|
+
|
|
584
|
+
For example, in rails app, you would write it in initializers:
|
|
585
|
+
|
|
586
|
+
```ruby
|
|
587
|
+
# config/initializers/apexcharts.rb
|
|
588
|
+
ApexCharts::Theme.create "rainbow", ["#ff0000", "#00ff00", "#0000ff"]
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
and later somewhere in your app views:
|
|
592
|
+
|
|
593
|
+
```ruby
|
|
594
|
+
# e.g. app/views/home/index.html.slim
|
|
595
|
+
...
|
|
596
|
+
= line_chart chart_data, theme: "rainbow"
|
|
597
|
+
...
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
If later for some reason I don't know you want to destroy the palette you can use:
|
|
601
|
+
|
|
602
|
+
```ruby
|
|
603
|
+
ApexCharts::Theme.destroy "rainbow"
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
### Local Palette
|
|
607
|
+
|
|
608
|
+
To create local palettes to be used only for current thread (usually for the duration
|
|
609
|
+
of a request), you can use the `create_palette` helper. The theme will only be available
|
|
610
|
+
on that page and inside its partials after the palette created.
|
|
611
|
+
|
|
612
|
+
For example:
|
|
613
|
+
|
|
614
|
+
```ruby
|
|
615
|
+
create_palette "ephemeral", ["#ab356d", "#12cdf3", "#665572", "#ababac"]
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
To destroy the palette:
|
|
619
|
+
|
|
620
|
+
```ruby
|
|
621
|
+
destroy_palette "ephemeral"
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
on the same page or in its partials. Otherwise, nothing will happen.
|
|
625
|
+
|
|
626
|
+
|
|
433
627
|
## Web Support
|
|
434
628
|
|
|
435
629
|
### Rails
|
|
630
|
+
|
|
436
631
|
After installing the gem, require it in your `app/assets/javascripts/application.js`.
|
|
437
632
|
```js
|
|
438
|
-
//= require
|
|
633
|
+
//= require apexcharts
|
|
439
634
|
```
|
|
440
635
|
|
|
441
636
|
Or, if you use `webpacker`, you can run:
|
|
442
637
|
```bash
|
|
443
|
-
yarn add apexcharts
|
|
638
|
+
$ yarn add apexcharts
|
|
444
639
|
```
|
|
445
640
|
and then require it in your `app/javascript/packs/application.js`.
|
|
446
641
|
```js
|
|
447
642
|
require("apexcharts")
|
|
448
643
|
```
|
|
449
644
|
|
|
450
|
-
### HTML+ERB
|
|
645
|
+
### Plain HTML+ERB (Without Framework)
|
|
646
|
+
|
|
451
647
|
After installing the gem, insert this to the top of your .html.erb files:
|
|
452
648
|
|
|
453
649
|
```html+erb
|
|
454
650
|
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
|
|
651
|
+
<% require 'set' %>
|
|
455
652
|
<% require 'apexcharts' %>
|
|
653
|
+
<% include ApexCharts::Helper %>
|
|
654
|
+
```
|
|
655
|
+
`require 'set'` is needed because of an issue in the dependency used, but not needed
|
|
656
|
+
in v0.2.x release of ApexCharts.RB.
|
|
657
|
+
|
|
658
|
+
You can then generate the static html page with e.g.
|
|
659
|
+
```bash
|
|
660
|
+
$ erb sample.html.erb > sample.html
|
|
456
661
|
```
|
|
457
662
|
|
|
458
663
|
|
|
459
|
-
##
|
|
460
|
-
|
|
461
|
-
- Create reusable theme palette
|
|
462
|
-
- Add more features (e.g. gradient line, background image, etc.)
|
|
463
|
-
- Range bar chart
|
|
664
|
+
## Roadmap
|
|
665
|
+
|
|
464
666
|
- Support other ruby frameworks (sinatra, hanami, etc.)
|
|
667
|
+
- v0.1.x
|
|
668
|
+
- Add more features (e.g. gradient line, background image, etc.)
|
|
669
|
+
- v0.2.x
|
|
670
|
+
- Replace dependency `smart_kv` with `dry-schema`
|
|
671
|
+
- Display warnings on browser console on development instead of error page when
|
|
672
|
+
schema doesn't meet
|
|
465
673
|
|
|
466
674
|
|
|
467
675
|
## Contributing
|
|
676
|
+
|
|
468
677
|
Everyone is encouraged to help improve this project by:
|
|
469
678
|
- Reporting bugs
|
|
470
679
|
- Fixing bugs and submiting pull requests
|
|
471
680
|
- Fixing documentation
|
|
472
681
|
- Suggesting new features
|
|
473
|
-
- Implementing
|
|
682
|
+
- Implementing todos on Roadmap above
|
|
474
683
|
|
|
475
684
|
|
|
476
685
|
## License
|
|
686
|
+
|
|
477
687
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
478
688
|
|
|
479
689
|
|
|
480
690
|
## Like the charts?
|
|
481
|
-
|
|
691
|
+
|
|
692
|
+
Consider donating to the author of ApexCharts.JS to support his awesome library.
|
|
482
693
|
This project wouldn't be possible without it.
|
|
483
694
|
|
|
484
695
|
Become a sponsor on [Patreon](https://patreon.com/junedchhipa).
|
data/lib/apexcharts/charts.rb
CHANGED
|
@@ -8,6 +8,7 @@ require_relative 'charts/bar'
|
|
|
8
8
|
require_relative 'charts/column'
|
|
9
9
|
require_relative 'charts/scatter'
|
|
10
10
|
require_relative 'charts/candlestick'
|
|
11
|
+
require_relative 'charts/range_bar'
|
|
11
12
|
require_relative 'charts/heatmap'
|
|
12
13
|
require_relative 'charts/bubble'
|
|
13
14
|
require_relative 'charts/radar'
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'set'
|
|
4
|
+
|
|
5
|
+
module ApexCharts
|
|
6
|
+
class Colors
|
|
7
|
+
def initialize colors
|
|
8
|
+
@color_set = Set.new(clean(colors))
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def values
|
|
12
|
+
@color_set.to_a
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def clean colors
|
|
18
|
+
colors = colors.respond_to?(:to_set) ? colors.to_a.flatten : Array(colors)
|
|
19
|
+
colors.map do |color|
|
|
20
|
+
unless color.tap{|c| c.upcase! }[/^#[0-9A-F]{6}/]
|
|
21
|
+
raise "unrecognized color #{color}"
|
|
22
|
+
end
|
|
23
|
+
color
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
data/lib/apexcharts/helper.rb
CHANGED
|
@@ -5,6 +5,7 @@ require_relative 'options_builder'
|
|
|
5
5
|
require_relative 'utils'
|
|
6
6
|
require_relative 'renderer'
|
|
7
7
|
require_relative 'charts'
|
|
8
|
+
require_relative 'theme'
|
|
8
9
|
|
|
9
10
|
module ApexCharts
|
|
10
11
|
module Helper
|
|
@@ -28,6 +29,11 @@ module ApexCharts
|
|
|
28
29
|
draw_chart(BarChart.new(bindings, *prepare_series_and_options(series, options), &block))
|
|
29
30
|
end
|
|
30
31
|
|
|
32
|
+
def range_bar_chart series, options={}, &block
|
|
33
|
+
bindings = eval("self", block.binding) if block_given?
|
|
34
|
+
draw_chart(RangeBarChart.new(bindings, *prepare_series_and_options(series, options), &block))
|
|
35
|
+
end
|
|
36
|
+
|
|
31
37
|
def scatter_chart series, options={}, &block
|
|
32
38
|
bindings = eval("self", block.binding) if block_given?
|
|
33
39
|
draw_chart(ScatterChart.new(bindings, *prepare_series_and_options(series, options), &block))
|
|
@@ -76,6 +82,14 @@ module ApexCharts
|
|
|
76
82
|
end
|
|
77
83
|
alias_method :circle_chart, :radial_bar_chart
|
|
78
84
|
|
|
85
|
+
def create_palette palette_name, colors
|
|
86
|
+
ApexCharts::Theme::Local.create palette_name, colors
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def destroy_palette palette_name
|
|
90
|
+
ApexCharts::Theme::Local.destroy palette_name
|
|
91
|
+
end
|
|
92
|
+
|
|
79
93
|
private
|
|
80
94
|
|
|
81
95
|
def draw_chart chart
|