├── template.html
├── .versions
├── package.js
├── template.js
├── README.md
└── c3
└── c3.css
/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.versions:
--------------------------------------------------------------------------------
1 | babel-compiler@6.24.7
2 | babel-runtime@1.1.1
3 | base64@1.0.10
4 | blaze@2.1.2
5 | blaze-tools@1.0.3
6 | d3js:d3@3.5.8
7 | deps@1.0.12
8 | diff-sequence@1.0.7
9 | ecmascript@0.9.0
10 | ecmascript-runtime@0.5.0
11 | ecmascript-runtime-client@0.5.0
12 | ecmascript-runtime-server@0.5.0
13 | ejson@1.1.0
14 | html-tools@1.0.4
15 | htmljs@1.0.4
16 | id-map@1.0.9
17 | jquery@1.11.10
18 | meteor@1.8.0
19 | minifiers@1.1.5
20 | modules@0.11.2
21 | modules-runtime@0.9.1
22 | mongo-id@1.0.6
23 | observe-sequence@1.0.16
24 | perak:c3@1.0.9
25 | promise@0.10.0
26 | random@1.0.10
27 | reactive-var@1.0.11
28 | spacebars-compiler@1.0.6
29 | templating@1.1.1
30 | tracker@1.1.3
31 | underscore@1.0.10
32 |
--------------------------------------------------------------------------------
/package.js:
--------------------------------------------------------------------------------
1 | Package.describe({
2 | name: 'perak:c3',
3 | summary: "Reactive C3 charting library based on D3",
4 | version: "1.1.0",
5 | git: "https://github.com/perak/meteor-c3.git"
6 | });
7 |
8 | // Before Meteor 0.9?
9 | if(!Package.onUse) Package.onUse = Package.on_use;
10 |
11 | Package.onUse(function (api) {
12 | if(api.versionsFrom) {
13 | api.versionsFrom('METEOR@0.9.0');
14 | }
15 |
16 | api.use("d3js:d3@3.5.8", 'client');
17 | api.use('templating');
18 |
19 | api.add_files('c3/c3.js', "client");
20 | api.add_files('c3/c3.css', "client");
21 | api.add_files('template.html', "client");
22 | api.add_files('template.js', "client");
23 |
24 | api.export('c3charts', "client");
25 | });
26 |
--------------------------------------------------------------------------------
/template.js:
--------------------------------------------------------------------------------
1 | c3charts = {};
2 |
3 | Template.c3.rendered = function() {
4 | var getData = function() {
5 | // this.data.data.data can only exist if template has been passed a data attribute
6 | // https://github.com/perak/meteor-c3/issues/1
7 | var thisData = UI.getData();
8 | var data;
9 | if (thisData && thisData.data && thisData.data.data) {
10 | data = thisData.data
11 | data.bindto = thisData.id ? "#"+thisData.id : "#chart"
12 | } else {
13 | data = thisData || { data: { columns: [] }}
14 | }
15 | return data;
16 | };
17 |
18 | var data = getData() || { columns: [] };
19 | var chart = c3.generate(data);
20 |
21 | var id = this.data.id || "chart";
22 | c3charts[id] = chart;
23 |
24 | this.autorun(function (tracker) {
25 | if(UI.getData()) {
26 | chart.load(getData().data || { columns: [] });
27 | }
28 | });
29 | };
30 |
31 | Template.c3.destroyed = function() {
32 | var id = this.data.id || "chart";
33 | delete c3charts[id];
34 | };
35 |
36 | Template.c3.helpers({
37 | chartId: function() {
38 | return this.id || "chart"
39 | }
40 | });
41 |
42 | Template.c3.events({
43 |
44 | });
45 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | C3 chart
2 | ========
3 |
4 | Reactive C3 charting library based on D3
5 |
6 |
7 | Usage
8 | =====
9 |
10 | Somewhere in your template, add this:
11 |
12 | ```Handlebars
13 |
14 |
15 | {{> c3 myChartData}}
16 |
17 |
18 | ```
19 |
20 | And in .js define helper that returns chart data object as described in c3 docs:
21 |
22 | ```JavaScript
23 | Template.someTemplate.helpers({
24 | "myChartData": function() {
25 | return {
26 | data: {
27 | columns: [
28 | ['data1', 30, 200, 100, 400, 150, 250],
29 | ['data2', 130, 100, 140, 200, 150, 50]
30 | ],
31 | type: 'spline'
32 | }
33 | };
34 | }
35 | });
36 | ```
37 |
38 | Of course, instead providing static data, you can reactively show data from collection:
39 |
40 | ```JavaScript
41 | Template.someTemplate.helpers({
42 | "myChartData": function() {
43 |
44 | theReport = SomeCollection.find().fetch();
45 |
46 | var theData = ["myData"];
47 | theData.concat(_.pluck(theReport, "expenses"));
48 |
49 | return {
50 | data: {
51 | columns: [
52 | theData
53 | ],
54 | type: 'line'
55 | }
56 | };
57 | }
58 | });
59 | ```
60 | In this example, `SomeCollection` contains key `expenses` that will be shown in the graph.
61 |
62 | JSON objects can also be given as data:
63 |
64 | ```JavaScript
65 | // ...
66 | return {
67 | data: {
68 | json: {
69 | data1: [4, 3, 5, 2],
70 | data2: [6, 4, 3, 6]
71 | }
72 | }
73 | }
74 | ```
75 |
76 | If you want to use **multiple charts on one page** you must specify a unique id, thus the syntax is a bit different:
77 |
78 | ```Handlebars
79 |
80 |
81 | {{> c3 data=myChartData id="chart4"}}
82 |
83 |
84 | ```
85 |
86 | Access C3 API
87 | =============
88 |
89 | You can access your chart's c3 variable via global `c3charts` object by referencing your chart's id attribute (please keep id unique).
90 |
91 | ```
92 | var myChart = c3charts["chart4"];
93 | ```
94 |
95 |
96 | Live example
97 | ============
98 |
99 | You can see live example built with Meteor Kitchen showing radiation level from geiger counter here.
100 |
101 |
102 | Credits
103 | =======
104 |
105 | - Thanks to @KristerV and @tripflex for fixes and improvements
106 |
107 |
108 | ---
109 |
110 | That's all folks.
111 |
112 | Enjoy! :)
113 |
--------------------------------------------------------------------------------
/c3/c3.css:
--------------------------------------------------------------------------------
1 | /*-- Chart --*/
2 | .c3 svg {
3 | font: 10px sans-serif;
4 | -webkit-tap-highlight-color: transparent; }
5 |
6 | .c3 path, .c3 line {
7 | fill: none;
8 | stroke: #000; }
9 |
10 | .c3 text {
11 | -webkit-user-select: none;
12 | -moz-user-select: none;
13 | user-select: none; }
14 |
15 | .c3-legend-item-tile,
16 | .c3-xgrid-focus,
17 | .c3-ygrid,
18 | .c3-event-rect,
19 | .c3-bars path {
20 | shape-rendering: crispEdges; }
21 |
22 | .c3-chart-arc path {
23 | stroke: #fff; }
24 |
25 | .c3-chart-arc text {
26 | fill: #fff;
27 | font-size: 13px; }
28 |
29 | /*-- Axis --*/
30 | /*-- Grid --*/
31 | .c3-grid line {
32 | stroke: #aaa; }
33 |
34 | .c3-grid text {
35 | fill: #aaa; }
36 |
37 | .c3-xgrid, .c3-ygrid {
38 | stroke-dasharray: 3 3; }
39 |
40 | /*-- Text on Chart --*/
41 | .c3-text.c3-empty {
42 | fill: #808080;
43 | font-size: 2em; }
44 |
45 | /*-- Line --*/
46 | .c3-line {
47 | stroke-width: 1px; }
48 |
49 | /*-- Point --*/
50 | .c3-circle._expanded_ {
51 | stroke-width: 1px;
52 | stroke: white; }
53 |
54 | .c3-selected-circle {
55 | fill: white;
56 | stroke-width: 2px; }
57 |
58 | /*-- Bar --*/
59 | .c3-bar {
60 | stroke-width: 0; }
61 |
62 | .c3-bar._expanded_ {
63 | fill-opacity: 1;
64 | fill-opacity: 0.75; }
65 |
66 | /*-- Focus --*/
67 | .c3-target.c3-focused {
68 | opacity: 1; }
69 |
70 | .c3-target.c3-focused path.c3-line, .c3-target.c3-focused path.c3-step {
71 | stroke-width: 2px; }
72 |
73 | .c3-target.c3-defocused {
74 | opacity: 0.3 !important; }
75 |
76 | /*-- Region --*/
77 | .c3-region {
78 | fill: steelblue;
79 | fill-opacity: .1; }
80 |
81 | /*-- Brush --*/
82 | .c3-brush .extent {
83 | fill-opacity: .1; }
84 |
85 | /*-- Select - Drag --*/
86 | /*-- Legend --*/
87 | .c3-legend-item {
88 | font-size: 12px; }
89 |
90 | .c3-legend-item-hidden {
91 | opacity: 0.15; }
92 |
93 | .c3-legend-background {
94 | opacity: 0.75;
95 | fill: white;
96 | stroke: lightgray;
97 | stroke-width: 1; }
98 |
99 | /*-- Title --*/
100 | .c3-title {
101 | font: 14px sans-serif; }
102 |
103 | /*-- Tooltip --*/
104 | .c3-tooltip-container {
105 | z-index: 10; }
106 |
107 | .c3-tooltip {
108 | border-collapse: collapse;
109 | border-spacing: 0;
110 | background-color: #fff;
111 | empty-cells: show;
112 | -webkit-box-shadow: 7px 7px 12px -9px #777777;
113 | -moz-box-shadow: 7px 7px 12px -9px #777777;
114 | box-shadow: 7px 7px 12px -9px #777777;
115 | opacity: 0.9; }
116 |
117 | .c3-tooltip tr {
118 | border: 1px solid #CCC; }
119 |
120 | .c3-tooltip th {
121 | background-color: #aaa;
122 | font-size: 14px;
123 | padding: 2px 5px;
124 | text-align: left;
125 | color: #FFF; }
126 |
127 | .c3-tooltip td {
128 | font-size: 13px;
129 | padding: 3px 6px;
130 | background-color: #fff;
131 | border-left: 1px dotted #999; }
132 |
133 | .c3-tooltip td > span {
134 | display: inline-block;
135 | width: 10px;
136 | height: 10px;
137 | margin-right: 6px; }
138 |
139 | .c3-tooltip td.value {
140 | text-align: right; }
141 |
142 | /*-- Area --*/
143 | .c3-area {
144 | stroke-width: 0;
145 | opacity: 0.2; }
146 |
147 | /*-- Arc --*/
148 | .c3-chart-arcs-title {
149 | dominant-baseline: middle;
150 | font-size: 1.3em; }
151 |
152 | .c3-chart-arcs .c3-chart-arcs-background {
153 | fill: #e0e0e0;
154 | stroke: none; }
155 |
156 | .c3-chart-arcs .c3-chart-arcs-gauge-unit {
157 | fill: #000;
158 | font-size: 16px; }
159 |
160 | .c3-chart-arcs .c3-chart-arcs-gauge-max {
161 | fill: #777; }
162 |
163 | .c3-chart-arcs .c3-chart-arcs-gauge-min {
164 | fill: #777; }
165 |
166 | .c3-chart-arc .c3-gauge-value {
167 | fill: #000;
168 | /* font-size: 28px !important;*/ }
169 |
170 | .c3-chart-arc.c3-target g path {
171 | opacity: 1; }
172 |
173 | .c3-chart-arc.c3-target.c3-focused g path {
174 | opacity: 1; }
175 |
--------------------------------------------------------------------------------