8000 Merge branch 'master' of https://github.com/github/developer.github.c… · abertranb/developer.github.com@062098e · GitHub
[go: up one dir, main page]

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 7440 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)
0