-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
87 lines (73 loc) · 1.99 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package main
import (
"encoding/json"
"net/http"
"os"
"time"
"github.com/wcharczuk/go-chart"
"github.com/xarantolus/jsonextract"
)
func main() {
var c = http.Client{
Timeout: 90 * time.Second,
}
// Download a StackOverflow user profile
// The profile page only contains the chart data if it ends with "?tab=topactivity"
resp, err := c.Get("https://stackoverflow.com/users/5728357/xarantolus?tab=topactivity")
if err != nil {
panic(err)
}
defer resp.Body.Close()
// There's two lines like this in the page source:
// var graphData = [984,984,984,984,...];
// StackExchange.user.renderMiniGraph(graphData);
// That's what we want to extract into this array
var yValues []float64
// Now we read the entire page source and extract into our yValues array
err = jsonextract.Reader(resp.Body, func(b []byte) error {
// Try to unmarshal
err := json.Unmarshal(b, &yValues)
if err == nil && len(yValues) > 5 {
// If it was successful, we stop parsing
return jsonextract.ErrStop
}
// continue with next object
return nil
})
if err != nil {
panic("cannot extract JSON objects: " + err.Error())
}
// Now we check the integrity of our extracted data.
// With a struct we should check if all struct fields we want
// were extracted, but here we just see if we got any numbers
if len(yValues) <= 5 {
panic("seems like we couldn't get chart data")
}
// Create the graph
graph := chart.Chart{
Series: []chart.Series{
chart.ContinuousSeries{
XValues: generateXValues(len(yValues)),
YValues: yValues,
Name: "Reputation",
},
},
}
// Create the file where we want to render it
f, err := os.Create("stackoverflow-chart.png")
if err != nil {
panic("creating chart file: " + err.Error())
}
defer f.Close()
// Render this graph
err = graph.Render(chart.PNG, f)
if err != nil {
panic("rendering chart: " + err.Error())
}
}
func generateXValues(limit int) (out []float64) {
for i := 0; i < limit; i++ {
out = append(out, float64(i))
}
return
}