Skip to content

Commit

Permalink
Merge pull request #9 from fbuchinger/image-metrics
Browse files Browse the repository at this point in the history
Image metrics
  • Loading branch information
fbuchinger authored Feb 7, 2017
2 parents 8fbe3d4 + f1127d2 commit 8af2a1b
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 15 deletions.
85 changes: 73 additions & 12 deletions src/layoutstats.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,30 @@
}



this.measure = function (node, options){
var nodes = self._getVisibleTextNodes(node);
var measurements = {};
self.metrics.forEach(function (metric) {
var key = metric.name;
var value = nodes.map(metric.value);
var value;

if (metric.selector){
var selectedItems = selectors[metric.selector](document);
value = Array.prototype.map.call(selectedItems,metric.value);
}
else {
value = nodes.map(metric.value);
}


if (metric.reduce) {

var metricReducers = (Array.isArray(metric.reduce) ? metric.reduce : [metric.reduce]);

metricReducers.forEach(function (metricReducer) {
var reducer = (reducers[metricReducer] ? reducers[metricReducer] : metricReducer);
//initialValue is an object property -> passed by reference, we need to clone it for a "clean" copy
var clonedInitial = JSON.parse(JSON.stringify(reducer.initialValue));
var reducedValue = value.reduce(reducer.fn, clonedInitial);
var reducer = (LayoutStats.getReducer(metricReducer) ? LayoutStats.getReducer(metricReducer) : metricReducer);
var reducedValue = value.reduce(reducer.fn, reducer.initialValue());
var reduceKey = metric.group + (reducer.metricPrefix || '') + key + (reducer.metricSuffix || '');
measurements[reduceKey] = reducedValue;
});
Expand Down Expand Up @@ -86,19 +95,32 @@ function sortKeysByValue (obj){
});
}

var selectors = {
'images': function (document){
//filter all images greater 50x50px;
return Array.prototype.filter.call(document.images,function(img){
return img.width > 50 && img.height > 50;
})
}
}

function emptyObject (){
return {}
}

var reducers = {
'sum': {
fn: function (acc, item){
return acc + item;
},
initialValue: 0
initialValue: function(){return 0}
},
'unique': {
fn: function (acc, item){
acc = incrementAcc(acc, item);
return acc;
},
initialValue: {},
initialValue: emptyObject,
metricPrefix: 'Unique',
metricSuffix: 's'
},
Expand All @@ -112,7 +134,7 @@ var reducers = {
}
return acc;
},
initialValue: {},
initialValue: emptyObject,
metricPrefix: 'Unique',
metricSuffix: 'Count'
},
Expand All @@ -125,7 +147,7 @@ var reducers = {
}
return acc;
},
initialValue: {},
initialValue: emptyObject,
metricSuffix: 'List',
},
'top': {
Expand All @@ -137,7 +159,7 @@ var reducers = {
}
return acc;
},
initialValue: {},
initialValue: emptyObject,
metricPrefix: "Top"
},
'average': {
Expand All @@ -154,13 +176,20 @@ var reducers = {
}
return acc;
},
initialValue: {},
initialValue: emptyObject,
metricPrefix: "Average"
}
}

LayoutStats.reducers = reducers;

LayoutStats.getReducer = function (reducerName){
if (this.reducers[reducerName]){
var reducer = this.reducers[reducerName];
return reducer;
}
}

var rgbToHex = function (rgbStr){

var rgbParts = rgbStr.split('(')[1].split(',').map(function(rgbPart){
Expand Down Expand Up @@ -279,10 +308,42 @@ LayoutStats.addMetric({
fn: function (acc, item){
return (acc + item).slice(0,1000);
},
initialValue: ''
initialValue: function (){
return '';
}
}
});

LayoutStats.addMetric({
group:"image",
selector: "images",
name: "Area",
value: function (img){
return img.width * img.height;
},
reduce: 'sum'
});

LayoutStats.addMetric({
group:"image",
selector: "images",
name: "Dimensions",
value: function (img){
return {key: img.width + ' x ' + img.height, value: 1};
},
reduce: ['unique','uniquecount','uniquekeylist','top']
});

LayoutStats.addMetric({
group:"image",
selector: "images",
name: "Count",
value: function (img){
return 1;
},
reduce: ['sum']
});



} )( window, document );
1 change: 1 addition & 0 deletions test/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@
<script src="setup.js"></script>
<script src="spec/layoutstats.reducers.js"></script>
<script src="spec/jquery.layoutstats.textmetrics.spec.js"></script>
<script src="spec/layoutstats.imagemetrics.js"></script>
</body>
</html>
2 changes: 1 addition & 1 deletion test/spec/jquery.layoutstats.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@
} );


}( jQuery, QUnit ) );
} );
32 changes: 32 additions & 0 deletions test/spec/layoutstats.imagemetrics.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
( function( window, QUnit ) {

"use strict";

var testCanvas = document.getElementById('testCanvas');

QUnit.module("Layoutstats Image Metrics", {
beforeEach: function () {

},
afterEach: function () {
// we empty the testcanvas
testCanvas.innerHTML = '';
}
});

function injectAndGetLayoutStats(htmlStr){
testCanvas.innerHTML = htmlStr;
return layoutstats(testCanvas);
}

QUnit.test("measure the area of all images on the page using the imageMegapixelArea metric. It ", function (assert) {
var ls = layoutstats(window.document.body);
var png1px = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==";
assert.notEqual(ls.imageArea, undefined, 'is available in the layoutstats object');
ls = injectAndGetLayoutStats('<img width="150" height="300" src="'+png1px+'">');
assert.equal(ls.imageArea,45000,'measures the dimension of a single image with width and height attributes' );
ls = injectAndGetLayoutStats('<img style="width:150px;height:300px;" src="'+png1px+'">');
assert.equal(ls.imageArea,45000,'measures the dimension of a single image with width and height set by css' );
});

})( window, QUnit );
4 changes: 2 additions & 2 deletions test/spec/layoutstats.reducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

QUnit.test( "The average reducer ", function( assert ) {
var lineheightsByCharacters = [{"key":"1.50px","value":20},{"key":"1.50px","value":12},{"key":"2.25px","value":4},{"key":"2.25px","value":4}];
var average = LayoutStats.reducers.average;
assert.equal(lineheightsByCharacters.reduce(average.fn, average.initialValue), 1.65, "can calculate the average of a key/value based metric");
var average = LayoutStats.getReducer("average");
assert.equal(lineheightsByCharacters.reduce(average.fn, average.initialValue()), 1.65, "can calculate the average of a key/value based metric");

})

Expand Down

0 comments on commit 8af2a1b

Please sign in to comment.