Cleanup
This commit is contained in:
parent
ae5dd26df3
commit
4fac0774cd
12
server.go
12
server.go
@ -59,8 +59,8 @@ func executeQuery(rw http.ResponseWriter, req *http.Request) {
|
||||
sorter.sort()
|
||||
|
||||
response := jsonQueryResponse{
|
||||
Count: len(foundEntries),
|
||||
Columns: make(map[string]jsonColumn),
|
||||
Count: len(foundEntries),
|
||||
MinScore: request.MinScore,
|
||||
Records: make([]jsonRecord, 0)}
|
||||
|
||||
@ -68,10 +68,10 @@ func executeQuery(rw http.ResponseWriter, req *http.Request) {
|
||||
mode, _ := modes[name]
|
||||
|
||||
column := jsonColumn{
|
||||
Bracket: jsonBracket{Max: -1, Min: 1},
|
||||
Bracket: jsonBracket{Max: -1.0, Min: 1.0},
|
||||
Mode: mode.String(),
|
||||
Value: value,
|
||||
Steps: request.Resolution}
|
||||
Steps: request.Resolution,
|
||||
Value: value}
|
||||
|
||||
hints := project(
|
||||
entries,
|
||||
@ -216,7 +216,6 @@ func removeCategory(rw http.ResponseWriter, req *http.Request) {
|
||||
}
|
||||
|
||||
_, err := db.Exec("DELETE FROM categories WHERE id = (?)", request.Id)
|
||||
|
||||
js, err := json.Marshal(jsonRemoveCategoryResponse{err == nil})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@ -295,8 +294,7 @@ func main() {
|
||||
flag.Parse()
|
||||
|
||||
var err error
|
||||
db, err = sql.Open("mysql", *dataSrc)
|
||||
if err != nil {
|
||||
if db, err = sql.Open("mysql", *dataSrc); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
@ -11,7 +11,7 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container-fluid">
|
||||
<div class="container">
|
||||
<!-- busy spinner -->
|
||||
<div class="page-header">
|
||||
<img id="spinner" alt="loading" class="pull-right" src="images/spinner.gif" style="display: none;" width="32" height="32">
|
||||
@ -80,14 +80,7 @@
|
||||
|
||||
<!-- visualizer -->
|
||||
<div class="col-md-9">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<big>Visualizer</big>
|
||||
</div>
|
||||
<div class="panel-body text-center">
|
||||
<svg id="svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="800" height="500"></svg>
|
||||
</div>
|
||||
</div>
|
||||
<svg id="svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="800" height="500"></svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -92,18 +92,18 @@
|
||||
var _tickSize = 5;
|
||||
var _width = 125;
|
||||
|
||||
var _indicatorAnim = null;
|
||||
var _bracketAnim = null;
|
||||
var _canvas = params.canvas;
|
||||
var _data = params.data;
|
||||
var _index = params.index;
|
||||
var _name = params.name;
|
||||
var _valueTrans = params.data.value;
|
||||
var _bracketTrans = params.data.bracket;
|
||||
var _onStateChanged = params.onStateChanged;
|
||||
var _range = params.range;
|
||||
var _scale = params.scale;
|
||||
var _elements = {};
|
||||
var _indicatorAnim = null;
|
||||
var _bracketAnim = null;
|
||||
var _canvas = params.canvas;
|
||||
var _data = params.data;
|
||||
var _index = params.index;
|
||||
var _name = params.name;
|
||||
var _valueTrans = params.data.value;
|
||||
var _bracketTrans = params.data.bracket;
|
||||
var _stateChanged = params.stateChanged;
|
||||
var _range = params.range;
|
||||
var _scale = params.scale;
|
||||
var _elements = {};
|
||||
|
||||
function createShapes() {
|
||||
// indicatorBg
|
||||
@ -298,23 +298,25 @@
|
||||
}
|
||||
|
||||
function updateMode() {
|
||||
var modeText = '( ' + _data.mode + ' )';
|
||||
var modes = {'product': 'importance', 'distance': 'similarity'};
|
||||
var mode = modes[_data.mode];
|
||||
|
||||
if (_.has(_elements, 'mode')) {
|
||||
_elements.mode.attr({
|
||||
text: modeText
|
||||
text: mode
|
||||
});
|
||||
}
|
||||
else {
|
||||
_elements.mode = _canvas.text(
|
||||
(_width - _bracketSize) / 2,
|
||||
_height - _panelSize / 4,
|
||||
modeText
|
||||
mode
|
||||
).attr({
|
||||
'dominant-baseline': 'middle',
|
||||
'text-anchor': 'middle',
|
||||
cursor: 'hand',
|
||||
'fill': _modeColor
|
||||
'text-decoration': 'underline',
|
||||
'fill': _modeColor,
|
||||
cursor: 'hand'
|
||||
}).click(modeClick);
|
||||
}
|
||||
}
|
||||
@ -354,8 +356,8 @@
|
||||
_data.value = _range.clamp(value);
|
||||
_data.mode = mode;
|
||||
|
||||
if (_onStateChanged) {
|
||||
_onStateChanged(_name, _data.value, _data.mode);
|
||||
if (_stateChanged) {
|
||||
_stateChanged(_name, _data.value, _data.mode);
|
||||
}
|
||||
|
||||
animateIndicator(_valueTrans, _data.value);
|
||||
@ -493,13 +495,13 @@
|
||||
//
|
||||
|
||||
grapher.Grapher = function(params) {
|
||||
var _canvas = params.canvas;
|
||||
var _columns = {};
|
||||
var _data = {};
|
||||
var _range = new Range(-1.0, 1.0);
|
||||
var _useLocalScale = params.useLocalScale || false;
|
||||
var _displayType = params.displayType || 'density';
|
||||
var _onStateChanged = params.onStateChanged;
|
||||
var _canvas = params.canvas;
|
||||
var _columns = {};
|
||||
var _data = {};
|
||||
var _range = new Range(-1.0, 1.0);
|
||||
var _useLocalScale = params.useLocalScale || false;
|
||||
var _displayType = params.displayType || 'density';
|
||||
var _stateChanged = params.stateChanged;
|
||||
|
||||
function processHintParameters(columns) {
|
||||
var displayTypes = {compatibility: 'compatibility', density: 'count'};
|
||||
@ -557,13 +559,13 @@
|
||||
}
|
||||
else {
|
||||
_columns[name] = new Column({
|
||||
onStateChanged: _onStateChanged,
|
||||
range: _range,
|
||||
canvas: _canvas,
|
||||
data: columnData,
|
||||
name: name,
|
||||
scale: scale,
|
||||
index: index++,
|
||||
stateChanged: _stateChanged,
|
||||
range: _range,
|
||||
canvas: _canvas,
|
||||
data: columnData,
|
||||
name: name,
|
||||
scale: scale,
|
||||
index: index++,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
var _ctx = {};
|
||||
|
||||
function onStateChanged(name, value, mode) {
|
||||
function stateChanged(name, value, mode) {
|
||||
_ctx.query.features[name] = value;
|
||||
_ctx.query.modes[name] = mode;
|
||||
|
||||
@ -35,7 +35,7 @@
|
||||
}, 'json');
|
||||
}
|
||||
|
||||
function onReady(geo) {
|
||||
function ready(geo) {
|
||||
_ctx = {
|
||||
sortKey: 'score',
|
||||
sortAsc: false,
|
||||
@ -98,10 +98,10 @@
|
||||
$.post('/query', JSON.stringify(_ctx.query), function(results) {
|
||||
if (!_.has(_ctx, 'grapher')) {
|
||||
_ctx.grapher = new grapher.Grapher({
|
||||
canvas: new Snap('#svg'),
|
||||
onStateChanged: onStateChanged,
|
||||
displayType: $('#displayType').val(),
|
||||
useLocalScale: $('#useLocalScale').is(':checked')
|
||||
canvas: new Snap('#svg'),
|
||||
stateChanged: stateChanged,
|
||||
displayType: $('#displayType').val(),
|
||||
useLocalScale: $('#useLocalScale').is(':checked')
|
||||
});
|
||||
|
||||
$('#useLocalScale').click(function() {
|
||||
@ -200,13 +200,13 @@
|
||||
ready: function() {
|
||||
if (navigator.geolocation) {
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
function(geo) { onReady(geo); },
|
||||
function(err) { onReady(null); },
|
||||
function(geo) { ready(geo); },
|
||||
function(err) { ready(null); },
|
||||
{ enableHighAccuracy: true }
|
||||
);
|
||||
}
|
||||
else {
|
||||
onReady(null);
|
||||
ready(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
34
types.go
34
types.go
@ -22,18 +22,20 @@
|
||||
|
||||
package main
|
||||
|
||||
import "sort"
|
||||
|
||||
type modeType int
|
||||
|
||||
const (
|
||||
ModeTypeNone modeType = iota
|
||||
ModeTypeProduct
|
||||
ModeTypeDistance
|
||||
import (
|
||||
"errors"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type featureMap map[string]float64
|
||||
type modeMap map[string]modeType
|
||||
type records []record
|
||||
type modeType int
|
||||
|
||||
const (
|
||||
modeTypeProd = iota + 1
|
||||
modeTypeDist
|
||||
)
|
||||
|
||||
type jsonAccessRequest struct {
|
||||
Id int `json:"id"`
|
||||
@ -150,8 +152,6 @@ type record struct {
|
||||
url string
|
||||
}
|
||||
|
||||
type records []record
|
||||
|
||||
type recordSorter struct {
|
||||
ascending bool
|
||||
entries records
|
||||
@ -198,22 +198,22 @@ func (s recordSorter) Swap(i, j int) {
|
||||
|
||||
func (m modeType) String() string {
|
||||
switch m {
|
||||
case ModeTypeProduct:
|
||||
case modeTypeProd:
|
||||
return "product"
|
||||
case ModeTypeDistance:
|
||||
case modeTypeDist:
|
||||
return "distance"
|
||||
default:
|
||||
return "invalid"
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func strToModeType(mode string) modeType {
|
||||
func parseModeType(mode string) (modeType, error) {
|
||||
switch mode {
|
||||
case "product":
|
||||
return ModeTypeProduct
|
||||
return modeTypeProd, nil
|
||||
case "distance":
|
||||
return ModeTypeDistance
|
||||
return modeTypeDist, nil
|
||||
default:
|
||||
return ModeTypeNone
|
||||
return 0, errors.New("invalid mode type")
|
||||
}
|
||||
}
|
||||
|
39
util.go
39
util.go
@ -40,8 +40,9 @@ func fixFeatures(features featureMap) featureMap {
|
||||
"atmospheric": 0.0}
|
||||
|
||||
for name := range fixedFeatures {
|
||||
value, _ := features[name]
|
||||
fixedFeatures[name] = value
|
||||
if value, ok := features[name]; ok {
|
||||
fixedFeatures[name] = value
|
||||
}
|
||||
}
|
||||
|
||||
return fixedFeatures
|
||||
@ -49,42 +50,48 @@ func fixFeatures(features featureMap) featureMap {
|
||||
|
||||
func fixModes(modes map[string]string) modeMap {
|
||||
fixedModes := modeMap{
|
||||
"nearby": ModeTypeProduct,
|
||||
"accessible": ModeTypeProduct,
|
||||
"delicious": ModeTypeProduct,
|
||||
"accommodating": ModeTypeProduct,
|
||||
"affordable": ModeTypeProduct,
|
||||
"atmospheric": ModeTypeProduct}
|
||||
"nearby": modeTypeProd,
|
||||
"accessible": modeTypeProd,
|
||||
"delicious": modeTypeProd,
|
||||
"accommodating": modeTypeProd,
|
||||
"affordable": modeTypeProd,
|
||||
"atmospheric": modeTypeProd}
|
||||
|
||||
for name := range fixedModes {
|
||||
if value, ok := modes[name]; ok {
|
||||
fixedModes[name] = strToModeType(value)
|
||||
if mode, err := parseModeType(value); err == nil {
|
||||
fixedModes[name] = mode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fixedModes
|
||||
}
|
||||
|
||||
func innerProduct(features1 featureMap, features2 featureMap) float64 {
|
||||
var result float64
|
||||
func distance(features1 featureMap, features2 featureMap) float64 {
|
||||
var sum float64
|
||||
|
||||
for key, value1 := range features1 {
|
||||
value2, _ := features2[key]
|
||||
result += value1 * value2
|
||||
sum += math.Pow(value1-value2, 2)
|
||||
}
|
||||
|
||||
return result
|
||||
return math.Sqrt(sum)
|
||||
}
|
||||
|
||||
func compare(features1 featureMap, features2 featureMap, modes modeMap) float64 {
|
||||
var result float64
|
||||
|
||||
for key, value1 := range features1 {
|
||||
value2, _ := features2[key]
|
||||
|
||||
switch mode, _ := modes[key]; mode {
|
||||
case ModeTypeDistance:
|
||||
case modeTypeDist:
|
||||
result += 1 - math.Abs(value1-value2)
|
||||
default:
|
||||
case modeTypeProd:
|
||||
result += value1 * value2
|
||||
default:
|
||||
log.Fatal("unsupported compare mode")
|
||||
}
|
||||
}
|
||||
|
||||
@ -228,7 +235,7 @@ func computeRecordPopularity(entries records, context queryContext) {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
groupSum += innerProduct(recordProfile, context.profile)
|
||||
groupSum += distance(recordProfile, context.profile)
|
||||
groupCount++
|
||||
}
|
||||
if err := historyRows.Err(); err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user