{{#corpus_link}}{{corpus_name}}{{/corpus_link}}
{{^corpus_link}}{{corpus_name}}{{/corpus_link}} About this corpus
Click ? button at bottom left for help with the topic explorer interface.
+
+
+
+
-
+
+
@@ -20,7 +25,7 @@
-
+
@@ -32,8 +37,8 @@
-
-
+
+
{{#topic_range}}
@@ -98,7 +103,7 @@
Document search
-
+
@@ -122,4 +127,7 @@
Topic Fingerp
+
+
+
diff --git a/www/bootstrap-tour.js b/www/bootstrap-tour.js
new file mode 100644
index 00000000..10d43fdf
--- /dev/null
+++ b/www/bootstrap-tour.js
@@ -0,0 +1,1737 @@
+/* ========================================================================
+ * bootstrap-tour - v0.11.0
+ * http://bootstraptour.com
+ * ========================================================================
+ * Copyright 2012-2015 Ulrich Sossou
+ *
+ * ========================================================================
+ * Licensed under the MIT License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/MIT
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================================
+ *
+ * Updated for CS by FFS 2018 - v0.5
+ * Features added:
+ *
+
+ 1. onNext/onPrevious - prevent auto-move to next step, allow .goTo
+ 2. *** Do not call Tour.init *** - fixed tours with hidden elements on page reload
+ 3. Dynamically determine step element by function
+ 4. Only continue tour when reflex element is clicked using reflexOnly
+ 5. Call onElementUnavailable if step element is missing
+ 6. Scroll flicker/continual step reload fixed
+ 7. Magic progress bar and progress text, plus options to customize per step
+ 8. Prevent user interaction with element using preventInteraction
+ 9. Wait for arbitrary DOM element to be visible before showing tour step/crapping out due to missing element, using delayOnElement
+ 10. Handle bootstrap modal dialogs better - autodetect modals or children of modals, and call onModalHidden when user dismisses modal without following tour steps
+ 11. Automagically fixes drawing issues with Bootstrap Selectpicker (https://github.com/snapappointments/bootstrap-select/)
+
+ --------------
+ 1. Control flow from onNext() / onPrevious() options:
+ Returning false from onNext/onPrevious handler will prevent Tour from automatically moving to the next/previous step.
+ Tour flow methods (Tour.goTo etc) now also work correctly in onNext/onPrevious.
+ Option is available per step or globally:
+
+ var tourSteps = [
+ {
+ element: "#inputBanana",
+ title: "Bananas!",
+ content: "Bananas are yellow, except when they're not",
+ onNext: function(tour){
+ if($('#inputBanana').val() !== "banana")
+ {
+ // no banana? highlight the banana field
+ $('#inputBanana').css("background-color", "red");
+ // do not jump to the next tour step!
+ return false;
+ }
+ }
+ }
+ ];
+
+ var Tour=new Tour({
+ steps: tourSteps,
+ onNext: function(tour)
+ {
+ if(someVar = true)
+ {
+ // force the tour to jump to slide 3
+ tour.goTo(3);
+ // Prevent default move to next step - important!
+ return false;
+ }
+ }
+ });
+
+ --------------
+ 2. Do not call Tour.init
+ When setting up Tour, do not call Tour.init().
+ Call Tour.start() to start/resume the Tour from previous step
+ Call Tour.restart() to always start Tour from first step
+
+ Tour.init() was a redundant method that caused conflict with hidden Tour elements.
+
+---------------
+ 3. Dynamically determine element by function
+ Step "element:" option allows element to be determined programmatically. Return a jquery object.
+ The following is possible:
+
+ var tourSteps = [
+ {
+ element: function() { return $(document).find("...something..."); },
+ title: "Dynamic",
+ content: "Element found by function"
+ },
+ {
+ element: "#static",
+ title: "Static",
+ content: "Element found by static ID"
+ }
+ ];
+
+---------------
+ 4. Only continue tour when reflex element is clicked
+ Use step option reflexOnly in conjunction with step option reflex to automagically hide the "next" button in the tour, and only continue when the user clicks the element:
+ var tourSteps = [
+ {
+ element: "#myButton",
+ reflex: true,
+ reflexOnly: true,
+ title: "Click it",
+ content: "Click to continue, or you're stuck"
+ }
+ ];
+
+----------------
+ 5. Call function when element is missing
+ If the element specified in the step (static or dynamically determined as per feature #3), onElementUnavailable is called.
+ Function signature: function(tour, stepNumber) {}
+ Option is available at global and per step levels.
+
+ function tourBroken(tour, stepNumber)
+ {
+ alert("Uhoh, tour element is done broke on step number " + stepNumber);
+ }
+
+ var tourSteps = [
+ {
+ element: "#btnMagic",
+ onElementUnavailable: tourBroken,
+ title: "Hold my beer",
+ content: "now watch this"
+ }
+ ];
+
+---------------
+ 6. Scroll flicker / continue reload fixed
+ Original Tour constantly reloaded the current tour step on scroll & similar events. This produced flickering, constant reloads and therefore constant calls to all the step function calls.
+ This is now fixed. Scrolling the browser window does not cause the tour step to reload.
+
+ IMPORTANT: orphan steps are stuck to the center of the screen. However steps linked to elements ALWAYS stay stuck to their element, even if user scrolls the element & tour popover
+ off the screen. This is my personal preference, as original functionality of tour step moving with the scroll even when the element was off the viewport seemed strange.
+
+---------------
+ 7. Progress bar & progress text:
+ Use the following options globally or per step to show tour progress:
+ showProgressBar - shows a bootstrap progress bar for tour progress at the top of the tour content
+ showProgressText - shows a textual progress (N/X, i.e.: 1/24 for slide 1 of 24) in the tour title
+
+ var tourSteps = [
+ {
+ element: "#inputBanana",
+ title: "Bananas!",
+ content: "Bananas are yellow, except when they're not",
+ },
+ {
+ element: "#inputOranges",
+ title: "Oranges!",
+ content: "Oranges are not bananas",
+ showProgressBar: false, // don't show the progress bar on this step only
+ showProgressText: false, // don't show the progress text on this step only
+ }
+ ];
+ var Tour=new Tour({
+ steps: tourSteps,
+ showProgressBar: true, // default show progress bar
+ showProgressText: true, // default show progress text
+ });
+
+ 7b. Customize the progressbar/progress text:
+ In conjunction with 7a, provide the following functions globally or per step to draw your own progressbar/progress text:
+
+ getProgressBarHTML(percent)
+ getProgressTextHTML(stepNumber, percent, stepCount)
+
+ These will be called when each step is shown, with the appropriate percentage/step number etc passed to your function. Return an HTML string of a "drawn" progress bar/progress text
+ which will be directly inserted into the tour step.
+
+ Example:
+ var tourSteps = [
+ {
+ element: "#inputBanana",
+ title: "Bananas!",
+ content: "Bananas are yellow, except when they're not",
+ },
+ {
+ element: "#inputOranges",
+ title: "Oranges!",
+ content: "Oranges are not bananas",
+ getProgressBarHTML: function(percent)
+ {
+ // override the global progress bar function for this step
+ return '
You're ' + percent + ' of the way through!
';
+ }
+ }
+ ];
+ var Tour=new Tour({
+ steps: tourSteps,
+ showProgressBar: true, // default show progress bar
+ showProgressText: true, // default show progress text
+ getProgressBarHTML: function(percent)
+ {
+ // default progress bar for all steps. Return valid HTML to draw the progress bar you want
+ return '
';
+ },
+ getProgressTextHTML: function(stepNumber, percent, stepCount)
+ {
+ // default progress text for all steps
+ return 'Slide ' + stepNumber + "/" + stepCount;
+ },
+
+ });
+
+----------------
+ 8. Prevent interaction with element
+ Sometimes you want to highlight a DOM element (button, input field) for a tour step, but don't want the user to be able to interact with it.
+ Use preventInteraction to stop the user touching the element:
+
+ var tourSteps = [
+ {
+ element: "#btnMCHammer",
+ preventInteraction: true,
+ title: "Hammer Time",
+ content: "You can't touch this"
+ }
+ ];
+
+----------------
+ 9. Wait for an element to appear before continuing tour
+ Sometimes a tour step element might not be immediately ready because of transition effects etc. This is a specific issue with bootstrap select, which is relatively slow to show the selectpicker
+ dropdown after clicking.
+ Use delayOnElement to instruct Tour to wait for **ANY** element to appear before showing the step (or crapping out due to missing element). Yes this means the tour step element can be one DOM
+ element, but the delay will wait for a completely separate DOM element to appear. This is really useful for hidden divs etc.
+ Use in conjunction with onElementUnavailable for robust tour step handling.
+
+ delayOnElement is an object with the following:
+ delayOnElement: {
+ delayElement: "#waitForMe", // the element to wait to become visible, or the string literal "element" to use the step element
+ maxDelay: 2000, // optional milliseconds to wait/timeout for the element, before crapping out. If maxDelay is not specified, this is 2000ms by default
+ }
+
+ var tourSteps = [
+ {
+ element: "#btnPrettyTransition",
+ delayOnElement: {
+ delayElement: "element" // use string literal "element" to wait for this step's element, i.e.: #btnPrettyTransition
+ },
+ title: "Ages",
+ content: "This button takes ages to appear"
+ },
+ {
+ element: "#inputUnrelated",
+ delayOnElement: {
+ delayElement: "#divStuff" // wait until DOM element "divStuff" is visible before showing this tour step against DOM element "inputUnrelated"
+ },
+ title: "Waiting",
+ content: "This input is nice, but you only see this step when the other div appears"
+ },
+ {
+ element: "#btnDontForgetThis",
+ delayOnElement: {
+ delayElement: "element", // use string literal "element" to wait for this step's element, i.e.: #btnDontForgetThis
+ maxDelay: 5000 // wait 5 seconds for it to appear before timing out
+ },
+ title: "Cool",
+ content: "Remember the onElementUnavailable option!",
+ onElementUnavailable: function(tour, stepNumber)
+ {
+ // This will be called if btnDontForgetThis is not visible after 5 seconds
+ console.log("Well that went badly wrong");
+ }
+ },
+ ];
+
+----------------
+ 10. Trigger when modal closes
+ If tour element is a modal, or is a DOM element inside a modal, the element can disappear "at random" if the user dismisses the dialog.
+ In this case, onModalHidden global and per step function is called. Only functional when step is not an orphan.
+ This is useful if a tour includes a step that launches a modal, and the tour requires the user to take some actions inside the modal before OK'ing it and moving to the next
+ tour step.
+
+ Return (int) step number to immediately move to that step
+ Return exactly false to not change tour state in any way - this is useful if you need to reshow the modal because some validation failed
+ Return anything else to move to the next step
+
+ element === Bootstrap modal, or element parent === bootstrap modal is automatically detected.
+
+ var Tour=new Tour({
+ steps: tourSteps,
+ onModalHidden: function(tour, stepNumber)
+ {
+ console.log("Well damn, this step's element was a modal, or inside a modal, and the modal just done got dismissed y'all. Moving to step 3.");
+
+ // move to step number 3
+ return 3;
+ },
+ });
+
+
+ var Tour=new Tour({
+ steps: tourSteps,
+ onModalHidden: function(tour, stepNumber)
+ {
+ if(validateSomeModalContent() == false)
+ {
+ // The validation failed, user dismissed modal without properly taking actions.
+ // Show the modal again
+ showModalAgain();
+
+ // Instruct tour to stay on same step
+ return false;
+ }
+ else
+ {
+ // Content was valid. Return null or do nothing to instruct tour to continue to next step
+ }
+ },
+ });
+
+----------------
+ 11. Fix conflict with Bootstrap Selectpicker: https://github.com/snapappointments/bootstrap-select/
+ Selectpicker draws a custom select. Tour now automagically finds and adjusts the selectpicker dropdown so that it appears correctly within the tour
+
+ *
+ */
+
+var bind = function (fn, me) {
+ return function () {
+ return fn.apply(me, arguments);
+ };
+};
+
+(function (window, factory) {
+ if (typeof define === 'function' && define.amd) {
+ return define(['jquery'], function (jQuery) {
+ return window.Tour = factory(jQuery);
+ });
+ } else if (typeof exports === 'object') {
+ return module.exports = factory(require('jquery'));
+ } else {
+ return window.Tour = factory(window.jQuery);
+ }
+})(window, function ($) {
+ var Tour,
+ document;
+ document = window.document;
+ Tour = (function () {
+ function Tour(options) {
+ this._showPopoverAndOverlay = bind(this._showPopoverAndOverlay, this);
+ var storage;
+ try {
+ storage = window.localStorage;
+ } catch (error) {
+ storage = false;
+ }
+ this._options = $.extend({
+ name: 'tour',
+ steps: [],
+ container: 'body',
+ autoscroll: true,
+ keyboard: true,
+ storage: storage,
+ debug: false,
+ backdrop: false,
+ backdropContainer: 'body',
+ backdropPadding: 0,
+ redirect: true,
+ orphan: false,
+ duration: false,
+ delay: false,
+ basePath: '',
+ template: '
Topic models are about contexts, rather than individual words.
- We search a topic model using full documents, rather than keywords. Enter the model by one of the following methods:
Topic models are about contexts, rather than individual words.
+ We search a topic model using full documents, rather than keywords. Enter the model by one of the
+ following methods:
The topic bars below show the composition of the selected document in different models. Scroll over the bars to see the most likely words in each topic. Click on a bar to open the Topic Explorer for that model focused on this document.
+
The topic bars below show the composition of the selected document in different models. Scroll over the bars
+ to see the most likely words in each topic. Click on a bar to open the Topic Explorer for that model focused
+ on this document.
After typing words above, the topics most likely to generate that word will appear below. Clicking "View topic clusters" will go to a view of the topic space, weighted by the terms in the box. This makes it easy to find groups of topics related to your interests.
+
After typing words above, the topics most likely to generate that word will appear below. Clicking "View
+ topic clusters" will go to a view of the topic space, weighted by the terms in the box. This makes it easy to
+ find groups of topics related to your interests.
-
+
-
+
+
diff --git a/www/topicprint.js b/www/topicprint.js
old mode 100644
new mode 100755
index e9c3b195..c470406f
--- a/www/topicprint.js
+++ b/www/topicprint.js
@@ -1,62 +1,151 @@
var taTimeout;
-$(".typeahead").typeahead({items: 12,
- source: function(query, process) {
+$(".typeahead").typeahead({
+ items: 12,
+ source: function (query, process) {
if (taTimeout)
clearTimeout(taTimeout);
this.$menu.find('.active').removeClass('active');
- var processAutocomplete = function(data) {
- labels = [];
- mapped = {};
- $.each(data, function(i, item) {
- mapped[item.label] = item;
- labels.push(item.label);
- })
-
- process(labels);
+ var processAutocomplete = function (data) {
+ labels = [];
+ mapped = {};
+ $.each(data, function (i, item) {
+ mapped[item.label] = item;
+ labels.push(item.label);
+ })
+
+ process(labels);
};
taTimeout = setTimeout(function () {
$.getJSON('../docs.json?q=' + encodeURIComponent(query), processAutocomplete)
- .error(function() {
- $.getJSON('docs.json?q=' + encodeURIComponent(query), processAutocomplete)
- })}, 300);
+ .error(function () {
+ $.getJSON('docs.json?q=' + encodeURIComponent(query), processAutocomplete)
+ })
+ }, 300);
},
- updater: function(item) {
- if (!item) {
- $('#hidden_id').val('');
- return this.$element.val();
- } else {
- $('#hidden_id').val(mapped[item].id);
- resetBars();
- return item;
- }
+ updater: function (item) {
+ if (!item) {
+ $('#hidden_id').val('');
+ return this.$element.val();
+ } else {
+ $('#hidden_id').val(mapped[item].id);
+ resetBars();
+ return item;
+ }
},
- sorter: function(items) {
- /*if (items.length == 1) {
- $('#hidden_id').val(mapped[items[0]].id);
- console.log("setting hidden_id" + $('#hidden_id').val());
- if (!$('#autocompleteDoc').hasClass('active')) {
- $('#autocompleteDoc').addClass('active');
- $('span.icon-font', '#autocompleteDoc').removeClass('icon-font').addClass('icon-file');
- }
- items.length = 0;
- } else*/
- var query = this.query;
- items = items.sort();
- var start = items.filter(function(item) { return item.lastIndexOf(query, 0) == 0;});
- var elsewhere = items.filter(function(item) { return item.lastIndexOf(query, 0) != 0;});
- return start.concat(elsewhere);
+ sorter: function (items) {
+ /*if (items.length == 1) {
+ $('#hidden_id').val(mapped[items[0]].id);
+ console.log("setting hidden_id" + $('#hidden_id').val());
+ if (!$('#autocompleteDoc').hasClass('active')) {
+ $('#autocompleteDoc').addClass('active');
+ $('span.icon-font', '#autocompleteDoc').removeClass('icon-font').addClass('icon-file');
+ }
+ items.length = 0;
+ } else*/
+ var query = this.query;
+ items = items.sort();
+ var start = items.filter(function (item) { return item.lastIndexOf(query, 0) == 0; });
+ var elsewhere = items.filter(function (item) { return item.lastIndexOf(query, 0) != 0; });
+ return start.concat(elsewhere);
}
});
-$('#randomDoc', '#fingerprintModal').click(function() {
- $.getJSON(fingerprint.host + 'docs.json?random=1', function(rand) {
- $('#hidden_id', '#fingerprintModal').val(rand[0].id);
- $('#doc', '#fingerprintModal').val(rand[0].label);
- resetBars();
+var tour = new Tour({
+ steps: [
+ {
+ element: "#doc",
+ title: "Document Selection",
+ content: "There are a few ways to select a new focal document. One is by typing in a few letters in the focal document entry area.",
+ placement: "top"
+ }, {
+ element: "#randomDoc",
+ title: "Random Document Selection",
+ content: "You can also click the button to the right of the focal document entry area for a random document.",
+ placement: "top"
+ }, {
+ element: "#tutorial",
+ title: "Random Document Selection",
+ content: "You may use this button to visualize the focal document and you may use the dropdown menu attached to the button to switch to a model with a different number of topics.",
+ placement: "top"
+ }, {
+ element: "#visualize_button",
+ title: "Continuation of Tutorial",
+ content: "From this point onwards, you can either exit the tutorial, type in a document yourself and click the 'Visualize' button, or you can click 'Next' and allow the tutorial to pick a document for you.",
+ placement: "bottom",
+ onNext: function(tour) {
+ $("#randomDoc").click();
+ //console.log(document.getElementById("#doc").value);
+ //$("#submit").click();
+
+ setTimeout(function () {
+ $("#submit").click();
+ }, 500);
+ /*
+ if(tour.started() && !tour.ended())
+ {
+ tour.init();
+ tour.start();
+ }
+ */
+
+ },
+
+ }, {
+ element:"#chart",
+ title: "Hypershelf",
+ content: "The Hypershelf shows up to 40 documents that are most similar to the focal document. Each document is represented by a bar whose colors show the mixture and proportions of topics assigned to each document by the training process. The relative lengths of the bars indicate the degree of similarity to the focal document according to the topic mixtures.",
+ placement: "top",
+ //delay: 1000
+ //autoscroll: false,
+ //smartPlacement: false
+
+ },
+ {
+ element:"#legend",
+ title: "Legend",
+ content: "This is a legend designed to navigate and manipulate data on the Hypershelf easier. You can click on any of the colored squares to focus on a particular topic, alphabetize the papers, and normalize the topic bars.",
+ placement:"left"
+ },
+ {
+ element: "#docDemonstration",
+ title: "Documents",
+ content:"The Hypershelf shows up to 40 documents that are most similar to the focal document. Each document is represented by a bar whose colors show the mixture and proportions of topics assigned to each document by the training process. The relative lengths of the bars indicate the degree of similarity to the focal document according to the topic mixtures.",
+ placement:"bottom"
+ },
+
+ {
+ element: "#home-page",
+ title: "Home Page",
+ content: "Click on this to return to the home page",
+ placement: "bottom"
+ }
+
+ ]
+});
+tour.init();
+
+if(!tour.ended())
+ {
+ tour.init();
+ tour.start();
+ }
+
+// start tour
+jQuery(document).ready(function ($){
+ $('#tour-button').click(function () {
+ tour.restart();
+ });
+});
+
+$('#randomDoc', '#fingerprintModal').click(function () {
+ $.getJSON(fingerprint.host + 'docs.json?random=1', function (rand) {
+ $('#hidden_id', '#fingerprintModal').val(rand[0].id);
+ $('#doc', '#fingerprintModal').val(rand[0].label);
+ resetBars();
});
});
-$('#randomDoc', '#fingerprintModal').tooltip({title: "Random Document", placement: 'bottom'});
+$('#randomDoc', '#fingerprintModal').tooltip({ title: "Random Document", placement: 'bottom' });
function resetBars() {
$('#singleBarsDl').html('');
@@ -66,150 +155,155 @@ function resetBars() {
function resetBar(i, k) {
var base_bar =
- '