"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const widgets = __importStar(require("@jupyter-widgets/base"));
const chai_1 = require("chai");
const dummy_manager_1 = require("./dummy-manager");
const bqplot = require("..");
const widget_utils_1 = require("./widget-utils");
const d3Timer = __importStar(require("d3-timer"));
// text pixel coordinate
const test_x = 200;
const test_y = 250;
const pixel_red = [255, 0, 0, 255];
const pixel_green = [0, 255, 0, 255];
const pixel_background = [255, 255, 255, 255];
describe('interacts >', () => {
    beforeEach(function () {
        return __awaiter(this, void 0, void 0, function* () {
            this.manager = new dummy_manager_1.DummyManager({ bqplot: bqplot });
        });
    });
    it('brush selector basics', function () {
        return __awaiter(this, void 0, void 0, function* () {
            const x = {
                dtype: 'float32',
                value: new DataView(new Float32Array([0, 1]).buffer),
            };
            const y = {
                dtype: 'float32',
                value: new DataView(new Float32Array([2, 3]).buffer),
            };
            const { figure, scatter } = yield widget_utils_1.create_figure_scatter(this.manager, x, y);
            const brush_selector = yield widget_utils_1.create_model_bqplot(this.manager, 'BrushSelector', 'brush_selector_1', {
                x_scale: figure.model.get('scale_x').toJSON(),
                y_scale: figure.model.get('scale_y').toJSON(),
                marks: [scatter.model.toJSON()],
                color: '#0f0', // green
            });
            brush_selector.set('selected_x', [0.5, 1.5]);
            brush_selector.set('selected_y', [2.5, 3.5]);
            let brush_selector_view = yield figure.set_interaction(brush_selector);
            const indices = scatter.model.get('selected');
            chai_1.expect([...indices]).to.deep.equal([1]);
            chai_1.expect(indices).to.be.an.instanceof(Uint32Array);
            brush_selector_view.d3el.select('.selection').attr('fill-opacity', 1.0); // make sure it's full green
            let brushColorData = yield figure.getPixel(390, 10); // upper right corner
            chai_1.expect([...brushColorData]).to.deep.equals(pixel_green);
            // removing the selector should not deselect
            figure.set_interaction(null);
            chai_1.expect([...scatter.model.get('selected')]).to.deep.equal([1]);
            // changing a disconnected brush, should not change the selection
            brush_selector.set('selected_x', [-0.5, 0.5]);
            brush_selector.set('selected_y', [1.5, 2.5]);
            chai_1.expect([...scatter.model.get('selected')]).to.deep.equal([1]);
            // we restore the brush
            brush_selector_view = yield figure.set_interaction(brush_selector);
            brush_selector_view.d3el.select('.selection').attr('fill-opacity', 1.0); // make sure it's full green
            // and the selection should be updated
            chai_1.expect([...scatter.model.get('selected')]).to.deep.equal([0]);
            brushColorData = yield figure.getPixel(10, 490); // lower left corner
            chai_1.expect([...brushColorData]).to.deep.equals(pixel_green);
            // we set the initial selection, and it should update the selection AND the DOM
            brush_selector.set('selected_x', [0.5, 1.5]);
            brush_selector.set('selected_y', [2.5, 3.5]);
            chai_1.expect([...scatter.model.get('selected')]).to.deep.equal([1]);
            brushColorData = yield figure.getPixel(390, 10); // upper right corner
            chai_1.expect([...brushColorData]).to.deep.equals(pixel_green);
        });
    });
    it('brush interval selector basics', function () {
        return __awaiter(this, void 0, void 0, function* () {
            const x = {
                dtype: 'float32',
                value: new DataView(new Float32Array([0, 1]).buffer),
            };
            const y = {
                dtype: 'float32',
                value: new DataView(new Float32Array([2, 3]).buffer),
            };
            const { figure, scatter } = yield widget_utils_1.create_figure_scatter(this.manager, x, y);
            const brush_interval_selector = yield widget_utils_1.create_model_bqplot(this.manager, 'BrushIntervalSelector', 'brush_interval_selector_1', {
                scale: figure.model.get('scale_y').toJSON(),
                orientation: 'vertical',
                marks: [scatter.model.toJSON()],
                color: '#0f0', // green
            });
            let brush_interval_selector_view = yield figure.set_interaction(brush_interval_selector);
            brush_interval_selector.set('selected', [2.5, 3.5]);
            chai_1.expect([...scatter.model.get('selected')]).to.deep.equal([1]);
            brush_interval_selector.set('selected', [1.5, 2.5]);
            chai_1.expect([...scatter.model.get('selected')]).to.deep.equal([0]);
            brush_interval_selector_view.relayout();
            brush_interval_selector_view.d3el
                .select('.selection')
                .attr('fill-opacity', 1.0); // make sure it's full green
            let brushColorData = yield figure.getPixel(test_x, 490); // bottom edge
            chai_1.expect([...brushColorData]).to.deep.equals(pixel_green);
            figure.set_interaction(null);
            chai_1.expect([...scatter.model.get('selected')]).to.deep.equal([0]);
            // changing a disconnected brush, should not change the selection
            brush_interval_selector.set('selected', [2.5, 3.5]);
            chai_1.expect([...scatter.model.get('selected')]).to.deep.equal([0]);
            // we restore the brush
            brush_interval_selector_view = yield figure.set_interaction(brush_interval_selector);
            brush_interval_selector_view.d3el
                .select('.selection')
                .attr('fill-opacity', 1.0); // make sure it's full green
            // and the selection should be updated
            brush_interval_selector_view.relayout();
            chai_1.expect([...scatter.model.get('selected')]).to.deep.equal([1]);
            brushColorData = yield figure.getPixel(test_x, 10); // top edge
            chai_1.expect([...brushColorData]).to.deep.equals(pixel_green);
            // we set the initial selection, and it should update the selection AND the DOM
            brush_interval_selector.set('selected', [1.5, 2.5]);
            chai_1.expect([...scatter.model.get('selected')]).to.deep.equal([0]);
            brushColorData = yield figure.getPixel(test_x, 490); // bottom edge
            chai_1.expect([...brushColorData]).to.deep.equals(pixel_green);
        });
    });
    it('brush interval selector on bars', function () {
        return __awaiter(this, void 0, void 0, function* () {
            const x = {
                dtype: 'float32',
                value: new DataView(new Float32Array([0, 1]).buffer),
            };
            const y = {
                dtype: 'float32',
                value: new DataView(new Float32Array([2, 3]).buffer),
            };
            const { figure, bars } = yield widget_utils_1.create_figure_bars(this.manager, x, y);
            const brush_interval_selector = yield widget_utils_1.create_model_bqplot(this.manager, 'BrushIntervalSelector', 'brush_interval_selector_1', {
                scale: figure.model.get('scale_x').toJSON(),
                orientation: 'horizontal',
                marks: [bars.model.toJSON()],
            });
            const brush_interval_selector_view = yield figure.set_interaction(brush_interval_selector);
            yield brush_interval_selector_view.displayed;
            // all the events in figure are async, and we don't have access
            // to the promises, so we manually call these methods
            yield brush_interval_selector_view.create_scales();
            yield brush_interval_selector_view.mark_views_promise;
            brush_interval_selector_view.relayout();
            d3Timer.timerFlush(); // this makes sure the animations are all executed
            brush_interval_selector.set('selected', [0.9, 1.1]);
            chai_1.expect([...bars.model.get('selected')]).to.deep.equal([1]);
            brush_interval_selector.set('selected', [-0.1, 1.1]);
            chai_1.expect([...bars.model.get('selected')]).to.deep.equal([0, 1]);
            chai_1.expect(bars.model.get('selected')).to.be.an.instanceof(Uint32Array);
        });
    });
    it('pan/zoom', function () {
        return __awaiter(this, void 0, void 0, function* () {
            const x = {
                dtype: 'float32',
                value: new DataView(new Float32Array([0.5]).buffer),
            };
            const y = {
                dtype: 'float32',
                value: new DataView(new Float32Array([2.5]).buffer),
            };
            const { figure, scatter } = yield widget_utils_1.create_figure_scatter(this.manager, x, y);
            // scatter.model.set("default_size", 100*100);
            scatter.model.set('default_size', 100 * 100);
            scatter.model.set('colors', ['red']);
            scatter.d3el.selectAll('.object_grp').data();
            const panzoom = yield widget_utils_1.create_model_bqplot(this.manager, 'PanZoom', 'panzoom', {
                scales: {
                    x: [figure.model.get('scale_x').toJSON()],
                    y: [figure.model.get('scale_y').toJSON()],
                },
            });
            const panzoom_view = yield figure.set_interaction(panzoom);
            yield panzoom_view.displayed;
            yield widgets.resolvePromisesDict(panzoom_view.scale_promises);
            yield figure.relayout();
            // we want two cycles to make sure relayout is done (it is using requestAnimationFrame)
            yield new Promise((resolve) => window.requestAnimationFrame(resolve));
            yield new Promise((resolve) => window.requestAnimationFrame(resolve));
            // first check if we have a red pixel in the center
            let canvas = yield figure.get_rendered_canvas();
            let context = canvas.getContext('2d');
            let pixel = context.getImageData(test_x * window.devicePixelRatio, test_y * window.devicePixelRatio, 1, 1);
            chai_1.expect(Array.prototype.slice.call(pixel.data)).to.deep.equals(pixel_red);
            // we pan to the right
            panzoom_view._mousedown([0, 0]);
            yield panzoom_view._mousemove([150, 0]);
            d3Timer.timerFlush();
            // and check if we find a red pixel there as well
            canvas = yield figure.get_rendered_canvas();
            context = canvas.getContext('2d');
            pixel = context.getImageData(test_x * window.devicePixelRatio, test_y * window.devicePixelRatio, 1, 1);
            chai_1.expect(Array.prototype.slice.call(pixel.data)).to.deep.equals(pixel_background);
            pixel = context.getImageData((test_x + 150) * window.devicePixelRatio, test_y * window.devicePixelRatio, 1, 1);
            chai_1.expect(Array.prototype.slice.call(pixel.data)).to.deep.equals(pixel_red);
            // check zooming
            const scale_x = figure.model.get('scale_x');
            const xmin = scale_x.get('min');
            const xmax = scale_x.get('max');
            yield panzoom_view._zoom([test_x + 150, test_y], 10);
            const xmin2 = scale_x.get('min');
            const xmax2 = scale_x.get('max');
            chai_1.expect(xmin2).to.be.greaterThan(xmin);
            chai_1.expect(xmax2).to.be.lessThan(xmax);
        });
    });
    it('pan/zoom log', function () {
        return __awaiter(this, void 0, void 0, function* () {
            const x = {
                dtype: 'float32',
                value: new DataView(new Float32Array([1]).buffer),
            };
            const y = {
                dtype: 'float32',
                value: new DataView(new Float32Array([1]).buffer),
            };
            const { figure, scatter } = yield widget_utils_1.create_figure_scatter(this.manager, x, y, false, true);
            // scatter.model.set("default_size", 100*100);
            scatter.model.set('default_size', 100 * 100);
            scatter.model.set('colors', ['red']);
            scatter.d3el.selectAll('.object_grp').data();
            const panzoom = yield widget_utils_1.create_model_bqplot(this.manager, 'PanZoom', 'panzoom', {
                scales: {
                    x: [figure.model.get('scale_x').toJSON()],
                    y: [figure.model.get('scale_y').toJSON()],
                },
            });
            const panzoom_view = yield figure.set_interaction(panzoom);
            yield panzoom_view.displayed;
            yield widgets.resolvePromisesDict(panzoom_view.scale_promises);
            yield figure.relayout();
            // we want two cycles to make sure relayout is done (it is using requestAnimationFrame)
            yield new Promise((resolve) => window.requestAnimationFrame(resolve));
            yield new Promise((resolve) => window.requestAnimationFrame(resolve));
            let canvas = yield figure.get_rendered_canvas();
            let context = canvas.getContext('2d');
            let pixel = context.getImageData(test_x * window.devicePixelRatio, test_y * window.devicePixelRatio, 1, 1);
            chai_1.expect(Array.prototype.slice.call(pixel.data)).to.deep.equals(pixel_red);
            // we pan to the right
            panzoom_view._mousedown([0, 0]);
            yield panzoom_view._mousemove([150, 0]);
            d3Timer.timerFlush();
            // and check if we find a red pixel there as well
            canvas = yield figure.get_rendered_canvas();
            context = canvas.getContext('2d');
            pixel = context.getImageData(test_x * window.devicePixelRatio, test_y * window.devicePixelRatio, 1, 1);
            chai_1.expect(Array.prototype.slice.call(pixel.data)).to.deep.equals(pixel_background);
            pixel = context.getImageData((test_x + 150) * window.devicePixelRatio, test_y * window.devicePixelRatio, 1, 1);
            chai_1.expect(Array.prototype.slice.call(pixel.data)).to.deep.equals(pixel_red);
        });
    });
});
//# sourceMappingURL=interacts.js.map