pairing_matrix 1.1.1 → 1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 35ec19065f4bfb24ce4adaefe51a4088984df74b
4
- data.tar.gz: 6e0a2b8c06c4b15b869b2313f3a49e80e383f775
3
+ metadata.gz: af02e69747fa79c094ca77ae52e262e9369af13c
4
+ data.tar.gz: 456b22b0d6793d219e9b106f98db4886b362a9af
5
5
  SHA512:
6
- metadata.gz: 8d23f19ef1643be44d8c46c596603e2afb519f852029b4085056ade26c8167c419ec46dfd4562126f0988419b2bcf9bf1147a19e38c84ea4a4ddb8c5cb14c19e
7
- data.tar.gz: c3779a6ee64625855d6dfad2f221e59faf0d62f510e0c4da88caa0efdd2aace6a20a48396a8e7e4fd3985b34ec63b19ed87bac970cfb9b5ed8a0e0ce9b38e4e6
6
+ metadata.gz: 7cf09ef83aabc1a4c21d95e26146b38eb6b94df47c7272c94bd941568987d15a5e45abba314da42e62e40a832ea4cd850a5f1c678fb03242b0f45da2dc15c21d
7
+ data.tar.gz: 649c8c4a4db5b91a536868eaa7a42dd56e30d062a1d3d9cb8402966025e58c75f397c08ca4aeeeb6a45d7c5e9c2ddf964ba77c1d3a27388004edc2cf683c3d4d
data/README.md CHANGED
@@ -1,6 +1,16 @@
1
1
  # PairingMatrix
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/pairing_matrix.svg)](https://badge.fury.io/rb/pairing_matrix)
4
+ ![Gem Downloads](http://ruby-gem-downloads-badge.herokuapp.com/pairing_matrix?type=total)
5
+ [![Open Source Love](https://badges.frapsoft.com/os/v1/open-source.svg?v=102)](https://opensource.org/licenses/MIT)
6
+ [![Twitter](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/Ajit5ingh)
7
+
8
+ <img src="https://github.com/ajitsing/ScreenShots/blob/master/pairing_matrix/pairing_mat.png" width="600" height="550" />
9
+
10
+ ## How to read this matrix?
11
+ 1. This matrix is purely based on commits.
12
+ 2. Darker the line more the pair has worked together.
13
+ 3. If you see a dark red circle around a name that means the person has worked alone
4
14
 
5
15
  ## Installation
6
16
 
@@ -18,12 +28,41 @@ Or install it yourself as:
18
28
 
19
29
  ## Usage
20
30
 
21
- Once you have installed the pairing matrix gem, simply run the pairing_matrix command as shown below and the gem will start the web server. Then hit the url ```localhost:4567/matrix``` in the browser.
31
+ First of all you need to decide a format for your commit messages e.g.
32
+ #Feature [Dev1/Dev2] Your commit message
33
+
34
+ You can choose any format as long as you are able to extract dev names from the message using a regex.
35
+ Once you have decided on the commit message format, create a pairing_matrix.yml file.
36
+
37
+ ```yml
38
+ authors_regex: ^.*\[([\w]*)(?:\/)?([\w]*)\].*$
39
+ github_access_token: 000324cff69wes5613f732c345hn679c0knt509c
40
+ github_repos:
41
+ - org1/repo1
42
+ - org1/repo2
43
+ - github_username/my_private_repo
44
+ ```
45
+
46
+ #### authors_regex:
47
+ This regex is used to extract dev names from the commit message. You can verify your regex in irb console using the below command. If your regex is correct it will return an array of dev names.
22
48
 
23
- ```pairing_matrix```
49
+ e.g
50
+ ```ruby
51
+ "#4324 [Ajit/Abhishek] My commit message".scan(/^.*\[([\w]*)(?:\/)?([\w]*)\].*$/).flatten
52
+ => ["Ajit", "Abhishek"]
53
+ ```
24
54
 
25
- To run the web server successfully, it needs a configuration file with name ```pairing_matrix.yml``` in the same directory where you are running the command.
55
+ #### github_access_token:
56
+ If you want to use private github repos for matrix, then create a github_access_token and give it the repo read permission. Here is how you can create this token: https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/
26
57
 
58
+ #### github_repos:
59
+ List your repos which you want to use for matrix. If you have your repos inside organization then follow the ```org/repo``` format else just mention ```github_username/repo```.
60
+
61
+
62
+ Now after installing the pairing matrix gem, simply run the ```pairing_matrix``` command in the repo where you have ```pairing_matrix.yml``` file. This command will start a web server.
63
+ Then hit the url ```localhost:4567/matrix``` in the browser.
64
+
65
+ ## Some example of pairing_matrix.yml
27
66
  ### Here is a sample pairing_matrix.yml file
28
67
 
29
68
  ```yml
@@ -56,8 +95,6 @@ github_repos:
56
95
  - github_username/my_public_repo2
57
96
  ```
58
97
 
59
- authors_regex is the regex which extracts developers name from the commit message. This regex will depend on the commit message format that you follow in your project.
60
-
61
98
  ## Contributing
62
99
 
63
100
  1. Fork it ( https://github.com/ajitsing/pairing_matrix/fork )
@@ -19,7 +19,7 @@ module PairingMatrix
19
19
  def authors(since)
20
20
  commits = read(since)
21
21
  commits.map do |commit|
22
- commit.scan(/#{@config.authors_regex}/).flatten.compact.reject(&:empty?).sort.join(',')
22
+ commit.scan(/#{@config.authors_regex}/).flatten.compact.reject(&:empty?).map { |name| name.gsub(' ', '') }.sort.join(',')
23
23
  end.compact.reject(&:empty?)
24
24
  end
25
25
 
@@ -1,230 +1,246 @@
1
1
  var playground;
2
2
 
3
-
4
3
  function PlayGround(selector) {
5
- this.el = null;
6
- this.centerX = 400;
7
- this.centerY = 350;
8
- this.radius = 300;
9
- this.selector = selector;
10
-
11
- this.pairingData = [];
12
- this.playersData = [];
13
-
14
- this.connectionScale = d3.scaleLinear()
15
- .domain([0, 200])
16
- .range([0, 50]);
17
-
18
- this.init = function () {
19
- playground = this;
20
- this.el = d3.select(this.selector);
21
- };
22
-
23
- this.load = function (pairingData) {
24
- this.pairingData = pairingData;
25
- this.validPairsData = this.getValidPairs(pairingData);
26
- this.playersData = this.getPlayerNames(pairingData);
27
- this.clear();
28
- this.setGround();
29
- this.setPairing();
30
- this.setPlayers();
31
- };
32
-
33
- this.clear = function () {
34
- $(this.selector).children().remove();
4
+ this.el = null;
5
+ this.centerX = 400;
6
+ this.centerY = 350;
7
+ this.radius = 300;
8
+ this.selector = selector;
9
+
10
+ this.pairingData = [];
11
+ this.playersData = [];
12
+
13
+ this.connectionScale = d3.scaleLinear()
14
+ .domain([0, 200])
15
+ .range([0, 50]);
16
+
17
+ this.init = function () {
18
+ playground = this;
19
+ this.el = d3.select(this.selector);
20
+ };
21
+
22
+ this.load = function (pairingData) {
23
+ this.pairingData = pairingData;
24
+ this.validPairsData = this.getValidPairs(pairingData);
25
+ this.playersData = this.getPlayerNames(pairingData);
26
+ this.clear();
27
+ this.setGround();
28
+ this.setPairing();
29
+ this.setPlayers();
30
+ };
31
+
32
+ this.clear = function () {
33
+ $(this.selector).children().remove();
34
+ };
35
+
36
+ this.setPairing = function () {
37
+ this.el.selectAll(".connect")
38
+ .data(playground.validPairsData)
39
+ .enter().append("path")
40
+ .attr("class", "connect")
41
+ .attr("d", function (d) {
42
+ var fromIndex = _.indexOf(playground.playersData, d[0]),
43
+ fromCoordinates = playground.getPlayerCoordinates(fromIndex);
44
+ var toIndex = (d[1] == "") ? fromIndex : _.indexOf(playground.playersData, d[1]),
45
+ toCoordinates = playground.getPlayerCoordinates(toIndex);
46
+ return "M " + fromCoordinates.x + " " + fromCoordinates.y + " Q 400 350 " +
47
+ toCoordinates.x + " " + toCoordinates.y;
48
+ })
49
+ .attr("id", function (d) {
50
+ return d.join('_')
51
+ })
52
+ .attr("stroke-width", function (d) {
53
+ return playground.connectionScale(d[2])
54
+ })
55
+ .attr("data-from", function (d) {
56
+ return d[0]
57
+ })
58
+ .attr("data-to", function (d) {
59
+ return d[1]
60
+ });
61
+ };
62
+
63
+ this.setGround = function () {
64
+ this.el.append("circle")
65
+ .attr("cx", this.centerX)
66
+ .attr("cy", this.centerY)
67
+ .attr("r", this.radius)
68
+ .style("fill-opacity", 0.05);
69
+ };
70
+
71
+ this.setPlayers = function () {
72
+ var colors = d3.scaleOrdinal(d3.schemeCategory20);
73
+ var players = this.el.selectAll(".players")
74
+ .data(playground.playersData)
75
+ .enter()
76
+ .append("g");
77
+ players.append("circle")
78
+ .attr("cx", function (d, i) {
79
+ return playground.getPlayerCoordinates(i).x
80
+ })
81
+ .attr("cy", function (d, i) {
82
+ return playground.getPlayerCoordinates(i).y
83
+ })
84
+ .attr("fill", colors)
85
+ .attr("stroke-width", function (d) {
86
+ return playground.connectionScale(playground.getSoloContribution(d))
87
+ })
88
+ .attr("class", "player")
89
+ .attr("id", function (d) {
90
+ return d
91
+ })
92
+ .on('mouseover', this.mouseOver)
93
+ .on('mouseout', this.mouseOut);
94
+ players.append("text")
95
+ .attr("class", "player_names")
96
+ .text(function (d) {
97
+ return d
98
+ })
99
+ .attr("x", function (d, i) {
100
+ return playground.getPlayerCoordinates(i).x + 2
101
+ })
102
+ .attr("y", function (d, i) {
103
+ return playground.getPlayerCoordinates(i).y + 3
104
+ })
105
+ .attr("fill", "#000000");
106
+ };
107
+
108
+ this.getAllPairsContaining = function (name) {
109
+ return _.filter(this.validPairsData, function (pair) {
110
+ return pair.indexOf(name) >= 0
111
+ });
112
+ };
113
+
114
+ this.toggleClass = function toggleClass(newClass, pair) {
115
+ for (ii = 0; ii < 2; ii++) {
116
+ d3.selectAll($("#" + pair[ii]))
117
+ .attr("class", newClass)
35
118
  }
36
-
37
- this.setPairing = function () {
38
- this.el.selectAll(".connect")
39
- .data(playground.validPairsData)
40
- .enter().append("path")
41
- .attr("class", "connect")
42
- .attr("d", function (d) {
43
- var fromIndex = _.indexOf(playground.playersData, d[0]),
44
- fromCoordinates = playground.getPlayerCoordinates(fromIndex);
45
- var toIndex = (d[1] == "") ? fromIndex : _.indexOf(playground.playersData, d[1]),
46
- toCoordinates = playground.getPlayerCoordinates(toIndex);
47
- return "M " + fromCoordinates.x + " " + fromCoordinates.y + " Q 400 350 " +
48
- toCoordinates.x + " " + toCoordinates.y;
49
- })
50
- .attr("id", function(d) {return d.join('_')})
51
- .attr("stroke-width", function (d) {
52
- return playground.connectionScale(d[2])
53
- })
54
- .attr("data-from", function (d) {
55
- return d[0]
56
- })
57
- .attr("data-to", function (d) {
58
- return d[1]
59
- });
60
- };
61
-
62
- this.setGround = function () {
63
- this.el.append("circle")
64
- .attr("cx", this.centerX)
65
- .attr("cy", this.centerY)
66
- .attr("r", this.radius)
67
- .style("fill-opacity", 0.05);
68
- };
69
-
70
- this.setPlayers = function () {
71
- var colors = d3.scaleOrdinal(d3.schemeCategory20);
72
- var players = this.el.selectAll(".players")
73
- .data(playground.playersData)
74
- .enter()
75
- .append("g");
76
- players.append("circle")
77
- .attr("cx", function (d, i) {
78
- return playground.getPlayerCoordinates(i).x
79
- })
80
- .attr("cy", function (d, i) {
81
- return playground.getPlayerCoordinates(i).y
82
- })
83
- .attr("fill", colors)
84
- .attr("stroke-width", function (d) {
85
- return playground.connectionScale(playground.getSoloContribution(d))
86
- })
87
- .attr("class", "player")
88
- .attr("id", function (d) {
89
- return d
90
- })
91
- .on('mouseover', this.mouseOver)
92
- .on('mouseout', this.mouseOut)
93
- players.append("text")
94
- .attr("class", "player_names")
95
- .text(function (d) {
96
- return d
97
- })
98
- .attr("x", function (d, i) {
99
- return playground.getPlayerCoordinates(i).x + 2
100
- })
101
- .attr("y", function (d, i) {
102
- return playground.getPlayerCoordinates(i).y + 3
103
- })
104
- .attr("fill", "#000000");
105
- };
106
-
107
- this.getAllPairsContaining = function(name) {
108
- return _.filter(this.validPairsData, function(pair) {
109
- return pair.indexOf(name) >= 0
110
- });
111
- };
112
-
113
- this.toggleClass = function toggleClass(newClass, pair) {
114
- for(ii = 0; ii < 2; ii++) {
115
- d3.selectAll($("#" + pair[ii]))
116
- .attr("class", newClass)
117
- }
118
- }
119
-
120
- this.mouseOut = function(id) {
121
- var connectedPairs = playground.getAllPairsContaining(id);
122
- connectedPairs.forEach(function(pair) {
123
- playground.toggleClass("player", pair);
124
- var pairId = pair.join('_');
125
- d3.selectAll($("#" + pairId))
126
- .attr("class", "connect")
127
- .style("stroke-width", function(d) {return playground.connectionScale(d[2])})
128
- })
129
- d3.selectAll($("#" + id))
130
- .attr("class", "player")
131
- }
132
-
133
- this.mouseOver = function (id) {
134
- var connectedPairs = playground.getAllPairsContaining(id);
135
- connectedPairs.forEach(function(pair) {
136
- playground.toggleClass("playerLarge", pair)
137
- var pairId = pair.join('_');
138
- d3.selectAll($("#" + pairId))
139
- .attr("class", "connectLarge")
140
- .style("stroke-width", function(d) {return playground.connectionScale(d[2])})
141
- })
142
- d3.selectAll($("#" + id))
143
- .attr("class", "playerLarge")
144
- };
145
-
146
- this.updateConnectorsPath = function (playerId, newPoint) {
147
- playground.el
148
- .selectAll(".connect[data-from='" + playerId + "']")
149
- .attr("d", function (d) {
150
- return playground.replaceFromInPath($(this).attr("d"), newPoint);
151
- }
152
- );
153
- playground.el
154
- .selectAll(".connect[data-to='" + playerId + "']")
155
- .attr("d", function (d) {
156
- return playground.replaceToInPath($(this).attr("d"), newPoint);
157
- }
158
- );
159
- }
160
-
161
- this.getCollidingPlayer = function (player) {
162
- var svg = $("svg")[0];
163
- var rectangle = svg.createSVGRect();
164
- rectangle.x = player.attr("cx");
165
- rectangle.y = player.attr("cy");
166
- rectangle.width = player.attr("r");
167
- rectangle.height = player.attr("r");
168
- var allElements = svg.getIntersectionList(rectangle, null);
169
- return _.filter(allElements, function (elem) {
170
- return $(elem).attr("class") == "player" && $(elem).attr("id") != player.attr("id")
171
- });
119
+ };
120
+
121
+ this.mouseOut = function (id) {
122
+ showMatrix();
123
+ };
124
+
125
+ this.mouseOver = function (id) {
126
+ var connectedPairs = _.unique(_.flatten(playground.getAllPairsContaining(id)));
127
+ hideMatrix();
128
+ if (connectedPairs.length == 0) {
129
+ showPlayer(id);
130
+ return;
172
131
  }
173
-
174
- this.replaceFromInPath = function (path, from) {
175
- var parts = path.split(" ");
176
- parts[1] = from[0];
177
- parts[2] = from[1];
178
- return parts.join(" ");
179
- }
180
-
181
- this.replaceToInPath = function (path, to) {
182
- var parts = path.split(" ");
183
- parts[6] = to[0];
184
- parts[7] = to[1];
185
- return parts.join(" ");
186
-
187
- }
188
-
189
- this.closestPointOnCircumference = function () {
190
- var vx = d3.event.x - this.centerX,
191
- vy = d3.event.y - this.centerY,
192
- magV = Math.sqrt(vx * vx + vy * vy);
193
- return [(this.centerX + vx / magV * this.radius), (this.centerY + vy / magV * this.radius)];
194
- };
195
-
196
- this.getPlayerCoordinates = function (index) {
197
- var distanceInDegrees = 2 * Math.PI / playground.playersData.length;
198
- return {
199
- x: (playground.radius * Math.sin(distanceInDegrees * index) + playground.centerX),
200
- y: (playground.radius * Math.cos(distanceInDegrees * index) + playground.centerY)
132
+
133
+ connectedPairs.forEach(function (pair) {
134
+ showPlayer(pair);
135
+ });
136
+ showPath(id);
137
+ };
138
+
139
+ this.updateConnectorsPath = function (playerId, newPoint) {
140
+ playground.el
141
+ .selectAll(".connect[data-from='" + playerId + "']")
142
+ .attr("d", function (d) {
143
+ return playground.replaceFromInPath($(this).attr("d"), newPoint);
201
144
  }
202
- };
203
-
204
- this.getValidPairs = function (pairingData) {
205
- return _.filter(pairingData, function (data) {
206
- return (!_.isEmpty(data[0]) && !_.isEmpty(data[1]));
207
- })
208
- };
209
-
210
- this.getPlayerNames = function (pairingData) {
211
- var playerNames = [];
212
- _.each(pairingData, function (data) {
213
- playerNames.push(data[0]);
214
- playerNames.push(data[1]);
215
- });
216
- playerNames = _.compact(playerNames);
217
- return _.sortBy(_.uniq(playerNames), function (d) {
218
- return d
219
- });
220
- };
221
-
222
- this.getSoloContribution = function (name) {
223
- var contrib = _.find(this.pairingData, function (data) {
224
- return ((data[0] == name && _.isEmpty(data[1])) || (data[1] == name && _.isEmpty(data[0])));
225
- });
226
- return contrib ? contrib[2] : 1;
227
- };
228
-
229
- this.init();
145
+ );
146
+ playground.el
147
+ .selectAll(".connect[data-to='" + playerId + "']")
148
+ .attr("d", function (d) {
149
+ return playground.replaceToInPath($(this).attr("d"), newPoint);
150
+ }
151
+ );
152
+ };
153
+
154
+ this.getCollidingPlayer = function (player) {
155
+ var svg = $("svg")[0];
156
+ var rectangle = svg.createSVGRect();
157
+ rectangle.x = player.attr("cx");
158
+ rectangle.y = player.attr("cy");
159
+ rectangle.width = player.attr("r");
160
+ rectangle.height = player.attr("r");
161
+ var allElements = svg.getIntersectionList(rectangle, null);
162
+ return _.filter(allElements, function (elem) {
163
+ return $(elem).attr("class") == "player" && $(elem).attr("id") != player.attr("id")
164
+ });
165
+ };
166
+
167
+ this.replaceFromInPath = function (path, from) {
168
+ var parts = path.split(" ");
169
+ parts[1] = from[0];
170
+ parts[2] = from[1];
171
+ return parts.join(" ");
172
+ };
173
+
174
+ this.replaceToInPath = function (path, to) {
175
+ var parts = path.split(" ");
176
+ parts[6] = to[0];
177
+ parts[7] = to[1];
178
+ return parts.join(" ");
179
+
180
+ };
181
+
182
+ this.closestPointOnCircumference = function () {
183
+ var vx = d3.event.x - this.centerX,
184
+ vy = d3.event.y - this.centerY,
185
+ magV = Math.sqrt(vx * vx + vy * vy);
186
+ return [(this.centerX + vx / magV * this.radius), (this.centerY + vy / magV * this.radius)];
187
+ };
188
+
189
+ this.getPlayerCoordinates = function (index) {
190
+ var distanceInDegrees = 2 * Math.PI / playground.playersData.length;
191
+ return {
192
+ x: (playground.radius * Math.sin(distanceInDegrees * index) + playground.centerX),
193
+ y: (playground.radius * Math.cos(distanceInDegrees * index) + playground.centerY)
194
+ }
195
+ };
196
+
197
+ this.getValidPairs = function (pairingData) {
198
+ return _.filter(pairingData, function (data) {
199
+ return (!_.isEmpty(data[0]) && !_.isEmpty(data[1]));
200
+ })
201
+ };
202
+
203
+ this.getPlayerNames = function (pairingData) {
204
+ var playerNames = [];
205
+ _.each(pairingData, function (data) {
206
+ playerNames.push(data[0]);
207
+ playerNames.push(data[1]);
208
+ });
209
+ playerNames = _.compact(playerNames);
210
+ return _.sortBy(_.uniq(playerNames), function (d) {
211
+ return d
212
+ });
213
+ };
214
+
215
+ this.getSoloContribution = function (name) {
216
+ var contrib = _.find(this.pairingData, function (data) {
217
+ return ((data[0] == name && _.isEmpty(data[1])) || (data[1] == name && _.isEmpty(data[0])));
218
+ });
219
+ return contrib ? contrib[2] : 1;
220
+ };
221
+
222
+ var showPlayer = function (player) {
223
+ $("#" + player).show();
224
+ $("#" + player).siblings().show();
225
+ };
226
+
227
+ var hideMatrix = function () {
228
+ $('circle').hide();
229
+ $('g.area>circle').show();
230
+ $('path').hide();
231
+ $('text').hide();
232
+ };
233
+
234
+ var showMatrix = function () {
235
+ $('circle').show();
236
+ $('path').show();
237
+ $('text').show();
238
+ };
239
+
240
+ var showPath = function (player) {
241
+ $("path[data-from='" + player + "']").show();
242
+ $("path[data-to='" + player + "']").show();
243
+ };
244
+
245
+ this.init();
230
246
  }
@@ -1,3 +1,3 @@
1
1
  module PairingMatrix
2
- VERSION = '1.1.1'
2
+ VERSION = '1.2'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pairing_matrix
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: '1.2'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ajit Singh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-28 00:00:00.000000000 Z
11
+ date: 2017-07-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler