mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-26 06:04:05 -08:00
Add fuzzy search to /graph textarea (#2081)
* Add fuzzy search to /graph textarea We have a few thousands different metrics and looking up some of them can be quite annoying with the simple string matching. This patch adds a fuzzy search to the textarea lookup box on the /graph page. It uses a small neat library from github.com/mattyork/fuzzy. * Add fuzzy lib to NOTICE and re-build assets Previously built assets changed the mode.
This commit is contained in:
parent
630b96c5f3
commit
50f8e35c54
6
NOTICE
6
NOTICE
|
@ -18,6 +18,12 @@ Original written by @mdo and @fat
|
||||||
Copyright 2014 Bass Jobsen @bassjobsen
|
Copyright 2014 Bass Jobsen @bassjobsen
|
||||||
Licensed under the Apache License, Version 2.0
|
Licensed under the Apache License, Version 2.0
|
||||||
|
|
||||||
|
fuzzy
|
||||||
|
https://github.com/mattyork/fuzzy
|
||||||
|
Original written by @mattyork
|
||||||
|
Copyright 2012 Matt York
|
||||||
|
Licensed under the MIT License
|
||||||
|
|
||||||
bootstrap-datetimepicker.js
|
bootstrap-datetimepicker.js
|
||||||
http://www.eyecon.ro/bootstrap-datepicker
|
http://www.eyecon.ro/bootstrap-datepicker
|
||||||
Copyright 2012 Stefan Petre
|
Copyright 2012 Stefan Petre
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -196,9 +196,44 @@ Prometheus.Graph.prototype.populateInsertableMetrics = function() {
|
||||||
self.insertMetric[0].options.add(new Option(metrics[i], metrics[i]));
|
self.insertMetric[0].options.add(new Option(metrics[i], metrics[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.fuzzyResult = {
|
||||||
|
query: null,
|
||||||
|
result: null,
|
||||||
|
map: {}
|
||||||
|
}
|
||||||
|
|
||||||
self.expr.typeahead({
|
self.expr.typeahead({
|
||||||
source: metrics,
|
source: metrics,
|
||||||
items: "all"
|
items: "all",
|
||||||
|
matcher: function(item) {
|
||||||
|
// If we have result for current query, skip
|
||||||
|
if (!self.fuzzyResult.query || self.fuzzyResult.query !== this.query) {
|
||||||
|
self.fuzzyResult.query = this.query;
|
||||||
|
self.fuzzyResult.map = {};
|
||||||
|
self.fuzzyResult.result = fuzzy.filter(this.query.replace('_', ' '), metrics, {
|
||||||
|
pre: '<strong>',
|
||||||
|
post: '</strong>',
|
||||||
|
extract: function(el) { return el.replace('_', ' ') }
|
||||||
|
});
|
||||||
|
self.fuzzyResult.result.forEach(function(r) {
|
||||||
|
self.fuzzyResult.map[r.original] = r;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return item in self.fuzzyResult.map;
|
||||||
|
},
|
||||||
|
|
||||||
|
sorter: function(items) {
|
||||||
|
items.sort(function(a,b) {
|
||||||
|
var i = self.fuzzyResult.map[b].score - self.fuzzyResult.map[a].score;
|
||||||
|
return i === 0 ? a.localeCompare(b) : i;
|
||||||
|
});
|
||||||
|
return items;
|
||||||
|
},
|
||||||
|
|
||||||
|
highlighter: function (item) {
|
||||||
|
return $('<div>' + self.fuzzyResult.map[item].string.replace(' ', '_') + '</div>')
|
||||||
|
},
|
||||||
});
|
});
|
||||||
// This needs to happen after attaching the typeahead plugin, as it
|
// This needs to happen after attaching the typeahead plugin, as it
|
||||||
// otherwise breaks the typeahead functionality.
|
// otherwise breaks the typeahead functionality.
|
||||||
|
|
26
web/ui/static/vendor/fuzzy.js
vendored
Normal file
26
web/ui/static/vendor/fuzzy.js
vendored
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright (c) 2012 Matt York
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person
|
||||||
|
// obtaining a copy of this software and associated documentation
|
||||||
|
// files (the "Software"), to deal in the Software without
|
||||||
|
// restriction, including without limitation the rights to use,
|
||||||
|
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following
|
||||||
|
// conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be
|
||||||
|
// included in all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
// OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// https://github.com/mattyork/fuzzy/blob/3613086aa40c180ca722aeaf48cef575dc57eb5d/fuzzy-min.js
|
||||||
|
|
||||||
|
(function(){var root=this;var fuzzy={};if(typeof exports!=="undefined"){module.exports=fuzzy}else{root.fuzzy=fuzzy}fuzzy.simpleFilter=function(pattern,array){return array.filter(function(str){return fuzzy.test(pattern,str)})};fuzzy.test=function(pattern,str){return fuzzy.match(pattern,str)!==null};fuzzy.match=function(pattern,str,opts){opts=opts||{};var patternIdx=0,result=[],len=str.length,totalScore=0,currScore=0,pre=opts.pre||"",post=opts.post||"",compareString=opts.caseSensitive&&str||str.toLowerCase(),ch;pattern=opts.caseSensitive&&pattern||pattern.toLowerCase();for(var idx=0;idx<len;idx++){ch=str[idx];if(compareString[idx]===pattern[patternIdx]){ch=pre+ch+post;patternIdx+=1;currScore+=1+currScore}else{currScore=0}totalScore+=currScore;result[result.length]=ch}if(patternIdx===pattern.length){totalScore=compareString===pattern?Infinity:totalScore;return{rendered:result.join(""),score:totalScore}}return null};fuzzy.filter=function(pattern,arr,opts){if(!arr||arr.length===0){return[]}if(typeof pattern!=="string"){return arr}opts=opts||{};return arr.reduce(function(prev,element,idx,arr){var str=element;if(opts.extract){str=opts.extract(element)}var rendered=fuzzy.match(pattern,str,opts);if(rendered!=null){prev[prev.length]={string:rendered.rendered,score:rendered.score,index:idx,original:element}}return prev},[]).sort(function(a,b){var compare=b.score-a.score;if(compare)return compare;return a.index-b.index})}})();
|
|
@ -9,6 +9,7 @@
|
||||||
<script src="{{ pathPrefix }}/static/vendor/rickshaw/rickshaw.min.js"></script>
|
<script src="{{ pathPrefix }}/static/vendor/rickshaw/rickshaw.min.js"></script>
|
||||||
<script src="{{ pathPrefix }}/static/vendor/bootstrap-datetimepicker/bootstrap-datetimepicker.js"></script>
|
<script src="{{ pathPrefix }}/static/vendor/bootstrap-datetimepicker/bootstrap-datetimepicker.js"></script>
|
||||||
<script src="{{ pathPrefix }}/static/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js"></script>
|
<script src="{{ pathPrefix }}/static/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js"></script>
|
||||||
|
<script src="{{ pathPrefix }}/static/vendor/fuzzy.js"></script>
|
||||||
|
|
||||||
<script src="{{ pathPrefix }}/static/vendor/js/handlebars.js"></script>
|
<script src="{{ pathPrefix }}/static/vendor/js/handlebars.js"></script>
|
||||||
<script src="{{ pathPrefix }}/static/vendor/js/jquery.selection.js"></script>
|
<script src="{{ pathPrefix }}/static/vendor/js/jquery.selection.js"></script>
|
||||||
|
|
Loading…
Reference in a new issue