<commit_before>var workQueue = [];
/**
 * Competence class
 */
function Competence(viewmodel, id, code, name, weight, locked, subcompetences) {
    return {
        id: ko.observable(id),
        code: ko.observable(code),
        name: ko.observable(name),
        weight: ko.observable(weight),
        locked: false,
        subcompetences: ko.observableArray(subcompetences),

        addSubCompetence: function() {
            this.subcompetences.push(new SubCompetence(this));
            automatedWeightCalculation(this.subcompetences());
        },

        removeThis: function() {
            if(this.id() !== undefined) // User deletes a competence that's been saved to the database
            {
                workQueue.push("/api/project/competence/delete/" + this.id())
            }

            viewmodel.removeCompetence(this);
        },

        toggleLock: function(data, event){
            if(this.locked == true)
            {
                $(event.target).addClass("icon-unlock").removeClass("icon-lock");
                this.locked = false;
            }
            else
            {
                $(event.target).addClass("icon-lock").removeClass("icon-unlock");
                this.locked = true;
            }
        },

        removeSubCompetence: function(subCompetence) {
            if(subCompetence.id() !== undefined) // User deletes a subcompetence that's been saved to the database
            {
                workQueue.push("/api/project/subcompetence/delete/" + subCompetence.id())
            }

            this.subcompetences.remove(subCompetence);
            automatedWeightCalculation(this.subcompetences());
        }
    };

}

/**
 * SubCompetence class
 */
function SubCompetence(parent, id, code, name, weight, locked, indicators) {
    return {

        id: ko.observable(id),
        code: ko.observable(code),
        name: ko.observable(name),
        weight: ko.observable(weight),
        locked: false,
        indicators: ko.observableArray(indicators),

        addIndicator: function() {
            this.indicators.push(new Indicator(this));
            automatedWeightCalculation(this.indicators());
        },

        /*calculateWeight: function(total){
            this.weight = total;
        },*/

        removeThis: function() {
            parent.removeSubCompetence(this);

        },

        toggleLock: function(data, event){
            if(this.locked == true)
            {
                $(event.target).addClass("icon-unlock").removeClass("icon-lock");
                this.locked = false;
            }
            else
            {
                $(event.target).addClass("icon-lock").removeClass("icon-unlock");
                this.locked = true;
            }
        },

        removeIndicator: function(indicator) {
            var self = this;

            if(indicator.id() != undefined) // User deletes an indicator that hasn't been saved to the database yet
            {
                workQueue.push("/api/project/indicator/delete/" + indicator.id())
            }

            self.indicators.remove(indicator);
            automatedWeightCalculation(this.indicators());
        }

    };
}

/**
 * Indicator class
 */
function Indicator(parent, id, name, weight, description, locked,pointType) {
    return {
        id: ko.observable(id),
        name: ko.observable(name),
        weight: ko.observable(weight),
        description : ko.observable(description),
        locked: false,
        pointType: pointType,

        removeThis: function() {
            parent.removeIndicator(this);
        },

        toggleLock: function(data, event){
            if(this.locked == true)
            {
                $(event.target).addClass("icon-unlock").removeClass("icon-lock");
                this.locked = false;
            }
            else
            {
                $(event.target).addClass("icon-lock").removeClass("icon-unlock");
                this.locked = true;
            }
        }
    };
}

// View model for the courses page
function pageViewModel(gvm) {
    // projecttitle
    gvm.projecttitle = ko.observable("");
    //gvm.competences = 0;
    gvm.subcomp = 0;

    // Page specific i18n bindings
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("ProjectTitle") + ": " + gvm.projecttitle();}, gvm);
    gvm.pageHeader = ko.observable("Project");
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);
    gvm.nextPage = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("NextPage");}, gvm);

    gvm.addCompetenceBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AddCompetence");}, gvm);
    gvm.savePage = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SaveBtn");}, gvm);

    gvm.competences = ko.observableArray([]);

    gvm.availableTypes = ko.observableArray(['Slider','Punten','Ja / Nee']);

    gvm.addCompetence = function() {
        gvm.competences.push(new Competence(this));
        automatedWeightCalculation(this.competences());

        // Update automated weight calculation
        ko.utils.arrayForEach(gvm.competences, function(competence){
            console.log(competence.weight);
            competence.weight(percent);
        });
    };

    gvm.removeCompetence = function(competence) {
        gvm.competences.remove(competence);
        automatedWeightCalculation(this.competences());
    }

    gvm.updateCompetence = function(id, code, description, max, weight) {
        var comp = new Competence(this, id, code, description, weight);
        gvm.competences.push(comp);
        return comp;
    }

    gvm.clearStructure = function() {
        gvm.competences.removeAll();
    }
}

function fetchProjectStructure() {
    viewModel.clearStructure();
    $.getJSON("/api/projectstructure/" + projectid, function(data){
        $.each(data, function(i, item){
            if(item.id > 0) {
                var competence = viewModel.updateCompetence(item.id, item.code, item.description, item.max, item.weight);
            }
            $.each(item.subcompetences, function(i, subcomp){
                if(subcomp.id > 0) {
                    var subcompetence = new SubCompetence(competence, subcomp.id, subcomp.code, subcomp.description, subcomp.weight);
                    competence.subcompetences.push(subcompetence);
                }

               $.each(subcomp.indicators, function(i, indic){
                   if(indic.id > 0) {
                       subcompetence.indicators.push(new Indicator(subcompetence, indic.id, indic.name, indic.weight, indic.description,false,indic.pointType));
                   }
               });
            });
        })
    });
}

function initPage() {
    fetchProjectStructure();

    $(".addCompetenceBtn").click(function() {
        viewModel.addCompetence();
    });

    $(".savePageBtn").click(function(){
        if(allValidationChecks()) {
            saveProjectStructure();
            var url = document.URL;
            var string = url.split("/");
            window.location.href = "http://" + string[2] + "/" + string[3] + "/students/" + string[4];
            console.log("Saved");
        }
        else
        {
            window.scrollTo(0,0);
            console.log("Not saved");
        }
    });
}

function saveProjectStructure() {
    var self = this;

    this.doTheRest = function()
    {
        $.ajax({
            type: "POST",
            url: "/api/projectstructure/" + projectid,
            data: ko.toJSON(viewModel.competences),
            success: function(){
                // TODO make multilangual and with modals
                alert("Saved projectstructure to server");

                fetchProjectStructure();
            }
        });
    }

    if(workQueue.length === 0)
    {
        this.doTheRest();
    }

    var processedIndex = 0;
    for(i = 0; i < workQueue.length; i++)
    {
        $.getJSON(
            workQueue[i],
            function(result)
            {
                if(!result.success)
                {
                    alert("Failed processing your request: " + result.error);
                }

                if(processedIndex === workQueue.length - 1)
                {
                    self.doTheRest();
                    workQueue = [];
                }
                processedIndex++;
            }
        );
    }

}

function allValidationChecks()
{
    $(".validationSummary").addClass('hide');
    $(".validationSummary ul").empty();
    result = validationCheck() && totalPercentCheck()
    if(!result)
    {
        $(".validationSummary").removeClass('hide');
    }

    return result;
}

function validationCheck()
{
    var allCompetencesValid = true;
    var allSubcompetencesValid = true;
    var allIndicatorsValid = true;

    for(var indexCompetences =0; indexCompetences < viewModel.competences().length; indexCompetences++)
    {
        if(!viewModel.competences()[indexCompetences].code() && !viewModel.competences()[indexCompetences].name())
        {
            if(allCompetencesValid)
            {
                $(".validationSummary ul").append("
Code or name in competences is empty
");
                $(".validationSummary").removeClass("hide");
            }
            allCompetencesValid = false;
        }
        for(var indexSubcompetence = 0; indexSubcompetence < viewModel.competences()[indexCompetences].subcompetences().length; indexSubcompetence++)
        {
            if(!viewModel.competences()[indexCompetences].subcompetences()[indexSubcompetence].name() && !viewModel.competences()[indexCompetences].subcompetences()[indexSubcompetence].code())
            {
                if(allSubcompetencesValid)
                {
                    $(".validationSummary ul").append("
Code or name in subcompetences is empty
");
                    $(".validationSummary").removeClass("hide");
                }
                allSubcompetencesValid = false;
            }
            for(var indexIndicators = 0; indexIndicators < viewModel.competences()[indexCompetences].subcompetences()[indexSubcompetence].indicators().length; indexIndicators++)
            {
                if(!viewModel.competences()[indexCompetences].subcompetences()[indexSubcompetence].indicators()[indexIndicators].name() && !viewModel.competences()[indexCompetences].subcompetences()[indexSubcompetence].indicators()[indexIndicators].description())
                {
                    if(allIndicatorsValid)
                    {
                        $(".validationSummary ul").append("
Description or name in indicators is empty
");
                        $(".validationSummary").removeClass("hide");
                    }
                    allIndicatorsValid = false;
                }
            }
        }
    }
    return allCompetencesValid && allSubcompetencesValid && allIndicatorsValid;
}

function totalPercentCheck()
{
    var cTotal = 0;
    var success = true;

    $.each(viewModel.competences(),
        function(cI, cVal) {
            cTotal += parseInt(cVal.weight());

            scTotal = 0;
            $.each(cVal.subcompetences(),
                function(scI, scVal)
                {
                    scTotal += parseInt(scVal.weight());

                    iTotal = 0;
                    $.each(scVal.indicators(),
                        function(iI, iVal)
                        {
                            iTotal += parseInt(iVal.weight());
                        }
                    );

                    if(scVal.indicators().length > 0 && iTotal !== 100)
                    {
                        $(".validationSummary ul").append('
Indicator weights in the subcompetence ' + scVal.name() + ' are not adding up to 100%
');
                        success = false;
                    }
                }
            );

            if(cVal.subcompetences().length > 0 && scTotal !== 100)
            {
                $(".validationSummary ul").append('
Subcompentence weights in the competence ' + cVal.name() + ' are not adding up to 100%
');
                success = false;
            }
        }
    );

    if(viewModel.competences().length > 0 && cTotal !== 100)
    {
        $(".validationSummary ul").append('
Competence weights are not adding up to 100%
');
        success = false;
    }

    return success;
}

function automatedWeightCalculation(data)
{
    var lockedPercent = 0;
    var nrOfUnlocked = 0;

    for(var index = 0; index < data.length; index++)
    {
        if(data[index].locked == true)
        {
            lockedPercent = lockedPercent + parseInt(data[index].weight());
        }
        else
        {
            nrOfUnlocked++;
        }
    }

    var remainingPercent = 100 - lockedPercent;

    var percentPerCompetence = remainingPercent / nrOfUnlocked;

    percentPerCompetence = Math.floor(percentPerCompetence);

    for(var index = 0; index < data.length; index++)
    {
        if(data[index].locked == false)
        {
            data[index].weight(percentPerCompetence);
        }
    }
}
<commit_msg>min max<commit_after>var workQueue = [];
/**
 * Competence class
 */
function Competence(viewmodel, id, code, name, weight, locked, subcompetences) {
    return {
        id: ko.observable(id),
        code: ko.observable(code),
        name: ko.observable(name),
        weight: ko.observable(weight),
        locked: false,
        subcompetences: ko.observableArray(subcompetences),

        addSubCompetence: function() {
            this.subcompetences.push(new SubCompetence(this));
            automatedWeightCalculation(this.subcompetences());
        },

        removeThis: function() {
            if(this.id() !== undefined) // User deletes a competence that's been saved to the database
            {
                workQueue.push("/api/project/competence/delete/" + this.id())
            }

            viewmodel.removeCompetence(this);
        },

        toggleLock: function(data, event){
            if(this.locked == true)
            {
                $(event.target).addClass("icon-unlock").removeClass("icon-lock");
                this.locked = false;
            }
            else
            {
                $(event.target).addClass("icon-lock").removeClass("icon-unlock");
                this.locked = true;
            }
        },

        removeSubCompetence: function(subCompetence) {
            if(subCompetence.id() !== undefined) // User deletes a subcompetence that's been saved to the database
            {
                workQueue.push("/api/project/subcompetence/delete/" + subCompetence.id())
            }

            this.subcompetences.remove(subCompetence);
            automatedWeightCalculation(this.subcompetences());
        }
    };

}

/**
 * SubCompetence class
 */
function SubCompetence(parent, id, code, name, weight, locked, indicators) {
    return {

        id: ko.observable(id),
        code: ko.observable(code),
        name: ko.observable(name),
        weight: ko.observable(weight),
        locked: false,
        indicators: ko.observableArray(indicators),

        addIndicator: function() {
            this.indicators.push(new Indicator(this));
            automatedWeightCalculation(this.indicators());
        },

        /*calculateWeight: function(total){
            this.weight = total;
        },*/

        removeThis: function() {
            parent.removeSubCompetence(this);

        },

        toggleLock: function(data, event){
            if(this.locked == true)
            {
                $(event.target).addClass("icon-unlock").removeClass("icon-lock");
                this.locked = false;
            }
            else
            {
                $(event.target).addClass("icon-lock").removeClass("icon-unlock");
                this.locked = true;
            }
        },

        removeIndicator: function(indicator) {
            var self = this;

            if(indicator.id() != undefined) // User deletes an indicator that hasn't been saved to the database yet
            {
                workQueue.push("/api/project/indicator/delete/" + indicator.id())
            }

            self.indicators.remove(indicator);
            automatedWeightCalculation(this.indicators());
        }

    };
}

/**
 * Indicator class
 */
function Indicator(parent, id, name, weight, description, locked,pointType) {
    return {
        id: ko.observable(id),
        name: ko.observable(name),
        weight: ko.observable(weight),
        description : ko.observable(description),
        locked: false,
        pointType: pointType,

        removeThis: function() {
            parent.removeIndicator(this);
        },

        toggleLock: function(data, event){
            if(this.locked == true)
            {
                $(event.target).addClass("icon-unlock").removeClass("icon-lock");
                this.locked = false;
            }
            else
            {
                $(event.target).addClass("icon-lock").removeClass("icon-unlock");
                this.locked = true;
            }
        }
    };
}

// View model for the courses page
function pageViewModel(gvm) {
    // projecttitle
    gvm.projecttitle = ko.observable("");
    //gvm.competences = 0;
    gvm.subcomp = 0;

    // Page specific i18n bindings
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("ProjectTitle") + ": " + gvm.projecttitle();}, gvm);
    gvm.pageHeader = ko.observable("Project");
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);
    gvm.nextPage = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("NextPage");}, gvm);

    gvm.addCompetenceBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AddCompetence");}, gvm);
    gvm.savePage = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SaveBtn");}, gvm);

    gvm.competences = ko.observableArray([]);

    gvm.availableTypes = ko.observableArray(['Slider','Punten','Ja/Nee']);

    gvm.addCompetence = function() {
        gvm.competences.push(new Competence(this));
        automatedWeightCalculation(this.competences());

        // Update automated weight calculation
        ko.utils.arrayForEach(gvm.competences, function(competence){
            console.log(competence.weight);
            competence.weight(percent);
        });
    };

    gvm.removeCompetence = function(competence) {
        gvm.competences.remove(competence);
        automatedWeightCalculation(this.competences());
    }

    gvm.updateCompetence = function(id, code, description, max, weight) {
        var comp = new Competence(this, id, code, description, weight);
        gvm.competences.push(comp);
        return comp;
    }

    gvm.clearStructure = function() {
        gvm.competences.removeAll();
    }
}

function fetchProjectStructure() {
    viewModel.clearStructure();
    $.getJSON("/api/projectstructure/" + projectid, function(data){
        $.each(data, function(i, item){
            if(item.id > 0) {
                var competence = viewModel.updateCompetence(item.id, item.code, item.description, item.max, item.weight);
            }
            $.each(item.subcompetences, function(i, subcomp){
                if(subcomp.id > 0) {
                    var subcompetence = new SubCompetence(competence, subcomp.id, subcomp.code, subcomp.description, subcomp.weight);
                    competence.subcompetences.push(subcompetence);
                }

               $.each(subcomp.indicators, function(i, indic){
                   if(indic.id > 0) {
                       subcompetence.indicators.push(new Indicator(subcompetence, indic.id, indic.name, indic.weight, indic.description,false,indic.pointType));
                   }
               });
            });
        })
    });
}

function initPage() {
    fetchProjectStructure();

    $(".addCompetenceBtn").click(function() {
        viewModel.addCompetence();
    });

    $(".savePageBtn").click(function(){
        if(allValidationChecks()) {
            saveProjectStructure();
            var url = document.URL;
            var string = url.split("/");
            window.location.href = "http://" + string[2] + "/" + string[3] + "/students/" + string[4];
            console.log("Saved");
        }
        else
        {
            window.scrollTo(0,0);
            console.log("Not saved");
        }
    });
}

function saveProjectStructure() {
    var self = this;

    this.doTheRest = function()
    {
        $.ajax({
            type: "POST",
            url: "/api/projectstructure/" + projectid,
            data: ko.toJSON(viewModel.competences),
            success: function(){
                // TODO make multilangual and with modals
                alert("Saved projectstructure to server");

                fetchProjectStructure();
            }
        });
    }

    if(workQueue.length === 0)
    {
        this.doTheRest();
    }

    var processedIndex = 0;
    for(i = 0; i < workQueue.length; i++)
    {
        $.getJSON(
            workQueue[i],
            function(result)
            {
                if(!result.success)
                {
                    alert("Failed processing your request: " + result.error);
                }

                if(processedIndex === workQueue.length - 1)
                {
                    self.doTheRest();
                    workQueue = [];
                }
                processedIndex++;
            }
        );
    }

}

function allValidationChecks()
{
    $(".validationSummary").addClass('hide');
    $(".validationSummary ul").empty();
    result = validationCheck() && totalPercentCheck()
    if(!result)
    {
        $(".validationSummary").removeClass('hide');
    }

    return result;
}

function validationCheck()
{
    var allCompetencesValid = true;
    var allSubcompetencesValid = true;
    var allIndicatorsValid = true;

    for(var indexCompetences =0; indexCompetences < viewModel.competences().length; indexCompetences++)
    {
        if(!viewModel.competences()[indexCompetences].code() && !viewModel.competences()[indexCompetences].name())
        {
            if(allCompetencesValid)
            {
                $(".validationSummary ul").append("
Code or name in competences is empty
");
                $(".validationSummary").removeClass("hide");
            }
            allCompetencesValid = false;
        }
        for(var indexSubcompetence = 0; indexSubcompetence < viewModel.competences()[indexCompetences].subcompetences().length; indexSubcompetence++)
        {
            if(!viewModel.competences()[indexCompetences].subcompetences()[indexSubcompetence].name() && !viewModel.competences()[indexCompetences].subcompetences()[indexSubcompetence].code())
            {
                if(allSubcompetencesValid)
                {
                    $(".validationSummary ul").append("
Code or name in subcompetences is empty
");
                    $(".validationSummary").removeClass("hide");
                }
                allSubcompetencesValid = false;
            }
            for(var indexIndicators = 0; indexIndicators < viewModel.competences()[indexCompetences].subcompetences()[indexSubcompetence].indicators().length; indexIndicators++)
            {
                if(!viewModel.competences()[indexCompetences].subcompetences()[indexSubcompetence].indicators()[indexIndicators].name() && !viewModel.competences()[indexCompetences].subcompetences()[indexSubcompetence].indicators()[indexIndicators].description())
                {
                    if(allIndicatorsValid)
                    {
                        $(".validationSummary ul").append("
Description or name in indicators is empty
");
                        $(".validationSummary").removeClass("hide");
                    }
                    allIndicatorsValid = false;
                }
            }
        }
    }
    return allCompetencesValid && allSubcompetencesValid && allIndicatorsValid;
}

function totalPercentCheck()
{
    var cTotal = 0;
    var success = true;

    $.each(viewModel.competences(),
        function(cI, cVal) {
            cTotal += parseInt(cVal.weight());

            scTotal = 0;
            $.each(cVal.subcompetences(),
                function(scI, scVal)
                {
                    scTotal += parseInt(scVal.weight());

                    iTotal = 0;
                    $.each(scVal.indicators(),
                        function(iI, iVal)
                        {
                            iTotal += parseInt(iVal.weight());
                        }
                    );

                    if(scVal.indicators().length > 0 && iTotal !== 100)
                    {
                        $(".validationSummary ul").append('
Indicator weights in the subcompetence ' + scVal.name() + ' are not adding up to 100%
');
                        success = false;
                    }
                }
            );

            if(cVal.subcompetences().length > 0 && scTotal !== 100)
            {
                $(".validationSummary ul").append('
Subcompentence weights in the competence ' + cVal.name() + ' are not adding up to 100%
');
                success = false;
            }
        }
    );

    if(viewModel.competences().length > 0 && cTotal !== 100)
    {
        $(".validationSummary ul").append('
Competence weights are not adding up to 100%
');
        success = false;
    }

    return success;
}

function automatedWeightCalculation(data)
{
    var lockedPercent = 0;
    var nrOfUnlocked = 0;

    for(var index = 0; index < data.length; index++)
    {
        if(data[index].locked == true)
        {
            lockedPercent = lockedPercent + parseInt(data[index].weight());
        }
        else
        {
            nrOfUnlocked++;
        }
    }

    var remainingPercent = 100 - lockedPercent;

    var percentPerCompetence = remainingPercent / nrOfUnlocked;

    percentPerCompetence = Math.floor(percentPerCompetence);

    for(var index = 0; index < data.length; index++)
    {
        if(data[index].locked == false)
        {
            data[index].weight(percentPerCompetence);
        }
    }
}
<|endoftext|>


<commit_before>var processorInstanciated = false;
var processor = {
    timerCallback: function () {
        if (this.video.paused || this.video.ended) {
            return;
        }
        this.computeFrame();
        let self = this;
        setTimeout(function () {
            self.timerCallback();
        }, 0);
    },

    doLoad: function (minR, minG, minB, maxR, maxG, maxB, instanceId) {
        console.log('Loading processor for video', instanceId);
        this.video = document.getElementById('chroma-video-' + instanceId);
        this.c1 = document.getElementById("c1-" + instanceId);
        this.minR = minR;
        this.minG = minG;
        this.minB = minB;
        this.maxR = maxR;
        this.maxG = maxG;
        this.maxB = maxB;
        if (this.c1) {
            this.ctx1 = this.c1.getContext("2d");
            this.c2 = document.getElementById("c2-" + instanceId);
            this.ctx2 = this.c2.getContext("2d");
            let self = this;
            // if (!processorInstanciated) {
            console.log('Adding event listeners');
            this.video.addEventListener("play", function () {
                self.width = self.video.videoWidth;
                self.height = self.video.videoHeight;
                self.timerCallback();
            }, false);

            this.video.addEventListener("ended", function () {
                chromaPauseVideo();
            });
            //   }
            processorInstanciated = true;
        }
    },

    computeFrame: function () {
        this.ctx1.drawImage(this.video, 0, 0, this.width, this.height);
        let frame = this.ctx1.getImageData(0, 0, this.width, this.height);
        let l = frame.data.length / 4;
        for (let i = 0; i < l; i++) {
            let r = frame.data[i * 4 + 0];
            let g = frame.data[i * 4 + 1];
            let b = frame.data[i * 4 + 2];
            if (g >= this.minG && g <= this.maxG
                && r >= this.minR && r <= this.maxR
                && b >= this.minB && b <= this.maxB)
                frame.data[i * 4 + 3] = 0;
        }
        this.ctx2.putImageData(frame, 0, 0);
        return;
    }

};

/*jQuery(document).ready(function ($) {
 if (typeof loadProcessor !== 'undefined') {
 loadProcessor();
 }
 });*/

function chromaStartVideo(minR, minG, minB, maxR, maxG, maxB, instanceId) {
    processor.doLoad(minR, minG, minB, maxR, maxG, maxB, instanceId);
    //  processor.timerCallback();
    console.log('Starting video', instanceId);
    jQuery('#chroma-play-link-' + instanceId).hide();
    jQuery('#chroma-placeholder-' + instanceId).hide();
    document.getElementById('chroma-video-' + instanceId).play();
    document.getElementById('chroma-pause-link-' + instanceId).style = '';
}

function chromaPauseVideo(instanceId) {
    console.log('Pausing video', instanceId);
    document.getElementById('chroma-video-' + instanceId).pause();
    jQuery('#chroma-pause-link-' + instanceId).hide();
    jQuery('#chroma-play-link-' + instanceId).show();
}<commit_msg>remove useless commemts<commit_after>var processorInstanciated = false;
var processor = {
    timerCallback: function () {
        if (this.video.paused || this.video.ended) {
            return;
        }
        this.computeFrame();
        let self = this;
        setTimeout(function () {
            self.timerCallback();
        }, 0);
    },

    doLoad: function (minR, minG, minB, maxR, maxG, maxB, instanceId) {
        console.log('Loading processor for video', instanceId);
        this.video = document.getElementById('chroma-video-' + instanceId);
        this.c1 = document.getElementById("c1-" + instanceId);
        this.minR = minR;
        this.minG = minG;
        this.minB = minB;
        this.maxR = maxR;
        this.maxG = maxG;
        this.maxB = maxB;
        if (this.c1) {
            this.ctx1 = this.c1.getContext("2d");
            this.c2 = document.getElementById("c2-" + instanceId);
            this.ctx2 = this.c2.getContext("2d");
            let self = this;
            // if (!processorInstanciated) {
            console.log('Adding event listeners');
            this.video.addEventListener("play", function () {
                self.width = self.video.videoWidth;
                self.height = self.video.videoHeight;
                self.timerCallback();
            }, false);

            this.video.addEventListener("ended", function () {
                chromaPauseVideo();
            });
            //   }
            processorInstanciated = true;
        }
    },

    computeFrame: function () {
        this.ctx1.drawImage(this.video, 0, 0, this.width, this.height);
        let frame = this.ctx1.getImageData(0, 0, this.width, this.height);
        let l = frame.data.length / 4;
        for (let i = 0; i < l; i++) {
            let r = frame.data[i * 4 + 0];
            let g = frame.data[i * 4 + 1];
            let b = frame.data[i * 4 + 2];
            if (g >= this.minG && g <= this.maxG
                && r >= this.minR && r <= this.maxR
                && b >= this.minB && b <= this.maxB)
                frame.data[i * 4 + 3] = 0;
        }
        this.ctx2.putImageData(frame, 0, 0);
        return;
    }

};

function chromaStartVideo(minR, minG, minB, maxR, maxG, maxB, instanceId) {
    processor.doLoad(minR, minG, minB, maxR, maxG, maxB, instanceId);
    //  processor.timerCallback();
    console.log('Starting video', instanceId);
    jQuery('#chroma-play-link-' + instanceId).hide();
    jQuery('#chroma-placeholder-' + instanceId).hide();
    document.getElementById('chroma-video-' + instanceId).play();
    document.getElementById('chroma-pause-link-' + instanceId).style = '';
}

function chromaPauseVideo(instanceId) {
    console.log('Pausing video', instanceId);
    document.getElementById('chroma-video-' + instanceId).pause();
    jQuery('#chroma-pause-link-' + instanceId).hide();
    jQuery('#chroma-play-link-' + instanceId).show();
}<|endoftext|>


<commit_before>game.spendExp = me.ScreenObject.extend({
	/**
	 *  action to perform on state change
	 */
	onResetEvent: function() {

		me.audio.playTrack("TillIt'sGone");

		me.game.world.addChild(new me.Sprite(0, 0, me.loader.getImage('exp-screen')), -10); // TODO

		me.game.world.addChild(new (me.Renderable.extend({
			init: function(){
				this._super(me.Renderable, 'init', [270, 240, 300, 50]);
				this.font = new me.Font('Arial', 26, 'black');

			},

			draw: function(renderer){
				this.font.draw(renderer.getContext(), 'Awesomenauts', 400, 130);
				this.font.draw(renderer.getContext(), 'Press F1-F4 TO BUY, F5 TO SKIP', this.pos.x, this.pos.y);
				this.font.draw(renderer.getContext(), 'CURRENT EXP:' + game.data.exp.toString(), this.pos.x, this.pos.y + 50);
				this.font.draw(renderer.getContext(), 'F1: INCREASE GOLD CURRENT LEVEL' + game.data.exp1.toString() + "COST: " + ((game.data.exp1 + 1) * 10), this.pos.x, this.pos.y + 100);
				this.font.draw(renderer.getContext(), 'F2: POWER UPS' , this.pos.x, this.pos.y + 150);
				this.font.draw(renderer.getContext(), 'F3: INCREASE DAMAGE' , this.pos.x, this.pos.y + 200);
				this.font.draw(renderer.getContext(), 'F4: INCREASE HEALTH' , this.pos.x, this.pos.y + 250);
			},

		})));

	},

	/**
	 *  action to perform when leaving this screen (state change)
	 */
	onDestroyEvent: function() {
		me.audio.stopTrack();
	}
});
<commit_msg>finished vid 44<commit_after>game.spendExp = me.ScreenObject.extend({
	/**
	 *  action to perform on state change
	 */
	onResetEvent: function() {

		me.audio.playTrack("TillIt'sGone");

		me.game.world.addChild(new me.Sprite(0, 0, me.loader.getImage('exp-screen')), -10); // TODO

		me.input.bindKey(me.input.KEY.F1, "F1");
		me.input.bindKey(me.input.KEY.F2, "F2");
		me.input.bindKey(me.input.KEY.F3, "F3");
		me.input.bindKey(me.input.KEY.F4, "F4");
		me.input.bindKey(me.input.KEY.F5, "F5");

		me.game.world.addChild(new (me.Renderable.extend({
			init: function(){
				this._super(me.Renderable, 'init', [270, 240, 300, 50]);
				this.font = new me.Font('Arial', 26, 'black');

			},

			draw: function(renderer){
				this.font.draw(renderer.getContext(), 'Awesomenauts', 400, 130);
				this.font.draw(renderer.getContext(), 'Press F1-F4 TO BUY, F5 TO SKIP', this.pos.x, this.pos.y);
				this.font.draw(renderer.getContext(), 'CURRENT EXP:' + game.data.exp.toString(), this.pos.x, this.pos.y + 50);
				this.font.draw(renderer.getContext(), 'F1: INCREASE GOLD CURRENT LEVEL' + game.data.exp1.toString() + "COST: " + ((game.data.exp1 + 1) * 10), this.pos.x, this.pos.y + 100);
				this.font.draw(renderer.getContext(), 'F2: POWER UPS' , this.pos.x, this.pos.y + 150);
				this.font.draw(renderer.getContext(), 'F3: INCREASE ATTACK DAMAGE' , this.pos.x, this.pos.y + 200);
				this.font.draw(renderer.getContext(), 'F4: INCREASE HEALTH' , this.pos.x, this.pos.y + 250);
			},

		})));

		this.handler = me.event.subscribe(me.event.KEYDOWN, function (action, keyCode, edge){
			if(action === "F1"){

			}else if(action === "F2"){

			}else if(action === "F3"){

			}else if(action === "F4"){

			}else if(action === "F5"){
				me.state.change(me.state.PLAY);
			}
		});

	},

	/**
	 *  action to perform when leaving this screen (state change)
	 */
	onDestroyEvent: function() {
		me.audio.stopTrack();

		me.input.unbindKey(me.input.KEY.F1, "F1");
		me.input.unbindKey(me.input.KEY.F2, "F2");
		me.input.unbindKey(me.input.KEY.F3, "F3");
		me.input.unbindKey(me.input.KEY.F4, "F4");
		me.input.unbindKey(me.input.KEY.F5, "F5");
		me.event.unsubscribe(this.handler);
	}
});
<|endoftext|>


<commit_before>// data
var occupation_data;
var regions_data;

// remembering what has been clicked
var clicked_location = false,
    clicked_occ_family = false,
    clicked_occ = false,
    clicked_map = false;

// do stuff when the page loads
(function(){

    initialize();

})()

function initialize(){

    $.when($.getJSON('data/merged_regions_simplified.geojson'), $.get('data/occupation_data.csv')).then(function(geojson, csv){

        regions_data = geojson
        occupation_data = _.map(
            $.csv.toObjects(csv[0]),
            function(row) {
                return {
                    geography_name: row.geography_name,
                    geography_type: row.geography_type,
                    job_family: cleanOccupation(row.job_family),
                    occupation: cleanOccupation(row.occupation),
                    demand_sum: parseInt(row.demand_entry_he)+parseInt(row.demand_entry_fe)+parseInt(row.demand_entry_sl),
                    demand_ticker: row.demand_ticker,
                    demand_entry_he: parseInt(row.demand_entry_he),
                    demand_entry_fe: parseInt(row.demand_entry_fe),
                    demand_entry_sl: parseInt(row.demand_entry_sl),
                    reg_salary: parseInt(row.reg_salary),
                    he_opportunity_score: parseInt(row.he_opportunity_score),
                    fe_opportunity_score: parseInt(row.fe_opportunity_score),
                    lq: row.lq,
                    lq_label: row.lq_label
                };
            }
        );

        if($.address.parameter("location_type") && $.address.parameter("location")){
            updateLocation(decodeURIComponent($.address.parameter("location_type")), decodeURIComponent($.address.parameter("location")))
        }
        else{
            updateLocation('Country', 'UK Total')
        }

        // populating select menu w/ regions & leps
        var $location_select_list = $('#location-select-list');
        $.each(geo_hierarchy['children'], function(index, value){
            n = value['name']
            n_link_html = makeLinkHTML(n, toTitleCase(n), 'option-nation')
            $location_select_list.append('
'+n_link_html+'
')
            // loop thru regions within nation
            $.each(value['children'] , function(index, value){
                r = value['name']
                r_link_html =  makeLinkHTML(r, toTitleCase(r), 'option-region')
                $location_select_list.append('
'+r_link_html+'
')
                // loop thru leps within region
                $.each(value['children'] , function(index, value){
                    l = value['name']
                    l_link_html = makeLinkHTML(l, l, 'option-lep')
                    $location_select_list.append('
'+l_link_html+'
')
                });
            });
        });

        var $control_pane = $('#control-pane');
        $control_pane.on('click', '.option-country', function() {
            updateLocation('Country', 'UK Total');
            return false;
        });
        $control_pane.on('click', '.option-nation', function() {
            updateLocation('Nation', $(this).attr('data'));
            return false;
        });
        $control_pane.on('click', '.option-region', function() {
            updateLocation('Region', $(this).attr('data'));
            return false;
        });
        $control_pane.on('click', '.option-lep', function() {
            updateLocation('LEP', $(this).attr('data'));
            return false;
        });

        $('#fe-select').click(function() {
            updateEducation('fe')
        });
        $('#he-select').click(function() {
            updateEducation('he')
        });

        var $occ_info_pane = $('#occ-info-pane');
        $("#close-occ").click(function(){
            $occ_info_pane.fadeTo(0, 0, function () {
                $occ_info_pane.fadeTo(800, 1)
            });

            $("#occ-detail").hide();
            $("#default-occ-info").show();

            $occ_info_pane.removeClass('well-occ-inactive');
            $occ_info_pane.addClass('well-occ-active');

            $.address.parameter('occupation', '');
            highlightOcc('');
        });

        var $cls_job_family = $(".job-family");
        $cls_job_family.hover(
            function(){
                highlightOccFamily($(this).attr('data'));
            },
            function(){
                highlightOccFamily('');
            }
        );
        $cls_job_family.click(function(){
            var clicked_job_fam_name = $(this).attr('data')
            // unselect other selected stuff
            $cls_job_family.each(function(index, elem){
                if ($(elem).attr('data')!=clicked_job_fam_name){
                    $(elem).removeClass('selected');
                };
            });
            if($(this).hasClass('selected')){
                // unselecting
                $(this).removeClass('selected');
                selectOccFamily('');
            }else{
                // selecting
                $(this).addClass('selected')
                selectOccFamily(clicked_job_fam_name);
            };

            hideHelperJobFamily();

        });

        // show & flash job family & occupation helpers
        // if user doesn't figure it out within 5 secs
        setTimeout(showHelperJobFamily, 4500);
        setTimeout(showHelperOcc, 5500);

        $("#location-select-list li").click(function() {
           $("#location-dropdown-menu").dropdown("toggle");
           if(clicked_location==false){
                clicked_location=true;
                $("#location-dropdown-menu").addClass('muted');
            };
        });

        $("#breadcrumbs a").click(function(){
            if(clicked_location==false){
                clicked_location=true;
                $("#location-dropdown-menu").addClass('muted');
            };
        });

        $('[data-toggle="tooltip"]').tooltip({
            html: true
        });
    });
}

function updateLocation(geo_type, geo_name){
    var education = decodeURIComponent($.address.parameter("education"))
    var geo_display_name = geo_name

    if(geo_type=="Country" && geo_name=='UK Total'){
        geo_display_name = "The United Kingdom"
        $.address.parameter('location_type', '')
        $.address.parameter('location', '')
    }
    else{
        $.address.parameter('location_type', encodeURIComponent(geo_type))
        $.address.parameter('location', encodeURIComponent(geo_name))
        if(geo_type=="Nation" || geo_type=="Region"){
            geo_display_name = toTitleCase(geo_name)
        }
    }

    clearJobFamilies();

    var place_data = _.where(occupation_data, {geography_type: geo_type, geography_name: geo_name})

    if(geo_display_name.length>32){
        $("#current-location-name").html(''+geo_display_name+'')
    }
    else{
        $("#current-location-name").html(geo_display_name)
    }

    // // updating breadcrumbs
    // var $breadcrumbs = $('#breadcrumbs');

    // $breadcrumbs.html(" Change location to explore occupations elsewhere")
    // var breadcrumb_links = makeBreadcrumbLinks(geo_name)
    // if(breadcrumb_links.length){
    //     $breadcrumbs.html("")
    //     $.each(breadcrumb_links, function(index, value){
    //         $breadcrumbs.append(value+' » ')
    //     });
    // }

    makeDemandChart(place_data)
    // makeDemandScatterPlot('#scatter-demand', agg_data_scatter)
    makeCompScatterPlot(place_data, education)

    if ($.address.parameter('occupation')){
        clicked_occ = true;
        selectOccupation(decodeURIComponent($.address.parameter('occupation')), place_data)
    }
}

function updateEducation(education){
    $.address.parameter('education', encodeURIComponent(education));

    // TO-DO: move this logic elsewhere
    if ($.address.parameter('location_type') && $.address.parameter('location')){
        var geo_type = decodeURIComponent($.address.parameter('location_type'))
        var geo_name = decodeURIComponent($.address.parameter('location'))
    }
    else {
        geo_type = 'Country'
        geo_name = 'UK Total'
    }

    var place_data = _.where(occupation_data, {geography_type: geo_type, geography_name: geo_name})

    makeCompScatterPlot(place_data, education)

    if ($.address.parameter('occupation')){
        highlightOcc(decodeURIComponent($.address.parameter('occupation')), place_data);
    }
}

function selectOccupation(occupation, place_data){
    highlightOcc(occupation);
    $.address.parameter('occupation', encodeURIComponent(occupation));

    // this populates the occupation detail pane on the main location view

    var $occ_info_pane = $('#occ-info-pane');
    $occ_info_pane.fadeTo(0, 0, function () {
        $occ_info_pane.fadeTo(800, 1)
    });
    $occ_info_pane.addClass('well-occ-inactive');
    $occ_info_pane.removeClass('well-occ-active');

    // show map helper if user doesn't figure it out after 5 secs
    setTimeout(showHelperMap, 5000);

    clearJobFamilies();

    $("#default-occ-info").hide();
    $("#occ-detail").show();

    if(occupation.length>50){
        $("#sel-occ-name").html(''+occupation+'')
    }else if(occupation.length>40){
        $("#sel-occ-name").html(''+occupation+'')
    }else{
        $("#sel-occ-name").html(occupation)
    }
    var tooltip_content = 'Jobs included:

'
    $.each(occupation_mapping[occupation]['example_titles'], function(index, title){
        tooltip_content = tooltip_content +'
'+ title + '
'
    });
    tooltip_content = tooltip_content+'
'+occupation_mapping[occupation]['description']
    $("#sel-occ-desc").html('')

    var place_occ_data = _.where(place_data, {occupation: occupation})[0]

    var salary_fig = place_occ_data['reg_salary']
    if (salary_fig){
        salary_fig_str = '£'+numberWithCommas(salary_fig)
    }
    else {
        salary_fig_str = '--'
    }

    var comp_fig_he = place_occ_data['he_opportunity_score']
    if (comp_fig_he){
        comp_fig_str_he = parseInt(comp_fig_he)+'/100'
    }
    else {
        comp_fig_str_he = '--'
    }

    var comp_fig_fe = place_occ_data['fe_opportunity_score']
    if (comp_fig_fe){
        comp_fig_str_fe = parseInt(comp_fig_fe)+'/100'
    }
    else {
        comp_fig_str_fe = '--'
    }

    $("#occ-label-demand").html(''+place_occ_data['demand_ticker']+'')
    $("#occ-label-comp-fe").html(''+oppLabel(comp_fig_fe)+'')
    $("#occ-label-comp-he").html(''+oppLabel(comp_fig_he)+'')
    $("#occ-label-salary").html(''+salaryLabel(salary_fig)+'')

    $("#occ-figure-demand").html(numberWithCommas(place_occ_data['demand_sum'])+' jobs')
    $("#occ-figure-salary").html(salary_fig_str)
    $("#occ-figure-comp-fe").html(comp_fig_str_fe)
    $("#occ-figure-comp-he").html(comp_fig_str_he)

    var $btn_occ_view = $('#btn-occ-view');
    var occ_view_url = '/occupation.html#/?occupation='+encodeURIComponent(occupation)
    $btn_occ_view.attr('href', occ_view_url)

    $('#occ-info-tooltip').tooltip({
        html: true
    });
}

// function makeBreadcrumbLinks(geo_name){
//     if(geo_name=='UK Total'){
//         return [];
//     }
//     else{
//         var links = [ makeLinkHTML("UK Total", "The United Kingdom", "option-country") ]
//         var b = breadcrumbs[geo_name]
//         if(b.length==0){
//             return links
//         }
//         else if(b.length==1){
//             var n = b[0]
//             return links.concat( [makeLinkHTML(n, toTitleCase(n), 'option-nation')] )
//         }
//         else if(b.length==2){
//             var n = b[0]
//             var r = b[1]
//             return links.concat( [makeLinkHTML(n, toTitleCase(n), 'option-nation'), makeLinkHTML(r, toTitleCase(r), 'option-region')] )
//         }
//     }
// }

function clearJobFamilies(){
    // clear any selected job families
    $(".cls_job_family").each(function(index, elem){
        if ($(elem).hasClass('selected')){
            $(elem).removeClass('selected');
        };
    });
}

function showHelperJobFamily(){
    if(clicked_occ_family==false){
        $("#helper-job-family").fadeTo(800, 1);
    };
};

function showHelperOcc(){
    if(clicked_occ==false){
        $("#helper-occupation").fadeTo(800, 1);
    };
};

function showHelperMap(){
    if(clicked_map==false){
        $("#helper-map").fadeIn(800);
    };
}

function hideHelperJobFamily(){
    if(clicked_occ_family==false){
        clicked_occ_family = true;
        $("#helper-job-family").fadeOut(800);
    }
};

function hideHelperOcc(){
    if(clicked_occ==false){
        clicked_occ = true;
        $("#helper-occupation").fadeOut(800)
    };
};

<commit_msg>adding uk to geography dropdown, #152<commit_after>// data
var occupation_data;
var regions_data;

// remembering what has been clicked
var clicked_location = false,
    clicked_occ_family = false,
    clicked_occ = false,
    clicked_map = false;

// do stuff when the page loads
(function(){

    initialize();

})()

function initialize(){

    $.when($.getJSON('data/merged_regions_simplified.geojson'), $.get('data/occupation_data.csv')).then(function(geojson, csv){

        regions_data = geojson
        occupation_data = _.map(
            $.csv.toObjects(csv[0]),
            function(row) {
                return {
                    geography_name: row.geography_name,
                    geography_type: row.geography_type,
                    job_family: cleanOccupation(row.job_family),
                    occupation: cleanOccupation(row.occupation),
                    demand_sum: parseInt(row.demand_entry_he)+parseInt(row.demand_entry_fe)+parseInt(row.demand_entry_sl),
                    demand_ticker: row.demand_ticker,
                    demand_entry_he: parseInt(row.demand_entry_he),
                    demand_entry_fe: parseInt(row.demand_entry_fe),
                    demand_entry_sl: parseInt(row.demand_entry_sl),
                    reg_salary: parseInt(row.reg_salary),
                    he_opportunity_score: parseInt(row.he_opportunity_score),
                    fe_opportunity_score: parseInt(row.fe_opportunity_score),
                    lq: row.lq,
                    lq_label: row.lq_label
                };
            }
        );

        if($.address.parameter("location_type") && $.address.parameter("location")){
            updateLocation(decodeURIComponent($.address.parameter("location_type")), decodeURIComponent($.address.parameter("location")))
        }
        else{
            updateLocation('Country', 'UK Total')
        }

        // populating select menu w/ regions & leps
        var $location_select_list = $('#location-select-list');
        $location_select_list.append('
The United Kingdom

')
        $.each(geo_hierarchy['children'], function(index, value){
            n = value['name']
            n_link_html = makeLinkHTML(n, toTitleCase(n), 'option-nation')
            $location_select_list.append('
'+n_link_html+'
')
            // loop thru regions within nation
            $.each(value['children'] , function(index, value){
                r = value['name']
                r_link_html =  makeLinkHTML(r, toTitleCase(r), 'option-region')
                $location_select_list.append('
'+r_link_html+'
')
                // loop thru leps within region
                $.each(value['children'] , function(index, value){
                    l = value['name']
                    l_link_html = makeLinkHTML(l, l, 'option-lep')
                    $location_select_list.append('
'+l_link_html+'
')
                });
            });
        });

        var $control_pane = $('#control-pane');
        $control_pane.on('click', '.option-country', function() {
            updateLocation('Country', 'UK Total');
            return false;
        });
        $control_pane.on('click', '.option-nation', function() {
            updateLocation('Nation', $(this).attr('data'));
            return false;
        });
        $control_pane.on('click', '.option-region', function() {
            updateLocation('Region', $(this).attr('data'));
            return false;
        });
        $control_pane.on('click', '.option-lep', function() {
            updateLocation('LEP', $(this).attr('data'));
            return false;
        });

        $('#fe-select').click(function() {
            updateEducation('fe')
        });
        $('#he-select').click(function() {
            updateEducation('he')
        });

        var $occ_info_pane = $('#occ-info-pane');
        $("#close-occ").click(function(){
            $occ_info_pane.fadeTo(0, 0, function () {
                $occ_info_pane.fadeTo(800, 1)
            });

            $("#occ-detail").hide();
            $("#default-occ-info").show();

            $occ_info_pane.removeClass('well-occ-inactive');
            $occ_info_pane.addClass('well-occ-active');

            $.address.parameter('occupation', '');
            highlightOcc('');
        });

        var $cls_job_family = $(".job-family");
        $cls_job_family.hover(
            function(){
                highlightOccFamily($(this).attr('data'));
            },
            function(){
                highlightOccFamily('');
            }
        );
        $cls_job_family.click(function(){
            var clicked_job_fam_name = $(this).attr('data')
            // unselect other selected stuff
            $cls_job_family.each(function(index, elem){
                if ($(elem).attr('data')!=clicked_job_fam_name){
                    $(elem).removeClass('selected');
                };
            });
            if($(this).hasClass('selected')){
                // unselecting
                $(this).removeClass('selected');
                selectOccFamily('');
            }else{
                // selecting
                $(this).addClass('selected')
                selectOccFamily(clicked_job_fam_name);
            };

            hideHelperJobFamily();

        });

        // show & flash job family & occupation helpers
        // if user doesn't figure it out within 5 secs
        setTimeout(showHelperJobFamily, 4500);
        setTimeout(showHelperOcc, 5500);

        $("#location-select-list li").click(function() {
           $("#location-dropdown-menu").dropdown("toggle");
           if(clicked_location==false){
                clicked_location=true;
                $("#location-dropdown-menu").addClass('muted');
            };
        });

        $("#breadcrumbs a").click(function(){
            if(clicked_location==false){
                clicked_location=true;
                $("#location-dropdown-menu").addClass('muted');
            };
        });

        $('[data-toggle="tooltip"]').tooltip({
            html: true
        });
    });
}

function updateLocation(geo_type, geo_name){
    var education = decodeURIComponent($.address.parameter("education"))
    var geo_display_name = geo_name

    if(geo_type=="Country" && geo_name=='UK Total'){
        geo_display_name = "The United Kingdom"
        $.address.parameter('location_type', '')
        $.address.parameter('location', '')
    }
    else{
        $.address.parameter('location_type', encodeURIComponent(geo_type))
        $.address.parameter('location', encodeURIComponent(geo_name))
        if(geo_type=="Nation" || geo_type=="Region"){
            geo_display_name = toTitleCase(geo_name)
        }
    }

    clearJobFamilies();

    var place_data = _.where(occupation_data, {geography_type: geo_type, geography_name: geo_name})

    if(geo_display_name.length>32){
        $("#current-location-name").html(''+geo_display_name+'')
    }
    else{
        $("#current-location-name").html(geo_display_name)
    }

    // // updating breadcrumbs
    // var $breadcrumbs = $('#breadcrumbs');

    // $breadcrumbs.html(" Change location to explore occupations elsewhere")
    // var breadcrumb_links = makeBreadcrumbLinks(geo_name)
    // if(breadcrumb_links.length){
    //     $breadcrumbs.html("")
    //     $.each(breadcrumb_links, function(index, value){
    //         $breadcrumbs.append(value+' » ')
    //     });
    // }

    makeDemandChart(place_data)
    // makeDemandScatterPlot('#scatter-demand', agg_data_scatter)
    makeCompScatterPlot(place_data, education)

    if ($.address.parameter('occupation')){
        clicked_occ = true;
        selectOccupation(decodeURIComponent($.address.parameter('occupation')), place_data)
    }
}

function updateEducation(education){
    $.address.parameter('education', encodeURIComponent(education));

    // TO-DO: move this logic elsewhere
    if ($.address.parameter('location_type') && $.address.parameter('location')){
        var geo_type = decodeURIComponent($.address.parameter('location_type'))
        var geo_name = decodeURIComponent($.address.parameter('location'))
    }
    else {
        geo_type = 'Country'
        geo_name = 'UK Total'
    }

    var place_data = _.where(occupation_data, {geography_type: geo_type, geography_name: geo_name})

    makeCompScatterPlot(place_data, education)

    if ($.address.parameter('occupation')){
        highlightOcc(decodeURIComponent($.address.parameter('occupation')), place_data);
    }
}

function selectOccupation(occupation, place_data){
    highlightOcc(occupation);
    $.address.parameter('occupation', encodeURIComponent(occupation));

    // this populates the occupation detail pane on the main location view

    var $occ_info_pane = $('#occ-info-pane');
    $occ_info_pane.fadeTo(0, 0, function () {
        $occ_info_pane.fadeTo(800, 1)
    });
    $occ_info_pane.addClass('well-occ-inactive');
    $occ_info_pane.removeClass('well-occ-active');

    // show map helper if user doesn't figure it out after 5 secs
    setTimeout(showHelperMap, 5000);

    clearJobFamilies();

    $("#default-occ-info").hide();
    $("#occ-detail").show();

    if(occupation.length>50){
        $("#sel-occ-name").html(''+occupation+'')
    }else if(occupation.length>40){
        $("#sel-occ-name").html(''+occupation+'')
    }else{
        $("#sel-occ-name").html(occupation)
    }
    var tooltip_content = 'Jobs included:

'
    $.each(occupation_mapping[occupation]['example_titles'], function(index, title){
        tooltip_content = tooltip_content +'
'+ title + '
'
    });
    tooltip_content = tooltip_content+'
'+occupation_mapping[occupation]['description']
    $("#sel-occ-desc").html('')

    var place_occ_data = _.where(place_data, {occupation: occupation})[0]

    var salary_fig = place_occ_data['reg_salary']
    if (salary_fig){
        salary_fig_str = '£'+numberWithCommas(salary_fig)
    }
    else {
        salary_fig_str = '--'
    }

    var comp_fig_he = place_occ_data['he_opportunity_score']
    if (comp_fig_he){
        comp_fig_str_he = parseInt(comp_fig_he)+'/100'
    }
    else {
        comp_fig_str_he = '--'
    }

    var comp_fig_fe = place_occ_data['fe_opportunity_score']
    if (comp_fig_fe){
        comp_fig_str_fe = parseInt(comp_fig_fe)+'/100'
    }
    else {
        comp_fig_str_fe = '--'
    }

    $("#occ-label-demand").html(''+place_occ_data['demand_ticker']+'')
    $("#occ-label-comp-fe").html(''+oppLabel(comp_fig_fe)+'')
    $("#occ-label-comp-he").html(''+oppLabel(comp_fig_he)+'')
    $("#occ-label-salary").html(''+salaryLabel(salary_fig)+'')

    $("#occ-figure-demand").html(numberWithCommas(place_occ_data['demand_sum'])+' jobs')
    $("#occ-figure-salary").html(salary_fig_str)
    $("#occ-figure-comp-fe").html(comp_fig_str_fe)
    $("#occ-figure-comp-he").html(comp_fig_str_he)

    var $btn_occ_view = $('#btn-occ-view');
    var occ_view_url = '/occupation.html#/?occupation='+encodeURIComponent(occupation)
    $btn_occ_view.attr('href', occ_view_url)

    $('#occ-info-tooltip').tooltip({
        html: true
    });
}

// function makeBreadcrumbLinks(geo_name){
//     if(geo_name=='UK Total'){
//         return [];
//     }
//     else{
//         var links = [ makeLinkHTML("UK Total", "The United Kingdom", "option-country") ]
//         var b = breadcrumbs[geo_name]
//         if(b.length==0){
//             return links
//         }
//         else if(b.length==1){
//             var n = b[0]
//             return links.concat( [makeLinkHTML(n, toTitleCase(n), 'option-nation')] )
//         }
//         else if(b.length==2){
//             var n = b[0]
//             var r = b[1]
//             return links.concat( [makeLinkHTML(n, toTitleCase(n), 'option-nation'), makeLinkHTML(r, toTitleCase(r), 'option-region')] )
//         }
//     }
// }

function clearJobFamilies(){
    // clear any selected job families
    $(".cls_job_family").each(function(index, elem){
        if ($(elem).hasClass('selected')){
            $(elem).removeClass('selected');
        };
    });
}

function showHelperJobFamily(){
    if(clicked_occ_family==false){
        $("#helper-job-family").fadeTo(800, 1);
    };
};

function showHelperOcc(){
    if(clicked_occ==false){
        $("#helper-occupation").fadeTo(800, 1);
    };
};

function showHelperMap(){
    if(clicked_map==false){
        $("#helper-map").fadeIn(800);
    };
}

function hideHelperJobFamily(){
    if(clicked_occ_family==false){
        clicked_occ_family = true;
        $("#helper-job-family").fadeOut(800);
    }
};

function hideHelperOcc(){
    if(clicked_occ==false){
        clicked_occ = true;
        $("#helper-occupation").fadeOut(800)
    };
};

<|endoftext|>


<commit_before>/* This software is licensed under a BSD license; see the LICENSE file for details. */

Message.name = "Message";
Message.obligatory = ["html"];
Message.countsForProgressBar = false;

function Message(div, options, finishedCallback, utils) {
    this.div = div;
    this.options = options;
    this.hideProgressBar = dget(options, "hideProgressBar", true);

    this.html = options.html;
    div.className = "message";
    //div.innerHTML = this.html;
    div.appendChild(htmlCodeToDOM(this.html));

    // Bit of copy/pasting from 'Separator' here.
    this.transfer = dget(options, "transfer", "keypress");
    assert(this.transfer == "keypress" || typeof(this.transfer) == "number",
           "Value of 'transfer' option of Message must either be the string 'keypress' or a number");

    if (this.transfer == "keypress") {
        this.handleKey = function(code, time) {
            finishedCallback(null);
            return true;
        }
    }
    else {
        utils.setTimeout(finishedCallback, this.transfer);
    }
}

Message.htmlDescription = function (opts) {
    var d = document.createElement("div");
    d.innerHTML = opts.html;
    return truncateHTML(d, 100);
}

<commit_msg>Change message.js to use htmlCodeToDOM function for overviews.<commit_after>/* This software is licensed under a BSD license; see the LICENSE file for details. */

Message.name = "Message";
Message.obligatory = ["html"];
Message.countsForProgressBar = false;

function Message(div, options, finishedCallback, utils) {
    this.div = div;
    this.options = options;
    this.hideProgressBar = dget(options, "hideProgressBar", true);

    this.html = options.html;
    div.className = "message";
    //div.innerHTML = this.html;
    div.appendChild(htmlCodeToDOM(this.html));

    // Bit of copy/pasting from 'Separator' here.
    this.transfer = dget(options, "transfer", "keypress");
    assert(this.transfer == "keypress" || typeof(this.transfer) == "number",
           "Value of 'transfer' option of Message must either be the string 'keypress' or a number");

    if (this.transfer == "keypress") {
        this.handleKey = function(code, time) {
            finishedCallback(null);
            return true;
        }
    }
    else {
        utils.setTimeout(finishedCallback, this.transfer);
    }
}

Message.htmlDescription = function (opts) {
    var d = htmlCodeToDOM(opts.html);
    return truncateHTML(d, 100);
}

<|endoftext|>


<commit_before>function TranslationBox() {
  this.div = document.createElement('div');
  this.opacity = 0;
  with (this.div.style) {
    zIndex = 2147483647;
    position = 'absolute';
    background = '#000000';
    color = '#ffffff';
    fontFamily = 'Hiragino Mincho Pro';
    fontSize = '11px';
    opacity = '0';
    textAlign = 'left';
    display = 'block';
    borderRadius = '5px';
    lineHeight = '16px';
    webkitFontSmoothing = 'auto';
  }
  document.body.appendChild(this.div);
}

TranslationBox.prototype.Fadein = function() {
  var self = this;
  clearInterval(self.fadeinSt);
  clearInterval(self.fadeoutSt);
  self.fadeinSt = setInterval(function() {
    self.div.style.opacity = self.opacity / 100;
    if (self.opacity == 75) {
      clearInterval(self.fadeinSt);
    } else {
      self.opacity += 5;
    }
  }, 10);
};

TranslationBox.prototype.Fadeout = function() {
  var self = this;
  clearInterval(self.fadeoutSt);
  clearInterval(self.fadeinSt);
  self.fadeoutSt = setInterval(function() {
    self.div.style.opacity = self.opacity / 100;
    if (self.opacity == 0) {
      self.div.innerHTML = '';
      clearInterval(self.fadeoutSt);
    } else {
      self.opacity -= 5;
    }
  }, 10);
};

TranslationBox.prototype.SetContent = function(results) {
  this.content = [];
  for (var i = 0; i < results.length; ++i) {
    var key = results[i].originalKey || results[i].key;
    var value = results[i].value;
    this.content.push({word: key, translation: value});
  }

  this.div.innerHTML = "";
  for (var i = 0; i < this.content.length; ++i) {
    var c = this.content[i];
    this.div.innerHTML +=
    ('' + (i + 1) + '. ' + c.word +
     '\n
' + c.translation + '
').
      replace(/\n/g, '
');
  }
};

TranslationBox.prototype.GetContent = function() {
  return this.content;
};

TranslationBox.prototype.SetLocation = function(mouse) {
  this.mouse = mouse;
  this.AdjustLocation();
};

TranslationBox.prototype.AdjustLocation = function() {
  // Redraw translation box.
  var box_width = Math.min(400, window.innerWidth);
  var box_left = Math.min(window.innerWidth - box_width, this.mouse.clientX) +
        this.mouse.pageX - this.mouse.clientX + 2;
  var box_top = this.mouse.pageY + 10;
  with (this.div.style) {
    width = box_width + 'px';
    left = box_left + 'px';
    top = box_top + 'px';
  }

  // Adjust when bottom of the translation box is out of the window.
  var bcr = this.div.getBoundingClientRect();
  with (this.div.style) {
    if (bcr.height >= window.innerHeight) {
      top = window.pageYOffset + 'px';
    } else if (bcr.bottom > window.innerHeight) {
      top = (window.pageYOffset + window.innerHeight - bcr.height) + 'px';
    }
  }
};
<commit_msg>Use normal instead of px.<commit_after>function TranslationBox() {
  this.div = document.createElement('div');
  this.opacity = 0;
  with (this.div.style) {
    zIndex = 2147483647;
    position = 'absolute';
    background = '#000000';
    color = '#ffffff';
    fontFamily = 'Hiragino Mincho Pro';
    fontSize = '11px';
    opacity = '0';
    textAlign = 'left';
    display = 'block';
    borderRadius = '5px';
    lineHeight = 'normal';
    webkitFontSmoothing = 'auto';
  }
  document.body.appendChild(this.div);
}

TranslationBox.prototype.Fadein = function() {
  var self = this;
  clearInterval(self.fadeinSt);
  clearInterval(self.fadeoutSt);
  self.fadeinSt = setInterval(function() {
    self.div.style.opacity = self.opacity / 100;
    if (self.opacity == 75) {
      clearInterval(self.fadeinSt);
    } else {
      self.opacity += 5;
    }
  }, 10);
};

TranslationBox.prototype.Fadeout = function() {
  var self = this;
  clearInterval(self.fadeoutSt);
  clearInterval(self.fadeinSt);
  self.fadeoutSt = setInterval(function() {
    self.div.style.opacity = self.opacity / 100;
    if (self.opacity == 0) {
      self.div.innerHTML = '';
      clearInterval(self.fadeoutSt);
    } else {
      self.opacity -= 5;
    }
  }, 10);
};

TranslationBox.prototype.SetContent = function(results) {
  this.content = [];
  for (var i = 0; i < results.length; ++i) {
    var key = results[i].originalKey || results[i].key;
    var value = results[i].value;
    this.content.push({word: key, translation: value});
  }

  this.div.innerHTML = "";
  for (var i = 0; i < this.content.length; ++i) {
    var c = this.content[i];
    this.div.innerHTML +=
    ('' + (i + 1) + '. ' + c.word +
     '\n
' + c.translation + '
').
      replace(/\n/g, '
');
  }
};

TranslationBox.prototype.GetContent = function() {
  return this.content;
};

TranslationBox.prototype.SetLocation = function(mouse) {
  this.mouse = mouse;
  this.AdjustLocation();
};

TranslationBox.prototype.AdjustLocation = function() {
  // Redraw translation box.
  var box_width = Math.min(400, window.innerWidth);
  var box_left = Math.min(window.innerWidth - box_width, this.mouse.clientX) +
        this.mouse.pageX - this.mouse.clientX + 2;
  var box_top = this.mouse.pageY + 10;
  with (this.div.style) {
    width = box_width + 'px';
    left = box_left + 'px';
    top = box_top + 'px';
  }

  // Adjust when bottom of the translation box is out of the window.
  var bcr = this.div.getBoundingClientRect();
  with (this.div.style) {
    if (bcr.height >= window.innerHeight) {
      top = window.pageYOffset + 'px';
    } else if (bcr.bottom > window.innerHeight) {
      top = (window.pageYOffset + window.innerHeight - bcr.height) + 'px';
    }
  }
};
<|endoftext|>


<commit_before>const timingHistoryChartConfig = {
    'width': 800,
    'height': 500,
    'autosize': 'fit',
    'data': [
        {
            'name': 'table',
            'values': [
            ],
            'transform': [
                {
                    'type': 'formula',
                    'as': 'adjElapsed',
                    'expr': 'clamp(datum.elapsed/1000,-86400,86400)'
                }
            ]
        },
        {
            'name': 'min_y',
            'values': []
        },
        {
            'name': 'stacked',
            'source': 'table',
            'transform': [
                {
                    'type': 'stack',
                    'groupby': ['id'],
                    'field': 'adjElapsed'
                }
            ]
        },
        {
            'name': 'stats',
            'source': 'table',
            'transform': [
                {
                    'type': 'aggregate',
                    'groupby': ['id', 'title', 'currentStatus'],
                    'fields': ['adjElapsed'],
                    'ops': ['sum'],
                    'as': ['sum_y']
                },
                {
                    'type': 'formula',
                    'as': 'min_y',
                    'expr': 'data("min_y")[0].data'
                }
            ]
        }
    ],
    'scales': [
        {
            'name': 'x',
            'type': 'band',
            'range': 'width',
            'domain': { 'data': 'table', 'field': 'id' }
        },
        {
            'name': 'y',
            'type': 'linear',
            'range': 'height',
            'clamp': true,
            'domain': {
                'fields': [
                    { 'data': 'table', 'field': 'adjElapsed' },
                    { 'data': 'stats', 'field': 'sum_y' }
                ]
            }
        },
        {
            'name': 'color',
            'type': 'ordinal',
            'range': 'category20c',
            'domain': [{ 'data': 'table', 'field': 'status' }]
        },
        {
            'name': 'xlabels',
            'type': 'ordinal',
            'domain': [],
            'range': []
        }
    ],
    'axes': [
        {
            'scale': 'x',
            'orient': 'bottom',
            'encode': {
                'labels': {
                    'update': {
                        'text': { 'field': 'value', 'scale': 'xlabels' },
                        'angle': { 'value': 50 },
                        'align': { 'value': 'left' },
                        'dy': { 'value': 5 },
                        'dx': { 'value': 7 }
                    }
                }
            }
        },
        {
            'orient': 'left',
            'scale': 'y',
            'format': 's',
            'title': 'seconds',
            'encode': {
                'labels': {
                    'update': {
                        'itemName': { 'value': 'ylabel' }
                    }
                }
            }
        }
    ],
    'signals': [
        {
            'name': 'hover',
            'value': { 'pos': {}, 'datum': {} },
            'on': [
                {
                    'events': '@timing:mousemove',
                    'update': '{ pos: {x: x(), y: y()}, datum:datum}'
                },
                {
                    'events': '@timing:mouseout',
                    'update': '{pos:{},datum:{}}'
                }
            ]
        },
        {
            'name': 'tt0',
            'value': {},
            'update': '{ title:hover.datum.title, updated:hover.datum.updated, status:!hover.datum.status?"":hover.datum.status+":", elapsed:abs(hover.datum["elapsed"]) }'
        },
        {
            'name': 'tt1',
            'value': {},
            'update': 'warn(tt0.elapsed, { elapsed:!tt0.elapsed?"":timeFormat(datetime(0,0,0,0,0,0,tt0.elapsed), tt0.elapsed>3600000? "%H:%M:%S.%Ls":(tt0.elapsed>60000?"%M:%S.%Ls":"%S.%Ls")) })'
        },
        {
            'name': 'tt2',
            'value': {},
            'update': '{ width:!tt0.title?0:max(max(max(tt0.title.length,tt0.status.length),tt1.elapsed.length),tt0.updated.length)*7 }'
        },
        {
            'name': 'tooltip',
            'value': {},
            'update': '{ y:hover.pos.y+30, x:(hover.pos.x>width-tt2.width-5?hover.pos.x-tt2.width-5:hover.pos.x+5), width:tt2.width, title:tt0.title, updated:tt0.updated, status:tt0.status, elapsed:tt1.elapsed }'
        },
        {
            'name': 'sHover',
            'value': { 'pos': {}, 'datum': {} },
            'on': [
                {
                    'events': '@statusmark:mousemove',
                    'update': '{ pos: {x: x(), y: y()}, datum:datum}'
                },
                {
                    'events': '@statusmark:mouseout',
                    'update': '{pos:{},datum:{}}'
                }
            ]
        },
        {
            'name': 'stt0',
            'value': {},
            'update': '{ status:sHover.datum?sHover.datum.currentStatus:"" }'
        },
        {
            'name': 'stt1',
            'value': {},
            'update': '{ width:(stt0.status?stt0.status.length:0)*9 }'
        },
        {
            'name': 'sTooltip',
            'value': {},
            'update': '{ y:sHover.pos.y+30, x:(sHover.pos.x>width-stt1.width-7?sHover.pos.x-stt1.width-5:sHover.pos.x+5), width:stt1.width, status:stt0.status }'
        }
    ],
    'marks': [
        {
            'type': 'rect',
            'name': 'timing',
            'from': {
                'data': 'stacked'
            },
            'encode': {
                'enter': {
                    'x': { 'scale': 'x', 'field': 'id' },
                    'width': { 'scale': 'x', 'band': true, 'offset': -2 },
                    'y': { 'scale': 'y', 'field': 'y0' },
                    'y2': { 'scale': 'y', 'field': 'y1' },
                    'fill': { 'scale': 'color', 'field': 'status' },
                    'itemName': { 'value': 'bar' },
                    'cursor': { 'value': 'pointer' }
                },
                'update': { 'fillOpacity': { 'value': 1 } },
                'hover': {
                    'fillOpacity': { 'value': 0.5 }
                }
            }
        },
        {
            'name': 'statusmarkbase',
            'type': 'rect',
            'from': {
                'data': 'stats'
            },
            'encode': {
                'enter': {
                    'width': { 'scale': 'x', 'band': true, 'offset': -4 },
                    'height': { 'value': 6 },
                    'x': { 'scale': 'x', 'field': 'id', 'offset': 1 },
                    'y': { 'scale': 'y', 'field': 'min_y', 'offset': 9 },
                    'fill': { 'value': 'rgb(204,204,204)' },
                    'itemName': { 'value': 'status' }
                },
                'update': { 'fillOpacity': { 'value': 1 } },
                'hover': {
                    'fillOpacity': { 'value': 0.5 }
                }
            }
        },
        {
            'name': 'statusmark',
            'type': 'rect',
            'from': {
                'data': 'stats'
            },
            'encode': {
                'enter': {
                    'width': { 'scale': 'x', 'band': true, 'offset': -4 },
                    'height': { 'value': 6 },
                    'x': { 'scale': 'x', 'field': 'id', 'offset': 1 },
                    'y': { 'scale': 'y', 'field': 'min_y', 'offset': 9 },
                    'fill': { 'scale': 'color', 'field': 'currentStatus' },
                    'itemName': { 'value': 'status' }
                },
                'update': { 'fillOpacity': { 'value': 1 } },
                'hover': {
                    'fillOpacity': { 'value': 0.5 }
                }
            }
        },
        {
            'name': 'timingTooltip',
            'type': 'group',
            'encode': {
                'update': {
                    'x': { 'signal': 'tooltip.x' },
                    'y': { 'signal': 'tooltip.y' },
                    'width': { 'signal': 'tooltip.width' },
                    'height': { 'value': 65 },
                    'fill': { 'value': '#fff' },
                    'fillOpacity': { 'value': 1 },
                    'stroke': { 'value': '#aaa' },
                    'strokeWidth': { 'value': 0.5 }
                }
            },
            'marks': [
                {
                    'name': 'title',
                    'type': 'text',
                    'encode': {
                        'update': {
                            'x': { 'value': 6 },
                            'y': { 'value': 14 },
                            'text': { 'signal': 'tooltip.title' },
                            'fill': { 'value': 'black' }
                        }
                    }
                },
                {
                    'name': 'updated',
                    'type': 'text',
                    'encode': {
                        'update': {
                            'x': { 'value': 6 },
                            'y': { 'value': 29 },
                            'text': { 'signal': 'tooltip.updated' },
                            'fill': { 'value': 'black' }
                        }
                    }
                },
                {
                    'name': 'status',
                    'type': 'text',
                    'encode': {
                        'update': {
                            'x': { 'value': 6 },
                            'y': { 'value': 44 },
                            'text': { 'signal': 'tooltip.status' },
                            'fill': { 'value': 'black' },
                            'fontWeight': { 'value': 'bold' }
                        }
                    }
                },
                {
                    'name': 'elapsed',
                    'type': 'text',
                    'encode': {
                        'update': {
                            'x': { 'value': 6 },
                            'y': { 'value': 59 },
                            'text': { 'signal': 'tooltip.elapsed' },
                            'fill': { 'value': 'black' },
                            'fontWeight': { 'value': 'bold' }
                        }
                    }
                }
            ]
        },
        {
            'name': 'statusTooltip',
            'type': 'group',
            'encode': {
                'update': {
                    'x': { 'signal': 'sTooltip.x' },
                    'y': { 'signal': 'sTooltip.y' },
                    'width': { 'signal': 'sTooltip.width' },
                    'height': { 'value': 24 },
                    'fill': { 'value': '#fff' },
                    'fillOpacity': { 'value': 1 },
                    'stroke': { 'value': '#aaa' },
                    'strokeWidth': { 'value': 0.5 }
                }
            },
            'marks': [
                {
                    'name': 'status',
                    'type': 'text',
                    'encode': {
                        'update': {
                            'x': { 'value': 8 },
                            'y': { 'value': 16 },
                            'text': { 'signal': 'sTooltip.status' },
                            'fill': { 'value': 'black' },
                            'fontWeight': { 'value': 'bold' }
                        }
                    }
                }
            ]
        }
    ],
    'legends': [
        {
            'fill': 'color',
            'title': 'Selected Phases',
            'offset': 20,
            'encode': {
                'title': {
                    'update': {
                        'fontSize': { 'value': 12 }
                    }
                },
                'symbols': {
                    'update': {
                        'shape': { 'value': 'square' }
                    }
                },
                'labels': {
                    'update': {
                        'fontSize': { 'value': 12 }
                    }
                }
            }
        }
    ]
};

export default timingHistoryChartConfig;
<commit_msg>Remove a stray `warn()` directive<commit_after>const timingHistoryChartConfig = {
    'width': 800,
    'height': 500,
    'autosize': 'fit',
    'data': [
        {
            'name': 'table',
            'values': [
            ],
            'transform': [
                {
                    'type': 'formula',
                    'as': 'adjElapsed',
                    'expr': 'clamp(datum.elapsed/1000,-86400,86400)'
                }
            ]
        },
        {
            'name': 'min_y',
            'values': []
        },
        {
            'name': 'stacked',
            'source': 'table',
            'transform': [
                {
                    'type': 'stack',
                    'groupby': ['id'],
                    'field': 'adjElapsed'
                }
            ]
        },
        {
            'name': 'stats',
            'source': 'table',
            'transform': [
                {
                    'type': 'aggregate',
                    'groupby': ['id', 'title', 'currentStatus'],
                    'fields': ['adjElapsed'],
                    'ops': ['sum'],
                    'as': ['sum_y']
                },
                {
                    'type': 'formula',
                    'as': 'min_y',
                    'expr': 'data("min_y")[0].data'
                }
            ]
        }
    ],
    'scales': [
        {
            'name': 'x',
            'type': 'band',
            'range': 'width',
            'domain': { 'data': 'table', 'field': 'id' }
        },
        {
            'name': 'y',
            'type': 'linear',
            'range': 'height',
            'clamp': true,
            'domain': {
                'fields': [
                    { 'data': 'table', 'field': 'adjElapsed' },
                    { 'data': 'stats', 'field': 'sum_y' }
                ]
            }
        },
        {
            'name': 'color',
            'type': 'ordinal',
            'range': 'category20c',
            'domain': [{ 'data': 'table', 'field': 'status' }]
        },
        {
            'name': 'xlabels',
            'type': 'ordinal',
            'domain': [],
            'range': []
        }
    ],
    'axes': [
        {
            'scale': 'x',
            'orient': 'bottom',
            'encode': {
                'labels': {
                    'update': {
                        'text': { 'field': 'value', 'scale': 'xlabels' },
                        'angle': { 'value': 50 },
                        'align': { 'value': 'left' },
                        'dy': { 'value': 5 },
                        'dx': { 'value': 7 }
                    }
                }
            }
        },
        {
            'orient': 'left',
            'scale': 'y',
            'format': 's',
            'title': 'seconds',
            'encode': {
                'labels': {
                    'update': {
                        'itemName': { 'value': 'ylabel' }
                    }
                }
            }
        }
    ],
    'signals': [
        {
            'name': 'hover',
            'value': { 'pos': {}, 'datum': {} },
            'on': [
                {
                    'events': '@timing:mousemove',
                    'update': '{ pos: {x: x(), y: y()}, datum:datum}'
                },
                {
                    'events': '@timing:mouseout',
                    'update': '{pos:{},datum:{}}'
                }
            ]
        },
        {
            'name': 'tt0',
            'value': {},
            'update': '{ title:hover.datum.title, updated:hover.datum.updated, status:!hover.datum.status?"":hover.datum.status+":", elapsed:abs(hover.datum["elapsed"]) }'
        },
        {
            'name': 'tt1',
            'value': {},
            'update': '{ elapsed:!tt0.elapsed?"":timeFormat(datetime(0,0,0,0,0,0,tt0.elapsed), tt0.elapsed>3600000? "%H:%M:%S.%Ls":(tt0.elapsed>60000?"%M:%S.%Ls":"%S.%Ls")) }'
        },
        {
            'name': 'tt2',
            'value': {},
            'update': '{ width:!tt0.title?0:max(max(max(tt0.title.length,tt0.status.length),tt1.elapsed.length),tt0.updated.length)*7 }'
        },
        {
            'name': 'tooltip',
            'value': {},
            'update': '{ y:hover.pos.y+30, x:(hover.pos.x>width-tt2.width-5?hover.pos.x-tt2.width-5:hover.pos.x+5), width:tt2.width, title:tt0.title, updated:tt0.updated, status:tt0.status, elapsed:tt1.elapsed }'
        },
        {
            'name': 'sHover',
            'value': { 'pos': {}, 'datum': {} },
            'on': [
                {
                    'events': '@statusmark:mousemove',
                    'update': '{ pos: {x: x(), y: y()}, datum:datum}'
                },
                {
                    'events': '@statusmark:mouseout',
                    'update': '{pos:{},datum:{}}'
                }
            ]
        },
        {
            'name': 'stt0',
            'value': {},
            'update': '{ status:sHover.datum?sHover.datum.currentStatus:"" }'
        },
        {
            'name': 'stt1',
            'value': {},
            'update': '{ width:(stt0.status?stt0.status.length:0)*9 }'
        },
        {
            'name': 'sTooltip',
            'value': {},
            'update': '{ y:sHover.pos.y+30, x:(sHover.pos.x>width-stt1.width-7?sHover.pos.x-stt1.width-5:sHover.pos.x+5), width:stt1.width, status:stt0.status }'
        }
    ],
    'marks': [
        {
            'type': 'rect',
            'name': 'timing',
            'from': {
                'data': 'stacked'
            },
            'encode': {
                'enter': {
                    'x': { 'scale': 'x', 'field': 'id' },
                    'width': { 'scale': 'x', 'band': true, 'offset': -2 },
                    'y': { 'scale': 'y', 'field': 'y0' },
                    'y2': { 'scale': 'y', 'field': 'y1' },
                    'fill': { 'scale': 'color', 'field': 'status' },
                    'itemName': { 'value': 'bar' },
                    'cursor': { 'value': 'pointer' }
                },
                'update': { 'fillOpacity': { 'value': 1 } },
                'hover': {
                    'fillOpacity': { 'value': 0.5 }
                }
            }
        },
        {
            'name': 'statusmarkbase',
            'type': 'rect',
            'from': {
                'data': 'stats'
            },
            'encode': {
                'enter': {
                    'width': { 'scale': 'x', 'band': true, 'offset': -4 },
                    'height': { 'value': 6 },
                    'x': { 'scale': 'x', 'field': 'id', 'offset': 1 },
                    'y': { 'scale': 'y', 'field': 'min_y', 'offset': 9 },
                    'fill': { 'value': 'rgb(204,204,204)' },
                    'itemName': { 'value': 'status' }
                },
                'update': { 'fillOpacity': { 'value': 1 } },
                'hover': {
                    'fillOpacity': { 'value': 0.5 }
                }
            }
        },
        {
            'name': 'statusmark',
            'type': 'rect',
            'from': {
                'data': 'stats'
            },
            'encode': {
                'enter': {
                    'width': { 'scale': 'x', 'band': true, 'offset': -4 },
                    'height': { 'value': 6 },
                    'x': { 'scale': 'x', 'field': 'id', 'offset': 1 },
                    'y': { 'scale': 'y', 'field': 'min_y', 'offset': 9 },
                    'fill': { 'scale': 'color', 'field': 'currentStatus' },
                    'itemName': { 'value': 'status' }
                },
                'update': { 'fillOpacity': { 'value': 1 } },
                'hover': {
                    'fillOpacity': { 'value': 0.5 }
                }
            }
        },
        {
            'name': 'timingTooltip',
            'type': 'group',
            'encode': {
                'update': {
                    'x': { 'signal': 'tooltip.x' },
                    'y': { 'signal': 'tooltip.y' },
                    'width': { 'signal': 'tooltip.width' },
                    'height': { 'value': 65 },
                    'fill': { 'value': '#fff' },
                    'fillOpacity': { 'value': 1 },
                    'stroke': { 'value': '#aaa' },
                    'strokeWidth': { 'value': 0.5 }
                }
            },
            'marks': [
                {
                    'name': 'title',
                    'type': 'text',
                    'encode': {
                        'update': {
                            'x': { 'value': 6 },
                            'y': { 'value': 14 },
                            'text': { 'signal': 'tooltip.title' },
                            'fill': { 'value': 'black' }
                        }
                    }
                },
                {
                    'name': 'updated',
                    'type': 'text',
                    'encode': {
                        'update': {
                            'x': { 'value': 6 },
                            'y': { 'value': 29 },
                            'text': { 'signal': 'tooltip.updated' },
                            'fill': { 'value': 'black' }
                        }
                    }
                },
                {
                    'name': 'status',
                    'type': 'text',
                    'encode': {
                        'update': {
                            'x': { 'value': 6 },
                            'y': { 'value': 44 },
                            'text': { 'signal': 'tooltip.status' },
                            'fill': { 'value': 'black' },
                            'fontWeight': { 'value': 'bold' }
                        }
                    }
                },
                {
                    'name': 'elapsed',
                    'type': 'text',
                    'encode': {
                        'update': {
                            'x': { 'value': 6 },
                            'y': { 'value': 59 },
                            'text': { 'signal': 'tooltip.elapsed' },
                            'fill': { 'value': 'black' },
                            'fontWeight': { 'value': 'bold' }
                        }
                    }
                }
            ]
        },
        {
            'name': 'statusTooltip',
            'type': 'group',
            'encode': {
                'update': {
                    'x': { 'signal': 'sTooltip.x' },
                    'y': { 'signal': 'sTooltip.y' },
                    'width': { 'signal': 'sTooltip.width' },
                    'height': { 'value': 24 },
                    'fill': { 'value': '#fff' },
                    'fillOpacity': { 'value': 1 },
                    'stroke': { 'value': '#aaa' },
                    'strokeWidth': { 'value': 0.5 }
                }
            },
            'marks': [
                {
                    'name': 'status',
                    'type': 'text',
                    'encode': {
                        'update': {
                            'x': { 'value': 8 },
                            'y': { 'value': 16 },
                            'text': { 'signal': 'sTooltip.status' },
                            'fill': { 'value': 'black' },
                            'fontWeight': { 'value': 'bold' }
                        }
                    }
                }
            ]
        }
    ],
    'legends': [
        {
            'fill': 'color',
            'title': 'Selected Phases',
            'offset': 20,
            'encode': {
                'title': {
                    'update': {
                        'fontSize': { 'value': 12 }
                    }
                },
                'symbols': {
                    'update': {
                        'shape': { 'value': 'square' }
                    }
                },
                'labels': {
                    'update': {
                        'fontSize': { 'value': 12 }
                    }
                }
            }
        }
    ]
};

export default timingHistoryChartConfig;
<|endoftext|>