1

Add display type to UI

This commit is contained in:
Alex Yatskov 2015-03-21 20:46:20 +09:00
parent d6bb53e870
commit cab7eb21bb
4 changed files with 97 additions and 56 deletions

View File

@ -19,7 +19,7 @@
<div class="model-header">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h3 class="modal-title">User Profile Editor</h3>
<h3 class="modal-title">Personal Profile Editor</h3>
</div>
<div class="modal-body">
<iframe src="/profile.html" width="100%" height="250" frameborder="0"></iframe>
@ -57,13 +57,20 @@
<label for="maxResults">Max results</label>
<input class="form-control" type="number" value="100" id="maxResults">
</div>
<div class="form-group">
<label for="displayType">Display type</label>
<select id="displayType" class="form-control">
<option value="density">Density</option>
<option value="compatibility">Compatibility</option>
</select>
</div>
<div class="checkbox">
<label><input type="checkbox" id="useLocalScale" checked="checked">Use local scale</label>
</div>
<div class="checkbox">
<label><input type="checkbox" id="useRelativeScale" checked="checked">Use relative scale</label>
</div>
<button type="button" data-toggle="modal" data-target="#profileDlg" class="btn btn-primary">Edit profile</button>
<button type="button" data-toggle="modal" data-target="#profileDlg" class="btn btn-primary">Edit personal profile</button>
</div>
</div>
</div>

View File

@ -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 || {}));

View File

@ -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 = {};

View File

@ -53,13 +53,23 @@ function walkMatches(data, features, minScore, callback) {
}
}
function countRecords(data, features, minScore) {
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) {