diff --git a/client/index.html b/client/index.html index 80d9930..d2bb188 100644 --- a/client/index.html +++ b/client/index.html @@ -19,7 +19,7 @@
+
+ + +
- +
diff --git a/client/scripts/grapher.js b/client/scripts/grapher.js index c9268e0..a433f60 100644 --- a/client/scripts/grapher.js +++ b/client/scripts/grapher.js @@ -70,21 +70,21 @@ // function Column(params) { - var _backdropColor = '#eeeeec'; - var _borderColor = '#babdb6'; - var _fillColorNeg = '#3465a4'; - var _fillColorPos = '#cc0000'; - var _panelColor = '#babdb6'; - var _tickColor = '#888a85'; + var _backdropColor = '#eeeeec'; + var _borderColor = '#babdb6'; + var _fillColorNeg = '#3465a4'; + var _fillColorPos = '#cc0000'; + var _panelColor = '#babdb6'; + var _tickColor = '#888a85'; - var _densitySize = 10; - var _desatOffset = -0.3; - var _height = 500; - var _padding = 5; - var _panelSize = 20; - var _tickSize = 5; - var _width = 100; - var _easeTime = 400; + var _densitySize = 10; + var _desatOffset = -0.3; + var _height = 500; + var _padding = 5; + var _panelSize = 20; + var _tickSize = 5; + var _width = 100; + var _easeTime = 400; var _animation = null; var _canvas = params.canvas; @@ -160,8 +160,12 @@ } function updateDensity() { - var fill = _data.hints.length === 0 ? _backdropColor : _canvas.gradient(decimateHints()); - _elements.density.attr({ fill: fill }); + var fill = _backdropColor; + if (_data.hints.length > 0) { + fill = _canvas.gradient(decimateHints()); + } + + _elements.density.attr({fill: fill}); } function decimateHints() { @@ -197,15 +201,15 @@ var stepMax = _range.max - stepSize * i; var stepMin = stepMax - stepSize; - var hintCount = 0; + var hintValue = 0; for (var j = 0, count = _data.hints.length; j < count; ++j) { var hint = _data.hints[j]; if (hint.sample > stepMin && hint.sample <= stepMax) { - hintCount += hint.count; + hintValue += hint.rating; } } - hintGroups.push(hintCount); + hintGroups.push(hintValue); } return hintGroups; @@ -307,18 +311,38 @@ var _steps = params.steps || 20; var _useLocalScale = params.useLocalScale || true; var _useRelativeScale = params.useRelativeScale || true; + var _displayType = params.displayType || 'density'; var _onValueChanged = params.onValueChanged; - function computeLocalScale(hints) { - var counts = _.pluck(hints, 'count'); - var min = _useRelativeScale ? _.min(counts) : 0; - return new Range(min, _.max(counts)); + function processHintParameters(columns) { + var displayTypes = {compatibility: 'compatibility', density: 'count'}; + var statKey = displayTypes[_displayType]; + + for (var name in columns) { + var column = columns[name]; + for (var i = 0, count = column.hints.length; i < count; ++i) { + column.hints[i].rating = column.hints[i].stats[statKey]; + } + } } - function computeGlobalScale(hintData) { + function computeLocalScale(column) { + var ratings = _.map(column.hints, function(hint) { + return hint.rating; + }); + + var min = 0; + if (_useRelativeScale) { + min = _.min(ratings); + } + + return new Range(min, _.max(ratings)); + } + + function computeGlobalScale(columns) { var globalScale = null; - for (var i = 0, count = hintData.length; i < count; ++i) { - var localScale = computeLocalScale(hintData[i]); + for (var i = 0, count = columns.length; i < count; ++i) { + var localScale = computeLocalScale(columns[i]); if (globalScale) { globalScale.include(localScale); } @@ -331,17 +355,18 @@ } this.setColumns = function(columns) { + processHintParameters(columns); + var scale = 0; if (!_useLocalScale) { - var hintData = _.pluck(columns, 'hints'); - scale = computeGlobalScale(hintData); + scale = computeGlobalScale(columns); } var index = 0; for (var name in columns) { var data = _data[name] = columns[name]; if (_useLocalScale) { - scale = computeLocalScale(data.hints); + scale = computeLocalScale(data); } var column = _columns[name]; @@ -376,5 +401,12 @@ this.setColumns(_data); } }; + + this.setDisplayType = function(displayType) { + if (displayType != _displayType) { + _displayType = displayType; + this.setColumns(_data); + } + }; }; }(window.grapher = window.grapher || {})); diff --git a/client/scripts/search.js b/client/scripts/search.js index cf7c5ae..987e8e7 100644 --- a/client/scripts/search.js +++ b/client/scripts/search.js @@ -63,7 +63,7 @@ function onSearch() { _ctx.query = { features: _ctx.query.features || {}, - range: { min: -1.0, max: 1.0 }, + range: {min: -1.0, max: 1.0}, profile: getProfile(), walkingDist: parseFloat($('#walkingDist').val()), minScore: parseFloat($('#minScore').val()), @@ -85,18 +85,21 @@ steps: _ctx.query.hintSteps, range: _ctx.query.range, onValueChanged: onAdjust, - useLocalScale: true, - useRelativeScale: true + displayType: $('#displayType').val(), + useLocalScale: $('#useLocalScale').is(':checked'), + useRelativeScale: $('#useRelativeScale').is(':checked') }); $('#useLocalScale').click(function() { - var useLocalScale = $('#useLocalScale').is(':checked'); - _ctx.grapher.setUseLocalScale(useLocalScale); + _ctx.grapher.setUseLocalScale($('#useLocalScale').is(':checked')); }); $('#useRelativeScale').click(function() { - var useRelativeScale = $('#useRelativeScale').is(':checked'); - _ctx.grapher.setUseRelativeScale(useRelativeScale); + _ctx.grapher.setUseRelativeScale($('#useRelativeScale').is(':checked')); + }); + + $('#displayType').change(function() { + _ctx.grapher.setDisplayType($('#displayType').val()); }); var columns = {}; diff --git a/server/search.js b/server/search.js index e1155d6..3899267 100644 --- a/server/search.js +++ b/server/search.js @@ -53,13 +53,23 @@ function walkMatches(data, features, minScore, callback) { } } -function countRecords(data, features, minScore) { - var count = 0; +function statRecords(data, features, minScore) { + var compatibility = 0; + var count = 0; + walkMatches(data, features, minScore, function(record, score) { + compatibility += record.compatibility; ++count; }); - return count; + if (count > 0) { + compatibility /= count; + } + + return { + compatibility: compatibility, + count: count + }; } function findRecords(data, features, minScore) { @@ -104,7 +114,7 @@ function project(data, features, feature, minScore, range, steps) { sample[feature] = position; results.push({ sample: position, - count: countRecords(data, sample, minScore) + stats: statRecords(data, sample, minScore) }); }); @@ -125,7 +135,7 @@ function buildHints(data, features, feature, minScore, range, steps) { _.each(projection, function(result) { hints.push({ sample: result.sample, - count: result.count + stats: result.stats }); }); @@ -193,8 +203,6 @@ function computeRecordGeo(records, context) { } function computeRecordPopularity(records, context, callback) { - var scoreMax = 0; - async.each( records, function(record, callback) { @@ -215,8 +223,6 @@ function computeRecordPopularity(records, context, callback) { }); var groupScore = innerProduct(context.profile, reviewFeatures); - scoreMax = Math.max(scoreMax, groupScore); - callback(err, groupScore); } ); @@ -228,13 +234,7 @@ function computeRecordPopularity(records, context, callback) { scoreAvg = scoreSum / groupScores.length; } - if (scoreMax !== 0) { - record.features.compatibility = scoreAvg / scoreMax; - } - else { - record.features.compatibility = 0; - } - + record.compatibility = scoreAvg; callback(err); } ); @@ -269,8 +269,7 @@ function fixupFeatures(features) { 'affordable', 'atmospheric', 'nearby', - 'accessible', - 'compatible' + 'accessible' ]; if (!features) {