aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2015-08-29 23:16:43 +0900
committerKazuki Yamaguchi <k@rhe.jp>2015-08-29 23:16:43 +0900
commit1eb63c9784e2c5017045f55580ac94604f326dd5 (patch)
tree327b135715d11516e4ce306b8131336bab26ad8f /app
parent472bc32aa7b674b86293f02be6350c049f4c316c (diff)
downloadaclog-1eb63c9784e2c5017045f55580ac94604f326dd5.tar.gz
web: users#status: better chart (donut chart)
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/application.js.erb2
-rw-r--r--app/assets/javascripts/controllers/users.js108
-rw-r--r--app/assets/stylesheets/application.scss1
-rw-r--r--app/assets/stylesheets/users.scss127
-rw-r--r--app/views/users/stats.html.haml15
5 files changed, 119 insertions, 134 deletions
diff --git a/app/assets/javascripts/application.js.erb b/app/assets/javascripts/application.js.erb
index 5418429..f8765ce 100644
--- a/app/assets/javascripts/application.js.erb
+++ b/app/assets/javascripts/application.js.erb
@@ -4,6 +4,8 @@
//= require twitter-text-1.11.0
//= require superagent-1.2.0
//= require vue-0.12.9-csp
+//= require d3
+//= require nvd3
//= require init
//= require_tree ./shared
diff --git a/app/assets/javascripts/controllers/users.js b/app/assets/javascripts/controllers/users.js
index 332285a..02b1b1a 100644
--- a/app/assets/javascripts/controllers/users.js
+++ b/app/assets/javascripts/controllers/users.js
@@ -1,49 +1,73 @@
Views.users = {
stats: function() {
var drawgraph = function(target, data_raw, det) {
- var vm = new Vue({
- el: target,
- data: {
- users: data_raw.users,
- users_count: data_raw.users_count,
- reactions_count: data_raw.reactions_count,
- colors: ["#393b79", "#5254a3", "#6b6ecf", "#9c9ede", "#637939", "#8ca252", "#b5cf6b", "#cedb9c", "#8c6d31", "#bd9e39", "#e7ba52", "#e7cb94", "#843c39", "#ad494a", "#d6616b", "#e7969c", "#7b4173", "#a55194", "#ce6dbd", "#de9ed6"],
- loading: false,
- showTweets: false,
- statuses: [],
- lastUser: null
- },
- computed: {
- tweetsUrl: function() {
- var d = det(this.lastUser);
- return "/" + d[0] + "/favorited_by/" + d[1];
- },
- tweetsApi: function() {
- var d = det(this.lastUser);
- return "/i/api/tweets/user_favorited_by.json?screen_name=" + d[0] + "&source_screen_name=" + d[1];
- }
- },
- methods: {
- openTweets: function(user, e) {
- if (!this.showTweets || user === this.lastUser) {
- this.showTweets = !this.showTweets;
+ nv.addGraph(function() {
+ var size = document.querySelector(target).offsetWidth * 0.6;
+ var iconSize = 48;
+ var chart = nv.models.pieChart()
+ .x(function(d) { return d.screen_name; })
+ .y(function(d) { return d.count; })
+ .showLabels(true)
+ .showLegend(false)
+ .donut(true)
+ .title("100 tweets / " + data_raw.reactions_count.toString() + " favs")
+ .labelsOutside(true);
+ var tooltip = chart.tooltip;
+ tooltip.contentGenerator(function(d) {
+ if (d.data.screen_name) {
+ var container, count, iconimg, leftcon, rightcon, screen_name;
+ iconimg = document.createElement("img");
+ iconimg.setAttribute("src", d.data.profile_image_url);
+ leftcon = document.createElement("div");
+ leftcon.className = "icon";
+ leftcon.appendChild(iconimg);
+ screen_name = document.createElement("span");
+ screen_name.appendChild(document.createTextNode("@" + d.data.screen_name));
+ count = document.createElement("span");
+ count.appendChild(document.createTextNode(d.data.count));
+ rightcon = document.createElement("div");
+ rightcon.className = "meta";
+ rightcon.appendChild(screen_name);
+ rightcon.appendChild(count);
+ container = document.createElement("div");
+ container.appendChild(leftcon);
+ container.appendChild(rightcon);
+ return container.outerHTML;
+ } else {
+ var container, count, iconimg, rightcon, screen_name;
+ screen_name = document.createElement("span");
+ screen_name.appendChild(document.createTextNode("Other " + (data_raw.users_count - data_raw.users.length).toString() + " users"));
+ count = document.createElement("span");
+ count.appendChild(document.createTextNode(d.data.count));
+ rightcon = document.createElement("div");
+ rightcon.className = "meta";
+ rightcon.appendChild(screen_name);
+ rightcon.appendChild(count);
+ container = document.createElement("div");
+ container.appendChild(rightcon);
+ return container.outerHTML;
}
- if (this.showTweets) {
- this.lastUser = user;
- vm = this;
- superagent
- .get(vm.tweetsApi)
- .query({ count: 3 })
- .accept("json")
- .end(function(err, res) {
- var json = res.body;
- vm.statuses = json.statuses;
- });
- }
- },
- },
- });
- };
+ });
+ var svg = d3.select(target + " .chart")
+ .attr("height", size)
+ .datum(data_raw.users.concat([{ count: (data_raw.reactions_count - data_raw.users.reduce(function(sum, c) { return sum + c.count; }, 0)) }]))
+ .transition()
+ .call(chart);
+ svg.selectAll(".nv-label").each(function(d, i) {
+ var group, text;
+ group = d3.select(this);
+ text = group.select("text").remove();
+ return group.append("image").attr("xlink:href", function(d) {
+ return d.data.profile_image_url;
+ }).attr("width", iconSize).attr("height", iconSize).attr("transform", "translate(-" + iconSize / 2 + ", -" + iconSize / 2 + ")").on("click", function(d) {
+ var d = det(d.data);
+ return "/" + d[0] + "/favorited_by/" + d[1];
+ });
+ });
+ nv.utils.windowResize(chart.update);
+ return chart;
+ });
+ };
superagent
.get("/i/api/users/favorited_by.json")
diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss
index 948f4c7..119a0a2 100644
--- a/app/assets/stylesheets/application.scss
+++ b/app/assets/stylesheets/application.scss
@@ -1,5 +1,6 @@
@import "bootstrap-sprockets";
@import "bootstrap";
+@import "nvd3";
@import "base";
@import "*";
diff --git a/app/assets/stylesheets/users.scss b/app/assets/stylesheets/users.scss
index 0beb9c3..22536fa 100644
--- a/app/assets/stylesheets/users.scss
+++ b/app/assets/stylesheets/users.scss
@@ -1,82 +1,53 @@
.chart {
- width: 100%;
- margin: 30px 0;
- display: flex;
- flex-direction: row-reverse;
-
- .chart-item {
- margin-top: 100px;
- height: 50px;
-
- &.other {
- flex-grow: 1;
- }
-
- > span {
- display: block;
- line-height: 50px;
- width: 100%;
- height: 100%;
- text-align: center;
- overflow: hidden;
- }
-
- .popout {
- display: inline-block;
- white-space: nowrap;
- position: relative;
- top: -100px;
- padding: 5px;
- text-align: center;
- background-color: #eeeeee;
- border: 1px solid #999999;
- border-radius: 3px;
- z-index: 1;
-
- .count span {
- font-size: larger;
- font-weight: bold;
- }
- }
-
- &:hover {
- .popout {
- z-index: 2;
- }
- }
- }
+ // margin: 30px 0;
+ // display: flex;
+ // flex-direction: row-reverse;
+
+ // .chart-item {
+ // margin-top: 100px;
+ // height: 50px;
+
+ // &.other {
+ // flex-grow: 1;
+ // }
+
+ // > span {
+ // display: block;
+ // line-height: 50px;
+ // width: 100%;
+ // height: 100%;
+ // text-align: center;
+ // overflow: hidden;
+ // }
+
+ // .popout {
+ // display: inline-block;
+ // white-space: nowrap;
+ // position: relative;
+ // top: -100px;
+ // padding: 5px;
+ // text-align: center;
+ // background-color: #eeeeee;
+ // border: 1px solid #999999;
+ // border-radius: 3px;
+ // z-index: 1;
+
+ // .count span {
+ // font-size: larger;
+ // font-weight: bold;
+ // }
+ // }
+
+ // &:hover {
+ // .popout {
+ // z-index: 2;
+ // }
+ // }
+ // }
+ height: 300px;
}
-ul.user-list {
- padding: 15px 0;
- padding-left: 0;
- list-style: none;
-
- li {
- display: inline-block;
- }
-
- li a {
- display: block;
- padding: 10px 20px;
- color: #333;
- font-size: 18px;
- text-decoration: none;
- text-align: right;
- }
-
- li a:hover {
- background-color: #cecac7;
- }
-
- li a img {
- width: 48px;
- height: 48px;
- margin-bottom: 5px;
- }
- li a span {
- display: block;
- margin-bottom: 0;
- font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
- }
+.nvtooltip {
+ .icon {}
+ .meta {}
}
diff --git a/app/views/users/stats.html.haml b/app/views/users/stats.html.haml
index 52fc9ba..7c913e1 100644
--- a/app/views/users/stats.html.haml
+++ b/app/views/users/stats.html.haml
@@ -12,19 +12,6 @@
- [["favorited_by", "Favorited by.."], ["favorited_users", "Favoriting.."]].each do |graph_id, graph_title|
%div{id: graph_id}
%h2= graph_title
- %template{data: {"v-if" => "!loading"}}
- .chart
- .chart-item.other{data: {"v-if" => "users_count > users.length", "v-style" => "background-color: colors[users.length % colors.length]"}}
- %span Other {{ users_count - users.length }} People
- .chart-item{data: {"v-repeat" => "users | orderBy 'count'", "v-style" => "width: (100 * count / reactions_count) + '%', background-color: colors[(users.length - $index - 1) % colors.length]", "v-on" => "click: openTweets(this)"}}
- .popout
- %img{data: {"v-attr" => "src: profile_image_url"}}
- .count
- %span {{ count }}
- favs
- .statuses{data: {"v-if" => "showTweets"}}
- = render "tweets/tweets_template"
- .refresh-box<
- %a{href: "{{ tweetsUrl }}"} &#187;
+ %svg.chart{xmlns: "http://www.w3.org/2000/svg"}
.loading-box{data: {"v-if" => "loading"}}
%img.loading-image{src: image_path("loading.gif")}