hi, my name is Ian Scrivener. I'm an Australian web technology specialist, fullstack/backend javascript web developer & cloud sysadmin. I've extensive (23 years) experience with medium to large scale web projects for .com, .gov & .org.

My main weapons include javascript; node.js, angular.js, d3.js and mean.js, with SQL & noSQL databases; mySQL, PostgresSQL, MSSQL, MongoDB, CouchDB, redis etc

... find out more


Product Evangelist versus Solution Scientist

A few conversations this week got me thinking about the way we look at, present, promote and even argue our ideas and solutions our work roles... and the kind of outcomes and efficiencies that results

Mike McGee, Chief Product Officer at Booodl said something very poignant to the other day.

"[At Booodl] we want people to argue like scientists, not lawyers."

Scientist: implies solid research, evidence & result based thinking & decision making, willingness to change position when presented with new evidence.

Lawyer: implies fervantly arguing a position irregardless if its right or wrong, irregardless of consequences/outcomes... all that matters is being right and winning the argument. Adversarial - always a winner and a looser.

I'd add a third class to that;

Evangelist: implies religiocity, blind faith, fundamentalism, closed mindedness, devotion/adherence despite suffering/inappropriatness... even deception/criminality to maintain a facade/system/position.

Which best describes the way you advocate in the workplace; Scientist, Evangelist or Lawyer?

Which type of professional would you rather employ/commission to do work for you?

Which type of 'public servant' would you rather have spending your tax dollars?

Comments

d3.js Cambodia Choropleth

Just the basic points to make a Heatmap. You need node.js installed.

1) Set up a working directory

mkdir kh-chloropeth
cd kh-kh-chloropeth

2) Grab Cambodia base map from Open Devleopment Cambodia

mkdir downloads
cd downloads
curl http://www.opendevelopmentcambodia.net/kml-maps/base-map.zip
unzip bas* -d kh_provinces

3) Grab World Bank Subnational Malnutrition Database

download CSV file from http://data.worldbank.org/data-catalog/subnational-malnutrition-database

4) Make topojsons

sudo npm install topojson -g
topojson  -o cambodia.topo.json ./kh_provinces/Provinces.shp

**5) See a demo

http://ianscrivener.github.io/d3-cambodia-population-density

**6) Grab the code

https://github.com/ianscrivener/d3-cambodia-population-density

**7) Here's the code

<!DOCTYPE html>
<html>
<head>

    <meta charset="utf-8">
    <style>
        body {
            margin-left:30px;
            background-color: #eee;
            font-family: "Trebuchet MS", Helvetica, Arial, sans-serif;
        }
        #zLabel{
            margin-left:70px;
        }
        .greyed {color: #ccc;}
        .provinces {
            fill: #fff;
            stroke: #222;
            stroke-linejoin: round;
            stroke-opacity: 0.7;
            stroke-width: 1px;
            opacity: 0.8;
        }

        .provinces:hover{
            stroke: #000;
            stroke-width: 2px;
            opacity:1;
        }

        .q0-9 { fill:rgb(247,251,255); }
        .q1-9 { fill:rgb(222,235,247); }
        .q2-9 { fill:rgb(198,219,239); }
        .q3-9 { fill:rgb(158,202,225); }
        .q4-9 { fill:rgb(107,174,214); }
        .q5-9 { fill:rgb(66,146,198); }
        .q6-9 { fill:rgb(33,113,181); }
        .q7-9 { fill:rgb(8,81,156); }
        .q8-9 { fill:rgb(8,48,107); }

        .country {
            fill: #ccc;
            stroke: #333;
            stroke-width: .5px;
            stroke-linejoin: round;
        }

        .graticule {
            fill: none;
            stroke: #000;
            stroke-opacity: .3;
            stroke-width: .5px;
        }

        .graticule.outline {
            stroke: #333;
            stroke-opacity: 1;
            stroke-width: 1.5px;
        }

    </style>
</head>
<body>
<h2>Cambodia population density</h2>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/d3.geo.projection.v0.min.js"></script>
<script src="http://d3js.org/queue.v1.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script>

    function numberWithCommas(x) {
        return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    }

    var width = 600,
            height = 350;

    var projection = d3.geo.mercator().center([108, 11.2]).scale(4000),
            color = d3.scale.category20(),
            graticule = d3.geo.graticule();

    var path = d3.geo.path()
            .projection(projection);

    var svg = d3.select("body").append("svg")
            .attr("width", width)
            .attr("height", height);
    var label = d3.select("body").append("div")
            .attr("id","zLabel")
            .classed("greyed",true)
            .text("mouseover the maps to see province")
            ;
    var rateById = d3.map();

    var zStats = d3.map();

    var quantize = d3.scale.threshold()
            .domain([5,15,30,80,150,200,300,500,5000])
            .range(d3.range(9).map(function (i) {
                return "q" + i + "-9";
            }));

    queue()
            .defer(d3.json, "KHM_adm1.topo.json")
            .defer(d3.tsv, "Census2008.tsv", function (d) {
                rateById.set(parseInt(d.ID_1), +(d.DENSITY));
                tmp = "[".concat(d.ID_1,'] ',d.PROV_NAME,' - ', numberWithCommas(d.TOTPOP),' people');

                zStats.set(parseInt(d.ID_1), tmp);
            })
            .await(ready);

    function ready(error, world) {
        svg.append("g")
                .selectAll("path")
                .data(topojson.feature(world, world.objects['KHM_adm1.geo']).features)
                .enter().append("path")
                .attr("d", path)
                .attr("class", function (d) {
                    return quantize(rateById.get(d.id));
                })
                .classed("provinces", true)
                .attr("province", function (d) {
                    return zStats.get(d.id);
                })
                .attr("id", function (d) {
                    return d.id;
                })
                .on('mouseover', function (d) {
                    d3.select("div")
                            .text(zStats.get(d.id))
                            .classed("greyed", false)
                })

                .on("mouseout",  function(d) {
                    d3.select("div")
                            .text('mouseover the maps to see province')
                            .classed("greyed", true)
                })
            ;
    }

</script>
</body>
</html>
Comments

An Angular directive for including external markdown files

This angular directive includes external markdown files, compiling them to HTML at runtime using marked.js.

I coded this as part of my notCMS.js project - which aims to offer basic content editing functionality via external markdown files to statically hosted (GitHub, DropBpox) websites.

<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <title>An Angular directive for including external markdown files</title>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/marked/0.3.0/marked.js"></script>

    <script type='text/javascript'>
        //<![CDATA[ 

        var app = angular.module('myApp', []);

        app.directive('markdown', ['$compile', '$http', '$templateCache',
            function($compile, $http, $templateCache) {
                return {
                    restrict: 'AE',
                    replace: true,
                    transclude: false,
                    compile: function(elem, attr) {
                        templateLoader = $http.get(attr.src, {
                            cache: $templateCache
                        })
                        .success(function(md) {
                            elem.html(marked(md));
                        })
                        .error(function(md) {
                            errStr = 'An error occurred processing markdown file <a target="_blank" href="' + attr.src + '">' + attr.src + '</a>: ' + md;
                            console.log(errStr);
                            elem.html(errStr);
                        })
                        ;
                    }
                };
            }
        ])

         //]]>
    </script>

</head>

<body ng-app="myApp">
    <markdown src="copy_1.md">This content will be replaced my markdown</markdown>
    n
    <p markdown src="copy_2.md" />

    <div markdown src="copy_3.md" />
</body>

</html>

Demo here - http://ianscrivener.com/markdown-include-angular-directive/

Soucrecocde here - https://github.com/ianscrivener/markdown-include-angular-directive

Comments

IFTTT now supports GitHub

IFTTT (if this then that) is cool glue for a whole range of mashups between different web services & social media. It lets you create 'recipres' that watch for actions then trigger events. No code required! For example: Add an note in Evernote when you are mentioned on Twitter.

The possibilities are quite endless and to help you get the creative juices flowing IFTTT has a pile of samples.

Today's announcement that IFTTT now supports GitHub brought a collective "cool" from devleopers universally.

IFTTT

Comments