<commit_before>// require esphinx_ui
// require esphinx/observer

var
    esPhinx,
    Flyweight,
    window;

(function ($module) {
    "use strict";

    var
        minimized = [],
        visible;

    $module.extend(true, {

        panels: {

            modal: {

                hide: function (animation) {
                    visible.hide(animation);
                },

                close: function () {
                    visible.close();
                },

                // functions are objects in js
                new: function (options) {
                    var
                        self = $module.panels.modal.new,
                        mainReference = this,

                        $ = esPhinx,
                        body = $("body"),
                        _classes = options.class || options.classes,
                        progress,
                        modal,
                        mask,
                        main,
                        loadingContainer,
                        container,
                        closeButton,
                        hideButton,
                        headers,
                        params,
                        instance,
                        _windowController,
                        timesUp,
                        calledback,
                        ready,
                        readyToShow,
                        instanceShowWasCalled,

                        isMinimized = function () {
                            var
                                index = minimized
                                .indexPerEquivalence(this);

                            if (index) {
                                return index;
                            }

                            return false;
                        },

                        addToMinimized = function () {
                            if (!isMinimized.call(this)) {
                                minimized.push(this);
                            }
                        },

                        removeFromMinimized = function () {
                            var
                                index = isMinimized.call(this);

                            if (index) {
                                minimized.delete(index);
                            }
                        },

                        maskTransitionDuration = function (mask) {
                            return parseFloat(mask
                                .css("transition-duration")) * 1000;
                        },

                        restartTransition = function (mask) {
                            mask.css("transition", "opacity 0s");
                        },

                        resolveParams = function () {
                            options = options || {};

                            if (typeof options.windowController != "boolean") {
                                _windowController = true;
                            } else {
                                _windowController = options.windowController;
                            }

                            if (typeof options.closeButton != "boolean") {
                                options.closeButton = true;
                            }

                            if (options.content) {
                                options.url = false;
                            }
                        },

                        create = function () {
                            modal = $("

")
                                .addClass("esphinx ui modal");

                            if (_classes) {
                                modal.addClass(_classes);
                            }

                            main = $("")
                                .addClass("hidden");
                            mask = $("

")
                                .addClass("fixed transparent mask");
                            container = $("

").addClass("container");
                            loadingContainer = $("

")
                                .addClass("container loading");

                            main.append(loadingContainer);

                            modal
                                .append(mask)
                                .append(main);

                            body.append(modal);

                            if (options.timeout) {
                                window.setTimeout(function () {
                                    if (options.timesUp &&
                                        typeof options.timesUp == "function" &&
                                                                        !ready) {
                                        timesUp = true;
                                        options.timesUp.call(mainReference);
                                    }
                                }, options.timeout * 1000);
                            }

                            observers(main, options);

                            if (options.url) {
                                headers = options.header || options.headers || null;
                                params = options.param || options.params || null;
                                $.Ajax.new(options.url, {
                                    params: params,
                                    headers: headers,
                                    progress: function () {
                                        if (options.loading) {
                                            if (!calledback) {
                                                calledback = true;
                                                options.loading
                                                    .call(mainReference);
                                            }
                                        }
                                    },
                                    success: function (a) {
                                        hide.call(mainReference, false);
                                        container.html(a);
                                    }
                                });
                            } else {
                                if (options.loading) {
                                    options.loading.call(mainReference);
                                }

                                hide.call(mainReference, false);
                                container.html(options.content);
                            }

                        },

                        bindHeaderEventListeners = function () {
                            if (closeButton) {
                                closeButton.on("click", function () {
                                    close.call(mainReference);
                                });
                            }

                            hideButton.on("click", function () {
                                hide.call(mainReference);
                            });
                        },

                        prependHeaderActions = function (main, options) {
                            var
                                header = main.find("header"),
                                actions;

                            if ((_windowController || timesUp) &&
                                !header.count()) {
                                header = $("");
                                actions = $("

").addClass("actions");
                                hideButton = $('')
                                    .addClass("hide-button");

                                header.append(actions);

                                if (options.closeButton || timesUp) {
                                    closeButton = $('')
                                        .addClass("close-button");
                                    actions.append(closeButton);
                                }

                                if (!timesUp) {
                                    actions.append(hideButton);
                                }

                                main
                                    .prepend(header)
                                    .css({
                                        "max-height": $(window.document).height(),
                                        "max-width": $(window.document).width()
                                    });

                                bindHeaderEventListeners();
                            }
                        },

                        show = function () {
                            // to execute without a complete key
                            $.FlowControl.new({
                                condition: function () {
                                    if (readyToShow) {
                                        return true;
                                    }

                                    return false;
                                },
                                ready: function () {
                                    modal.css("z-index", 0);

                                    if (options.fadeIn) {
                                        restartTransition(mask);
                                        mask.css("transition", "opacity " +
                                                 options.fadeIn);
                                    }

                                    mask.removeClass("transparent");
                                    main.show();

                                    visible = mainReference;

                                    removeFromMinimized.call(this);
                                }
                            });
                        },

                        // hide = function (animation = true) {
                        hide = function (animation) {
                            if (typeof animation !== "boolean") {
                                animation = true;
                            }

                            main.hide();

                            restartTransition(mask);
                            if (animation) {
                                if (options.fadeOut) {
                                    mask.css("transition", "opacity " +
                                             options.fadeOut);

                                    modal.css("z-index", -1,
                                        maskTransitionDuration(mask));
                                }
                            }
                            mask.addClass("transparent");
                            addToMinimized.call(this);
                        },

                        close = function () {
                            main.hide();

                            restartTransition(mask);
                            if (options.fadeOut) {
                                mask.css("transition", "opacity " +
                                         options.fadeOut);
                            }

                            mask.addClass("transparent");
                            modal.remove(maskTransitionDuration(mask));
                            mainReference.deleteSingleton();
                        },

                        observers = function (main, options) {
                            var
                                loadingContainerObserver;

                            main.observe(function () {
                                var
                                    count = 0,
                                    imgs = main.find("img");

                                if (imgs.some()) {
                                    imgs.select(function (img) {
                                        $(img).on("load", function (e) {
                                            count += 1;
                                        });
                                    });

                                    $.FlowControl.new({
                                        condition: function () {
                                            if (count == imgs.length ||
                                                timesUp) {
                                                return true;
                                            }

                                            return false;
                                        },
                                        ready: function () {
                                            main.centralizeAt(window.document);
                                            if (progress ||
                                                progress === undefined) {
                                                readyToShow = true;
                                                show.call(mainReference);
                                            }
                                        }
                                    });

                                } else {
                                    prependHeaderActions(main, options);
                                    main.centralizeAt(window.document);
                                    readyToShow = true;
                                    if (options.complete && !progress) {
                                        options.complete
                                            .call(mainReference);
                                    }
                                }

                            });

                            container.observe(function () {
                                var
                                    count = 0,
                                    imgs;

                                loadingContainerObserver = this;
                                imgs = container.find("img");

                                if (imgs.some()) {

                                    imgs.select(function (img) {
                                        $(img).on("load", function (e) {
                                            count += 1;
                                        });
                                    });

                                    $.FlowControl.new({
                                        condition: function () {
                                            progress = true;
                                            if (count == imgs.length ||
                                                timesUp) {
                                                return true;
                                            }

                                            return false;
                                        },
                                        ready: function () {
                                            progress = false;
                                            hide.call(mainReference, false);
                                            if (!timesUp) {
                                                main.html(container);
                                            }
                                            prependHeaderActions(main, options);
                                            main.centralizeAt(window.document);
                                            ready = true;
                                            readyToShow = true;
                                            if (instanceShowWasCalled) {
                                                show.call(mainReference);
                                            }

                                            if (options.complete) {
                                                options.complete
                                                    .call(mainReference);
                                            }
                                        }
                                    });

                                // doesn't have imgs
                                } else {
                                    progress = false;
                                    hide.call(mainReference, false);
                                    if (!timesUp) {
                                        main.html(container);
                                    }
                                    prependHeaderActions(main, options);
                                    main.centralizeAt(window.document);
                                    ready = true;
                                    readyToShow = true;
                                }

                                this.disconnect();
                            });
                        };

                    resolveParams();

                    if (!(this instanceof self)) {
                        // debugger
                        // if (!self.instance) {
                        //     return self.functionalSingleton(arguments);
                        // } else if (isMinimized.call(self.instance)) {
                        //     self.instance.show();
                        // }

                        instance = Flyweight
                            .exists(self, arguments);
                        if (!instance) {
                            return Flyweight.new(self, arguments);
                        } else if (isMinimized.call(instance)) {
                            mainReference = instance;
                            show.call(mainReference);
                        }

                    } else {
                        // global scope (public)

                        // this.hide = function (animation = true) {
                        this.hide = function (animation) {
                            if (typeof animation !== "boolean") {
                                animation = true;
                            }

                            hide.call(mainReference, animation);

                            return mainReference;
                        };

                        this.show = function () {
                            show.call(mainReference);
                            instanceShowWasCalled = true;

                            return mainReference;
                        };

                        this.close = function () {
                            close.call(mainReference);
                            return mainReference;
                        };

                        this.content = function (content) {
                            var
                                node = $(content);

                            if (!node.some()) {
                                node = window.document.createTextNode(content);
                            }

                            hide.call(mainReference, false);
                            loadingContainer.html(node);
                            return mainReference;
                        };

                        create();

                    }

                    return mainReference;
                }

            }

        }

    });

}(esPhinx.ui));
<commit_msg>adequations<commit_after>// require esphinx_ui
// require esphinx/observer

var
    esPhinx,
    FlyweightFactory,
    window;

(function ($module) {
    "use strict";

    var
        minimized = [],
        visible;

    $module.extend(true, {

        panels: {

            modal: {

                hide: function (animation) {
                    visible.hide(animation);
                },

                close: function () {
                    visible.close();
                },

                // functions are objects in js
                new: function (options) {
                    var
                        self = $module.panels.modal.new,
                        mainReference = this,

                        $ = esPhinx,
                        body = $("body"),
                        _classes = options.class || options.classes,
                        progress,
                        modal,
                        mask,
                        main,
                        loadingContainer,
                        container,
                        closeButton,
                        hideButton,
                        headers,
                        params,
                        instance,
                        _windowController,
                        timesUp,
                        calledback,
                        ready,
                        readyToShow,
                        instanceShowWasCalled,

                        isMinimized = function () {
                            var
                                index = minimized
                                .indexPerEquivalence(this);

                            if (index) {
                                return index;
                            }

                            return false;
                        },

                        addToMinimized = function () {
                            if (!isMinimized.call(this)) {
                                minimized.push(this);
                            }
                        },

                        removeFromMinimized = function () {
                            var
                                index = isMinimized.call(this);

                            if (index) {
                                minimized.delete(index);
                            }
                        },

                        maskTransitionDuration = function (mask) {
                            return parseFloat(mask
                                .css("transition-duration")) * 1000;
                        },

                        restartTransition = function (mask) {
                            mask.css("transition", "opacity 0s");
                        },

                        resolveParams = function () {
                            options = options || {};

                            if (typeof options.windowController != "boolean") {
                                _windowController = true;
                            } else {
                                _windowController = options.windowController;
                            }

                            if (typeof options.closeButton != "boolean") {
                                options.closeButton = true;
                            }

                            if (options.content) {
                                options.url = false;
                            }
                        },

                        create = function () {
                            modal = $("

")
                                .addClass("esphinx ui modal");

                            if (_classes) {
                                modal.addClass(_classes);
                            }

                            main = $("")
                                .addClass("hidden");
                            mask = $("

")
                                .addClass("fixed transparent mask");
                            container = $("

").addClass("container");
                            loadingContainer = $("

")
                                .addClass("container loading");

                            main.append(loadingContainer);

                            modal
                                .append(mask)
                                .append(main);

                            body.append(modal);

                            if (options.timeout) {
                                window.setTimeout(function () {
                                    if (options.timesUp &&
                                        typeof options.timesUp == "function" &&
                                                                        !ready) {
                                        timesUp = true;
                                        options.timesUp.call(mainReference);
                                    }
                                }, options.timeout * 1000);
                            }

                            observers(main, options);

                            if (options.url) {
                                headers = options.header || options.headers || null;
                                params = options.param || options.params || null;
                                $.Ajax.new(options.url, {
                                    params: params,
                                    headers: headers,
                                    progress: function () {
                                        if (options.loading) {
                                            if (!calledback) {
                                                calledback = true;
                                                options.loading
                                                    .call(mainReference);
                                            }
                                        }
                                    },
                                    success: function (a) {
                                        hide.call(mainReference, false);
                                        container.html(a);
                                    }
                                });
                            } else {
                                if (options.loading) {
                                    options.loading.call(mainReference);
                                }

                                hide.call(mainReference, false);
                                container.html(options.content);
                            }

                        },

                        bindHeaderEventListeners = function () {
                            if (closeButton) {
                                closeButton.on("click", function () {
                                    close.call(mainReference);
                                });
                            }

                            hideButton.on("click", function () {
                                hide.call(mainReference);
                            });
                        },

                        prependHeaderActions = function (main, options) {
                            var
                                header = main.find("header"),
                                actions;

                            if ((_windowController || timesUp) &&
                                !header.count()) {
                                header = $("");
                                actions = $("

").addClass("actions");
                                hideButton = $('')
                                    .addClass("hide-button");

                                header.append(actions);

                                if (options.closeButton || timesUp) {
                                    closeButton = $('')
                                        .addClass("close-button");
                                    actions.append(closeButton);
                                }

                                if (!timesUp) {
                                    actions.append(hideButton);
                                }

                                main
                                    .prepend(header)
                                    .css({
                                        "max-height": $(window.document).height(),
                                        "max-width": $(window.document).width()
                                    });

                                bindHeaderEventListeners();
                            }
                        },

                        show = function () {
                            // to execute without a complete key
                            $.FlowControl.new({
                                condition: function () {
                                    if (readyToShow) {
                                        return true;
                                    }

                                    return false;
                                },
                                ready: function () {
                                    modal.css("z-index", 0);

                                    if (options.fadeIn) {
                                        restartTransition(mask);
                                        mask.css("transition", "opacity " +
                                                 options.fadeIn);
                                    }

                                    mask.removeClass("transparent");
                                    main.show();

                                    visible = mainReference;

                                    removeFromMinimized.call(this);
                                }
                            });
                        },

                        // hide = function (animation = true) {
                        hide = function (animation) {
                            if (typeof animation !== "boolean") {
                                animation = true;
                            }

                            main.hide();

                            restartTransition(mask);
                            if (animation) {
                                if (options.fadeOut) {
                                    mask.css("transition", "opacity " +
                                             options.fadeOut);

                                    modal.css("z-index", -1,
                                        maskTransitionDuration(mask));
                                }
                            }
                            mask.addClass("transparent");
                            addToMinimized.call(this);
                        },

                        close = function () {
                            main.hide();

                            restartTransition(mask);
                            if (options.fadeOut) {
                                mask.css("transition", "opacity " +
                                         options.fadeOut);
                            }

                            mask.addClass("transparent");
                            modal.remove(maskTransitionDuration(mask));
                            mainReference.deleteSingleton();
                        },

                        observers = function (main, options) {
                            var
                                loadingContainerObserver;

                            main.observe(function () {
                                var
                                    count = 0,
                                    imgs = main.find("img");

                                if (imgs.some()) {
                                    imgs.select(function (img) {
                                        $(img).on("load", function (e) {
                                            count += 1;
                                        });
                                    });

                                    $.FlowControl.new({
                                        condition: function () {
                                            if (count == imgs.length ||
                                                timesUp) {
                                                return true;
                                            }

                                            return false;
                                        },
                                        ready: function () {
                                            main.centralizeAt(window.document);
                                            if (progress ||
                                                progress === undefined) {
                                                readyToShow = true;
                                                show.call(mainReference);
                                            }
                                        }
                                    });

                                } else {
                                    prependHeaderActions(main, options);
                                    main.centralizeAt(window.document);
                                    readyToShow = true;
                                    if (options.complete && !progress) {
                                        options.complete
                                            .call(mainReference);
                                    }
                                }

                            });

                            container.observe(function () {
                                var
                                    count = 0,
                                    imgs;

                                loadingContainerObserver = this;
                                imgs = container.find("img");

                                if (imgs.some()) {

                                    imgs.select(function (img) {
                                        $(img).on("load", function (e) {
                                            count += 1;
                                        });
                                    });

                                    $.FlowControl.new({
                                        condition: function () {
                                            progress = true;
                                            if (count == imgs.length ||
                                                timesUp) {
                                                return true;
                                            }

                                            return false;
                                        },
                                        ready: function () {
                                            progress = false;
                                            hide.call(mainReference, false);
                                            if (!timesUp) {
                                                main.html(container);
                                            }
                                            prependHeaderActions(main, options);
                                            main.centralizeAt(window.document);
                                            ready = true;
                                            readyToShow = true;
                                            if (instanceShowWasCalled) {
                                                show.call(mainReference);
                                            }

                                            if (options.complete) {
                                                options.complete
                                                    .call(mainReference);
                                            }
                                        }
                                    });

                                // doesn't have imgs
                                } else {
                                    progress = false;
                                    hide.call(mainReference, false);
                                    if (!timesUp) {
                                        main.html(container);
                                    }
                                    prependHeaderActions(main, options);
                                    main.centralizeAt(window.document);
                                    ready = true;
                                    readyToShow = true;
                                }

                                this.disconnect();
                            });
                        };

                    resolveParams();

                    if (!(this instanceof self)) {
                        // debugger
                        // if (!self.instance) {
                        //     return self.functionalSingleton(arguments);
                        // } else if (isMinimized.call(self.instance)) {
                        //     self.instance.show();
                        // }

                        instance = FlyweightFactory
                            .exists(self, arguments);
                        if (!instance) {
                            return FlyweightFactory.new(self, arguments);
                        } else if (isMinimized.call(instance)) {
                            mainReference = instance;
                            show.call(mainReference);
                        }

                    } else {
                        // global scope (public)

                        // this.hide = function (animation = true) {
                        this.hide = function (animation) {
                            if (typeof animation !== "boolean") {
                                animation = true;
                            }

                            hide.call(mainReference, animation);

                            return mainReference;
                        };

                        this.show = function () {
                            show.call(mainReference);
                            instanceShowWasCalled = true;

                            return mainReference;
                        };

                        this.close = function () {
                            close.call(mainReference);
                            return mainReference;
                        };

                        this.content = function (content) {
                            var
                                node = $(content);

                            if (!node.some()) {
                                node = window.document.createTextNode(content);
                            }

                            hide.call(mainReference, false);
                            loadingContainer.html(node);
                            return mainReference;
                        };

                        create();

                    }

                    return mainReference;
                }

            }

        }

    });

}(esPhinx.ui));
<|endoftext|>


<commit_before>class FormFields {
    constructor() {
        this.id = null;
        this.nodesRef = null;
    }

    setId() {
        let id = "",
            length = 32,
            charSet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        for(let i = 0; i < length; i++) {
            let index = Math.floor(Math.random() * charSet.length);
            id += charSet[index];
        }
        return id;
    }
}

class MaterialText extends FormFields {
    constructor(toolTip, rxPattern, rxDesc, required, name, label, value) {
        super();
        this.id            = this.setId();
        this.toolTip       = toolTip || "";
        this.rxPattern     = rxPattern || "";
        this.rxDesc        = rxDesc || "";
        this.required      = required || false;
        this.name          = name || "";
        this.label         = label || "";
        this.value         = value || "";
        this.validInput    = "";
        this.containerNode = "";
        this.labelNode     = "";
        this.inputNode     = "";
        this.nodesRef      = this.generateTree();
        this.validity      = true;

        this.addTextFieldListeners();

        document.getElementById("clouds-form-options")
            .addEventListener("keypress", e => {
                let key = e.charCode || e.keyCode || 0;
                if(key === 13) e.preventDefault();
            });
    }

    generateTree() {
        let c = document.createElement("div"),
            l = document.createElement("label"),
            i = document.createElement("input");

        c.classList.add("text");

        l.classList.add("label-field");
        l.innerText = this.label;
        l.setAttribute("for", this.id);

        i.id = this.id;
        i.value = this.value;
        i.setAttribute("type", "text");
        i.setAttribute("name", this.name);
        if(this.required) {
            i.setAttribute("required", "");
        }

        c.appendChild(l);
        c.appendChild(i);

        this.containerNode = c;
        this.labelNode     = l;
        this.inputNode     = i;

        return c;
    }

    modifyTextFieldLabel(e) {
        if(!this.labelNode) {
            return;
        }
        this.labelNode.classList.toggle("label-field-focus", this.focused);
        this.labelNode.classList.toggle("label-field-filled", this.value);
    }

    modifyTooltip(e) {
        let toolTip;
        /**if(this.toolTip && this.inputNode === document.activeElement) {
            toolTip = this.label ? "" + this.label + "
" + this.toolTip : this.toolTip;
            tooltipContainer.innerHTML = toolTip;
        } else {
            return;
        }**/
    }

    showErrorMessages() {
        let errorInfo = this.containerNode.querySelectorAll(".error-info")[0];
        if(this.inputNode.classList.contains("invalid")) {
            if(!errorInfo) {
                errorInfo = document.createElement("span");
                if(this.required) {
                    errorInfo.innerText = "Required; " + this.rxDesc;
                } else {
                    errorInfo.innerText = this.rxDesc;
                }
                errorInfo.classList.add("error-info");
                this.containerNode.appendChild(errorInfo);
            }
        } else if(errorInfo) {
            this.containerNode.removeChild(errorInfo);
        }
    }

    validateInputEvent(e) {
        let rx = new RegExp(this.rxPattern);
        this.validity = rx.test(this.value);

        if(this.rxPattern && this.rxPattern.length > 0) {
            if(this.validity) {
                this.inputNode.className = "";
            } else if(!this.value.length > 0) {
                this.inputNode.className = "";
                if(!this.required) {
                    this.validity = true;
                }
            } else {
                this.inputNode.className = "";
                this.inputNode.classList.add("invalid");
            }
        }
        if(this.validity || this.value === "") {
            this.validInput = this.value;
        }

        this.showErrorMessages();

        return true;
    }

    addTextFieldListeners() {
        let modifyTextFieldLabel = this.modifyTextFieldLabel.bind(this),
            modifyTooltip = this.modifyTooltip.bind(this),
            validateInputEvent = this.validateInputEvent.bind(this);

        this.inputNode.addEventListener("focus", modifyTextFieldLabel);
        this.inputNode.addEventListener("blur", modifyTextFieldLabel);
        this.inputNode.focus();
        this.inputNode.blur();

        this.inputNode.addEventListener("focus", modifyTooltip);
        this.inputNode.addEventListener("blur", modifyTooltip);
        this.inputNode.addEventListener("input", validateInputEvent);
        this.inputNode.addEventListener("onchange", validateInputEvent);

        this.validateInputEvent();
    }

    get value() {
        this.value = this.inputNode.value || "";
        return this._value;
    }

    set value(value) {
        return this._value = value;
    }

    get focused() {
        return this.inputNode === document.activeElement;
    }
}

class MaterialSelect extends FormFields {
    constructor(selectableOptions, toolTip, sorted, changeCallback) {
        super();
        this.id                = this.setId();
        this.toolTip           = toolTip || "";
        this.value             = "";
        this.containerNode     = "";
        this.ulNode            = "";
        this.curOpt            = "";
        this.curIndex          = "";
        this._preSortIndex     = [];
        this.curOptNode        = "";
        this.optAllNode        = "";
        this.optionsNodes      = [];
        this.selectableOptions = selectableOptions || {};
        this.sorted            = sorted || false;
        this.changeCallback    = changeCallback || null;
        this.nodesRef          = this.generateTree();

        this.addSelectorListeners();
    }

    generateTree() {
        let s = document.createElement("div"), // Selector container
            u = document.createElement("ul"),  // Outer ul
            c = document.createElement("li"),  // Current option
            a = document.createElement("li");  // All options

        s.id = this.id;
        s.classList.add("selection-container");

        u.classList.add("select-input");

        c.id = "opt-cur";
        c.classList.add("opt-cur");

        a.id = "opt-all";
        a.classList.add("opt-all");

        s.appendChild(u);
        u.appendChild(c);
        u.appendChild(a);

        let _selectableKeys = Object.keys(this.selectableOptions),
            selectableKeys  = _selectableKeys.slice();
        if(this.sorted) {
            selectableKeys.sort((a, b) => a.localeCompare(b));
        }

        let groups = {};
        selectableKeys.forEach(key => {
            let n            = this.selectableOptions[key],
                preSortIndex = _selectableKeys.indexOf(key),
                index        = selectableKeys.indexOf(key);

            if(n.group.toLowerCase() === "default") {
                this.curOpt               = key;
                this.curIndex             = index;
                this.value                = n.value;
            }

            let tmp = document.createElement("li");
            tmp.innerText             = n.value;
            tmp.dataset.optionVal     = key;
            tmp.dataset.optionIndex   = index;
            this._preSortIndex[index] = preSortIndex;
            tmp.id                    = key.split(" ").join("-");
            this.curOptNode           = tmp;
            tmp.classList.add("material-select-option");
            this.optionsNodes.push(tmp);

            if(!(n.group in groups)) {
                let g     = document.createElement("div"), // Group container
                    group = n.group;
                g.classList.add("group");
                g.id = "group-" + group;
                groups[group] = g;
            }
            groups[n.group].appendChild(tmp);
        });

        Object.keys(groups)
            .sort((a, b) => b === "default" ? true : (a === "default" ? false : a.localeCompare(b)))
            .forEach(key => a.appendChild(groups[key]));

        c.innerText = this.value;

        this.containerNode = s;
        this.ulNode        = u;
        this.curOptNode    = c;
        this.optAllNode    = a;

        return s;
    }

    clickOffReset(e) {
        let target = e.target;
        let resetCallback = this.clickOffReset.bind(this);
        if(!this.containerNode.contains(target)){
            this.containerNode.classList.remove("showing");
            window.removeEventListener("click", resetCallback);
        }
    }

    chooseOptions(e) {
        let target = e.target;
        let isCurOpt = target === this.curOptNode;
        let resetCallback = this.clickOffReset.bind(this);
        window.addEventListener("click", resetCallback);
        if(isCurOpt) {
            this.containerNode.classList.toggle("showing");
            return;
        }
        else {
            this.containerNode.classList.remove("showing");
            window.removeEventListener("click", resetCallback);
        }
        if(target.classList.contains("material-select-option")) {
            this.curIndex = target.dataset.optionIndex;
            this.setOptionByIndex(this.Index);
        }
        if(this.changeCallback !== null) {
            this.changeCallback();
        }
    }

    addSelectorListeners(){
        let chooseOptions = this.chooseOptions.bind(this);
        this.containerNode.addEventListener("click", chooseOptions);
    }

    getInverseIndex(theIndex){
        return this._preSortIndex.indexOf(theIndex);
    }

    setOptionByIndex(presortIndex){
        let keys = Object.keys(this.selectableOptions),
            curOption = this.selectableOptions[keys[presortIndex]];
        this.curOpt = keys[presortIndex];
        this.value  = curOption.value;
        this.curOptNode.innerText = this.value;
    }

    nextItem(){
        if(this.curIndex < this._preSortIndex.length - 1){
            this.curIndex++;
            this.setOptionByIndex(this.Index);
            if(this.changeCallback) {
                this.changeCallback();
            }
        }
        return;
    }

    previousItem(){
        if(this.curIndex > 0){
            this.curIndex--;
            this.setOptionByIndex(this.Index);
            if(this.changeCallback) {
                this.changeCallback();
            }
        }
        return;
    }

    get Index(){
        return this._preSortIndex[this.curIndex];
    }

}
<commit_msg>Removed some unnecessary code.<commit_after>class FormFields {
    constructor() {
        this.id = null;
        this.nodesRef = null;
    }

    setId() {
        let id = "",
            length = 32,
            charSet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        for(let i = 0; i < length; i++) {
            let index = Math.floor(Math.random() * charSet.length);
            id += charSet[index];
        }
        return id;
    }
}

class MaterialText extends FormFields {
    constructor(toolTip, rxPattern, rxDesc, required, name, label, value) {
        super();
        this.id            = this.setId();
        this.toolTip       = toolTip || "";
        this.rxPattern     = rxPattern || "";
        this.rxDesc        = rxDesc || "";
        this.required      = required || false;
        this.name          = name || "";
        this.label         = label || "";
        this.value         = value || "";
        this.validInput    = "";
        this.containerNode = "";
        this.labelNode     = "";
        this.inputNode     = "";
        this.nodesRef      = this.generateTree();
        this.validity      = true;

        this.addTextFieldListeners();

        document.getElementById("clouds-form-options")
            .addEventListener("keypress", e => {
                let key = e.charCode || e.keyCode || 0;
                if(key === 13) e.preventDefault();
            });
    }

    generateTree() {
        let c = document.createElement("div"),
            l = document.createElement("label"),
            i = document.createElement("input");

        c.classList.add("text");

        l.classList.add("label-field");
        l.innerText = this.label;
        l.setAttribute("for", this.id);

        i.id = this.id;
        i.value = this.value;
        i.setAttribute("type", "text");
        i.setAttribute("name", this.name);
        if(this.required) {
            i.setAttribute("required", "");
        }

        c.appendChild(l);
        c.appendChild(i);

        this.containerNode = c;
        this.labelNode     = l;
        this.inputNode     = i;

        return c;
    }

    modifyTextFieldLabel(e) {
        if(!this.labelNode) {
            return;
        }
        this.labelNode.classList.toggle("label-field-focus", this.focused);
        this.labelNode.classList.toggle("label-field-filled", this.value);
    }

    modifyTooltip(e) {
        let toolTip;
        /**if(this.toolTip && this.inputNode === document.activeElement) {
            toolTip = this.label ? "" + this.label + "
" + this.toolTip : this.toolTip;
            tooltipContainer.innerHTML = toolTip;
        } else {
            return;
        }**/
    }

    showErrorMessages() {
        let errorInfo = this.containerNode.querySelectorAll(".error-info")[0];
        if(this.inputNode.classList.contains("invalid")) {
            if(!errorInfo) {
                errorInfo = document.createElement("span");
                if(this.required) {
                    errorInfo.innerText = "Required; " + this.rxDesc;
                } else {
                    errorInfo.innerText = this.rxDesc;
                }
                errorInfo.classList.add("error-info");
                this.containerNode.appendChild(errorInfo);
            }
        } else if(errorInfo) {
            this.containerNode.removeChild(errorInfo);
        }
    }

    validateInputEvent(e) {
        let rx = new RegExp(this.rxPattern);
        this.validity = rx.test(this.value);

        if(this.rxPattern && this.rxPattern.length > 0) {
            if(this.validity) {
                this.inputNode.className = "";
            } else if(!this.value.length > 0) {
                this.inputNode.className = "";
                if(!this.required) {
                    this.validity = true;
                }
            } else {
                this.inputNode.className = "";
                this.inputNode.classList.add("invalid");
            }
        }
        if(this.validity || this.value === "") {
            this.validInput = this.value;
        }

        this.showErrorMessages();

        return true;
    }

    addTextFieldListeners() {
        let modifyTextFieldLabel = this.modifyTextFieldLabel.bind(this),
            modifyTooltip = this.modifyTooltip.bind(this),
            validateInputEvent = this.validateInputEvent.bind(this);

        this.inputNode.addEventListener("focus", modifyTextFieldLabel);
        this.inputNode.addEventListener("blur", modifyTextFieldLabel);
        this.inputNode.focus();
        this.inputNode.blur();

        this.inputNode.addEventListener("focus", modifyTooltip);
        this.inputNode.addEventListener("blur", modifyTooltip);
        this.inputNode.addEventListener("input", validateInputEvent);
        this.inputNode.addEventListener("onchange", validateInputEvent);

        this.validateInputEvent();
    }

    get value() {
        this.value = this.inputNode.value || "";
        return this._value;
    }

    set value(value) {
        return this._value = value;
    }

    get focused() {
        return this.inputNode === document.activeElement;
    }
}

class MaterialSelect extends FormFields {
    constructor(selectableOptions, toolTip, sorted, changeCallback) {
        super();
        this.id                = this.setId();
        this.toolTip           = toolTip || "";
        this.value             = "";
        this.containerNode     = "";
        this.ulNode            = "";
        this.curOpt            = "";
        this.curIndex          = "";
        this._preSortIndex     = [];
        this.curOptNode        = "";
        this.optAllNode        = "";
        this.optionsNodes      = [];
        this.selectableOptions = selectableOptions || {};
        this.sorted            = sorted || false;
        this.changeCallback    = changeCallback || null;
        this.nodesRef          = this.generateTree();

        this.addSelectorListeners();
    }

    generateTree() {
        let s = document.createElement("div"), // Selector container
            u = document.createElement("ul"),  // Outer ul
            c = document.createElement("li"),  // Current option
            a = document.createElement("li");  // All options

        s.id = this.id;
        s.classList.add("selection-container");

        u.classList.add("select-input");

        c.id = "opt-cur";
        c.classList.add("opt-cur");

        a.id = "opt-all";
        a.classList.add("opt-all");

        s.appendChild(u);
        u.appendChild(c);
        u.appendChild(a);

        let _selectableKeys = Object.keys(this.selectableOptions),
            selectableKeys  = _selectableKeys.slice();
        if(this.sorted) {
            selectableKeys.sort((a, b) => a.localeCompare(b));
        }

        let groups = {};
        selectableKeys.forEach(key => {
            let n            = this.selectableOptions[key],
                preSortIndex = _selectableKeys.indexOf(key),
                index        = selectableKeys.indexOf(key);

            if(n.group.toLowerCase() === "default") {
                this.curOpt               = key;
                this.curIndex             = index;
                this.value                = n.value;
            }

            let tmp = document.createElement("li");
            tmp.innerText             = n.value;
            tmp.dataset.optionVal     = key;
            tmp.dataset.optionIndex   = index;
            this._preSortIndex[index] = preSortIndex;
            tmp.id                    = key.split(" ").join("-");
            this.curOptNode           = tmp;
            tmp.classList.add("material-select-option");
            this.optionsNodes.push(tmp);

            if(!(n.group in groups)) {
                let g     = document.createElement("div"), // Group container
                    group = n.group;
                g.classList.add("group");
                g.id = "group-" + group;
                groups[group] = g;
            }
            groups[n.group].appendChild(tmp);
        });

        Object.keys(groups)
            .sort((a, b) => b === "default" ? true : (a === "default" ? false : a.localeCompare(b)))
            .forEach(key => a.appendChild(groups[key]));

        c.innerText = this.value;

        this.containerNode = s;
        this.ulNode        = u;
        this.curOptNode    = c;
        this.optAllNode    = a;

        return s;
    }

    clickOffReset(e) {
        let target = e.target;
        let resetCallback = this.clickOffReset.bind(this);
        if(!this.containerNode.contains(target)){
            this.containerNode.classList.remove("showing");
            window.removeEventListener("click", resetCallback);
        }
    }

    chooseOptions(e) {
        let target = e.target;
        let isCurOpt = target === this.curOptNode;
        let resetCallback = this.clickOffReset.bind(this);
        window.addEventListener("click", resetCallback);
        if(isCurOpt) {
            this.containerNode.classList.toggle("showing");
            return;
        }
        else {
            this.containerNode.classList.remove("showing");
            window.removeEventListener("click", resetCallback);
        }
        if(target.classList.contains("material-select-option")) {
            this.curIndex = target.dataset.optionIndex;
            this.setOptionByIndex(this.Index);
        }
        if(this.changeCallback !== null) {
            this.changeCallback();
        }
    }

    addSelectorListeners(){
        let chooseOptions = this.chooseOptions.bind(this);
        this.containerNode.addEventListener("click", chooseOptions);
    }

    setOptionByIndex(presortIndex){
        let keys = Object.keys(this.selectableOptions),
            curOption = this.selectableOptions[keys[presortIndex]];
        this.curOpt = keys[presortIndex];
        this.value  = curOption.value;
        this.curOptNode.innerText = this.value;
    }

    nextItem(){
        if(this.curIndex < this._preSortIndex.length - 1){
            this.curIndex++;
            this.setOptionByIndex(this.Index);
            if(this.changeCallback) {
                this.changeCallback();
            }
        }
        return;
    }

    previousItem(){
        if(this.curIndex > 0){
            this.curIndex--;
            this.setOptionByIndex(this.Index);
            if(this.changeCallback) {
                this.changeCallback();
            }
        }
        return;
    }

    get Index(){
        return this._preSortIndex[this.curIndex];
    }

}
<|endoftext|>


<commit_before>import 'draft-js-inlineToolbar-plugin/lib/plugin.css'; // eslint-disable-line import/no-unresolved
<commit_msg>Fix css import typo<commit_after>import 'draft-js-inline-toolbar-plugin/lib/plugin.css'; // eslint-disable-line import/no-unresolved
<|endoftext|>


<commit_before>d3.queue()
    .defer(d3.json, '../json/nhv_neighborhoods.json')
    .defer(d3.json, '../json/nhv_tracts.json')
    .defer(d3.csv, '../data/workforce/underemployment_by_location.csv')
    .defer(d3.csv, '../data/workforce/underemployment_by_year.csv')
    .defer(d3.csv, '../data/workforce/unemployment_rate_by_year.csv')
    .defer(d3.csv, '../data/workforce/acs_public_transit_by_neighborhood.csv')
    .defer(d3.csv, '../data/workforce/acs_median_income_by_tract.csv')
    .await(init);

///////////// INIT
function init(error, hoods, tracts, underempLoc, underempTrend, unempTrend, transit, income) {
    if (error) throw error;

    underempLoc.forEach(function(d) {
        d.value = +d.value;
    });

    underempTrend.forEach(function(d) {
        d.value = +d.value;
    });

    unempTrend.forEach(function(d) {
        d.value = +d.value;
    });

    transit.forEach(function(d) {
        d.value = +d.value;
    });

    income.forEach(function(d) {
        d.value = +d.value;
    });

    var commuteMap = d3map();
    d3.select('#commute-map')
        .datum(topojson.feature(hoods, hoods.objects.shapes))
        .call(commuteMap);
    commuteMap.color(transit, choroscale)
        .tip('d3-tip', d3.format('.2p'), true)
        .legend(d3.format('.0%'), 15, 0);

    var incomeMap = d3map();
    d3.select('#income-map')
        .datum(topojson.feature(tracts, tracts.objects.nhv_tracts))
        .call(incomeMap);
    incomeMap.color(income, choroscale)
        .tip('d3-tip', d3.format('$,'), false)
        .legend(d3.format('$,'), 15, 0);

    var locationChart = makeUnderLocation(underempLoc);
    var underTrend = makeUnderTrend(underempTrend);
    var unTrend = makeUnTrend(unempTrend);

    d3.select(window).on('resize', function() {
        locationChart.draw(0, true);

        underTrend = makeUnderTrend(under_tr);
        unTrend = makeUnTrend(un_tr);

        commuteMap.draw();
        incomeMap.draw();

        redrawDots();
    });

    redrawDots();

}

function makeUnderLocation(data) {
    var margin = { top: 12, right: 18, bottom: 40, left: 100 };
    var svg = d3.select('#underemployment-chart')
        .append('svg')
        .attr('width', '100%')
        .attr('height', '100%');
        // .attr('viewBox', '0 0 ' + fullwidth + ' ' + fullheight);
    var chart = new dimple.chart(svg, data);
    chart.setMargins(margin.left, margin.top, margin.right, margin.bottom);
    chart.defaultColors = [ pink ];

    var y = chart.addCategoryAxis('y', 'name');
    y.addOrderRule(['CT', 'GNH', 'New Haven', 'NHV low-income', 'Other NHV'], true);
    y.title = null;

    var x = chart.addMeasureAxis('x', 'value');
    // x.title = '';
    x.tickFormat = '.0%';
    x.ticks = 4;
    x.title = null;

    var bars = chart.addSeries(null, dimple.plot.bar);

    chart.draw();

    var tip = d3.tip()
        .attr('class', 'd3-tip')
        .html(horizTip);

    svg.selectAll('rect.dimple-bar')
        .call(tip)
        .on('mouseover', function(d) {
            tip.show(d);
            barOver(this);
        })
        .on('mouseout', function(d) {
            tip.hide(d);
            barOut(this);
        })
        .on('touchend', function(d) {
            tip.show(d);
            barOver(this);
        });

    return chart;
}

function makeUnderTrend(data) {
    var margin = { top: 24, right: 32, bottom: 48, left: 32 };

    var svg = d3.select('#underemployment-trend')
        .select('svg')
        .attr('width', '100%')
        .attr('height', '100%')
        .html('');

    var chart = new dimple.chart(svg, data);
    chart.setMargins(margin.left, margin.top, margin.right, margin.bottom);

    var x = chart.addTimeAxis('x', 'year', '%Y', '%Y');
    x.title = null;

    var y = chart.addMeasureAxis('y', 'value');
    y.tickFormat = '.0%';
    y.ticks = 4;

    chart.defaultColors = [ ltblue, pink ];

    // var colorline = chart.addSeries('Type', dimple.plot.line);
    // colorline.lineMarkers = true;
    var past = dimple.filterData(data, 'type', 'past');
    var goal = dimple.filterData(data, 'type', 'goal');

    var goalline = chart.addSeries('type', dimple.plot.line);
    var pastline = chart.addSeries(null, dimple.plot.line);
    pastline.lineMarkers = true;
    goalline.lineMarkers = true;
    pastline.data = past;
    goalline.data = goal;

    // chart.addLegend('80%', '8%', '10%', '20%', 'right', colorline);
    chart.draw();

    d3.select('#dimple-goal')
        .style('stroke-dasharray', ('5, 5'));

    var tip = d3.tip()
        .attr('class', 'd3-tip')
        .html(trendTip);

    svg.selectAll('circle.dimple-marker')
        .call(tip)
        .on('mouseover', function(d) {
            tip.show(d);
            dotOver(this);
        })
        .on('mouseout', function(d) {
            tip.hide(d);
            dotOut(this);
        })
        .on('touchstart', function(d) {
            d3.event.preventDefault();
            tip.show(d);
            dotOver(this);
        });

    // svg.selectAll('.dimple-marker.dimple-goal:first-child')
    //     .attr('display', 'none');

    return chart;
}

function makeUnTrend(data) {
    var margin = { top: 24, right: 32, bottom: 48, left: 32 };

    var svg = d3.select('#unemployment-trend')
        .select('svg')
        .attr('width', '100%')
        .attr('height', '100%')
        .html('');

    var chart = new dimple.chart(svg, data);
    chart.setMargins(margin.left, margin.top, margin.right, margin.bottom);

    var x = chart.addTimeAxis('x', 'year', '%Y', '%Y');
    x.title = null;

    var y = chart.addMeasureAxis('y', 'value');
    y.tickFormat = '.0%';
    y.ticks = 6;

    chart.defaultColors = [ pink, ltblue ];

    var colorline = chart.addSeries('name', dimple.plot.line);
    colorline.lineMarkers = true;

    chart.addLegend('80%', '8%', '10%', '20%', 'right', colorline);
    chart.draw();

    var tip = d3.tip()
        .attr('class', 'd3-tip')
        .html(trendGroupTip);

    svg.selectAll('circle.dimple-marker')
        .call(tip)
        .on('mouseover', function(d) {
            tip.show(d);
            dotOver(this);
        })
        .on('mouseout', function(d) {
            tip.hide(d);
            dotOut(this);
        });

    return chart;
}
<commit_msg>Fix typos with workforce trends<commit_after>d3.queue()
    .defer(d3.json, '../json/nhv_neighborhoods.json')
    .defer(d3.json, '../json/nhv_tracts.json')
    .defer(d3.csv, '../data/workforce/underemployment_by_location.csv')
    .defer(d3.csv, '../data/workforce/underemployment_by_year.csv')
    .defer(d3.csv, '../data/workforce/unemployment_rate_by_year.csv')
    .defer(d3.csv, '../data/workforce/acs_public_transit_by_neighborhood.csv')
    .defer(d3.csv, '../data/workforce/acs_median_income_by_tract.csv')
    .await(init);

///////////// INIT
function init(error, hoods, tracts, underempLoc, underempTrend, unempTrend, transit, income) {
    if (error) throw error;

    underempLoc.forEach(function(d) {
        d.value = +d.value;
    });

    underempTrend.forEach(function(d) {
        d.value = +d.value;
    });

    unempTrend.forEach(function(d) {
        d.value = +d.value;
    });

    transit.forEach(function(d) {
        d.value = +d.value;
    });

    income.forEach(function(d) {
        d.value = +d.value;
    });

    var commuteMap = d3map();
    d3.select('#commute-map')
        .datum(topojson.feature(hoods, hoods.objects.shapes))
        .call(commuteMap);
    commuteMap.color(transit, choroscale)
        .tip('d3-tip', d3.format('.2p'), true)
        .legend(d3.format('.0%'), 15, 0);

    var incomeMap = d3map();
    d3.select('#income-map')
        .datum(topojson.feature(tracts, tracts.objects.nhv_tracts))
        .call(incomeMap);
    incomeMap.color(income, choroscale)
        .tip('d3-tip', d3.format('$,'), false)
        .legend(d3.format('$,'), 15, 0);

    var locationChart = makeUnderLocation(underempLoc);
    var underTrend = makeUnderTrend(underempTrend);
    var unTrend = makeUnTrend(unempTrend);

    d3.select(window).on('resize', function() {
        locationChart.draw(0, true);

        underTrend = makeUnderTrend(underempTrend);
        unTrend = makeUnTrend(unempTrend);

        commuteMap.draw();
        incomeMap.draw();

        redrawDots();
    });

    redrawDots();

}

function makeUnderLocation(data) {
    var margin = { top: 12, right: 18, bottom: 40, left: 100 };
    var svg = d3.select('#underemployment-chart')
        .append('svg')
        .attr('width', '100%')
        .attr('height', '100%');
        // .attr('viewBox', '0 0 ' + fullwidth + ' ' + fullheight);
    var chart = new dimple.chart(svg, data);
    chart.setMargins(margin.left, margin.top, margin.right, margin.bottom);
    chart.defaultColors = [ pink ];

    var y = chart.addCategoryAxis('y', 'name');
    y.addOrderRule(['CT', 'GNH', 'New Haven', 'NHV low-income', 'Other NHV'], true);
    y.title = null;

    var x = chart.addMeasureAxis('x', 'value');
    // x.title = '';
    x.tickFormat = '.0%';
    x.ticks = 4;
    x.title = null;

    var bars = chart.addSeries(null, dimple.plot.bar);

    chart.draw();

    var tip = d3.tip()
        .attr('class', 'd3-tip')
        .html(horizTip);

    svg.selectAll('rect.dimple-bar')
        .call(tip)
        .on('mouseover', function(d) {
            tip.show(d);
            barOver(this);
        })
        .on('mouseout', function(d) {
            tip.hide(d);
            barOut(this);
        })
        .on('touchend', function(d) {
            tip.show(d);
            barOver(this);
        });

    return chart;
}

function makeUnderTrend(data) {
    var margin = { top: 24, right: 32, bottom: 48, left: 32 };

    var svg = d3.select('#underemployment-trend')
        .select('svg')
        .attr('width', '100%')
        .attr('height', '100%')
        .html('');

    var chart = new dimple.chart(svg, data);
    chart.setMargins(margin.left, margin.top, margin.right, margin.bottom);

    var x = chart.addTimeAxis('x', 'year', '%Y', '%Y');
    x.title = null;

    var y = chart.addMeasureAxis('y', 'value');
    y.tickFormat = '.0%';
    y.ticks = 4;

    chart.defaultColors = [ ltblue, pink ];

    // var colorline = chart.addSeries('Type', dimple.plot.line);
    // colorline.lineMarkers = true;
    var past = dimple.filterData(data, 'type', 'past');
    var goal = dimple.filterData(data, 'type', 'goal');

    var goalline = chart.addSeries('type', dimple.plot.line);
    var pastline = chart.addSeries(null, dimple.plot.line);
    pastline.lineMarkers = true;
    goalline.lineMarkers = true;
    pastline.data = past;
    goalline.data = goal;

    // chart.addLegend('80%', '8%', '10%', '20%', 'right', colorline);
    chart.draw();

    d3.select('#dimple-goal')
        .style('stroke-dasharray', ('5, 5'));

    var tip = d3.tip()
        .attr('class', 'd3-tip')
        .html(trendTip);

    svg.selectAll('circle.dimple-marker')
        .call(tip)
        .on('mouseover', function(d) {
            tip.show(d);
            dotOver(this);
        })
        .on('mouseout', function(d) {
            tip.hide(d);
            dotOut(this);
        })
        .on('touchstart', function(d) {
            d3.event.preventDefault();
            tip.show(d);
            dotOver(this);
        });

    // svg.selectAll('.dimple-marker.dimple-goal:first-child')
    //     .attr('display', 'none');

    return chart;
}

function makeUnTrend(data) {
    var margin = { top: 24, right: 32, bottom: 48, left: 32 };

    var svg = d3.select('#unemployment-trend')
        .select('svg')
        .attr('width', '100%')
        .attr('height', '100%')
        .html('');

    var chart = new dimple.chart(svg, data);
    chart.setMargins(margin.left, margin.top, margin.right, margin.bottom);

    var x = chart.addTimeAxis('x', 'year', '%Y', '%Y');
    x.title = null;

    var y = chart.addMeasureAxis('y', 'value');
    y.tickFormat = '.0%';
    y.ticks = 6;

    chart.defaultColors = [ pink, ltblue ];

    var colorline = chart.addSeries('name', dimple.plot.line);
    colorline.lineMarkers = true;

    chart.addLegend('80%', '8%', '10%', '20%', 'right', colorline);
    chart.draw();

    var tip = d3.tip()
        .attr('class', 'd3-tip')
        .html(trendGroupTip);

    svg.selectAll('circle.dimple-marker')
        .call(tip)
        .on('mouseover', function(d) {
            tip.show(d);
            dotOver(this);
        })
        .on('mouseout', function(d) {
            tip.hide(d);
            dotOut(this);
        });

    return chart;
}
<|endoftext|>


<commit_before>// Copyright 2018, University of Colorado Boulder

/**
 * Base type for ScreenViews in this sim.
 *
 * @author Andrea Lin
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( require => {
  'use strict';

  // modules
  const GQConstants = require( 'GRAPHING_QUADRATICS/common/GQConstants' );
  const GraphContentsToggleButton = require( 'GRAPHING_QUADRATICS/common/view/GraphContentsToggleButton' );
  const graphingQuadratics = require( 'GRAPHING_QUADRATICS/graphingQuadratics' );
  const Node = require( 'SCENERY/nodes/Node' );
  const PointToolNode = require( 'GRAPHING_QUADRATICS/common/view/PointToolNode' );
  const ResetAllButton = require( 'SCENERY_PHET/buttons/ResetAllButton' );
  const ScreenView = require( 'JOIST/ScreenView' );
  const Tandem = require( 'TANDEM/Tandem' );
  const VBox = require( 'SCENERY/nodes/VBox' );

  // constants
  const X_SPACING = 15; // between graph and control panels

  class GQScreenView extends ScreenView {

    /**
     * @param {GQModel} model
     * @param {GQViewProperties} viewProperties
     * @param {Node} graphNode
     * @param {Node} equationControls
     * @param {Node} graphControls
     * @param {Object} options
     */
    constructor( model, viewProperties, graphNode, equationControls, graphControls, options ) {

      options = _.extend( {
        layoutBounds: GQConstants.SCREEN_VIEW_LAYOUT_BOUNDS,
        tandem: Tandem.required
      }, options );

      super( options );

      // Point tools moveToFront when dragged, so give them a common parent to preserve rendering order.
      const pointToolsParent = new Node();
      pointToolsParent.addChild( new PointToolNode(
        model.rightPointTool,
        model.modelViewTransform,
        model.graph,
        viewProperties.graphContentsVisibleProperty, {
          tandem: options.tandem.createTandem( 'rightPointToolNode' ),
          phetioInstanceDocumentation: 'the point tool Node whose probe is on the right side'
        } ) );
      pointToolsParent.addChild( new PointToolNode(
        model.leftPointTool,
        model.modelViewTransform,
        model.graph,
        viewProperties.graphContentsVisibleProperty, {
          tandem: options.tandem.createTandem( 'leftPointToolNode' ),
          phetioInstanceDocumentation: 'the point tool Node whose probe is on the left side'
        } ) );

      // Toggle button for showing/hiding contents of graph
      const eyeToggleButton = new GraphContentsToggleButton( viewProperties.graphContentsVisibleProperty, {
        scale: 0.75,
        left: model.modelViewTransform.modelToViewX( model.graph.xRange.max ) + 10,
        bottom: model.modelViewTransform.modelToViewY( model.graph.yRange.min ),
        tandem: options.tandem.createTandem( 'eyeToggleButton' ),
        phetioInstanceDocumentation: 'button that shows/hides the contents of the graph'
      } );

      const controlPanelMaxWidth = this.layoutBounds.width - graphNode.width - ( 2 * GQConstants.SCREEN_VIEW_X_MARGIN ) - X_SPACING;

      // Parent for all control panels, to simplify layout
      const controlsParent = new VBox( {
        maxWidth: controlPanelMaxWidth,
        resize: false,
        align: 'center',
        spacing: 10,
        children: [
          equationControls,
          graphControls
        ]
      } );

      // rendering order
      this.addChild( controlsParent );
      this.addChild( graphNode );
      this.addChild( eyeToggleButton );
      this.addChild( pointToolsParent );

      // Horizontally center controls in the space to the right of the graph.
      controlsParent.centerX = graphNode.right + X_SPACING + ( controlPanelMaxWidth / 2 );
      controlsParent.top = GQConstants.SCREEN_VIEW_Y_MARGIN;

      // Reset All Button
      const resetAllButton = new ResetAllButton( {
        listener: () => {
          model.reset();
          viewProperties.reset();
        },
        right: this.layoutBounds.maxX - GQConstants.SCREEN_VIEW_X_MARGIN,
        bottom: this.layoutBounds.maxY - GQConstants.SCREEN_VIEW_Y_MARGIN,
        tandem: options.tandem.createTandem( 'resetAllButton' ),
        phetioInstanceDocumentation: 'button that resets the screen to its initial state'
      } );
      this.addChild( resetAllButton );
    }
  }

  return graphingQuadratics.register( 'GQScreenView', GQScreenView );
} );
<commit_msg>set maxHeight of control panels to account for variation in font height<commit_after>// Copyright 2018, University of Colorado Boulder

/**
 * Base type for ScreenViews in this sim.
 *
 * @author Andrea Lin
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( require => {
  'use strict';

  // modules
  const GQConstants = require( 'GRAPHING_QUADRATICS/common/GQConstants' );
  const GraphContentsToggleButton = require( 'GRAPHING_QUADRATICS/common/view/GraphContentsToggleButton' );
  const graphingQuadratics = require( 'GRAPHING_QUADRATICS/graphingQuadratics' );
  const Node = require( 'SCENERY/nodes/Node' );
  const PointToolNode = require( 'GRAPHING_QUADRATICS/common/view/PointToolNode' );
  const ResetAllButton = require( 'SCENERY_PHET/buttons/ResetAllButton' );
  const ScreenView = require( 'JOIST/ScreenView' );
  const Tandem = require( 'TANDEM/Tandem' );
  const VBox = require( 'SCENERY/nodes/VBox' );

  // constants
  const X_SPACING = 15; // between graph and control panels

  class GQScreenView extends ScreenView {

    /**
     * @param {GQModel} model
     * @param {GQViewProperties} viewProperties
     * @param {Node} graphNode
     * @param {Node} equationControls
     * @param {Node} graphControls
     * @param {Object} options
     */
    constructor( model, viewProperties, graphNode, equationControls, graphControls, options ) {

      options = _.extend( {
        layoutBounds: GQConstants.SCREEN_VIEW_LAYOUT_BOUNDS,
        tandem: Tandem.required
      }, options );

      super( options );

      // Point tools moveToFront when dragged, so give them a common parent to preserve rendering order.
      const pointToolsParent = new Node();
      pointToolsParent.addChild( new PointToolNode(
        model.rightPointTool,
        model.modelViewTransform,
        model.graph,
        viewProperties.graphContentsVisibleProperty, {
          tandem: options.tandem.createTandem( 'rightPointToolNode' ),
          phetioInstanceDocumentation: 'the point tool Node whose probe is on the right side'
        } ) );
      pointToolsParent.addChild( new PointToolNode(
        model.leftPointTool,
        model.modelViewTransform,
        model.graph,
        viewProperties.graphContentsVisibleProperty, {
          tandem: options.tandem.createTandem( 'leftPointToolNode' ),
          phetioInstanceDocumentation: 'the point tool Node whose probe is on the left side'
        } ) );

      // Toggle button for showing/hiding contents of graph
      const eyeToggleButton = new GraphContentsToggleButton( viewProperties.graphContentsVisibleProperty, {
        scale: 0.75,
        left: model.modelViewTransform.modelToViewX( model.graph.xRange.max ) + 10,
        bottom: model.modelViewTransform.modelToViewY( model.graph.yRange.min ),
        tandem: options.tandem.createTandem( 'eyeToggleButton' ),
        phetioInstanceDocumentation: 'button that shows/hides the contents of the graph'
      } );

      const controlPanelMaxWidth = this.layoutBounds.width - graphNode.width - ( 2 * GQConstants.SCREEN_VIEW_X_MARGIN ) - X_SPACING;
      const controlPanelMaxHeight = this.layoutBounds.height - ( 2 * GQConstants.SCREEN_VIEW_Y_MARGIN );

      // Parent for all control panels, to simplify layout
      const controlsParent = new VBox( {
        maxWidth: controlPanelMaxWidth,
        maxHeight: controlPanelMaxHeight,
        resize: false,
        align: 'center',
        spacing: 10,
        children: [
          equationControls,
          graphControls
        ]
      } );

      // rendering order
      this.addChild( controlsParent );
      this.addChild( graphNode );
      this.addChild( eyeToggleButton );
      this.addChild( pointToolsParent );

      // Horizontally center controls in the space to the right of the graph.
      controlsParent.centerX = graphNode.right + X_SPACING + ( controlPanelMaxWidth / 2 );
      controlsParent.top = GQConstants.SCREEN_VIEW_Y_MARGIN;

      // Reset All Button
      const resetAllButton = new ResetAllButton( {
        listener: () => {
          model.reset();
          viewProperties.reset();
        },
        right: this.layoutBounds.maxX - GQConstants.SCREEN_VIEW_X_MARGIN,
        bottom: this.layoutBounds.maxY - GQConstants.SCREEN_VIEW_Y_MARGIN,
        tandem: options.tandem.createTandem( 'resetAllButton' ),
        phetioInstanceDocumentation: 'button that resets the screen to its initial state'
      } );
      this.addChild( resetAllButton );
    }
  }

  return graphingQuadratics.register( 'GQScreenView', GQScreenView );
} );
<|endoftext|>


<commit_before>import RenderNode from "./node";
import {renderNodesBoundingBox, textBoundingBox} from "../utils/measure";

const _renderBlocks = Symbol("renderBlocks");
const _svgRect = Symbol("svgRect");
const _svgName = Symbol("svgName");

export default class RenderGroup extends RenderNode {

    constructor() {
        super();

        this[_renderBlocks] = [];
        this.name = "";
    }

    /**
     * Returns this group render blocks
     * @returns {Array<RenderBlock>}
     */
    get renderBlocks() { return this[_renderBlocks]; }

    /**
     * Adds the specified render block to this render group
     * @param {RenderBlock} renderBlock - specifies the render block
     */
    addRenderBlock(renderBlock) {
        if (this.renderer === null) {
            throw new Error(this.fancyName + " cannot add renderBlock when not bound to a renderer");
        }
        if (this.renderer !== renderBlock.renderer) {
            throw new Error(this.fancyName + " is not in the same renderer as " + renderBlock.fancyName);
        }
        if (renderBlock.parent !== null) {
            throw new Error(renderBlock.fancyName + " cannot redefine parent");
        }
        this.renderBlocks.push(renderBlock);
        renderBlock.parent = this;
    }
    /**
     * Removes the specified render block from this render group
     * @param {RenderBlock} renderBlock - specifies the render block
     */
    removeRenderBlock(renderBlock) {
        if (this.renderer === null) {
            throw new Error(this.fancyName + " cannot remove renderBlock when not bound to a renderer");
        }
        if (renderBlock.parent !== this || !this.renderBlocks.includes(renderBlock)) {
            throw new Error(this.fancyName + " has no " + renderBlock.fancyName);
        }
        this.renderBlocks.splice(this.renderBlocks.indexOf(renderBlock), 1);
        renderBlock.parent = null;
    }

    /**
     * Called when this render group is added
     * @override
     */
    added() {
        this[_svgRect] = this.element.append("svg:rect").classed("dude-graph-group-background", true);
        this[_svgName] = this.element.append("svg:text").classed("dude-graph-group-name", true);

        this[_svgRect].attr("rx", this.renderer.config.block.borderRadius);
        this[_svgRect].attr("ry", this.renderer.config.block.borderRadius);

        this[_svgName].attr("text-anchor", "middle");
        this[_svgName].attr("dominant-baseline", "text-before-edge");
    }

    /**
     * Called when this render group data changed and should update the element
     * @override
     */
    updateData() { this[_svgName].text(this.name); }
    /**
     * Called when this render group size changed and should update its element
     * @override
     */
    updateSize() {
        this.size = this.preferredSize();

        this[_svgRect].attr("width", this.size[0]);
        this[_svgRect].attr("height", this.size[1]);

        this[_svgName].attr("x", this.size[0] / 2);
        this[_svgName].attr("y", this.renderer.config.group.padding);
    }
    /**
     * Called when this render group position changed and should update its element
     * @override
     */
    updatePosition() {
        this.position = this.preferredPosition();

        this.element.attr("transform", "translate(" + this.position + ")");
    }

    /**
     * Returns the preferred position of this render group
     * @returns {Array<number>}
     */
    preferredPosition() {
        const contentBoundingBox = renderNodesBoundingBox(this.renderBlocks);
        if (contentBoundingBox !== null) {
            return [
                contentBoundingBox[0][0] - this.renderer.config.group.padding,
                contentBoundingBox[0][1] - this.renderer.config.group.padding - this.renderer.config.group.header
            ];
        }
        return this.position;
    }

    /**
     * Returns the preferred size of this render group
     * @returns {Array<number>}
     */
    preferredSize() {
        const size = [0, 0];
        const contentBoundingBox = renderNodesBoundingBox(this.renderBlocks);
        if (contentBoundingBox !== null) {
            size[0] = contentBoundingBox[1][0] - contentBoundingBox[0][0] + this.renderer.config.group.padding * 2;
            size[1] = contentBoundingBox[1][1] - contentBoundingBox[0][1] + this.renderer.config.group.padding * 2 + this.renderer.config.group.header;
        }
        size[0] = Math.max(size[0], this.renderer.config.group.minSize[0] + this.renderer.config.group.padding * 2);
        size[1] = Math.max(size[1], this.renderer.config.group.minSize[1] + this.renderer.config.group.padding * 2 + this.renderer.config.group.header);
        size[0] = Math.max(size[0], textBoundingBox(this.name || "")[0] + this.renderer.config.group.padding * 2);
        return size;
    }

}
<commit_msg>Use group default size only when the group is empty<commit_after>import RenderNode from "./node";
import {renderNodesBoundingBox, textBoundingBox} from "../utils/measure";

const _renderBlocks = Symbol("renderBlocks");
const _svgRect = Symbol("svgRect");
const _svgName = Symbol("svgName");

export default class RenderGroup extends RenderNode {

    constructor() {
        super();

        this[_renderBlocks] = [];
        this.name = "";
    }

    /**
     * Returns this group render blocks
     * @returns {Array<RenderBlock>}
     */
    get renderBlocks() { return this[_renderBlocks]; }

    /**
     * Adds the specified render block to this render group
     * @param {RenderBlock} renderBlock - specifies the render block
     */
    addRenderBlock(renderBlock) {
        if (this.renderer === null) {
            throw new Error(this.fancyName + " cannot add renderBlock when not bound to a renderer");
        }
        if (this.renderer !== renderBlock.renderer) {
            throw new Error(this.fancyName + " is not in the same renderer as " + renderBlock.fancyName);
        }
        if (renderBlock.parent !== null) {
            throw new Error(renderBlock.fancyName + " cannot redefine parent");
        }
        this.renderBlocks.push(renderBlock);
        renderBlock.parent = this;
    }
    /**
     * Removes the specified render block from this render group
     * @param {RenderBlock} renderBlock - specifies the render block
     */
    removeRenderBlock(renderBlock) {
        if (this.renderer === null) {
            throw new Error(this.fancyName + " cannot remove renderBlock when not bound to a renderer");
        }
        if (renderBlock.parent !== this || !this.renderBlocks.includes(renderBlock)) {
            throw new Error(this.fancyName + " has no " + renderBlock.fancyName);
        }
        this.renderBlocks.splice(this.renderBlocks.indexOf(renderBlock), 1);
        renderBlock.parent = null;
    }

    /**
     * Called when this render group is added
     * @override
     */
    added() {
        this[_svgRect] = this.element.append("svg:rect").classed("dude-graph-group-background", true);
        this[_svgName] = this.element.append("svg:text").classed("dude-graph-group-name", true);

        this[_svgRect].attr("rx", this.renderer.config.block.borderRadius);
        this[_svgRect].attr("ry", this.renderer.config.block.borderRadius);

        this[_svgName].attr("text-anchor", "middle");
        this[_svgName].attr("dominant-baseline", "text-before-edge");
    }

    /**
     * Called when this render group data changed and should update the element
     * @override
     */
    updateData() { this[_svgName].text(this.name); }
    /**
     * Called when this render group size changed and should update its element
     * @override
     */
    updateSize() {
        this.size = this.preferredSize();

        this[_svgRect].attr("width", this.size[0]);
        this[_svgRect].attr("height", this.size[1]);

        this[_svgName].attr("x", this.size[0] / 2);
        this[_svgName].attr("y", this.renderer.config.group.padding);
    }
    /**
     * Called when this render group position changed and should update its element
     * @override
     */
    updatePosition() {
        this.position = this.preferredPosition();

        this.element.attr("transform", "translate(" + this.position + ")");
    }

    /**
     * Returns the preferred position of this render group
     * @returns {Array<number>}
     */
    preferredPosition() {
        const contentBoundingBox = renderNodesBoundingBox(this.renderBlocks);
        if (contentBoundingBox !== null) {
            return [
                contentBoundingBox[0][0] - this.renderer.config.group.padding,
                contentBoundingBox[0][1] - this.renderer.config.group.padding - this.renderer.config.group.header
            ];
        }
        return this.position;
    }

    /**
     * Returns the preferred size of this render group
     * @returns {Array<number>}
     */
    preferredSize() {
        const size = [0, 0];
        const contentBoundingBox = renderNodesBoundingBox(this.renderBlocks);
        if (contentBoundingBox !== null) {
            size[0] = contentBoundingBox[1][0] - contentBoundingBox[0][0] + this.renderer.config.group.padding * 2;
            size[1] = contentBoundingBox[1][1] - contentBoundingBox[0][1] + this.renderer.config.group.padding * 2 + this.renderer.config.group.header;
        } else {
            size[0] = this.renderer.config.group.minSize[0] + this.renderer.config.group.padding * 2;
            size[1] = this.renderer.config.group.minSize[1] + this.renderer.config.group.padding * 2 + this.renderer.config.group.header;
        }
        size[0] = Math.max(size[0], textBoundingBox(this.name || "")[0] + this.renderer.config.group.padding * 2);
        return size;
    }

}
<|endoftext|>


<commit_before>define(['class'], function(Class) {
  var Network = Class.extend({
    init: function(host, port) {
      this.url = "ws://"+ host +":"+ port +"/";
      this.callbacks = [];

      this.socket = io.connect(this.url);
    },
    send: function(name, data) {
      this.socket.emit(name, data);
    },
    command: function(command, args) {

      if (args === undefined || args === null) {
        args = [];
      }

      this.socket.emit('command', {
        command: command,
        args: args
      });
    },
    commands: function(commands) {
      this.socket.emit('commands', commands);
    },
    publish: function(name, data) {
      for (var i=0, l=this.callbacks.length; i < l; i++) {
        this.callbacks[i](name, data);
      }
    },
    subscribe: function(callback) {
      this.callbacks.push(callback);
    },
    unsubscribe: function(callback) {
      for (var i=0, l=this.callbacks.length; i < l; i++) {
        if (this.callbacks[i] === callback) {
          this.callbacks.splice(i, 1);
        }
      }
    },
    on: function(name, callback) {
      this.socket.on(name, callback);
    },
    off: function(name, callback) {
      this.socket.of(name, callback);
    },
    createPublish: function(name) {
      return function(data) {
        this.publish(name, data);
      }.bind(this);
    }
  });

  return Network;
});
<commit_msg>Fixed a bug in socket.io.<commit_after>define(['class'], function(Class) {
  var Network = Class.extend({
    init: function(host, port) {
      this.url = "ws://"+ host +":"+ port +"/";
      this.callbacks = [];

      this.socket = io.connect(this.url);
    },
    send: function(name, data) {
      this.socket.emit(name, data);
    },
    command: function(command, args) {

      if (args === undefined || args === null) {
        args = [];
      }

      this.socket.emit('command', {
        command: command,
        args: args
      });
    },
    commands: function(commands) {
      this.socket.emit('commands', commands);
    },
    publish: function(name, data) {
      for (var i=0, l=this.callbacks.length; i < l; i++) {
        this.callbacks[i](name, data);
      }
    },
    subscribe: function(callback) {
      this.callbacks.push(callback);
    },
    unsubscribe: function(callback) {
      for (var i=0, l=this.callbacks.length; i < l; i++) {
        if (this.callbacks[i] === callback) {
          this.callbacks.splice(i, 1);
        }
      }
    },
    on: function(name, callback) {
      this.socket.on(name, callback);
    },
    off: function(name, callback) {
      this.socket.off(name, callback);
    },
    createPublish: function(name) {
      return function(data) {
        this.publish(name, data);
      }.bind(this);
    }
  });

  return Network;
});
<|endoftext|>