<commit_before>(function () {
    "use strict";

    var gpii = fluid.registerNamespace("gpii");
    var d3 = fluid.registerNamespace("d3");

    // Sonification presentation panel
    fluid.defaults("gpii.nexusSensorVisualizationPanel", {
        gradeNames: ["gpii.nexusSensorPresentationPanel"],
        // Key-value pairs of sensorIds / sensorPresenter grades
        perSensorPresentationGrades: {
            "fakeSensor": "gpii.nexusSensorVisualizer.lineChart",
            "fakeSensorPH": "gpii.nexusSensorVisualizer.pHScale"
        },
        defaultSensorPresentationGrade: "gpii.nexusSensorVisualizer.circleRadius",
        dynamicComponents: {
            sensorPresenter: {
                type: "@expand:gpii.nexusSensorVisualizationPanel.getSensorPresenterType({that}, {arguments}.0)",
                createOnEvent: "onSensorAppearance",
                options: "@expand:gpii.nexusSensorVisualizationPanel.getSensorPresenterOptions({arguments}.0)"
            }
        }
    });

    gpii.nexusSensorVisualizationPanel.getSensorPresenterType = function (that, sensorId) {
        var perSensorPresentationGrades = that.options.perSensorPresentationGrades;
        if(perSensorPresentationGrades[sensorId]) {
            return perSensorPresentationGrades[sensorId];
        } else {
            return that.options.defaultSensorPresentationGrade;
        }
    };

    gpii.nexusSensorVisualizationPanel.getSensorPresenterOptions = function (sensorId) {

        var sensorModelOptions = gpii.nexusSensorPresentationPanel.getSensorModelOptions(sensorId);

        var sensorContainerClass = "nexus-nexusSensorVisualizationPanel-sensorDisplay-" + sensorId;

        var sensorVisualizerListenerOptions = gpii.nexusSensorPresentationPanel.getSensorPresenterListenerOptions(sensorId, sensorContainerClass);

        var sensorVisualizerOptions = {
                events: {
                    onSensorDisplayContainerAppended: null
                },
                listeners: sensorVisualizerListenerOptions,
                components: {
                    sensor: {
                        options: {
                            model: sensorModelOptions
                        }
                    },
                    visualizer: {
                        container: "." + sensorContainerClass
                    }
                }
        };

        return sensorVisualizerOptions;
    };

    // Abstract grade
    fluid.defaults("gpii.nexusSensorVisualizerBase", {
        gradeNames: ["fluid.component"],
        events: {
            onSensorDisplayContainerAppended: null
        },
        components: {
            sensor: {
                type: "fluid.modelComponent"
            },
            visualizer: {
                createOnEvent: "{nexusSensorVisualizerBase}.events.onSensorDisplayContainerAppended"
                // Must be specified; handled by dynamicComponents behaviour
                // container: ""
            }
        }
    });

    fluid.defaults("gpii.nexusSensorVisualizer.lineChart", {
        gradeNames: ["gpii.nexusSensorVisualizerBase"],
        components: {
            visualizer: {
                type: "gpii.nexusSensorVisualizer.lineChart.visualizer",
                options: {
                    scaleOptions: {
                        // transform rules to apply to yScale min
                        yScaleMinTransform: {
                            "literalValue": "{sensor}.model.sensorMin"
                        },
                        // transform rules to apply to yScale max
                        yScaleMaxTransform: {
                            "literalValue": "{sensor}.model.sensorMax"
                        }
                    },
                    modelListeners: {
                        "{sensor}.model.sensorValue": {
                            func: "gpii.nexusSensorVisualizer.lineChart.accumulateSensorValues",
                            args: ["{sensorValueAccumulator}", "{visualizer}", "{change}"]
                        }
                    }
                }
            },
            sensorValueAccumulator: {
                type: "fluid.modelComponent",
                options: {
                    model: {
                        sensorValues: [],
                        maxValuesRetained: 50
                    }
                }
            }
        }
    });

    gpii.nexusSensorVisualizer.lineChart.accumulateSensorValues = function (sensorValueAccumulator, visualizer, change) {

        var maxValuesRetained = fluid.get(sensorValueAccumulator.model, "maxValuesRetained");

        var currentSensorValues = fluid.copy(fluid.get(sensorValueAccumulator.model, "sensorValues"));
        var currentTime = new Date();

        if(currentSensorValues.length >= maxValuesRetained) {
            currentSensorValues.shift();
        }

        var sensorRecord = {
            "date": currentTime,
            "value": change.value
        };

        currentSensorValues.push(sensorRecord);

        sensorValueAccumulator.applier.change("sensorValues", currentSensorValues);

        visualizer.applier.change("dataSet", currentSensorValues);
    };

    fluid.defaults("gpii.nexusSensorVisualizer.lineChart.visualizer", {
        gradeNames: ["gpii.nexusSensorPresentationPanel.fadeInPresenter", "floe.chartAuthoring.lineChart.timeSeriesSingleDataSet"],
        listeners: {
            "onCreate.prependSensorTitle": {
                "this": "{that}.container",
                method: "prepend",
                args: {
                    expander: {
                        funcName: "fluid.stringTemplate",
                        args: ["
%description
", "{sensor}.model"]
                    }
                }
            }
        },
        invokers: {
            transitionChartLine: {
                funcName: "floe.chartAuthoring.lineChart.timeSeries.line.updateChartLine.defaultTransition"
            }
        }
    });

    fluid.defaults("gpii.nexusSensorVisualizer.sensorPercentage", {
        gradeNames: ["fluid.modelComponent"],
        modelRelay: [{
            target: "sensorPercentage",
            singleTransform: {
                type: "gpii.sensorPlayer.transforms.minMaxScale",
                input: "{sensor}.model.sensorValue",
                inputScaleMax: "{sensor}.model.sensorMax",
                inputScaleMin: "{sensor}.model.sensorMin",
                outputScaleMax: 100,
                outputScaleMin: 0
            }
        }]
    });

    fluid.defaults("gpii.nexusSensorVisualizer.circleRadius", {
        gradeNames: ["gpii.nexusSensorVisualizerBase"],
        components: {
            visualizer: {
                type: "gpii.nexusSensorVisualizer.circleRadius.visualizer"
            }
        }
    });

    fluid.defaults("gpii.nexusSensorVisualizer.circleRadius.visualizer", {
        gradeNames: ["gpii.nexusSensorPresentationPanel.fadeInPresenter", "gpii.nexusSensorVisualizer.sensorPercentage", "fluid.viewComponent"],
        selectors: {
            circle: ".nexus-nexusSensorVisualizationPanel-sensorDisplay-circle"
        },
        modelListeners: {
            "sensorPercentage": {
                funcName: "gpii.nexusSensorVisualizer.circleRadius.visualizer.updateVisualization",
                args: ["{that}", "{change}"]
            }
        },
        listeners: {
            "onCreate.appendCircle": {
                "this": "{that}.container",
                method: "html",
                args: {
                expander: {
                        funcName: "fluid.stringTemplate",
                        args: ["
%description

 <svg viewBox=\"0 0 200 200\" xmlns=\"http://www.w3.org/2000/svg\"><circle class=\"nexus-nexusSensorVisualizationPanel-sensorDisplay-circleOutline\" cx=\"100\" cy=\"100\" r=\"100\" fill=\"red\" /><circle class=\"nexus-nexusSensorVisualizationPanel-sensorDisplay-circle\" cx=\"100\" cy=\"100\" r=\"0\" /></svg>", "{sensor}.model"]
                    }
                }
            }
        }
    });

    gpii.nexusSensorVisualizer.circleRadius.visualizer.updateVisualization = function (visualizer, change) {
        var circle = visualizer.locate("circle");
        circle.animate({"r": change.value}, 500);
    };

    fluid.defaults("gpii.nexusSensorVisualizer.horizontalBar", {
        gradeNames: ["gpii.nexusSensorVisualizerBase"],
        components: {
            visualizer: {
                type: "gpii.nexusSensorVisualizer.horizontalBar.visualizer"
            }
        }
    });

    fluid.defaults("gpii.nexusSensorVisualizer.horizontalBar.visualizer", {
        gradeNames: ["gpii.nexusSensorPresentationPanel.fadeInPresenter", "gpii.nexusSensorVisualizer.sensorPercentage", "fluid.viewComponent"],
        selectors: {
            bar: ".nexus-nexusSensorVisualizationPanel-sensorDisplay-bar"
        },
        modelListeners: {
            "sensorPercentage": {
                funcName: "gpii.nexusSensorVisualizer.horizontalBar.visualizer.updateVisualization",
                args: ["{that}", "{change}"]
            }
        },
        listeners: {
            "onCreate.appendBar": {
                "this": "{that}.container",
                method: "html",
                args: {
                expander: {
                        funcName: "fluid.stringTemplate",
                        args: ["
%description

 <svg viewBox=\"0 0 200 200\" xmlns=\"http://www.w3.org/2000/svg\"><rect class=\"nexus-nexusSensorVisualizationPanel-sensorDisplay-barBackground\" width=\"200\" height=\"100\" fill=\"red\" /><rect class=\"nexus-nexusSensorVisualizationPanel-sensorDisplay-bar\" width=\"0\" height=\"100\" fill=\"blue\" /></svg>", "{sensor}.model"]
                    }
                }
            }
        }
    });

    gpii.nexusSensorVisualizer.horizontalBar.visualizer.updateVisualization = function (visualizer, change) {
        var circle = visualizer.locate("bar");
        circle.animate({"width": change.value * 2}, 500);
    };

    fluid.defaults("gpii.nexusSensorVisualizer.pHScale", {
        gradeNames: ["gpii.nexusSensorVisualizerBase"],
        components: {
            visualizer: {
                type: "gpii.nexusSensorVisualizer.pHScale.visualizer",
                options: {
                    modelListeners: {
                        "{pHScale}.sensor.model.sensorValue": {
                            funcName: "gpii.nexusSensorVisualizer.pHScale.visualizer.updateVisualization",
                            args: ["{that}", "{change}"]
                        }
                    }
                }
            }
        }
    });

    fluid.defaults("gpii.nexusSensorVisualizer.pHScale.visualizer", {
        gradeNames: ["floe.svgDrawingArea"],
        model: {
            svgTitle: "An animated pH scale.",
            svgDescription: "An animated ph scale."
        },
        colorScaleOptions: {
            // Must be 14 colors
            // This set generated using the tool at https://gka.github.io/palettes/
            colors: ["#ff0000","#ff7100","#f49b00","#d9b100","#b3b500","#81ab00","#409200","#3a7539","#576071","#604b95","#6636a8","#6e20ab","#78079d","#800080"]
        },
        listeners: {
            "onCreate.prependSensorTitle": {
                "this": "{that}.container",
                method: "prepend",
                args: {
                    expander: {
                        funcName: "fluid.stringTemplate",
                        args: ["
%description
", "{sensor}.model"]
                    }
                }
            },
            "onCreate.createBaseSVGDrawingArea": {
                func: "{that}.createBaseSVGDrawingArea"
            },
            "onCreate.createPHVisualizer": {
                funcName: "gpii.nexusSensorVisualizer.pHScale.visualizer.create",
                args: ["{that}"],
                priority: "after:createBaseSVGDrawingArea"
            }
        }
    });

    gpii.nexusSensorVisualizer.pHScale.visualizer.create = function (that) {

        var h = that.options.svgOptions.height,
            padding = 20,
            colors = that.options.colorScaleOptions.colors,
            svg = that.svg;

        var colorScaleLength = colors.length;

        that.yScale = d3.scale
               .linear()
               .domain([0,colorScaleLength])
               .range([h - padding, 0 + padding]);

    that.barHeight = (h - padding) / colorScaleLength;

    var barHeight = that.barHeight;

    for(var i=0; i< colorScaleLength; i++) {
      svg.append("rect")
         .attr({
            "x": 75,
            "y": function() {
              return that.yScale(i) - barHeight;
            },
            "width": 425,
            "height": barHeight,
            "fill": colors[i],
            "stroke": "black"
        });
    }

    for(i=0; i< colorScaleLength; i++) {
      svg.append("text")
        .text("pH Value " + i + " - " + (i+1))
        .attr({
          "text-anchor": "middle",
          "transform": "translate(75)",
          "fill": "white",
          "x": 212.5,
          "y": function() {
            return that.yScale(i) - barHeight / 2;
          },
          "font-size": 16
        })
    }

    // Draw the PH indicator

    var startingPHValue = 1;
    var pointLocation = that.yScale(startingPHValue) - 12.5;

    svg.append("polygon")
    .attr({
       "class": "phIndicator",
       "points": "0,0 0,25 25,12.5",
       "transform": "translate(45, "+ pointLocation +")",
       "fill": function() {
           var colorIdx = Math.floor(startingPHValue-1) > 0 ? Math.floor(startingPHValue-1) : 0;
           return colors[colorIdx];
       },
       "stroke": "black"
     });
    };

    gpii.nexusSensorVisualizer.pHScale.visualizer.updateVisualization = function (visualizer, change) {
        var colors = visualizer.options.colorScaleOptions.colors,
            barHeight = visualizer.barHeight;

            var padding = 20;
            var pointLocation = visualizer.yScale(change.value)  - 12.5;

            d3.select(".phIndicator")
            .transition()
            .duration(1000)
            .attr({
                "transform": "translate(45, "+ pointLocation +")",
                "fill": function() {
                    var colorIdx = Math.floor(change.value-1) > 0 ? Math.floor(change.value-1) : 0;
                    return colors[colorIdx];
                }
            });

    };

}());
<commit_msg>GPII-2189: path-based arrow.<commit_after>(function () {
    "use strict";

    var gpii = fluid.registerNamespace("gpii");
    var d3 = fluid.registerNamespace("d3");

    // Sonification presentation panel
    fluid.defaults("gpii.nexusSensorVisualizationPanel", {
        gradeNames: ["gpii.nexusSensorPresentationPanel"],
        // Key-value pairs of sensorIds / sensorPresenter grades
        perSensorPresentationGrades: {
            "fakeSensor": "gpii.nexusSensorVisualizer.lineChart",
            "fakeSensorPH": "gpii.nexusSensorVisualizer.pHScale"
        },
        defaultSensorPresentationGrade: "gpii.nexusSensorVisualizer.circleRadius",
        dynamicComponents: {
            sensorPresenter: {
                type: "@expand:gpii.nexusSensorVisualizationPanel.getSensorPresenterType({that}, {arguments}.0)",
                createOnEvent: "onSensorAppearance",
                options: "@expand:gpii.nexusSensorVisualizationPanel.getSensorPresenterOptions({arguments}.0)"
            }
        }
    });

    gpii.nexusSensorVisualizationPanel.getSensorPresenterType = function (that, sensorId) {
        var perSensorPresentationGrades = that.options.perSensorPresentationGrades;
        if(perSensorPresentationGrades[sensorId]) {
            return perSensorPresentationGrades[sensorId];
        } else {
            return that.options.defaultSensorPresentationGrade;
        }
    };

    gpii.nexusSensorVisualizationPanel.getSensorPresenterOptions = function (sensorId) {

        var sensorModelOptions = gpii.nexusSensorPresentationPanel.getSensorModelOptions(sensorId);

        var sensorContainerClass = "nexus-nexusSensorVisualizationPanel-sensorDisplay-" + sensorId;

        var sensorVisualizerListenerOptions = gpii.nexusSensorPresentationPanel.getSensorPresenterListenerOptions(sensorId, sensorContainerClass);

        var sensorVisualizerOptions = {
                events: {
                    onSensorDisplayContainerAppended: null
                },
                listeners: sensorVisualizerListenerOptions,
                components: {
                    sensor: {
                        options: {
                            model: sensorModelOptions
                        }
                    },
                    visualizer: {
                        container: "." + sensorContainerClass
                    }
                }
        };

        return sensorVisualizerOptions;
    };

    // Abstract grade
    fluid.defaults("gpii.nexusSensorVisualizerBase", {
        gradeNames: ["fluid.component"],
        events: {
            onSensorDisplayContainerAppended: null
        },
        components: {
            sensor: {
                type: "fluid.modelComponent"
            },
            visualizer: {
                createOnEvent: "{nexusSensorVisualizerBase}.events.onSensorDisplayContainerAppended"
                // Must be specified; handled by dynamicComponents behaviour
                // container: ""
            }
        }
    });

    fluid.defaults("gpii.nexusSensorVisualizer.lineChart", {
        gradeNames: ["gpii.nexusSensorVisualizerBase"],
        components: {
            visualizer: {
                type: "gpii.nexusSensorVisualizer.lineChart.visualizer",
                options: {
                    scaleOptions: {
                        // transform rules to apply to yScale min
                        yScaleMinTransform: {
                            "literalValue": "{sensor}.model.sensorMin"
                        },
                        // transform rules to apply to yScale max
                        yScaleMaxTransform: {
                            "literalValue": "{sensor}.model.sensorMax"
                        }
                    },
                    modelListeners: {
                        "{sensor}.model.sensorValue": {
                            func: "gpii.nexusSensorVisualizer.lineChart.accumulateSensorValues",
                            args: ["{sensorValueAccumulator}", "{visualizer}", "{change}"]
                        }
                    }
                }
            },
            sensorValueAccumulator: {
                type: "fluid.modelComponent",
                options: {
                    model: {
                        sensorValues: [],
                        maxValuesRetained: 50
                    }
                }
            }
        }
    });

    gpii.nexusSensorVisualizer.lineChart.accumulateSensorValues = function (sensorValueAccumulator, visualizer, change) {

        var maxValuesRetained = fluid.get(sensorValueAccumulator.model, "maxValuesRetained");

        var currentSensorValues = fluid.copy(fluid.get(sensorValueAccumulator.model, "sensorValues"));
        var currentTime = new Date();

        if(currentSensorValues.length >= maxValuesRetained) {
            currentSensorValues.shift();
        }

        var sensorRecord = {
            "date": currentTime,
            "value": change.value
        };

        currentSensorValues.push(sensorRecord);

        sensorValueAccumulator.applier.change("sensorValues", currentSensorValues);

        visualizer.applier.change("dataSet", currentSensorValues);
    };

    fluid.defaults("gpii.nexusSensorVisualizer.lineChart.visualizer", {
        gradeNames: ["gpii.nexusSensorPresentationPanel.fadeInPresenter", "floe.chartAuthoring.lineChart.timeSeriesSingleDataSet"],
        listeners: {
            "onCreate.prependSensorTitle": {
                "this": "{that}.container",
                method: "prepend",
                args: {
                    expander: {
                        funcName: "fluid.stringTemplate",
                        args: ["
%description
", "{sensor}.model"]
                    }
                }
            }
        },
        invokers: {
            transitionChartLine: {
                funcName: "floe.chartAuthoring.lineChart.timeSeries.line.updateChartLine.defaultTransition"
            }
        }
    });

    fluid.defaults("gpii.nexusSensorVisualizer.sensorPercentage", {
        gradeNames: ["fluid.modelComponent"],
        modelRelay: [{
            target: "sensorPercentage",
            singleTransform: {
                type: "gpii.sensorPlayer.transforms.minMaxScale",
                input: "{sensor}.model.sensorValue",
                inputScaleMax: "{sensor}.model.sensorMax",
                inputScaleMin: "{sensor}.model.sensorMin",
                outputScaleMax: 100,
                outputScaleMin: 0
            }
        }]
    });

    fluid.defaults("gpii.nexusSensorVisualizer.circleRadius", {
        gradeNames: ["gpii.nexusSensorVisualizerBase"],
        components: {
            visualizer: {
                type: "gpii.nexusSensorVisualizer.circleRadius.visualizer"
            }
        }
    });

    fluid.defaults("gpii.nexusSensorVisualizer.circleRadius.visualizer", {
        gradeNames: ["gpii.nexusSensorPresentationPanel.fadeInPresenter", "gpii.nexusSensorVisualizer.sensorPercentage", "fluid.viewComponent"],
        selectors: {
            circle: ".nexus-nexusSensorVisualizationPanel-sensorDisplay-circle"
        },
        modelListeners: {
            "sensorPercentage": {
                funcName: "gpii.nexusSensorVisualizer.circleRadius.visualizer.updateVisualization",
                args: ["{that}", "{change}"]
            }
        },
        listeners: {
            "onCreate.appendCircle": {
                "this": "{that}.container",
                method: "html",
                args: {
                expander: {
                        funcName: "fluid.stringTemplate",
                        args: ["
%description

 <svg viewBox=\"0 0 200 200\" xmlns=\"http://www.w3.org/2000/svg\"><circle class=\"nexus-nexusSensorVisualizationPanel-sensorDisplay-circleOutline\" cx=\"100\" cy=\"100\" r=\"100\" fill=\"red\" /><circle class=\"nexus-nexusSensorVisualizationPanel-sensorDisplay-circle\" cx=\"100\" cy=\"100\" r=\"0\" /></svg>", "{sensor}.model"]
                    }
                }
            }
        }
    });

    gpii.nexusSensorVisualizer.circleRadius.visualizer.updateVisualization = function (visualizer, change) {
        var circle = visualizer.locate("circle");
        circle.animate({"r": change.value}, 500);
    };

    fluid.defaults("gpii.nexusSensorVisualizer.horizontalBar", {
        gradeNames: ["gpii.nexusSensorVisualizerBase"],
        components: {
            visualizer: {
                type: "gpii.nexusSensorVisualizer.horizontalBar.visualizer"
            }
        }
    });

    fluid.defaults("gpii.nexusSensorVisualizer.horizontalBar.visualizer", {
        gradeNames: ["gpii.nexusSensorPresentationPanel.fadeInPresenter", "gpii.nexusSensorVisualizer.sensorPercentage", "fluid.viewComponent"],
        selectors: {
            bar: ".nexus-nexusSensorVisualizationPanel-sensorDisplay-bar"
        },
        modelListeners: {
            "sensorPercentage": {
                funcName: "gpii.nexusSensorVisualizer.horizontalBar.visualizer.updateVisualization",
                args: ["{that}", "{change}"]
            }
        },
        listeners: {
            "onCreate.appendBar": {
                "this": "{that}.container",
                method: "html",
                args: {
                expander: {
                        funcName: "fluid.stringTemplate",
                        args: ["
%description

 <svg viewBox=\"0 0 200 200\" xmlns=\"http://www.w3.org/2000/svg\"><rect class=\"nexus-nexusSensorVisualizationPanel-sensorDisplay-barBackground\" width=\"200\" height=\"100\" fill=\"red\" /><rect class=\"nexus-nexusSensorVisualizationPanel-sensorDisplay-bar\" width=\"0\" height=\"100\" fill=\"blue\" /></svg>", "{sensor}.model"]
                    }
                }
            }
        }
    });

    gpii.nexusSensorVisualizer.horizontalBar.visualizer.updateVisualization = function (visualizer, change) {
        var circle = visualizer.locate("bar");
        circle.animate({"width": change.value * 2}, 500);
    };

    fluid.defaults("gpii.nexusSensorVisualizer.pHScale", {
        gradeNames: ["gpii.nexusSensorVisualizerBase"],
        components: {
            visualizer: {
                type: "gpii.nexusSensorVisualizer.pHScale.visualizer",
                options: {
                    modelListeners: {
                        "{pHScale}.sensor.model.sensorValue": {
                            funcName: "gpii.nexusSensorVisualizer.pHScale.visualizer.updateVisualization",
                            args: ["{that}", "{change}"]
                        }
                    }
                }
            }
        }
    });

    fluid.defaults("gpii.nexusSensorVisualizer.pHScale.visualizer", {
        gradeNames: ["floe.svgDrawingArea"],
        model: {
            svgTitle: "An animated pH scale.",
            svgDescription: "An animated ph scale."
        },
        colorScaleOptions: {
            // Must be 14 colors
            // This set generated using the tool at https://gka.github.io/palettes/
            colors: ["#ff0000","#ff7100","#f49b00","#d9b100","#b3b500","#81ab00","#409200","#3a7539","#576071","#604b95","#6636a8","#6e20ab","#78079d","#800080"]
        },
        listeners: {
            "onCreate.prependSensorTitle": {
                "this": "{that}.container",
                method: "prepend",
                args: {
                    expander: {
                        funcName: "fluid.stringTemplate",
                        args: ["
%description
", "{sensor}.model"]
                    }
                }
            },
            "onCreate.createBaseSVGDrawingArea": {
                func: "{that}.createBaseSVGDrawingArea"
            },
            "onCreate.createPHVisualizer": {
                funcName: "gpii.nexusSensorVisualizer.pHScale.visualizer.createPHVisualizer",
                args: ["{that}"],
                priority: "after:createBaseSVGDrawingArea"
            }
        }
    });

    gpii.nexusSensorVisualizer.pHScale.visualizer.createPHVisualizer = function (that) {

        var h = that.options.svgOptions.height,
            padding = 20,
            colors = that.options.colorScaleOptions.colors,
            svg = that.svg;

        var colorScaleLength = colors.length;

        that.yScale = d3.scale
               .linear()
               .domain([0,colorScaleLength])
               .range([h - padding, 0 + padding]);

    that.barHeight = (h - padding) / colorScaleLength;

    var barHeight = that.barHeight;

    for(var i=0; i< colorScaleLength; i++) {
      svg.append("rect")
         .attr({
            "x": 75,
            "y": function() {
              return that.yScale(i) - barHeight;
            },
            "width": 425,
            "height": barHeight,
            "fill": colors[i],
            "stroke": "black"
        });
    }

    for(i=0; i< colorScaleLength; i++) {
      svg.append("text")
        .text("pH Value " + i + " - " + (i+1))
        .attr({
          "text-anchor": "middle",
          "transform": "translate(75)",
          "fill": "white",
          "x": 212.5,
          "y": function() {
            return that.yScale(i) - barHeight / 2;
          },
          "font-size": 16
        })
    }

    // Draw the PH indicator

    var startingPHValue = 7;
    var pointLocation = that.yScale(startingPHValue) - 15;

    var pHIndicatorGroup = svg.append("g")
    .attr({
        "class" : "phIndicatorGroup",
        "transform": "translate(25, "+ pointLocation +")",
        "fill": function() {
            var colorIdx = Math.floor(startingPHValue-1) > 0 ? Math.floor(startingPHValue-1) : 0;
            return colors[colorIdx];
        }
    });

    pHIndicatorGroup
    .append("path")
    .attr({
        "d": "M20 20 h-40 v-10 h40 v-10 l15 15 l-15 15 v-10",
        "stroke": "black"
    });
 };

    gpii.nexusSensorVisualizer.pHScale.visualizer.updateVisualization = function (visualizer, change) {
        var colors = visualizer.options.colorScaleOptions.colors,
            barHeight = visualizer.barHeight;

            var padding = 20;
            var pointLocation = visualizer.yScale(change.value)  - 15;

            d3.select(".phIndicatorGroup")
            .transition()
            .duration(1000)
            .attr({
                "transform": "translate(25, "+ pointLocation +")",
                "fill": function() {
                    var colorIdx = Math.floor(change.value-1) > 0 ? Math.floor(change.value-1) : 0;
                    return colors[colorIdx];
                }
            });

    };

}());
<|endoftext|>


<commit_before>var b1 = document.getElementById('b1');
var b2 = document.getElementById('b2');
var b3 = document.getElementById('b3');
var b4 = document.getElementById('b4');
var b5 = document.getElementById('b5');
var b6 = document.getElementById('b6');
var b7 = document.getElementById('b7');
var b8 = document.getElementById('b8');
var b9 = document.getElementById('b9');
var b10 = document.getElementById('b10');
var b11 = document.getElementById('b11');
var b12 = document.getElementById('b12');
var b13 = document.getElementById('b13');
var b14 = document.getElementById('b14');
var b6b = document.getElementById('b6b');
var b7b = document.getElementById('b7b');
var b8b = document.getElementById('b8b');
var b9b = document.getElementById('b9b');
var b10b = document.getElementById('b10b');
var b11b = document.getElementById('b11b');
var b12b = document.getElementById('b12b');
var b13b = document.getElementById('b13b');
var b14b = document.getElementById('b14b');
var q1 = document.getElementById('q1');
var q2 = document.getElementById('q2');
var q3 = document.getElementById('q3');
var q4 = document.getElementById('q4');
var q5 = document.getElementById('q5');
var q6 = document.getElementById('q6');
var q7 = document.getElementById('q7');
var q4b = document.getElementById('q4b');
var q5b = document.getElementById('q5b');
var q6b = document.getElementById('q6b');
var q7b = document.getElementById('q7b');
var deathbtn1 = document.getElementById('deathbtn1');
var deathbtn2 = document.getElementById('deathbtn2');
var deathbtn3 = document.getElementById('deathbtn3');
var deathbtn4 = document.getElementById('deathbtn4');
var deathbtn5 = document.getElementById('deathbtn5');
var deathbtn6 = document.getElementById('deathbtn6');
var deathbtn7 = document.getElementById('deathbtn7');
var deathbtn4b = document.getElementById('deathbtn4b');
var deathbtn5b = document.getElementById('deathbtn5b');
var deathbtn6b = document.getElementById('deathbtn6b');
var deathbtn7b = document.getElementById('deathbtn7b');
var reply1 = document.getElementById('reply1');
var reply2 = document.getElementById('reply2');

var player = {
 pName: null,
 species: null,
 gameStage: null
};

function loadGame() {
  var savedChar = localStorage.getItem("LOTR");
    var parseChar = JSON.parse(savedChar);
    // console.log(parseChar);
    if (parseChar != null || parseChar != ""){
        player.pName = parseChar.pName;
        player.species = parseChar.species;
        player.gameStage = parseChar.gameStage;
    }
}
loadGame();
document.getElementById('intro').innerHTML = 'Congrats ' + player.pName + ', you are a ' + player.species +'!';
function death (q, btn1, btn2, deathbtn) {
	q.hidden = true;
	btn1.hidden = true;
	btn2.hidden = true;
	deathbtn.hidden = false;
}

function diediedie (q, btn1, btn2, deathbtn) {
	q.hidden = false;
	btn1.hidden = false;
	btn2.hidden = false;
	deathbtn.hidden = true;
}

function itsAlive (q, btn1, btn2) {
	q.hidden = false;
	btn1.hidden = false;
	btn2.hidden = false;
}

function parentChild (q, btn1, btn2) {
	var parent = document.getElementById(q);
	var child1 = document.getElementById(btn1);
	var child2 = document.getElementById(btn2);
	parent.removeChild(child1);
	parent.removeChild(child2);
}

b1.addEventListener('click', function() {
	death(q2, b1, b2, deathbtn1);
})
b2.addEventListener('click', function() {
	itsAlive(q2, b3, b4);
	parentChild('q1', 'b1', 'b2');
})
b3.addEventListener('click', function() {
    death(q3, b3, b4, deathbtn2);
    b6b.hidden = true;
})
b4.addEventListener('click', function() {
    itsAlive(q3, b5, b6);
    parentChild('q2', 'b3', 'b4');
    b6b.hidden = false;
})
b5.addEventListener('click', function() {
    death(q4, b5, b6, deathbtn3);
    b6b.hidden = true;
})
b6.addEventListener('click', function() {
    itsAlive(q4, b7, b8, b5, b6);
    parentChild('q3', 'b5', 'b6')
    b6b.hidden = true;

})
b7.addEventListener('click', function() {
    death(q5, b7, b8, deathbtn4);
})
b8.addEventListener('click', function() {
    itsAlive(q5, b9, b10);
    parentChild('q4', 'b7', 'b8')
})
b9.addEventListener('click', function() {
    death(q6, b9, b10, deathbtn5);
})
b10.addEventListener('click', function() {
    itsAlive(q6, b11, b12);
    parentChild('q5', 'b9', 'b10')
})
b11.addEventListener('click', function() {
    death(q7, b11, b12, deathbtn6);
})
b12.addEventListener('click', function() {
    itsAlive(q7, b13, b14);
    parentChild('q6', 'b11', 'b12')
})
b13.addEventListener('click', function() {
    deathbtn7.hidden = false;
    b13.hidden = true;
    b14.hidden = true;
})
b14.addEventListener('click', function() {
    b13.hidden = true;
    b14.hidden = true;
    reply1.hidden = false;
})

b6b.addEventListener('click', function() {
    b6b.hidden = true;
    itsAlive(q4b, b7b, b8b, b5, b6b);
    parentChild('q3', 'b5', 'b6')
})
b7b.addEventListener('click', function() {
    death(q5b, b7b, b8b, deathbtn4b);
})
b8b.addEventListener('click', function() {
    itsAlive(q5b, b9b, b10b);
    parentChild('q4b', 'b7b', 'b8b')
})
b9b.addEventListener('click', function() {
    death(q6b, b9b, b10b, deathbtn5b);
})
b10b.addEventListener('click', function() {
    itsAlive(q6b, b11b, b12b);
    parentChild('q5b', 'b9b', 'b10b')
})
b11b.addEventListener('click', function() {
    death(q7b, b11b, b12b, deathbtn6b);
})
b12b.addEventListener('click', function() {
    itsAlive(q7b, b13b, b14b);
    parentChild('q6b', 'b11b', 'b12b')
})
b13b.addEventListener('click', function() {
    deathbtn7b.hidden = false;
    b13b.hidden = true;
    b14b.hidden = true;
})
b14b.addEventListener('click', function() {
    b13b.hidden = true;
    b14b.hidden = true;
    reply2.hidden = false;
})

deathbtn1.addEventListener('click', function () {
    diediedie(q1, b1, b2, deathbtn1);
})
deathbtn2.addEventListener('click', function () {
    diediedie(q2, b3, b4, deathbtn2);
})
deathbtn3.addEventListener('click', function() {
    diediedie(q3, b5, b6, deathbtn3);
    b6b.hidden = false;
})
deathbtn4.addEventListener('click', function() {
    diediedie(q4, b7, b8, deathbtn4);
})
deathbtn5.addEventListener('click', function() {
    diediedie(q5, b9, b10, deathbtn5);
})
deathbtn6.addEventListener('click', function() {
    diediedie(q6, b11, b12, deathbtn6);
})
deathbtn7.addEventListener('click', function() {
    diediedie(q7, b13, b14, deathbtn7);
})

deathbtn4b.addEventListener('click', function() {
    diediedie(q4b, b7b, b8b, deathbtn4b);
})

deathbtn5b.addEventListener('click', function() {
    diediedie(q5b, b9b, b10b, deathbtn5b);
})
deathbtn6b.addEventListener('click', function() {
    diediedie(q6b, b11b, b12b, deathbtn6b);
})
deathbtn7b.addEventListener('click', function() {
    diediedie(q7b, b13b, b14b, deathbtn7b);
})

<commit_msg>fixed null error when loading a game without a save<commit_after>var b1 = document.getElementById('b1');
var b2 = document.getElementById('b2');
var b3 = document.getElementById('b3');
var b4 = document.getElementById('b4');
var b5 = document.getElementById('b5');
var b6 = document.getElementById('b6');
var b7 = document.getElementById('b7');
var b8 = document.getElementById('b8');
var b9 = document.getElementById('b9');
var b10 = document.getElementById('b10');
var b11 = document.getElementById('b11');
var b12 = document.getElementById('b12');
var b13 = document.getElementById('b13');
var b14 = document.getElementById('b14');
var b6b = document.getElementById('b6b');
var b7b = document.getElementById('b7b');
var b8b = document.getElementById('b8b');
var b9b = document.getElementById('b9b');
var b10b = document.getElementById('b10b');
var b11b = document.getElementById('b11b');
var b12b = document.getElementById('b12b');
var b13b = document.getElementById('b13b');
var b14b = document.getElementById('b14b');
var q1 = document.getElementById('q1');
var q2 = document.getElementById('q2');
var q3 = document.getElementById('q3');
var q4 = document.getElementById('q4');
var q5 = document.getElementById('q5');
var q6 = document.getElementById('q6');
var q7 = document.getElementById('q7');
var q4b = document.getElementById('q4b');
var q5b = document.getElementById('q5b');
var q6b = document.getElementById('q6b');
var q7b = document.getElementById('q7b');
var deathbtn1 = document.getElementById('deathbtn1');
var deathbtn2 = document.getElementById('deathbtn2');
var deathbtn3 = document.getElementById('deathbtn3');
var deathbtn4 = document.getElementById('deathbtn4');
var deathbtn5 = document.getElementById('deathbtn5');
var deathbtn6 = document.getElementById('deathbtn6');
var deathbtn7 = document.getElementById('deathbtn7');
var deathbtn4b = document.getElementById('deathbtn4b');
var deathbtn5b = document.getElementById('deathbtn5b');
var deathbtn6b = document.getElementById('deathbtn6b');
var deathbtn7b = document.getElementById('deathbtn7b');
var reply1 = document.getElementById('reply1');
var reply2 = document.getElementById('reply2');

var player = {
    pName: "Guest",
    species: "hobbit",
    gameStage: null
};
var savedChar = localStorage.getItem("LOTR");
function loadGame(){
    var savedChar = localStorage.getItem("LOTR");
    var parseChar = JSON.parse(savedChar);
    // console.log(parseChar);
    player.pName = parseChar.pName;
    player.species = parseChar.species;
    player.gameStage = parseChar.gameStage;

}
if (savedChar != null ){
    loadGame();
};
document.getElementById('intro').innerHTML = 'Congrats ' + player.pName + ', you are a ' + player.species +'!';
function death (q, btn1, btn2, deathbtn) {
	q.hidden = true;
	btn1.hidden = true;
	btn2.hidden = true;
	deathbtn.hidden = false;
}

function diediedie (q, btn1, btn2, deathbtn) {
	q.hidden = false;
	btn1.hidden = false;
	btn2.hidden = false;
	deathbtn.hidden = true;
}

function itsAlive (q, btn1, btn2) {
	q.hidden = false;
	btn1.hidden = false;
	btn2.hidden = false;
}

function parentChild (q, btn1, btn2) {
	var parent = document.getElementById(q);
	var child1 = document.getElementById(btn1);
	var child2 = document.getElementById(btn2);
	parent.removeChild(child1);
	parent.removeChild(child2);
}

b1.addEventListener('click', function() {
	death(q2, b1, b2, deathbtn1);
})
b2.addEventListener('click', function() {
	itsAlive(q2, b3, b4);
	parentChild('q1', 'b1', 'b2');
})
b3.addEventListener('click', function() {
    death(q3, b3, b4, deathbtn2);
    b6b.hidden = true;
})
b4.addEventListener('click', function() {
    itsAlive(q3, b5, b6);
    parentChild('q2', 'b3', 'b4');
    b6b.hidden = false;
})
b5.addEventListener('click', function() {
    death(q4, b5, b6, deathbtn3);
    b6b.hidden = true;
})
b6.addEventListener('click', function() {
    itsAlive(q4, b7, b8, b5, b6);
    parentChild('q3', 'b5', 'b6')
    b6b.hidden = true;

})
b7.addEventListener('click', function() {
    death(q5, b7, b8, deathbtn4);
})
b8.addEventListener('click', function() {
    itsAlive(q5, b9, b10);
    parentChild('q4', 'b7', 'b8')
})
b9.addEventListener('click', function() {
    death(q6, b9, b10, deathbtn5);
})
b10.addEventListener('click', function() {
    itsAlive(q6, b11, b12);
    parentChild('q5', 'b9', 'b10')
})
b11.addEventListener('click', function() {
    death(q7, b11, b12, deathbtn6);
})
b12.addEventListener('click', function() {
    itsAlive(q7, b13, b14);
    parentChild('q6', 'b11', 'b12')
})
b13.addEventListener('click', function() {
    deathbtn7.hidden = false;
    b13.hidden = true;
    b14.hidden = true;
})
b14.addEventListener('click', function() {
    b13.hidden = true;
    b14.hidden = true;
    reply1.hidden = false;
})

b6b.addEventListener('click', function() {
    b6b.hidden = true;
    itsAlive(q4b, b7b, b8b, b5, b6b);
    parentChild('q3', 'b5', 'b6')
})
b7b.addEventListener('click', function() {
    death(q5b, b7b, b8b, deathbtn4b);
})
b8b.addEventListener('click', function() {
    itsAlive(q5b, b9b, b10b);
    parentChild('q4b', 'b7b', 'b8b')
})
b9b.addEventListener('click', function() {
    death(q6b, b9b, b10b, deathbtn5b);
})
b10b.addEventListener('click', function() {
    itsAlive(q6b, b11b, b12b);
    parentChild('q5b', 'b9b', 'b10b')
})
b11b.addEventListener('click', function() {
    death(q7b, b11b, b12b, deathbtn6b);
})
b12b.addEventListener('click', function() {
    itsAlive(q7b, b13b, b14b);
    parentChild('q6b', 'b11b', 'b12b')
})
b13b.addEventListener('click', function() {
    deathbtn7b.hidden = false;
    b13b.hidden = true;
    b14b.hidden = true;
})
b14b.addEventListener('click', function() {
    b13b.hidden = true;
    b14b.hidden = true;
    reply2.hidden = false;
})

deathbtn1.addEventListener('click', function () {
    diediedie(q1, b1, b2, deathbtn1);
})
deathbtn2.addEventListener('click', function () {
    diediedie(q2, b3, b4, deathbtn2);
})
deathbtn3.addEventListener('click', function() {
    diediedie(q3, b5, b6, deathbtn3);
    b6b.hidden = false;
})
deathbtn4.addEventListener('click', function() {
    diediedie(q4, b7, b8, deathbtn4);
})
deathbtn5.addEventListener('click', function() {
    diediedie(q5, b9, b10, deathbtn5);
})
deathbtn6.addEventListener('click', function() {
    diediedie(q6, b11, b12, deathbtn6);
})
deathbtn7.addEventListener('click', function() {
    diediedie(q7, b13, b14, deathbtn7);
})

deathbtn4b.addEventListener('click', function() {
    diediedie(q4b, b7b, b8b, deathbtn4b);
})

deathbtn5b.addEventListener('click', function() {
    diediedie(q5b, b9b, b10b, deathbtn5b);
})
deathbtn6b.addEventListener('click', function() {
    diediedie(q6b, b11b, b12b, deathbtn6b);
})
deathbtn7b.addEventListener('click', function() {
    diediedie(q7b, b13b, b14b, deathbtn7b);
})

<|endoftext|>


<commit_before>$(document).ready(function() {

  // add the title to the submit button form
  $('#submit-button-form').submit(function() {
      var title = $('#page-title').val();
      var newinput = $('<input type="hidden" name="name" value="' + title + '" />');
      newinput.appendTo($(this));
      return true;
  });

  // clicking on page title erases text already there
  $('#page-title').focus(function() {
      if ($(this).val() == "Page Name") {
        $(this).val("");
      }
  }).blur(function() {
      if ($(this).val() == "") {
        $(this).val("Page Name");
      }
  });

  var tools = [{
      link: $('#text-tool'),
      submitfn: submit_handler
    }, {
      link: $('#map-tool'),
                submitfn: submit_handler
    }
  ];

  for (var i = 0; i < tools.length; i++) {
      var fn = function(i) {
        var tool = tools[i];
        var link = tool.link;
        var submitfn = tool.submitfn;

        // when somebody tries to add a particular media type, fetch the form from
        // the server, and attach the behavior to it
        link.click(function(e) {
          e.preventDefault();
          var url = $(this).attr('href');

          var formcontainer = $('#form-container');
          $.get(url, null, function(data) {
            formcontainer.empty();
            formcontainer.show();
            $(data).appendTo(formcontainer).slideDown('fast');
            $('form.media-item a.media-cancel').click(function(e) {
              e.preventDefault();
              formcontainer.slideUp('fast').empty();
            });
            $('form.media-item').submit(submitfn);
          });
        });
      }
      fn(i);
    }
});

function submit_handler(e) {
  e.preventDefault();
  var url = $(this).attr('action');
  var data = $('form.media-item').serialize();
  var formcontainer = $('#form-container');

  $.ajax({
    contentType: 'application/x-www-form-urlencoded',
    data: data,
    success: function(data, textStatus) {
      formcontainer.empty();
      var newLi = $('

');
      newLi.appendTo($('.session-data ul'));
      $('
' + data + '
').appendTo(newLi).fadeIn('slow');
      },
    type: "POST",
    url: url
  });
};
<commit_msg>focus the text input when adding a text story<commit_after>$(document).ready(function() {

  // add the title to the submit button form
  $('#submit-button-form').submit(function() {
      var title = $('#page-title').val();
      var newinput = $('<input type="hidden" name="name" value="' + title + '" />');
      newinput.appendTo($(this));
      return true;
  });

  // clicking on page title erases text already there
  $('#page-title').focus(function() {
      if ($(this).val() == "Page Name") {
        $(this).val("");
      }
  }).blur(function() {
      if ($(this).val() == "") {
        $(this).val("Page Name");
      }
  });

  var tools = [{
      link: $('#text-tool'),
      submitfn: submit_handler
    }, {
      link: $('#map-tool'),
                submitfn: submit_handler
    }
  ];

  for (var i = 0; i < tools.length; i++) {
      var fn = function(i) {
        var tool = tools[i];
        var link = tool.link;
        var submitfn = tool.submitfn;

        // when somebody tries to add a particular media type, fetch the form from
        // the server, and attach the behavior to it
        link.click(function(e) {
          e.preventDefault();
          var url = $(this).attr('href');

          var formcontainer = $('#form-container');
          $.get(url, null, function(data) {
            formcontainer.empty();
            formcontainer.show();
            $(data).appendTo(formcontainer).hide().slideDown('fast', function() {
              $(this).find('input[type=text]').focus();
            });
            $('form.media-item a.media-cancel').click(function(e) {
              e.preventDefault();
              formcontainer.slideUp('fast').empty();
            });
            $('form.media-item').submit(submitfn);
          });
        });
      }
      fn(i);
    }
});

function submit_handler(e) {
  e.preventDefault();
  var url = $(this).attr('action');
  var data = $('form.media-item').serialize();
  var formcontainer = $('#form-container');

  $.ajax({
    contentType: 'application/x-www-form-urlencoded',
    data: data,
    success: function(data, textStatus) {
      formcontainer.empty();
      var newLi = $('

');
      newLi.appendTo($('.session-data ul'));
      $('
' + data + '
').appendTo(newLi).fadeIn('slow');
      },
    type: "POST",
    url: url
  });
};
<|endoftext|>


<commit_before>openerp.google_docs = function(instance, m) {
var _t = instance.web._t,
    QWeb = instance.web.qweb;

    instance.web.Sidebar.include({
        redraw: function() {
            var self = this;
            this._super.apply(this, arguments);
            self.$el.find('.oe_sidebar_add_attachment').after(QWeb.render('AddGoogleDocumentItem', {widget: self}))
            self.$el.find('.oe_sidebar_add_google_doc').on('click', function (e) {
                self.on_google_doc();
            });
        },
        on_google_doc: function() {
            var self = this;
            var view = self.getParent();
            var ids = ( view.fields_view.type != "form" )? view.groups.get_selection().ids : [ view.datarecord.id ];
            if( !_.isEmpty(ids) ){
                view.sidebar_context().then(function (context) {
                    var ds = new instance.web.DataSet(this, 'ir.attachment', context);
                    ds.call('google_doc_get', [view.dataset.model, ids, context]).then(function(r) {
                        if (r == 'False') {
                            var params = {
                                error: response,
                                message: _t("The user google credentials are not set yet. Contact your administrator for help.")
                            }
                            $(openerp.web.qweb.render("DialogWarning", params)).dialog({
                                title: _t("User Google credentials are not yet set."),
                                modal: true,
                            });
                        }
                    }).done(function(){
                        window.open(r.url,"_blank");
                        view.reload();
                    });
                });
            }
        }
    });
};
<commit_msg>[FIX] corrected code for opening new google doc.<commit_after>openerp.google_docs = function(instance, m) {
var _t = instance.web._t,
    QWeb = instance.web.qweb;

    instance.web.Sidebar.include({
        redraw: function() {
            var self = this;
            this._super.apply(this, arguments);
            self.$el.find('.oe_sidebar_add_attachment').after(QWeb.render('AddGoogleDocumentItem', {widget: self}))
            self.$el.find('.oe_sidebar_add_google_doc').on('click', function (e) {
                self.on_google_doc();
            });
        },
        on_google_doc: function() {
            var self = this;
            var view = self.getParent();
            var ids = ( view.fields_view.type != "form" )? view.groups.get_selection().ids : [ view.datarecord.id ];
            if( !_.isEmpty(ids) ){
                view.sidebar_context().then(function (context) {
                    var ds = new instance.web.DataSet(this, 'ir.attachment', context);
                    ds.call('google_doc_get', [view.dataset.model, ids, context]).then(function(r) {
                        if (r == 'False') {
                            var params = {
                                error: response,
                                message: _t("The user google credentials are not set yet. Contact your administrator for help.")
                            }
                            $(openerp.web.qweb.render("DialogWarning", params)).dialog({
                                title: _t("User Google credentials are not yet set."),
                                modal: true,
                            });
                        }
                    }).done(function(r){
                        window.open(r.url,"_blank");
                        view.reload();
                    });
                });
            }
        }
    });
};
<|endoftext|>


<commit_before>//================================================================
// RS_AnimataionVisibility.js
// ---------------------------------------------------------------
// The MIT License
// Copyright (c) 2019 biud436
// ---------------------------------------------------------------
// Free for commercial and non commercial use.
//================================================================
/*:
 * @target MV
 * @plugindesc This plugin allows you to remove the animation on the screen when the character is deactivated. <RS_AnimataionVisibility>
 * @author biud436
 * @help
 * ================================================================
 * Introduction
 * ================================================================
 * In case of the RPG Maker MV,
 * The Animation will be played until the last cell even if the character doesn't show up anymore on the screen.
 * This plugin allows you to remove the animation on the screen when the character is deactivated.
 *
 * ◆ Animation Stop Condition
 *   - erased event.
 *   - if the event execution conditions are not met.
 *   - empty graphic.
 *
 * ================================================================
 * Version Log
 * ================================================================
 * 2019.03.24 (v1.0.0) - First Release.
 * 2020.09.13 (v1.0.1) :
 * - Fixed the issue that is not working when playing a animation to player.
 * 2020.09.14 (v1.0.2) :
 * - Fixed the bug that is not playing the animation to object character.
 * 2020.09.17 (v1.0.3) :
 * - Fixed the issue that is not working an animation in tile event.
 */
/*:ko
 * @plugindesc 애니메이션을 바로 정지시킵니다. <RS_AnimataionVisibility>
 * @author biud436
 * @help
 * ================================================================
 * 소개
 * ================================================================
 * RPG Maker MV의 경우, 캐릭터가 화면에서 보이지 않아도 애니메이션이 끝까지 재생됩니다.
 * 이 플러그인은 캐릭터가 화면에서 보이지 않으면 애니메이션을 바로 정지시킵니다.
 *
 *  ◆ 정지 조건
 *    - 이벤트 일시 삭제
 *    - 이벤트 실행 조건이 충족하지 않을 때 (변수, 스위치, 셀프 스위치)
 *    - 캐릭터 그래픽이 비어있을 때
 *
 * ================================================================
 * Version Log
 * ================================================================
 * 2019.03.24 (v1.0.0) - First Release.
 * 2020.09.13 (v1.0.1) :
 * - 플레이어에 애니메이션 재생 시 오류가 나는 문제를 수정하였습니다.
 * 2020.09.14 (v1.0.2) :
 * - 애니메이션이 재생되지 않는 문제를 수정하였습니다.
 * 2020.09.17 (v1.0.3) :
 * - 타일 이벤트에서 애니메이션이 동작하지 않는 문제를 수정하였습니다.
 */

(() => {
    const parameters = $plugins.filter(function (i) {
        return i.description.contains("<RS_AnimataionVisibility>");
    })[0].parameters;

    const alias_Sprite_Animation_update = Sprite_Animation.prototype.update;
    Sprite_Animation.prototype.update = function () {
        alias_Sprite_Animation_update.call(this);
        this.updateVisibility();
    };

    Sprite_Animation.prototype.isTargetReady = function () {
        if (!this._target) return false;
        if (!(this._target instanceof Sprite_Character)) return false;
        const target = this._target._character;

        let isActivated = false;

        if (target instanceof Game_Event) {
            isActivated = target.findProperPageIndex() > -1;
        } else if (target instanceof Game_CharacterBase) {
            isActivated = true;
        } else {
            return false;
        }

        const isTransparent = target.isTransparent(); // 투명한가?
        const isErased = target._erased;

        if (!isErased) {
            isErased = target.isTile() ? isErased : !target._characterName;
        }

        return isActivated && !isTransparent && !isErased;
    };

    Sprite_Animation.prototype.updateVisibility = function () {
        this.visible = this.isTargetReady();
    };

    const alias_Sprite_Animation_processTimingData =
        Sprite_Animation.prototype.processTimingData;
    Sprite_Animation.prototype.processTimingData = function (timing) {
        if (!this.isTargetReady()) return;
        alias_Sprite_Animation_processTimingData.call(this, timing);
    };
})();
<commit_msg>chore: apply eslint.<commit_after>//================================================================
// RS_AnimataionVisibility.js
// ---------------------------------------------------------------
// The MIT License
// Copyright (c) 2019 biud436
// ---------------------------------------------------------------
// Free for commercial and non commercial use.
//================================================================
/*:
 * @target MV
 * @plugindesc This plugin allows you to remove the animation on the screen when the character is deactivated. <RS_AnimataionVisibility>
 * @author biud436
 * @help
 * ================================================================
 * Introduction
 * ================================================================
 * In case of the RPG Maker MV,
 * The Animation will be played until the last cell even if the character doesn't show up anymore on the screen.
 * This plugin allows you to remove the animation on the screen when the character is deactivated.
 *
 * ◆ Animation Stop Condition
 *   - erased event.
 *   - if the event execution conditions are not met.
 *   - empty graphic.
 *
 * ================================================================
 * Version Log
 * ================================================================
 * 2019.03.24 (v1.0.0) - First Release.
 * 2020.09.13 (v1.0.1) :
 * - Fixed the issue that is not working when playing a animation to player.
 * 2020.09.14 (v1.0.2) :
 * - Fixed the bug that is not playing the animation to object character.
 * 2020.09.17 (v1.0.3) :
 * - Fixed the issue that is not working an animation in tile event.
 */
/*:ko
 * @plugindesc 애니메이션을 바로 정지시킵니다. <RS_AnimataionVisibility>
 * @author biud436
 * @help
 * ================================================================
 * 소개
 * ================================================================
 * RPG Maker MV의 경우, 캐릭터가 화면에서 보이지 않아도 애니메이션이 끝까지 재생됩니다.
 * 이 플러그인은 캐릭터가 화면에서 보이지 않으면 애니메이션을 바로 정지시킵니다.
 *
 *  ◆ 정지 조건
 *    - 이벤트 일시 삭제
 *    - 이벤트 실행 조건이 충족하지 않을 때 (변수, 스위치, 셀프 스위치)
 *    - 캐릭터 그래픽이 비어있을 때
 *
 * ================================================================
 * Version Log
 * ================================================================
 * 2019.03.24 (v1.0.0) - First Release.
 * 2020.09.13 (v1.0.1) :
 * - 플레이어에 애니메이션 재생 시 오류가 나는 문제를 수정하였습니다.
 * 2020.09.14 (v1.0.2) :
 * - 애니메이션이 재생되지 않는 문제를 수정하였습니다.
 * 2020.09.17 (v1.0.3) :
 * - 타일 이벤트에서 애니메이션이 동작하지 않는 문제를 수정하였습니다.
 */

(() => {
    const aliasSpriteAnimationUpdate = Sprite_Animation.prototype.update;
    Sprite_Animation.prototype.update = function () {
        aliasSpriteAnimationUpdate.call(this);
        this.updateVisibility();
    };

    Sprite_Animation.prototype.isTargetReady = function () {
        if (!this._target) return false;
        if (!(this._target instanceof Sprite_Character)) return false;
        const target = this._target._character;

        let isActivated = false;

        if (target instanceof Game_Event) {
            isActivated = target.findProperPageIndex() > -1;
        } else if (target instanceof Game_CharacterBase) {
            isActivated = true;
        } else {
            return false;
        }

        const isTransparent = target.isTransparent(); // 투명한가?
        let isErased = target._erased;

        if (!isErased) {
            isErased = target.isTile() ? isErased : !target._characterName;
        }

        return isActivated && !isTransparent && !isErased;
    };

    Sprite_Animation.prototype.updateVisibility = function () {
        this.visible = this.isTargetReady();
    };

    const aliasSpriteAnimationProcessTimingData =
        Sprite_Animation.prototype.processTimingData;
    Sprite_Animation.prototype.processTimingData = function (timing) {
        if (!this.isTargetReady()) return;
        aliasSpriteAnimationProcessTimingData.call(this, timing);
    };
})();
<|endoftext|>


<commit_before>import React, {	Component } from 'react';
import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table';
import CommonQueries from './CommonGraphQLQueries';
import DataIndex from './DataIndex';
import Link from './Link';

class Report extends Component {

	constructor(props) {
		super(props);
		this._initReport = this._initReport.bind(this);
		this._handleData = this._handleData.bind(this);
		this.state = {
			setup: null,
			data: []
		};
	}

	componentDidMount() {
		lx.init().then(this._initReport);
	}

	_initReport(setup) {
		lx.ready(this._createConfig());
		this.setState({
			setup: setup
		});
		// get all tags, then the data
		lx.executeGraphQL(CommonQueries.tagGroups).then((tagGroups) => {
			const index = new DataIndex();
			index.put(tagGroups);
			const appMapID = index.getFirstTagID('BC Type', 'AppMap');
			lx.executeGraphQL(this._createQuery(appMapID)).then((data) => {
				index.put(data);
				this._handleData(index, appMapID);
			});
		});
	}

	_createConfig() {
		return {
			allowEditing: false
		};
	}

	_createQuery(appMapID) {
		let appMapIDFilter = ''; // initial assume tagGroup.name changed or the id couldn't be determined otherwise
		let tagNameDef = 'tags { name }'; // initial assume to get it
		if (appMapID) {
			// query filtering only bc with tag 'AppMap'
			appMapIDFilter = `, {facetKey: "BC Type", keys: ["${appMapID}"]}`;
			tagNameDef = '';
		}
		return `{businessCapabilities: allFactSheets(
					sort: {mode: BY_FIELD, key: "displayName", order: asc},
					filter: {facetFilters: [
						{facetKey: "FactSheetTypes", keys: ["BusinessCapability"]}
						${appMapIDFilter}
					]}
				) {
					edges { node {
						id name ${tagNameDef}
						... on BusinessCapability {
							relBusinessCapabilityToDataObject {
								edges { node { factSheet {
									id name
									... on DataObject {
										relToParent { edges { node { factSheet { id name } } } }
									}
								}}}
							}
							relToParent { edges { node { factSheet { id name } } } }
						}
					}}
				}}`;
	}

	_handleData(index, appMapID) {
		const tableData = [];
		index.businessCapabilities.nodes.forEach((appMapL2) => {
			if (!appMapID && !index.includesTag(appMapL2, 'AppMap')) {
				return;
			}
			const subIndex = appMapL2.relBusinessCapabilityToDataObject;
			if (!subIndex) {
				return;
			}
			subIndex.nodes.forEach((cimL2) => {
				const cimL1 = cimL2.relToParent ? cimL2.relToParent.nodes[0] : undefined;
				const appMapL1 = appMapL2.relToParent ? appMapL2.relToParent.nodes[0] : undefined;
				tableData.push({
					appMapL1ID: appMapL1 ? appMapL1.id : '',
					appMapL1Name: appMapL1 ? appMapL1.name : '',
					appMapL2ID: appMapL2.id,
					appMapL2Name: appMapL2.name,
					cimL1ID: cimL1 ? cimL1.id : '',
					cimL1Name: cimL1 ? cimL1.name : '',
					cimL2ID: cimL2.id,
					cimL2Name: cimL2.name
				});
			});
		});
		this.setState({
			data: tableData
		});
	}

	/* formatting functions for the table */

	_formatLinkBC(cell, row, idName) {
		if (!cell) {
			return '';
		}
		return (<Link link={'factsheet/BusinessCapability/' + row[idName]} target='_blank' text={cell} />);
	}

	_formatLinkDO(cell, row, idName) {
		if (!cell) {
			return '';
		}
		return (<Link link={'factsheet/DataObject/' + row[idName]} target='_blank' text={cell} />);
	}

	render() {
		if (this.state.data.length === 0) {
			return null;
		}
		return (
			<BootstrapTable data={this.state.data} keyField='appMapL2ID'
				striped hover search pagination ignoreSinglePage exportCSV
				options={{ clearSearch: true }}>
				<TableHeaderColumn hidden export
					 dataField='appMapL1ID'
					 csvHeader='appmap-domain-id'
					>appMapL1ID</TableHeaderColumn>
				<TableHeaderColumn dataSort
					dataField='appMapL1Name'
					dataAlign='left'
					dataFormat={this._formatLinkBC}
					formatExtraData={'appMapL1ID'}
					csvHeader='appmap-domain'
					filter={{ type: 'TextFilter', placeholder: 'Please enter a value' }}
				>AppMap Domain</TableHeaderColumn>
				<TableHeaderColumn hidden export
					 dataField='appMapL2ID'
					 csvHeader='appmap-solution-area-id'
					>appMapL2ID</TableHeaderColumn>
				<TableHeaderColumn dataSort
					dataField='appMapL2Name'
					dataAlign='left'
					dataFormat={this._formatLinkBC}
					formatExtraData={'appMapL2ID'}
					csvHeader='appmap-solution-area'
					filter={{ type: 'TextFilter', placeholder: 'Please enter a value' }}
				>AppMap Solution Area</TableHeaderColumn>
				<TableHeaderColumn hidden export
					 dataField='cimL1ID'
					 csvHeader='cim-domain-id'
					>cimL1ID</TableHeaderColumn>
				<TableHeaderColumn dataSort
					dataField='cimL1Name'
					dataAlign='left'
					dataFormat={this._formatLinkDO}
					formatExtraData={'cimL1ID'}
					csvHeader='cim-domain'
					filter={{ type: 'TextFilter', placeholder: 'Please enter a value' }}
				>CIM Domain</TableHeaderColumn>
				<TableHeaderColumn hidden export
					 dataField='cimL2ID'
					 csvHeader='cim-entity-id'
					>cimL2ID</TableHeaderColumn>
				<TableHeaderColumn dataSort
					dataField='cimL2Name'
					dataAlign='left'
					dataFormat={this._formatLinkDO}
					formatExtraData={'cimL2ID'}
					csvHeader='cim-entity'
					filter={{ type: 'TextFilter', placeholder: 'Please enter a value' }}
				>CIM Entity</TableHeaderColumn>
			</BootstrapTable>
		);
	}
}

export default Report;
<commit_msg>fixing unix problem<commit_after><|endoftext|>


<commit_before>/*---------------------------------------------------------
 * OpenERP diagram library
 *---------------------------------------------------------*/

openerp.web_diagram = function (instance) {
var QWeb = instance.web.qweb,
      _t = instance.web._t,
     _lt = instance.web._lt;
instance.web.views.add('diagram', 'instance.web.DiagramView');
instance.web.DiagramView = instance.web.View.extend({
    display_name: _lt('Diagram'),
    searchable: false,
    init: function(parent, dataset, view_id, options) {
        this._super(parent);
        this.set_default_options(options);
        this.view_manager = parent;
        this.dataset = dataset;
        this.model = this.dataset.model;
        this.view_id = view_id;
        this.domain = this.dataset._domain || [];
        this.context = {};
        this.ids = this.dataset.ids;
    },
    start: function() {
        return this.rpc("/web_diagram/diagram/load", {"model": this.model, "view_id": this.view_id}, this.on_loaded);
    },

    toTitleCase: function(str) {
        return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
    },

    on_loaded: function(result) {

        var self = this;
        if(this.ids && this.ids.length) {
            this.id = this.ids[self.dataset.index || 0];
        }

        this.fields_view = result.fields_view,
        this.view_id = this.fields_view.view_id,
        this.fields = this.fields_view.fields,
        this.nodes = this.fields_view.arch.children[0],
        this.connectors = this.fields_view.arch.children[1],
        this.node = this.nodes.attrs.object,
        this.connector = this.connectors.attrs.object;
        this.labels = _.filter(this.fields_view.arch.children, function(label) {
            return label.tag == "label";
        });

        this.$el.html(QWeb.render("DiagramView", {'widget': this}));
        this.$el.addClass(this.fields_view.arch.attrs['class']);

        _.each(self.labels,function(label){
            html_label = '
' + label.attrs.string + "
";
            self.$el.find('.oe_diagram_header').append(html_label);
        })

        this.$el.find('div.oe_diagram_pager button[data-pager-action]').click(function() {
            var action = $(this).data('pager-action');
            self.execute_pager_action(action);
        });

        this.do_update_pager();

        // New Node,Edge
        this.$el.find('#new_node.oe_diagram_button_new').click(function(){self.add_node();});

        if(this.id) {
            self.get_diagram_info();
        }

    },

    get_diagram_info: function() {
        var self = this;
        var params = {
            'id': this.id,
            'model': this.model,
            'node': this.node,
            'connector': this.connector,
            'bgcolor': this.nodes.attrs.bgcolor,
            'shape': this.nodes.attrs.shape,
            'src_node': this.connectors.attrs.source,
            'des_node': this.connectors.attrs.destination,
            'label': this.connectors.attrs.label || false,
            'visible_nodes': [],
            'invisible_nodes': [],
            'node_fields': [],
            'connectors': [],
            'connectors_fields': []
        };

        _.each(this.nodes.children, function(child) {
            if(child.attrs.invisible == '1')
                params['invisible_nodes'].push(child.attrs.name);
            else {
                params['visible_nodes'].push(child.attrs.name);
                params['node_fields'].push(self.fields[child.attrs.name]['string']|| this.toTitleCase(child.attrs.name));
            }
        });

        _.each(this.connectors.children, function(conn) {
            params['connectors_fields'].push(self.fields[conn.attrs.name]['string']|| this.toTitleCase(conn.attrs.name));
            params['connectors'].push(conn.attrs.name);
        });

        this.rpc(
            '/web_diagram/diagram/get_diagram_info',params).then(function(result) {
                self.draw_diagram(result);
            }
        );
    },

    on_diagram_loaded: function(record) {
        var id_record = record['id'];
        if(id_record) {
            this.id = id_record;
            this.get_diagram_info();
        }
    },

    // Set-up the drawing elements of the diagram
    draw_diagram: function(result) {
        var self = this;
        var res_nodes  = result['nodes'];
        var res_edges  = result['conn'];
        this.parent_field = result.parent_field;
        this.$el.find('h3.oe_diagram_title').text(result.name);

        var id_to_node = {};

        var style = {
            edge_color: "#A0A0A0",
            edge_label_color: "#555",
            edge_label_font_size: 10,
            edge_width: 2,
            edge_spacing: 100,
            edge_loop_radius: 100,

            node_label_color: "#333",
            node_label_font_size: 12,
            node_outline_color: "#333",
            node_outline_width: 1,
            node_selected_color: "#0097BE",
            node_selected_width: 2,
            node_size_x: 110,
            node_size_y: 80,
            connector_active_color: "#FFF",
            connector_radius: 4,

            close_button_radius: 8,
            close_button_color: "#333",
            close_button_x_color: "#FFF",

            gray: "#DCDCDC",
            white: "#FFF",

            viewport_margin: 50
        };

        // remove previous diagram
        var canvas = self.$el.find('div.oe_diagram_diagram')
                             .empty().get(0);

        var r  = new Raphael(canvas, '100%','100%');

        var graph  = new CuteGraph(r,style,canvas.parentNode);

        var confirm_dialog = $('#dialog').dialog({
            autoOpen: false,
            title: _t("Are you sure?") });

        _.each(res_nodes, function(node) {
            var n = new CuteNode(
                graph,
                node.x + 50,  //FIXME the +50 should be in the layout algorithm
                node.y + 50,
                CuteGraph.wordwrap(node.name, 14),
                node.shape === 'rectangle' ? 'rect' : 'circle',
                node.color === 'white' ? style.white : style.gray);

            n.id = node.id;
            id_to_node[node.id] = n;
        });

        _.each(res_edges, function(edge) {
            var e =  new CuteEdge(
                graph,
                CuteGraph.wordwrap(edge.signal, 32),
                id_to_node[edge.s_id],
                id_to_node[edge.d_id] || id_to_node[edge.s_id]  );  //WORKAROUND
            e.id = edge.id;
        });

        CuteNode.double_click_callback = function(cutenode){
            self.edit_node(cutenode.id);
        };
        var i = 0;
        CuteNode.destruction_callback = function(cutenode){
            if(!confirm(_t("Deleting this node cannot be undone.\nIt will also delete all connected transitions.\n\nAre you sure ?"))){
                return $.Deferred().reject().promise();
            }
            return new instance.web.DataSet(self,self.node).unlink([cutenode.id]);
        };
        CuteEdge.double_click_callback = function(cuteedge){
            self.edit_connector(cuteedge.id);
        };

        CuteEdge.creation_callback = function(node_start, node_end){
            return {label:_t("")};
        };
        CuteEdge.new_edge_callback = function(cuteedge){
            self.add_connector(cuteedge.get_start().id,
                               cuteedge.get_end().id,
                               cuteedge);
        };
        CuteEdge.destruction_callback = function(cuteedge){
            if(!confirm(_t("Deleting this transition cannot be undone.\n\nAre you sure ?"))){
                return $.Deferred().reject().promise();
            }
            return new instance.web.DataSet(self,self.connector).unlink([cuteedge.id]);
        };

    },

    // Creates a popup to edit the content of the node with id node_id
    edit_node: function(node_id){
        var self = this;
        var title = _t('Activity');
        var pop = new instance.web.form.FormOpenPopup(self);

        pop.show_element(
                self.node,
                node_id,
                self.context || self.dataset.context,
                {
                    title: _t("Open: ") + title
                }
            );
        pop.on('on_write_complete', self, function() {
            self.dataset.read_index(_.keys(self.fields_view.fields)).pipe(self.on_diagram_loaded);
            });

        var form_fields = [self.parent_field];
        var form_controller = pop.view_form;

       form_controller.on("load_record", self, function(){
            _.each(form_fields, function(fld) {
                if (!(fld in form_controller.fields)) { return; }
                var field = form_controller.fields[fld];
                field.$input.prop('disabled', true);
                field.$drop_down.unbind();
            });
         });

    },

    // Creates a popup to add a node to the diagram
    add_node: function(){
        var self = this;
        var title = _t('Activity');
        var pop = new instance.web.form.SelectCreatePopup(self);
        pop.select_element(
            self.node,
            {
                title: _t("Create:") + title,
                initial_view: 'form',
                disable_multiple_selection: true
            },
            self.dataset.domain,
            self.context || self.dataset.context
        );
        pop.on("elements_selected", self, function(element_ids) {
            self.dataset.read_index(_.keys(self.fields_view.fields)).pipe(self.on_diagram_loaded);
        });

        var form_controller = pop.view_form;
        var form_fields = [this.parent_field];

        form_controller.on("load_record", self, function(){
            _.each(form_fields, function(fld) {
                if (!(fld in form_controller.fields)) { return; }
                var field = form_controller.fields[fld];
                field.set_value(self.id);
                field.dirty = true;
            });
        });
    },

    // Creates a popup to edit the connector of id connector_id
    edit_connector: function(connector_id){
        var self = this;
        var title = _t('Transition');
        var pop = new instance.web.form.FormOpenPopup(self);
        pop.show_element(
            self.connector,
            parseInt(connector_id,10),      //FIXME Isn't connector_id supposed to be an int ?
            self.context || self.dataset.context,
            {
                title: _t("Open: ") + title
            }
        );
        pop.on('on_write_complete', self, function() {
            self.dataset.read_index(_.keys(self.fields_view.fields)).pipe(self.on_diagram_loaded);
        });
    },

    // Creates a popup to add a connector from node_source_id to node_dest_id.
    // dummy_cuteedge if not null, will be removed form the graph after the popup is closed.
    add_connector: function(node_source_id, node_dest_id, dummy_cuteedge){
        var self = this;
        var title = _t('Transition');
        var pop = new instance.web.form.SelectCreatePopup(self);

        pop.select_element(
            self.connector,
            {
                title: _t("Create:") + title,
                initial_view: 'form',
                disable_multiple_selection: true
            },
            this.dataset.domain,
            this.context || this.dataset.context
        );
        pop.on("elements_selected", self, function(element_ids) {
            self.dataset.read_index(_.keys(self.fields_view.fields)).pipe(self.on_diagram_loaded);
        });
        // We want to destroy the dummy edge after a creation cancel. This destroys it even if we save the changes.
        // This is not a problem since the diagram is completely redrawn on saved changes.
        pop.$el.bind("dialogbeforeclose",function(){
            if(dummy_cuteedge){
                dummy_cuteedge.remove();
            }
        });

        var form_controller = pop.view_form;

       form_controller.on("load_record", self, function(){
            form_controller.fields[self.connectors.attrs.source].set_value(node_source_id);
            form_controller.fields[self.connectors.attrs.source].dirty = true;
            form_controller.fields[self.connectors.attrs.destination].set_value(node_dest_id);
            form_controller.fields[self.connectors.attrs.destination].dirty = true;
       });
    },

    execute_pager_action: function(action) {
        switch (action) {
            case 'first':
                this.dataset.index = 0;
                break;
            case 'previous':
                this.dataset.previous();
                break;
            case 'next':
                this.dataset.next();
                break;
            case 'last':
                this.dataset.index = this.dataset.ids.length - 1;
                break;
        }
        var loaded = this.dataset.read_index(_.keys(this.fields_view.fields))
                .pipe(this.on_diagram_loaded);
        this.do_update_pager();
        return loaded;
    },

    do_update_pager: function(hide_index) {
        var $pager = this.$el.find('div.oe_diagram_pager');
        var index = hide_index ? '-' : this.dataset.index + 1;
        if(!this.dataset.count) {
            this.dataset.count = this.dataset.ids.length;
        }
        $pager.find('span.oe_pager_index').html(index);
        $pager.find('span.oe_pager_count').html(this.dataset.count);
    },

    do_show: function() {
        this.do_push_state({});
        return $.when(this._super(), this.execute_pager_action('reload'));
    }
});
};

// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
<commit_msg>[FIX] diagram view record not reload on refresh<commit_after>/*---------------------------------------------------------
 * OpenERP diagram library
 *---------------------------------------------------------*/

openerp.web_diagram = function (instance) {
var QWeb = instance.web.qweb,
      _t = instance.web._t,
     _lt = instance.web._lt;
instance.web.views.add('diagram', 'instance.web.DiagramView');
instance.web.DiagramView = instance.web.View.extend({
    display_name: _lt('Diagram'),
    searchable: false,
    init: function(parent, dataset, view_id, options) {
        this._super(parent);
        this.set_default_options(options);
        this.view_manager = parent;
        this.dataset = dataset;
        this.model = this.dataset.model;
        this.view_id = view_id;
        this.domain = this.dataset._domain || [];
        this.context = {};
        this.ids = this.dataset.ids;
    },
    start: function() {
        return this.rpc("/web_diagram/diagram/load", {"model": this.model, "view_id": this.view_id}, this.on_loaded);
    },

    toTitleCase: function(str) {
        return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
    },

    on_loaded: function(result) {

        var self = this;
        if(this.ids && this.ids.length) {
            this.id = this.ids[self.dataset.index || 0];
        }

        this.fields_view = result.fields_view,
        this.view_id = this.fields_view.view_id,
        this.fields = this.fields_view.fields,
        this.nodes = this.fields_view.arch.children[0],
        this.connectors = this.fields_view.arch.children[1],
        this.node = this.nodes.attrs.object,
        this.connector = this.connectors.attrs.object;
        this.labels = _.filter(this.fields_view.arch.children, function(label) {
            return label.tag == "label";
        });

        this.$el.html(QWeb.render("DiagramView", {'widget': this}));
        this.$el.addClass(this.fields_view.arch.attrs['class']);

        _.each(self.labels,function(label){
            html_label = '
' + label.attrs.string + "
";
            self.$el.find('.oe_diagram_header').append(html_label);
        })

        this.$el.find('div.oe_diagram_pager button[data-pager-action]').click(function() {
            var action = $(this).data('pager-action');
            self.execute_pager_action(action);
        });

        this.do_update_pager();

        // New Node,Edge
        this.$el.find('#new_node.oe_diagram_button_new').click(function(){self.add_node();});

        if(this.id) {
            self.get_diagram_info();
        }

    },

    get_diagram_info: function() {
        var self = this;
        var params = {
            'id': this.id,
            'model': this.model,
            'node': this.node,
            'connector': this.connector,
            'bgcolor': this.nodes.attrs.bgcolor,
            'shape': this.nodes.attrs.shape,
            'src_node': this.connectors.attrs.source,
            'des_node': this.connectors.attrs.destination,
            'label': this.connectors.attrs.label || false,
            'visible_nodes': [],
            'invisible_nodes': [],
            'node_fields': [],
            'connectors': [],
            'connectors_fields': []
        };

        _.each(this.nodes.children, function(child) {
            if(child.attrs.invisible == '1')
                params['invisible_nodes'].push(child.attrs.name);
            else {
                params['visible_nodes'].push(child.attrs.name);
                params['node_fields'].push(self.fields[child.attrs.name]['string']|| this.toTitleCase(child.attrs.name));
            }
        });

        _.each(this.connectors.children, function(conn) {
            params['connectors_fields'].push(self.fields[conn.attrs.name]['string']|| this.toTitleCase(conn.attrs.name));
            params['connectors'].push(conn.attrs.name);
        });

        this.rpc(
            '/web_diagram/diagram/get_diagram_info',params).then(function(result) {
                self.draw_diagram(result);
            }
        );
    },

    on_diagram_loaded: function(record) {
        var id_record = record['id'];
        if(id_record) {
            this.id = id_record;
            this.get_diagram_info();
            this.do_push_state({id:record.id});
        }
    },

    do_load_state: function(state, warm) {
        if (state && !this.dataset.get_id_index(state.id)) {
            this.dataset.ids.push(state.id);
        }
        this.dataset.select_id(state.id);
        if (warm) {
            this.do_show();
        }
     },

    // Set-up the drawing elements of the diagram
    draw_diagram: function(result) {
        var self = this;
        var res_nodes  = result['nodes'];
        var res_edges  = result['conn'];
        this.parent_field = result.parent_field;
        this.$el.find('h3.oe_diagram_title').text(result.name);

        var id_to_node = {};

        var style = {
            edge_color: "#A0A0A0",
            edge_label_color: "#555",
            edge_label_font_size: 10,
            edge_width: 2,
            edge_spacing: 100,
            edge_loop_radius: 100,

            node_label_color: "#333",
            node_label_font_size: 12,
            node_outline_color: "#333",
            node_outline_width: 1,
            node_selected_color: "#0097BE",
            node_selected_width: 2,
            node_size_x: 110,
            node_size_y: 80,
            connector_active_color: "#FFF",
            connector_radius: 4,

            close_button_radius: 8,
            close_button_color: "#333",
            close_button_x_color: "#FFF",

            gray: "#DCDCDC",
            white: "#FFF",

            viewport_margin: 50
        };

        // remove previous diagram
        var canvas = self.$el.find('div.oe_diagram_diagram')
                             .empty().get(0);

        var r  = new Raphael(canvas, '100%','100%');

        var graph  = new CuteGraph(r,style,canvas.parentNode);

        var confirm_dialog = $('#dialog').dialog({
            autoOpen: false,
            title: _t("Are you sure?") });

        _.each(res_nodes, function(node) {
            var n = new CuteNode(
                graph,
                node.x + 50,  //FIXME the +50 should be in the layout algorithm
                node.y + 50,
                CuteGraph.wordwrap(node.name, 14),
                node.shape === 'rectangle' ? 'rect' : 'circle',
                node.color === 'white' ? style.white : style.gray);

            n.id = node.id;
            id_to_node[node.id] = n;
        });

        _.each(res_edges, function(edge) {
            var e =  new CuteEdge(
                graph,
                CuteGraph.wordwrap(edge.signal, 32),
                id_to_node[edge.s_id],
                id_to_node[edge.d_id] || id_to_node[edge.s_id]  );  //WORKAROUND
            e.id = edge.id;
        });

        CuteNode.double_click_callback = function(cutenode){
            self.edit_node(cutenode.id);
        };
        var i = 0;
        CuteNode.destruction_callback = function(cutenode){
            if(!confirm(_t("Deleting this node cannot be undone.\nIt will also delete all connected transitions.\n\nAre you sure ?"))){
                return $.Deferred().reject().promise();
            }
            return new instance.web.DataSet(self,self.node).unlink([cutenode.id]);
        };
        CuteEdge.double_click_callback = function(cuteedge){
            self.edit_connector(cuteedge.id);
        };

        CuteEdge.creation_callback = function(node_start, node_end){
            return {label:_t("")};
        };
        CuteEdge.new_edge_callback = function(cuteedge){
            self.add_connector(cuteedge.get_start().id,
                               cuteedge.get_end().id,
                               cuteedge);
        };
        CuteEdge.destruction_callback = function(cuteedge){
            if(!confirm(_t("Deleting this transition cannot be undone.\n\nAre you sure ?"))){
                return $.Deferred().reject().promise();
            }
            return new instance.web.DataSet(self,self.connector).unlink([cuteedge.id]);
        };

    },

    // Creates a popup to edit the content of the node with id node_id
    edit_node: function(node_id){
        var self = this;
        var title = _t('Activity');
        var pop = new instance.web.form.FormOpenPopup(self);

        pop.show_element(
                self.node,
                node_id,
                self.context || self.dataset.context,
                {
                    title: _t("Open: ") + title
                }
            );
        pop.on('on_write_complete', self, function() {
            self.dataset.read_index(_.keys(self.fields_view.fields)).pipe(self.on_diagram_loaded);
            });

        var form_fields = [self.parent_field];
        var form_controller = pop.view_form;

       form_controller.on("load_record", self, function(){
            _.each(form_fields, function(fld) {
                if (!(fld in form_controller.fields)) { return; }
                var field = form_controller.fields[fld];
                field.$input.prop('disabled', true);
                field.$drop_down.unbind();
            });
         });

    },

    // Creates a popup to add a node to the diagram
    add_node: function(){
        var self = this;
        var title = _t('Activity');
        var pop = new instance.web.form.SelectCreatePopup(self);
        pop.select_element(
            self.node,
            {
                title: _t("Create:") + title,
                initial_view: 'form',
                disable_multiple_selection: true
            },
            self.dataset.domain,
            self.context || self.dataset.context
        );
        pop.on("elements_selected", self, function(element_ids) {
            self.dataset.read_index(_.keys(self.fields_view.fields)).pipe(self.on_diagram_loaded);
        });

        var form_controller = pop.view_form;
        var form_fields = [this.parent_field];

        form_controller.on("load_record", self, function(){
            _.each(form_fields, function(fld) {
                if (!(fld in form_controller.fields)) { return; }
                var field = form_controller.fields[fld];
                field.set_value(self.id);
                field.dirty = true;
            });
        });
    },

    // Creates a popup to edit the connector of id connector_id
    edit_connector: function(connector_id){
        var self = this;
        var title = _t('Transition');
        var pop = new instance.web.form.FormOpenPopup(self);
        pop.show_element(
            self.connector,
            parseInt(connector_id,10),      //FIXME Isn't connector_id supposed to be an int ?
            self.context || self.dataset.context,
            {
                title: _t("Open: ") + title
            }
        );
        pop.on('on_write_complete', self, function() {
            self.dataset.read_index(_.keys(self.fields_view.fields)).pipe(self.on_diagram_loaded);
        });
    },

    // Creates a popup to add a connector from node_source_id to node_dest_id.
    // dummy_cuteedge if not null, will be removed form the graph after the popup is closed.
    add_connector: function(node_source_id, node_dest_id, dummy_cuteedge){
        var self = this;
        var title = _t('Transition');
        var pop = new instance.web.form.SelectCreatePopup(self);

        pop.select_element(
            self.connector,
            {
                title: _t("Create:") + title,
                initial_view: 'form',
                disable_multiple_selection: true
            },
            this.dataset.domain,
            this.context || this.dataset.context
        );
        pop.on("elements_selected", self, function(element_ids) {
            self.dataset.read_index(_.keys(self.fields_view.fields)).pipe(self.on_diagram_loaded);
        });
        // We want to destroy the dummy edge after a creation cancel. This destroys it even if we save the changes.
        // This is not a problem since the diagram is completely redrawn on saved changes.
        pop.$el.bind("dialogbeforeclose",function(){
            if(dummy_cuteedge){
                dummy_cuteedge.remove();
            }
        });

        var form_controller = pop.view_form;

       form_controller.on("load_record", self, function(){
            form_controller.fields[self.connectors.attrs.source].set_value(node_source_id);
            form_controller.fields[self.connectors.attrs.source].dirty = true;
            form_controller.fields[self.connectors.attrs.destination].set_value(node_dest_id);
            form_controller.fields[self.connectors.attrs.destination].dirty = true;
       });
    },

    execute_pager_action: function(action) {
        switch (action) {
            case 'first':
                this.dataset.index = 0;
                break;
            case 'previous':
                this.dataset.previous();
                break;
            case 'next':
                this.dataset.next();
                break;
            case 'last':
                this.dataset.index = this.dataset.ids.length - 1;
                break;
        }
        var loaded = this.dataset.read_index(_.keys(this.fields_view.fields))
                .pipe(this.on_diagram_loaded);
        this.do_update_pager();
        return loaded;
    },

    do_update_pager: function(hide_index) {
        var $pager = this.$el.find('div.oe_diagram_pager');
        var index = hide_index ? '-' : this.dataset.index + 1;
        if(!this.dataset.count) {
            this.dataset.count = this.dataset.ids.length;
        }
        $pager.find('span.oe_pager_index').html(index);
        $pager.find('span.oe_pager_count').html(this.dataset.count);
    },

    do_show: function() {
        this.do_push_state({});
        return $.when(this._super(), this.execute_pager_action('reload'));
    }
});
};

// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import { List } from 'stardust'

export default class ListHeaderExample extends Component {
  render() {
    return (
      <List>
        <List.Item header='Chapter 1' description='The chapter in which we meet the characters' />
        <List.Item header='Chapter 2' description='The chapter in which the bad guy is introduced' />
        <List.Item header='Chapter 3' description='Spoiler alert: The chapter in which the good guy wins!'/>
      </List>
    )
  }
}
<commit_msg>refactor(ListHeaderExample): fix lint issues<commit_after>import React, { Component } from 'react'
import { List } from 'stardust'

export default class ListHeaderExample extends Component {
  render() {
    return (
      <List>
        <List.Item header='Chapter 1' description='The chapter in which we meet the characters' />
        <List.Item header='Chapter 2' description='The chapter in which the bad guy is introduced' />
        <List.Item header='Chapter 3' description='Spoiler alert: The chapter in which the good guy wins!' />
      </List>
    )
  }
}
<|endoftext|>