Created
May 15, 2014 04:41
-
-
Save josephcc/6cf1a1c254a07f1c4b9d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Place all the behaviors and hooks related to the matching controller here. | |
| # All this logic will automatically be available in application.js. | |
| # You can use CoffeeScript in this file: http://coffeescript.org/ | |
| # | |
| # | |
| current_stage = 1 | |
| clips = null | |
| id2idx = null | |
| all_keywords = [] | |
| final_labels = [] | |
| textToHtml = (text, keywords) -> | |
| out = '' | |
| for token in text | |
| term = cleanTerm(token) | |
| if keywords.indexOf(term) >= 0 | |
| out += '<span class="token keyword">' + token + '</span> ' | |
| else | |
| if keywords.length == 0 | |
| out += '<span class="token">' + token + '</span> ' | |
| else | |
| out += token + ' ' | |
| return out | |
| loadRandomSeeds = (targets) -> | |
| clusters = $('.cluster') | |
| seeds = [] | |
| for cluster in clusters | |
| id = $(cluster).attr('data-cluster-id') | |
| if id | |
| seeds.push id | |
| for cluster in targets | |
| $(cluster).children('.seed').html() | |
| id = $(cluster).attr('data-cluster-id') | |
| if id | |
| index = seeds.indexOf(id) | |
| seeds.splice(index, 1) | |
| $(cluster).removeAttr('data-cluster-id') | |
| for cluster in targets | |
| seed = Math.random() * clips.length | |
| seed = Math.round(seed) | |
| if seeds.indexOf(seed) >= 0 | |
| continue | |
| seeds.push seed | |
| clip = clips[seed] | |
| $(cluster).children('.seed').html(textToHtml(clip['text'], [])) | |
| $(cluster).attr('data-cluster-id', clip['id']) | |
| $(cluster).children('.list').html('') | |
| get_tf_score = (clip, terms) -> | |
| _score = 0 | |
| for term in terms | |
| score = clip['terms'][term] | |
| if score? | |
| score = score[0] | |
| else | |
| score = 0 | |
| _score += score | |
| score = _score / terms.length | |
| cleanTerm = (term) -> | |
| term = term.replace(/^[^\w]+/gi, '').toLowerCase() | |
| term = term.replace(/[^\w]+$/gi, '').toLowerCase() | |
| term = term.replace(/'s$/gi, '').toLowerCase() | |
| term = term.replace(/’s$/gi, '').toLowerCase() | |
| return term | |
| cleanTerms = (terms) -> | |
| _terms = [] | |
| for term in terms | |
| _terms.push cleanTerm(term) | |
| terms = _terms | |
| similar_ranker = (clip_idx, terms, similarity, clips) -> | |
| _ranker = (x, y) -> | |
| # x-y # small -> large | |
| # y-x # large -> small | |
| tx = get_tf_score(clips[x], terms) | |
| ty = get_tf_score(clips[y], terms) | |
| if ty - tx != 0 | |
| return ty - tx | |
| else | |
| return similarity[y] - similarity[x] | |
| return _ranker | |
| bindClipEvents = () -> | |
| $('.add-clip').live 'click', (e) -> | |
| console.log 'add-clip clicked' | |
| e.preventDefault | |
| if $('.workspace').hasClass('inactive-this') | |
| alert 'Please read the instructions and click the Start button before you start.' | |
| return | |
| if $(this).hasClass('add-clip-disabled') | |
| $(this).parent().children().addClass('add-clip-disabled') | |
| $(this).removeClass('add-clip-disabled') | |
| else | |
| $(this).addClass('add-clip-disabled') | |
| bindSeedEvents = () -> | |
| $('.clip.seed .token').live 'click', (e) -> | |
| console.log 'token clicked' | |
| e.preventDefault | |
| if $('.workspace').hasClass('inactive-this') | |
| alert 'Please read the instructions and click the Start button before you start.' | |
| return | |
| if $(this).parent().hasClass('inactive-seed') | |
| return | |
| if current_stage < 2 | |
| return | |
| term = $(this).text() | |
| term = cleanTerm(term) | |
| console.log term | |
| console.log all_keywords | |
| console.log $.inArray(term, all_keywords) | |
| if (not $(this).hasClass('keyword')) and all_keywords.indexOf(term) >= 0 | |
| if current_stage < 3 | |
| alert 'Please select unique keywords, request another clip if necessary.' | |
| else | |
| alert 'This keyword is already used in one of the seed clips.' | |
| return | |
| $(this).toggleClass('keyword') | |
| if $(this).hasClass('keyword') | |
| all_keywords.push term | |
| else | |
| all_keywords.splice all_keywords.indexOf(term), 1 | |
| console.log all_keywords | |
| if current_stage < 3 | |
| return | |
| searchClips($(this).parent().parent()) | |
| $('.inactive-seed').live 'click', (e) -> | |
| e.preventDefault | |
| if $('.workspace').hasClass('inactive-this') | |
| alert 'Please read the instructions and click the Start button before you start.' | |
| return | |
| #TODO: remember to persist before leaving this stage | |
| list = $('.clip_list').html() | |
| $('.clip.seed:not(.inactive-seed)').parent().children('.list').html(list) | |
| $('.clip.seed').addClass('inactive-seed') | |
| $(this).removeClass('inactive-seed') | |
| list = $(this).parent().children('.list').html() | |
| $('.clip_list').html(list) | |
| $('.seed_tabs').scrollTo($(this)) | |
| $('.clip_list').scrollTop(0) | |
| searchClips = (cluster) -> | |
| keywords = cluster.children('.clip.seed').children('.token.keyword') | |
| console.log keywords | |
| if keywords.length == 0 | |
| $(cluster).children('.list').html('') | |
| $('.clip_list').html('') | |
| return | |
| console.log 'continued' | |
| terms = [] | |
| for keyword in keywords | |
| terms.push $(keyword).html() | |
| terms = cleanTerms(terms) | |
| id = cluster.attr('data-cluster-id') | |
| clip_idx = id2idx[id] | |
| clip = clips[clip_idx] | |
| idxs = for i in [0...clips.length] | |
| i | |
| idxs.sort(similar_ranker(clip_idx, terms, clip['similarity'], clips)) | |
| html = '' | |
| for idx in idxs.slice(0, 10) | |
| if idx == clip_idx | |
| continue | |
| similarity = clip['similarity'][idx] | |
| score = get_tf_score(clips[idx], terms) | |
| tfs = [] | |
| for term in terms | |
| tfs.push [term, get_tf_score(clips[idx], [term])] | |
| stats = 'score:' + score.toFixed(4) + ' sim:' + similarity.toFixed(4) + '<br>' | |
| for tf in tfs | |
| stats += '"' + tf[0] + '":' + tf[1].toFixed(2) + ' ' | |
| stats = '<div class="stats col-xs-6">' + stats + '</div>' | |
| stats = '<div class="row"><div class="col-xs-6 add-clip-container"><i class="add-clip add-clip-disabled fa fa-check"><a href="#">similar solution</a></i> <i class="add-clip add-clip-disabled fa fa-times"><a href="#">different solution</a></i></div>' + stats + '</div>' | |
| _html = textToHtml(clips[idx]['text'], terms) | |
| html += '<div class="clip" data-cluster-id="' + clips[idx]['id'] + '">' + stats + _html + '</div><hr>' | |
| $(cluster).children('.list').html(html) | |
| $('.clip_list').html(html) | |
| updateStage = () -> | |
| if current_stage > 2 | |
| return | |
| $('.stage').hide() | |
| $('.stage-'+current_stage).show() | |
| h = $(window).height() | |
| h = h - $('.header').height() | |
| $('.clips').css('height', h) | |
| $('.clusters').css('height', h) | |
| canContinue = (stage) -> | |
| if stage == 2 | |
| _clips = $('.clip.seed') | |
| for _clip in _clips | |
| highlights = $(_clip).children('.token.keyword') | |
| count = highlights.length | |
| if count == 0 or count > 3 | |
| alert 'Please highlight one to three keywords in each clip' | |
| return false | |
| return true | |
| if stage == 3 | |
| list = $('.clip_list').html() | |
| $('.clip.seed:not(.inactive-seed)').parent().children('.list').html(list) | |
| final_labels = [] | |
| clusters = $('.cluster') | |
| for cluster in clusters | |
| cluster = $(cluster) | |
| positive = [] | |
| negative = [] | |
| seed = cluster.children('.clip.seed') | |
| seed_id = parseInt(cluster.attr('data-cluster-id')) | |
| highlights = seed.children('.token.keyword') | |
| highlights = (cleanTerm($(highlight).text()) for highlight in highlights) | |
| console.log cluster.attr('data-cluster-id') | |
| console.log highlights | |
| console.log '-----------' | |
| _clips = cluster.children('.list').children('.clip') | |
| for _clip in _clips | |
| _clip = $(_clip) | |
| console.log _clip | |
| _clip_id = parseInt(_clip.attr('data-cluster-id')) | |
| control = _clip.children('.row').children('.add-clip-container') | |
| console.log control | |
| label = control.children('i.add-clip:not(.add-clip-disabled)') | |
| if label.length == 0 | |
| alert 'Please label all clips searched with all four seed clips on the left.' | |
| return false | |
| console.log 'clip tagged' | |
| label = $(label[0]) | |
| if label.hasClass('fa-check') | |
| positive.push _clip_id | |
| else | |
| negative.push _clip_id | |
| final_labels.push {'seed': seed_id, 'positive': positive, 'negative': negative, 'keywords': highlights} | |
| console.log final_labels | |
| return true | |
| # default bypass | |
| return true | |
| jQuery -> | |
| if not jQuery('body').hasClass('v-option-manager-2') | |
| return | |
| $('.dot').live 'click', (e) -> | |
| console.log 'dot clicked' | |
| e.preventDefault | |
| $(this).parent().children('.dot').removeClass('fa-circle') | |
| $(this).parent().children('.dot').addClass('fa-circle-o') | |
| $(this).removeClass('fa-circle-o') | |
| $(this).addClass('fa-circle') | |
| cid = $(this).attr('data-cid') | |
| $(this).parent().parent().parent().find('.cluster-clips .clip').hide() | |
| $(this).parent().parent().parent().find('.cluster-clips .clip[data-cid="' + cid + '"]').show() | |
| console.log $(this) | |
| $('.dot:nth-child(1)').click() | |
| $('.clips').sortable | |
| connectWith: '.cluster-clips' | |
| items: "> .clip.draggable" | |
| appendTo: 'body' | |
| cursor: "move" | |
| helper: 'clone' | |
| containment: 'window' | |
| zIndex: 9999999 | |
| tolerance: "pointer" | |
| start: (event, ui) -> | |
| console.log 'start' | |
| $('.cluster-clips .clip').css('opacity', '0.35') | |
| stop: (event, ui) -> | |
| console.log 'start' | |
| $('.cluster-clips .clip').css('opacity', '1.0') | |
| $('.cluster-clips').sortable | |
| connectWith: '.clips, .cluster-clips' | |
| items: "> .clip.draggable" | |
| cursor: "move" | |
| appendTo: 'body' | |
| helper: 'clone' | |
| appendTo: 'body' | |
| containment: 'window' | |
| tolerance: "pointer" | |
| zIndex: 9999999 | |
| receive: (event, ui) -> | |
| cid = ui.item.attr('data-cid') | |
| console.log cid | |
| $(this).parent().find('.selector').append('<i class="fa fa-circle-o dot draggable" data-cid="' + cid + '"></i>') | |
| $(this).parent().find('.selector .dot[data-cid="' + cid + '"]').click() | |
| remove: (event, ui) -> | |
| cid = ui.item.attr('data-cid') | |
| console.log cid | |
| $(this).parent().find('.selector .dot[data-cid="' + cid + '"]').remove() | |
| $(this).parent().find('.selector .dot:nth-child(1)').click() | |
| start: (event, ui) -> | |
| console.log 'start' | |
| $('.cluster-clips .clip').css('opacity', '0.35') | |
| $('.clips .clip').css('opacity', '0.75') | |
| $('.clips').addClass('drop-zone') | |
| stop: (event, ui) -> | |
| console.log 'start' | |
| $('.cluster-clips .clip').css('opacity', '1.0') | |
| $('.clips .clip').css('opacity', '1.0') | |
| $('.clips').removeClass('drop-zone') | |
| updateStage() | |
| $('.next-stage').hide() | |
| $('.next').hide() | |
| $('.start-stage').click (e) -> | |
| console.log 'start clicked' | |
| e.preventDefault | |
| $('.next-stage').show() | |
| $('.workspace').removeClass('inactive-this') | |
| $(this).hide() | |
| $('.next').click (e) -> | |
| console.log 'next clicked' | |
| e.preventDefault | |
| if $('.workspace').hasClass('inactive-this') | |
| alert 'Please read the instructions and click the Start button before you start.' | |
| return | |
| target = $($(this).parent().parent()) | |
| loadRandomSeeds(target) | |
| $('.next-stage').click (e) -> | |
| e.preventDefault | |
| if not canContinue(current_stage) | |
| return | |
| $('.start-stage').show() | |
| $('.next-stage').hide() | |
| current_stage += 1 | |
| console.log 'current stage is ' + current_stage | |
| if current_stage == 3 | |
| for cluster in $('.cluster') | |
| searchClips($(cluster)) | |
| if current_stage > 3 | |
| url = '/feedback/question/' + ka.current.question_id + '/option_manager?labels=' + JSON.stringify(final_labels) + '&' + aws_params | |
| console.log url | |
| window.location = url | |
| updateStage() | |
| $('.workspace').addClass('inactive-this') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment