Clustering now filters the results
This commit is contained in:
parent
376880c0c1
commit
fba5f7df8b
3 changed files with 47 additions and 22 deletions
|
@ -24,8 +24,9 @@
|
||||||
<main>
|
<main>
|
||||||
<div id="visualization"></div>
|
<div id="visualization"></div>
|
||||||
<div id="docs">
|
<div id="docs">
|
||||||
<div style="grid-column: 1 / 5; text-align: center; padding: 2em;
|
<div style="grid-column: 1 / calc(var(--columns) + 1);
|
||||||
background: #CCC;">
|
text-align: center; padding: 2em;
|
||||||
|
background: #CCC;">
|
||||||
Input your query in the search box above and then press Enter.
|
Input your query in the search box above and then press Enter.
|
||||||
Result clustering will appear on the left sidebar.
|
Result clustering will appear on the left sidebar.
|
||||||
</div>
|
</div>
|
||||||
|
@ -34,9 +35,10 @@
|
||||||
<div class="document" id="doc{{ id }}">
|
<div class="document" id="doc{{ id }}">
|
||||||
<a class="img_box" href="{{ url }}" target="_blank"
|
<a class="img_box" href="{{ url }}" target="_blank"
|
||||||
style="background-image: url({{ url }})"/></a>
|
style="background-image: url({{ url }})"/></a>
|
||||||
|
<div class="description">
|
||||||
<h2><a href="{{ site_url }}">{{ title }}</a></h2>
|
<h2><a href="{{ site_url }}">{{ title }}</a></h2>
|
||||||
<h3>By {{ author }}</h3>
|
<h3>By {{ author }}</h3>
|
||||||
{{ description }}
|
{{ description }}</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
47
ui/search.js
47
ui/search.js
|
@ -1,13 +1,17 @@
|
||||||
// vim: set ts=2 sw=2 et tw=80:
|
// vim: set ts=2 sw=2 et tw=80:
|
||||||
|
|
||||||
|
const solr = "http://localhost:8983/solr/photo";
|
||||||
|
|
||||||
|
const q = document.querySelector("#q");
|
||||||
|
const docs = document.querySelector("#docs");
|
||||||
|
const templateHTML = document.querySelector("#document").innerHTML;
|
||||||
|
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
const query = urlParams.get('q');
|
const query = urlParams.get('q');
|
||||||
const solr = "http://localhost:8983/solr/photo";
|
|
||||||
const q = document.querySelector("#q");
|
|
||||||
const templateHTML = document.querySelector("#document").innerHTML;
|
|
||||||
const docs = document.querySelector("#docs");
|
|
||||||
let foamtree = null;
|
let foamtree = null;
|
||||||
let queryResult = null;
|
let queryResult = null;
|
||||||
|
let docMap = {}
|
||||||
|
|
||||||
function buildCard(docData) {
|
function buildCard(docData) {
|
||||||
const emptyOr = s => s ? s : "";
|
const emptyOr = s => s ? s : "";
|
||||||
|
@ -20,21 +24,31 @@ function buildCard(docData) {
|
||||||
.replaceAll("{{ site_url }}", "#");
|
.replaceAll("{{ site_url }}", "#");
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateResults() {
|
function updateResults(docList) {
|
||||||
docs.innerHTML = queryResult.response.docs.map(d => {
|
docs.innerHTML = docList.map(d => {
|
||||||
return buildCard(d);
|
return buildCard(d);
|
||||||
}).reduce((a, b) => a + b, "");
|
}).reduce((a, b) => a.trim() + b.trim(), "");
|
||||||
|
//docs.innerHTML += "<div class='document white'></div>".repeat(28);
|
||||||
|
}
|
||||||
|
|
||||||
|
function filterGroup(info) {
|
||||||
|
if (info.groups.length == 0) {
|
||||||
|
updateResults(queryResult.response.docs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const list = [].concat(...info.groups.map(e => e.docs)).map(id => docMap[id]);
|
||||||
|
updateResults(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function buildQuery(e) {
|
async function buildQuery(e) {
|
||||||
if (e) e.preventDefault();
|
if (e) e.preventDefault();
|
||||||
let docMap = {}
|
|
||||||
|
|
||||||
let list = await fetch(solr + "/clustering?q=" + q.value);
|
let list = await fetch(solr + "/clustering?q=" + q.value);
|
||||||
queryResult = await list.json();
|
queryResult = await list.json();
|
||||||
console.log(queryResult);
|
console.log(queryResult);
|
||||||
|
|
||||||
updateResults();
|
updateResults(queryResult.response.docs);
|
||||||
for (const e of queryResult.response.docs) {
|
for (const e of queryResult.response.docs) {
|
||||||
docMap[e.id] = e;
|
docMap[e.id] = e;
|
||||||
}
|
}
|
||||||
|
@ -43,20 +57,18 @@ async function buildQuery(e) {
|
||||||
return {
|
return {
|
||||||
label: e.labels[0],
|
label: e.labels[0],
|
||||||
weight: e.score,
|
weight: e.score,
|
||||||
groups: e.docs.map(id => {
|
docs: e.docs,
|
||||||
return { id, label: docMap[id].t_title };
|
|
||||||
})
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
if (foamtree === null) {
|
if (foamtree === null) {
|
||||||
foamtree = new CarrotSearchFoamTree({
|
foamtree = new CarrotSearchFoamTree({
|
||||||
id: "visualization",
|
id: "visualization",
|
||||||
layout: "squarified",
|
layout: "squarified",
|
||||||
groupLabelFontFamily: "Fira Sans",
|
groupLabelFontFamily: "Fira Sans",
|
||||||
dataObject: {
|
dataObject: { groups: clusters },
|
||||||
groups: clusters
|
onGroupSelectionChanged: [filterGroup],
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
foamtree.set({ dataObject: { groups: clusters }});
|
foamtree.set({ dataObject: { groups: clusters }});
|
||||||
|
@ -65,7 +77,10 @@ async function buildQuery(e) {
|
||||||
|
|
||||||
if (query) {
|
if (query) {
|
||||||
q.value = query;
|
q.value = query;
|
||||||
buildQuery().catch(console.error);
|
window.addEventListener("load", () => buildQuery().catch(console.error));
|
||||||
}
|
}
|
||||||
|
|
||||||
document.querySelector("#form").addEventListener("submit", buildQuery);
|
document.querySelector("#form").addEventListener("submit", buildQuery);
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
if (foamtree) foamtree.resize()
|
||||||
|
});
|
||||||
|
|
14
ui/style.css
14
ui/style.css
|
@ -52,7 +52,7 @@ main {
|
||||||
flex: 2;
|
flex: 2;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(var(--columns),1fr);
|
grid-template-columns: repeat(var(--columns),1fr);
|
||||||
overflow-y: scroll;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
|
@ -77,15 +77,16 @@ main {
|
||||||
}
|
}
|
||||||
|
|
||||||
.document {
|
.document {
|
||||||
float: left;
|
|
||||||
margin: .25rem;
|
margin: .25rem;
|
||||||
background: #CCC;
|
background: #CCC;
|
||||||
border-radius: .125rem;
|
border-radius: .125rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
max-width: calc((100vw - 16rem - 20px) / var(--columns) + 1rem);
|
max-width: calc((100vw - 16rem - 20px) / var(--columns) + 1rem);
|
||||||
max-width: calc((100vw - 16rem - 20px) / var(--columns) + 1rem);
|
max-height: calc((100vw - 16rem - 20px) / var(--columns) + 20rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.document.white { background: white; height: 1rem; }
|
||||||
|
|
||||||
.document .img_box {
|
.document .img_box {
|
||||||
background: #222;
|
background: #222;
|
||||||
padding: .5rem;
|
padding: .5rem;
|
||||||
|
@ -98,6 +99,13 @@ main {
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.document .description {
|
||||||
|
bottom: 0;
|
||||||
|
margin-top: .5rem;
|
||||||
|
max-height: 20rem;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.document p {
|
.document p {
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue