DZone
Java Zone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Java Zone > Angular Commit Bubbles

Angular Commit Bubbles

Paul Hammant user avatar by
Paul Hammant
·
Nov. 04, 14 · Java Zone · Interview
Like (0)
Save
Tweet
6.59K Views

Join the DZone community and get the full member experience.

Join For Free

i’m obsessed with the pseudo-declarative side of angular. making html turing-complete was a stroke of genius. to test the theory, and towards something that would be genuinely useful, i thought i’d blow the dust off something else that miško had made in the past…

commit bubbles!

miško hevery wrote an actionscript app that showed the enthusiasm for testing of the developers within a team. he’d previously worked at adobe and was quite skilled with the flash eco-system. i’m sure he’s forgotten much of that now, given how significant and time consuming angular has become. former thoughtworker jon wolter blogged about it . i think jon even helped miško develop it a couple of years before. we only have screen-shots of the original app to go with:

anyway, we recreated it in angular as a team-effort after-work activity. to be fair it’s also an angular teaching tool for people new to it, with me switching between “product owner” and “angular coder” as needed. it served as a tutorial for svg too, as it happens.

if you have ie 10 or better, you can play with it here (mobile too): http://paul-hammant.github.io/angular-commit-bubbles/commits.html

the checkboxes and buttons work. they remove (or add back) committers so that you can hone in on best performer (or worst, or both). you can also click on bubbles for an overlay showing more info about the commit. that’s only a jpeg above though, so don’t get too upset if you’ve been clicking it. the real deal is here

in the implementation, we has a deliberate non-functional goal: what would the solution look like with least possible lines of javascript. the source is here , but for your convenience inline here too:

<!doctype html>
<html>
<head>
    <meta content="text/html;charset=utf-8" http-equiv="content-type">
    <meta content="utf-8" http-equiv="encoding">
    <title>commit bubbles</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js"></script>
    <script src="http://underscorejs.org/underscore-min.js"></script>
    <script src="http://vitalets.github.io/checklist-model/checklist-model.js"></script>
    <script src="http://momentjs.com/downloads/moment.min.js"></script>
    <script>
        var app = angular.module("app", ["checklist-model"]);
        app.controller('commitbubbles', function ($scope) {
            $scope.c = {
                chartheight: 680,
                topmargin: 100,
                colors: ["#ffa07a","#20b2aa","#778899","#b0c4de","#f5f5dc","#00ff00","#000000","#32cd32","#faf0e6","#0000ff","#ff00ff","#8a2be2","#800000","#a52a2a","#66cdaa","#deb887","#0000cd","#5f9ea0","#7fff00","#9370db","#d2691e","#ff7f50","#7b68ee","#6495ed","#48d1cc","#dc143c","#c71585","#00ffff","#191970","#00008b","#f5fffa","#008b8b","#ffe4e1","#b8860b","#a9a9a9","#006400","#000080","#bdb76b","#8b008b","#808000","#6b8e23","#ff8c00","#ffa500","#9932cc","#ff4500","#8b0000","#da70d6","#e9967a","#eee8aa","#8fbc8f","#98fb98","#483d8b","#afeeee","#2f4f4f","#db7093","#00ced1","#9400d3","#ffdab9","#ff1493","#cd853f","#00bfff","#ffc0cb","#696969","#dda0dd","#1e90ff","#b0e0e6","#b22222","#800080","#fffaf0","#ff0000","#228b22","#bc8f8f","#ff00ff","#4169e1","#dcdcdc","#fa8072","#ffd700","#faa460","#daa520","#2e8b57","#808080","#008000","#a0522d","#adff2f","#c0c0c0","#87ceeb","#ff69b4","#6a5acd","#cd5c5c","#708090","#4b0082","#00ff7f","#f0e68c","#4682b4","#e6e6fa","#d2b48c","#008080","#7cfc00","#d8bfd8","#fffacd","#ff6347","#add8e6","#40e0d0","#f08080","#ee82ee","#f5deb3","#fafad2","#90ee90","#d3d3d3","#ffff00","#ffb6c1"]
            };
            $scope.commits = [
                {
                    ts:1288202623006,
                    hash:"1234567890",
                    testpercentage:100,
                    size:55,
                    author:"john doe"
                },
                {
                    ts:1288121623006,
                    hash:"13432435645",
                    testpercentage:30,
                    size:81,
                    author:"john doe"
                },
                {
                    ts:1288128023006,
                    hash:"12232435645",
                    testpercentage:50,
                    size:50,
                    author:"hector"
                },
                {
                    ts:1288202823006,
                    hash:"12332343455",
                    testpercentage:55,
                    size:50,
                    author:"hector"
                },
                {
                    ts:1288323623006,
                    hash:"2342342344",
                    testpercentage:15,
                    size:22,
                    author:"mildred"
                }
            ];
            $scope.authors = _.uniq(_.pluck($scope.commits, 'author'));
            $scope.selected = { authors: $scope.authors.slice(0) };
            $scope.from = _.min($scope.commits, "ts").ts;
            $scope.to = _.max($scope.commits, "ts").ts;
            $scope.timespan = moment.duration(moment($scope.from).diff(moment($scope.to))).humanize();
            $scope.checkallauthors = function() {
              $scope.selected.authors = angular.copy($scope.authors);
            };
        });
    </script>
</head>
<body ng-app="app" ng-controller="commitbubbles" bgcolor="#ffffff">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" width="1220"
     height="{{c.chartheight + c.topmargin + 5}}"
     xmlns:dc="http://purl.org/dc/elements/1.1/">
    <rect fill="#fefcff" x="100" y="{{c.topmargin}}" width="1100" height="{{c.chartheight}}" ng-click="selected.commit = false"/>
    <g font-family="verdana" font-size="16">
        <text x="0" y="{{c.topmargin + 8}}">all test</text>
        <text x="0" y="{{c.chartheight/2 + 5 + c.topmargin}}">equal</text>
        <text x="0" y="{{c.chartheight + c.topmargin}}">all prod</text>
        <text x="1140" y="{{c.chartheight/2 + 17 + c.topmargin}}">time &#10148;</text>
    </g>
    <g style="stroke:rgb(0,0,0);stroke-width:2">
        <line x1="100" y1="{{c.chartheight/2 + c.topmargin}}" x2="1200" y2="{{c.chartheight/2 + c.topmargin}}" />
        <line x1="100" y1="{{c.topmargin +2}}" x2="100" y2="{{c.chartheight + c.topmargin+2}}"/>
    </g>
    <g font-family="verdana" font-size="8" ng-repeat="i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]" style="stroke:rgb(0,0,0);stroke-width:0.5">
        <line ng-show="i != 5" x1="100" stroke-dasharray="10,35"
              y1="{{c.chartheight + 2 - (c.chartheight/10 * i) + c.topmargin}}" x2="1200"
              y2="{{c.chartheight - (c.chartheight/10 * i) + c.topmargin}}" />
        <text fill="white" x="70" y="{{c.chartheight + 3  - (c.chartheight/10 * i) + c.topmargin}}">{{100 - (10*i)}}:{{(10*i)}}</text>
    </g>
    <g stroke="black">
        <circle ng-repeat="commit in commits" ng-show="selected.authors.indexof(commit.author) > -1"
                cx="{{100 + (commit.ts - from) * 1100 / (to - from) }}"
                cy="{{c.chartheight - (commit.testpercentage * c.chartheight/100) + c.topmargin}}"
                r="{{commit.size * (c.chartheight/600)}}"
                stroke-opacity="{{(selected.commit === commit) ? 1 : 0}}"
                fill="{{c.colors}}" fill-opacity="0.5"
                ng-click="selected.commit = commit"/>
    </g>
    <foreignobject class="node" x="0" y="0" width="1200" height="{{c.topmargin}}">
        <body xmlns="http://www.w3.org/1999/xhtml">
        <h2>{{timespan}} shown between {{from | date:'mm/dd/yy hh:mm'}} and {{to | date:'mm/dd/yy hh:mm'}}</h2>
        <div>show authors:
            <label ng-repeat="author in authors" style="{{'color: ' + c.colors[$index] }}">
                <input type="checkbox" checklist-model="selected.authors" checklist-value="author"> {{author}}
            </label>
            <button ng-click="checkallauthors()" style="margin: 0 0 5px 5px">all authors</button>
            <button ng-click="selected.authors.splice(0,selected.authors.length)" style="margin: 0 0 5px 5px">none</button>
        </div>
        </body>
    </foreignobject>
    <g font-family="verdana" font-size="16" ng-show="selected.commit" ng-click="selected.commit = false">
        <rect style="stroke:rgb(0,0,0);stroke-width:2" x="300" y="300" height="300" width="400" fill="white" opacity="0.7"/>
        <text x="320" y="330">selected commit</text>
        <text x="320" y="380">hash: {{selected.commit.hash}}</text>
        <text x="320" y="430">author: {{selected.commit.author}}</text>
        <text x="320" y="480">date/time: {{selected.commit.ts | date:'yyyy-mm-dd hh:mm:ss z'}}</text>
        <text x="320" y="530">size: {{selected.commit.size}}</text>
        <text x="320" y="580">test percentage: {{selected.commit.testpercentage}}</text>
    </g>
</svg>
</body>
</html>

if we ignore the array of non-clashing colors, some constants, and the simulation of four commits that’s inlined rather than pulled via $resource, there’s only ten lines of javascript. underscore has helped us reduce lines quite a bit. the downside is that the html is pretty angular-attribute heavy.

next?

colleagues [a href="http://www.grahambrooks.com"]graham brooks and premanand chandrasekaran are working to use it in a real (and larger system ), and populate the commit info (at least for subversion).

a d3 alternative

colleague pawel badenski forked my repo, and quickly made a d3 version of the same thing . i don’t want to give him too much publicity, so i’ll leave it at that

20% less lines of code, grumble grumble……

Commit (data management) AngularJS

Published at DZone with permission of Paul Hammant, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • An Overview of Key Components of a Data Pipeline
  • Stupid Things Orgs Do That Kill Productivity w/ Netflix, FloSports & Refactoring.club
  • Types of UI Design Patterns Depending on Your Idea
  • What Are Cookies in Servlets?

Comments

Java Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo