Skip to content

Commit 062098e

Browse files
committed
Merge branch 'master' of https://github.com/github/developer.github.com into contents_crud
2 parents e59f309 + 3cddadf commit 062098e

File tree

3 files changed

+75
-60
lines changed

3 files changed

+75
-60
lines changed

content/guides/rendering-data-as-graphs.md

Lines changed: 72 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,21 @@ title: Rendering Data as Graphs | GitHub API
77
* TOC
88
{:toc}
99

10-
In this guide, we're going to poll repositories that we own, and render the
11-
information there with graphs, using the [d3.js][d3.js] library. We'll also
12-
be using Octokit, a Ruby library designed to interact with the GitHub API.
10+
In this guide, we're going to use the API to fetch information about repositories
11+
that we own, and the programming languages that make them up. Then, we'll
12+
visualize that information in a couple of different ways using the [D3.js][D3.js] library. To
13+
interact with the GitHub API, we'll be using the excellent Ruby library, [Octokit][Octokit].
1314

14-
We're going to jump right in and assume you've already read the ["Basics of Authentication"][basics-of-authentication]
15-
guide.
15+
If you haven't already, you should read the ["Basics of Authentication"][basics-of-authentication]
16+
guide before starting this example. You can find the complete source code for this project in the [platform-samples][platform samples] repository.
1617

17-
Note: you can download the complete source code for this project [from the platform-samples repo](https://github.com/github/platform-samples/tree/master/api/ruby/rendering-data-as-graphs).
18+
Let's jump right in!
1819

19-
Go ahead and register an application through GitHub. Set the main URL and callback
20-
URL to `http://localhost:4567/`. As before, we're going to be implementing a Rack middleware
21-
using [sinatra-auth-github][sinatra auth github]:
20+
## Setting up an OAuth application
21+
22+
First, [register a new application][new oauth application] on GitHub. Set the main and callback
23+
URLs to `http://localhost:4567/`. As [before][basics-of-authentication], we're going to handle authentication for the API by
24+
implementing a Rack middleware using [sinatra-auth-github][sinatra auth github]:
2225

2326
require 'sinatra/auth/github'
2427

@@ -68,10 +71,11 @@ Set up a similar _config.ru_ file as in the previous example:
6871
## Fetching repository information
6972

7073
This time, in order to talk to the GitHub API, we're going to use the [Octokit
71-
Ruby library][Octokit]. This is supremly better than directly making a bunch of
72-
REST calls. Plus, Octokit was developed by a GitHubber, so you know it'll work.
74+
Ruby library][Octokit]. This is much easier than directly making a bunch of
75+
REST calls. Plus, Octokit was developed by a GitHubber, and is actively maintained,
76+
so you know it'll work.
7377

74-
Establishing an Octokit instance is extremly easy; just pass your login
78+
Authentication with the API via Octokit is easy. Just pass your login
7579
and token to the `Octokit::Client` constructor:
7680

7781
if !authenticated?
@@ -80,18 +84,19 @@ and token to the `Octokit::Client` constructor:
8084
octokit_client = Octokit::Client.new(:login => github_user.login, :oauth_token => github_user.token)
8185
end
8286

83-
Let's do something interesting with our repository information; let's list the count
84-
of each language found in our repositories. To do that, we'll first have to grab
85-
a list of repositories we own. With Octokit, that looks like this:
87+
Let's do something interesting with the data about our repositories. We're going
88+
to see the different programming languages they use, and count which ones are used
89+
most often. To do that, we'll first need a list of our repositories from the API.
90+
With Octokit, that looks like this:
8691

8792
repos = client.repositories
8893

89-
Next, we'll want to iterate each repository, and count the language that GitHub
90-
identifies:
94+
Next, we'll iterate over each repository, and count the language that GitHub
95+
associates with it:
9196

9297
language_obj = {}
9398
repos.each do |repo|
94-
# sometimes language can be nil
99+
# sometimes language can be nil
95100
if repo.language
96101
if !language_obj[repo.language]
97102
language_obj[repo.language] = 1
@@ -103,32 +108,38 @@ identifies:
103108

104109
languages.to_s
105110

106-
When you restart your server, your web page should display some information
111+
When you restart your server, your web page should display something
107112
that looks like this:
108113

109-
{"JavaScript"=>13, "PHP"=>1, "Perl"=>1, "CoffeeScript"=>2, nil=>4, "Python"=>1, "Java"=>3, "Ruby"=>3, "Go"=>1, "C++"=>1}
114+
{"JavaScript"=>13, "PHP"=>1, "Perl"=>1, "CoffeeScript"=>2, "Python"=>1, "Java"=>3, "Ruby"=>3, "Go"=>1, "C++"=>1}
115+
116+
So far, so good, but not very human-friendly. A visualization
117+
would be great in helping us understand how these language counts are distributed. Let's feed
118+
our counts into D3 to get a neat bar graph representing the popularity of the languages we use.
110119

111-
So far, so good! Now, let's represent this information in a human-friendly format
112-
(no offense to JSON). We'll feed this information into d3.js to get a neat bar
113-
graph representing the popularity of the languages we use.
120+
## Visualizing language counts
114121

115-
d3.js likes working with arrays of JSON, so let's convert our Ruby hash into one:
122+
D3.js, or just D3, is a comprehensive library for creating many kinds of charts, graphs, and interactive visualizations.
123+
Using D3 in detail is beyond the scope of this guide, but for a good introductory article,
124+
check out ["D3 for Mortals"][D3 mortals].
116125

126+
D3 is a JavaScript library, and likes working with data as arrays. So, let's convert our Ruby hash into
127+
a JSON array for use by JavaScript in the browser.
117128

118129
languages = []
119130
language_obj.each do |lang, count|
120131
languages.push :language => lang, :count => count
121132
end
122-
133+
123134
erb :lang_freq, :locals => { :languages => languages.to_json}
124135

125-
We're iterating over each key-value pair in our object, and just pushing them into
126-
a new array. The reason we didn't do this earlier is because we didn't want to iterate
127-
over our `language_obj` object whilst we were creating it.
136+
We're simply iterating over each key-value pair in our object and pushing them into
137+
a new array. The reason we didn't do this earlier is because we didn't want to iterate
138+
over our `language_obj` object while we were creating it.
128139

129-
Now, _lang_freq.erb_ is going to need a bunch of code to support rendering a bar graph.
130-
For a really good tutorial on the basics of d3, check out [this article called
131-
"D3 for Mortals"][d3 mortals]. For now, you can just use the code provided here:
140+
Now, _lang_freq.erb_ is going to need some JavaScript to support rendering a bar graph.
141+
For now, you can just use the code provided here, and refer to the resources linked above
142+
if you want to learn more about how D3 works:
132143

133144
<!DOCTYPE html>
134145
<meta charset="utf-8">
@@ -146,7 +157,7 @@ For a really good tutorial on the basics of d3, check out [this article called
146157
fill: white;
147158
}
148159
text.yAxis {
149-
font-size: 12px;
160+
font-size: 12px;
150161
font-family: Helvetica, sans-serif;
151162
fill: black;
152163
}
@@ -208,32 +219,32 @@ For a really good tutorial on the basics of d3, check out [this article called
208219
</html>
209220

210221
Phew! Again, don't worry about what most of this code is doing. The relevant part
211-
here is a line way at the top--`var data = <%= languages %>;`--which indicates
222+
here is a line way at the top--`var data = <%= languages %>;`--which indicates
212223
that we're passing our previously created `languages` array into ERB for manipulation.
213224

214225
As the "D3 for Mortals" guide suggests, this isn't necessarily the best use of
215-
d3. But it does serve to illustrate how you can use the library, along with Octokit,
226+
D3. But it does serve to illustrate how you can use the library, along with Octokit,
216227
to make some really amazing things.
217228

218229
## Combining different API calls
219230

220231
Now it's time for a confession: the `language` attribute within repositories
221-
only identifies the "primary" language defined. That means that if you have
232+
only identifies the "primary" language defined. That means that if you have
222233
a repository that combines several languages, the one with the most bytes of code
223234
is considered to be the primary language.
224235

225-
Let's combine a few API calls to get a _true_ representation of which language
226-
has the greatest number of bytes written across all our code. A [treemap][d3 treemap]
227-
should be a great way to visualize the sizes of our coding languages used, rather
228-
than simply the count. We'll need to construct an array of objects that looks
236+
Let's combine a few API calls to get a _true_ representation of which language
237+
has the greatest number of bytes written across all our code. A [treemap][D3 treemap]
238+
should be a great way to visualize the sizes of our coding languages used, rather
239+
than simply the count. We'll need to construct an array of objects that looks
229240
something like this:
230241

231242
[ { "name": "language1", "size": 100},
232243
{ "name": "language2", "size": 23}
233244
...
234245
]
235246

236-
Since we already have a list of repositories above, let's inspect each one, and
247+
Since we already have a list of repositories above, let's inspect each one, and
237248
call [the language listing API method][language API]:
238249

239250
repos.each do |repo|
@@ -251,25 +262,24 @@ From there, we'll cumulatively add each language found to a "master list":
251262
end
252263
end
253264

254-
After that, we'll format the contents into a structure that d3 understands:
265+
After that, we'll format the contents into a structure that D3 understands:
255266

256267
language_obj.each do |lang, count|
257268
language_byte_count.push :name => "#{lang} (#{count})", :count => count
258269
end
259270

260-
# some mandatory formatting for d3
271+
# some mandatory formatting for D3
261272
language_bytes = [ :name => "language_bytes", :elements => language_byte_count]
262273

263-
(For more information on d3 tree map magic, check out [this simple tutorial][language API].)
274+
(For more information on D3 tree map magic, check out [this simple tutorial][language API].)
264275

265-
266-
To wrap up, we'll want to just pass this JSON information over to the same ERB file:
276+
To wrap up, we pass this JSON information over to the same ERB template:
267277

268278
erb :lang_freq, :locals => { :languages => languages.to_json, :language_byte_count => language_bytes.to_json}
269279

270280

271-
Just like we did before, here's a bunch of d3 JavaScript code that you can just drop
272-
directly into your template:
281+
Like before, here's a bunch of JavaScript that you can drop
282+
directly into your template:
273283

274284
<div id="byte_freq"></div>
275285
<script>
@@ -279,26 +289,26 @@ directly into your template:
279289
var sizeFunction = function(d){return d.count;};
280290
var colorFunction = function(d){return Math.floor(Math.random()*20)};
281291
var nameFunction = function(d){return d.name;};
282-
292+
283293
var color = d3.scale.linear()
284294
.domain([0,10,15,20])
285295
.range(["grey","green","yellow","red"]);
286-
296+
287297
drawTreemap(5000, 2000, '#byte_freq', language_bytes, childrenFunction, nameFunction, sizeFunction, colorFunction, color);
288298

289299
function drawTreemap(height,width,elementSelector,language_bytes,childrenFunction,nameFunction,sizeFunction,colorFunction,colorScale){
290-
300+
291301
var treemap = d3.layout.treemap()
292302
.children(childrenFunction)
293303
.size([width,height])
294304
.value(sizeFunction);
295-
305+
296306
var div = d3.select(elementSelector)
297307
.append("div")
298308
.style("position","relative")
299309
.style("width",width + "px")
300310
.style("height",height + "px");
301-
311+
302312
div.data(language_bytes).selectAll("div")
303313
.data(function(d){return treemap.nodes(d);})
304314
.enter()
@@ -308,7 +318,7 @@ directly into your template:
308318
.call(cell)
309319
.text(nameFunction);
310320
}
311-
321+
312322
function cell(){
313323
this
314324
.style("left",function(d){return d.x + "px";})
@@ -318,15 +328,19 @@ directly into your template:
318328
}
319329
</script>
320330

321-
And voila! Beautiful rectangles containing your repo languages. You might need to
322-
tweak the width and height to get all the information to show up properly.
331+
Et voila! Beautiful rectangles containing your repo languages, with relative
332+
proportions that are easy to see at a glance. You might need to
333+
tweak the height and width of your treemap, passed as the first two
334+
arguments to `drawTreemap` above, to get all the information to show up properly.
323335

324336

325-
[d3.js]: http://d3js.org/
337+
[D3.js]: http://d3js.org/
326338
[basics-of-authentication]: ../basics-of-authentication/
327339
[sinatra auth github]: https://github.com/atmos/sinatra_auth_github
328340
[Octokit]: https://github.com/pengwynn/octokit
329-
[d3 mortals]: http://www.recursion.org/d3-for-mere-mortals/
330-
[d3 treemap]: http://bl.ocks.org/mbostock/4063582
341+
[D3 mortals]: http://www.recursion.org/d3-for-mere-mortals/
342+
[D3 treemap]: http://bl.ocks.org/mbostock/4063582
331343
[language API]: http://developer.github.com/v3/repos/#list-languages
332344
[simple tree map]: http://2kittymafiasoftware.blogspot.com/2011/09/simple-treemap-visualization-with-d3.html
345+
[platform samples]: https://github.com/github/platform-samples/tree/master/api/ruby/rendering-data-as-graphs
346+
[new oauth application]: https://github.com/settings/applications/new

content/v3/pulls.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ to _test_ whether the pull request can be automatically merged into the base
7070
branch. (This _test_ commit is not added to the base branch or the head branch.)
7171
The `merge_commit_sha` attribute holds the SHA of the _test_ merge commit;
7272
however, this attribute is [deprecated](/#expected-changes) and is scheduled for
73-
removal in the next version of the API. The Boolean `mergable` attribute will
73+
removal in the next version of the API. The Boolean `mergeable` attribute will
7474
remain to indicate whether the pull request can be automatically merged.
7575

7676
### Alternative Response Formats

lib/resources.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -963,7 +963,8 @@ def text_html(response, status, head = {})
963963
"token" => "abc123",
964964
"app" => {
965965
"url" => "http://my-github-app.com",
966-
"name" => "my github app"
966+
"name" => "my github app",
967+
"client_id" => "abcde12345fghij67890"
967968
},
968969
"note" => "optional note",
969970
"note_url" => "http://optional/note/url",

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy