<commit_before>define(['jquery', 'marionette',
        'modules/dc/models/distl',
        'modules/dc/models/grid',
        'modules/dc/models/xfm',
        'utils/canvas',
        'tpl!templates/dc/gridplot.html',
        'caman',
        'heatmap',
        'utils',
        'utils/xhrimage',
        'jquery-ui',
    ], function($, Marionette, DISTL, GridInfo, XFMap, canvas, template, Caman, HeatMap, utils, XHRImage) {
    
    return Marionette.ItemView.extend(_.extend({}, canvas, {
        template: template,
        className: 'content',
        
        ui: {
            canvas: 'canvas',
            hmt: 'input[name=heatmap]',
            ty: 'select[name=type]',
            xfm: '.xfm',
            flu: 'input[name=fluo]',
            el: 'select[name=element]',
        },

        events: {
            'mousemove @ui.canvas': 'mouseMove',
            'mousedown @ui.canvas': 'mouseDown',

            'change @ui.ty': 'setType',
            'change @ui.hmt': 'setHM',

            'change @ui.flu': 'toggleFluo',
            'change @ui.el': 'changeElement',
        },


        setHM: function() {
            this.heatmapToggle = this.ui.hmt.is(':checked')
            console.log('htm', this.heatmapToggle)
            this.draw()
        },

        setType: function() {
            var types  = { 1: 0, 2: 1, 3: 3 }

            this.type = types[parseInt(this.ui.ty.val())] 
            console.log('ty', this.type)
            this.draw()
        },



        initialize: function(options) {
            this.draw = _.debounce(this.draw, 10)
            this.listenTo(options.imagestatuses, 'sync', this.getModel, this)

            var timestamp = utils._date_to_unix(this.getOption('ST'))
            this.distl = new DISTL({ id: this.getOption('ID'), nimg: this.getOption('NUMIMG'), timestamp: timestamp })
            this.listenTo(this.distl, 'change', this.draw, this)
            this.grid = new GridInfo({ id: this.getOption('ID') })


            this.distl.fetch()
            var self = this
            this.gridFetched = false
            this.grid.fetch().done(function() {
                self.gridFetched = true
                if (self.grid.get('ORIENTATION')) self.vertical = self.grid.get('ORIENTATION') == 'vertical'
                else self.vertical = (self.grid.get('STEPS_Y') > self.grid.get('STEPS_X')) && app.config.gsMajorAxisOrientation
                console.log('grid', self.grid.get('DATACOLLECTIONID'), self.grid.get('ORIENTATION'), 'vertical', self.vertical)
            })

            this.xfm = new XFMap({ id: this.getOption('ID') })
            this.xfm.fetch().done(this.populateXFM.bind(this))

            this.hasSnapshot = false
            this.snapshot = new XHRImage()
            this.snapshot.onload = this.snapshotLoaded.bind(this)

            this.offset_w = 0
            this.offset_h = 0
            this.scale = 1
            this.current = -1

            this.heatmapToggle = false
            this.type = 1
        },

        toggleFluo: function() {
            if (this.ui.flu.is(':checked')) {
                this.ui.ty.prop('disabled', true)
                this.draw()
            } else {
                this.ui.ty.prop('disabled', false)
                this.draw()
            }
        },

        changeElement: function() {
            this.draw()
        },

        populateXFM: function() {
            if (!this.xfm.get('data').length) return
            this.ui.xfm.show()

            var opts = _.map(_.unique(_.pluck(this.xfm.get('data'), 'ELEMENT')), function(e) {
                return '<option value="'+e+'">'+e+'</option>'
            })
            this.ui.el.html(opts.join())
        },

        getModel: function() {
            var m = this.getOption('imagestatuses').findWhere({ ID: this.getOption('ID') })
            if (m.get('SNS').length)
                if (m.get('SNS')[2] && this.hasSnapshot == false) {
                this.snapshot.load(app.apiurl+'/image/id/'+this.getOption('ID')+'/f/1/n/3')
                //this.draw()
            }
        },

        snapshotLoaded: function() {
            console.log('snapshot loaded')
            this.hasSnapshot = true
            this.draw()
        },

        onRender: function() {
            this.ui.xfm.hide()
        },


        onDomRefresh: function() {
            this.canvas = this.ui.canvas[0]
            this.ctx = this.canvas.getContext('2d')

            this.canvas.width = this.$el.parent().width()
            this.canvas.height = this.$el.parent().height()

            this.heatmap = new HeatMap.create({ 
                container: this.$el[0],
                maxOpacity: .4,
            })
        },


        draw: function() {
            console.log('draw', this.ctx, this.hasSnapshot)
            if (!this.ctx || !this.gridFetched) return

            var bw = 1000*this.grid.get('DX_MM')/this.grid.get('PIXELSPERMICRONX')
            var bh = 1000*this.grid.get('DY_MM')/this.grid.get('PIXELSPERMICRONY')

            var radius = bw * 1.1

            this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)

            // plot cropped snapshot
            if (this.hasSnapshot) {
                var scalef = this.snapshot.width/1024

                var stx = (Math.floor(this.grid.get('SNAPSHOT_OFFSETXPIXEL'))+1)*scalef
                var sty = (Math.floor(this.grid.get('SNAPSHOT_OFFSETYPIXEL'))+1)*scalef

                var w = bw*this.grid.get('STEPS_X')*scalef*0.97
                var h = bh*this.grid.get('STEPS_Y')*scalef*0.97

                var cvratio = this.canvas.width / this.canvas.height
                var snratio = w/h
                
                if (cvratio < snratio) {
                    this.offset_h = (w/cvratio)-h
                } else {
                    this.offset_w = (cvratio*h)-w
                }

                this.scale = this.canvas.width/(w+this.offset_w)

                this.ctx.globalAlpha = 1
                this.ctx.drawImage(this.snapshot, stx-this.offset_w/2, sty-this.offset_h/2, w+this.offset_w, h+this.offset_h-1, 0, 0, this.canvas.width, this.canvas.height)
            }

            var d = []
            if (this.ui.flu.is(':checked')) {
                var tmp = _.where(this.xfm.get('data'), { ELEMENT: this.ui.el.val() })
                _.each(tmp, function(r) {
                    d.push([r.IMAGENUMBER, r.COUNTS])
                })
                this.heatmap.configure({ maxOpacity: .4, gradient: { 0: 'rgba(0,0,0,0)', 1: 'rgb('+tmp[0]['R']+','+tmp[0]['G']+','+tmp[0]['B']+')' } })
            } else {
                if (this.distl.get('data')) d = this.distl.get('data')[this.type] <commit_msg>changed snapshot no, remove bodge factor, still not right<commit_after>define(['jquery', 'marionette',
        'modules/dc/models/distl',
        'modules/dc/models/grid',
        'modules/dc/models/xfm',
        'utils/canvas',
        'tpl!templates/dc/gridplot.html',
        'caman',
        'heatmap',
        'utils',
        'utils/xhrimage',
        'jquery-ui',
    ], function($, Marionette, DISTL, GridInfo, XFMap, canvas, template, Caman, HeatMap, utils, XHRImage) {
    
    return Marionette.ItemView.extend(_.extend({}, canvas, {
        template: template,
        className: 'content',
        
        ui: {
            canvas: 'canvas',
            hmt: 'input[name=heatmap]',
            ty: 'select[name=type]',
            xfm: '.xfm',
            flu: 'input[name=fluo]',
            el: 'select[name=element]',
        },

        events: {
            'mousemove @ui.canvas': 'mouseMove',
            'mousedown @ui.canvas': 'mouseDown',

            'change @ui.ty': 'setType',
            'change @ui.hmt': 'setHM',

            'change @ui.flu': 'toggleFluo',
            'change @ui.el': 'changeElement',
        },


        setHM: function() {
            this.heatmapToggle = this.ui.hmt.is(':checked')
            console.log('htm', this.heatmapToggle)
            this.draw()
        },

        setType: function() {
            var types  = { 1: 0, 2: 1, 3: 3 }

            this.type = types[parseInt(this.ui.ty.val())] 
            console.log('ty', this.type)
            this.draw()
        },



        initialize: function(options) {
            this.draw = _.debounce(this.draw, 10)
            this.listenTo(options.imagestatuses, 'sync', this.getModel, this)

            var timestamp = utils._date_to_unix(this.getOption('ST'))
            this.distl = new DISTL({ id: this.getOption('ID'), nimg: this.getOption('NUMIMG'), timestamp: timestamp })
            this.listenTo(this.distl, 'change', this.draw, this)
            this.grid = new GridInfo({ id: this.getOption('ID') })


            this.distl.fetch()
            var self = this
            this.gridFetched = false
            this.grid.fetch().done(function() {
                self.gridFetched = true
                if (self.grid.get('ORIENTATION')) self.vertical = self.grid.get('ORIENTATION') == 'vertical'
                else self.vertical = (self.grid.get('STEPS_Y') > self.grid.get('STEPS_X')) && app.config.gsMajorAxisOrientation
                console.log('grid', self.grid.get('DATACOLLECTIONID'), self.grid.get('ORIENTATION'), 'vertical', self.vertical)
            })

            this.xfm = new XFMap({ id: this.getOption('ID') })
            this.xfm.fetch().done(this.populateXFM.bind(this))

            this.hasSnapshot = false
            this.snapshot = new XHRImage()
            this.snapshot.onload = this.snapshotLoaded.bind(this)

            this.offset_w = 0
            this.offset_h = 0
            this.scale = 1
            this.current = -1

            this.heatmapToggle = false
            this.type = 1
        },

        toggleFluo: function() {
            if (this.ui.flu.is(':checked')) {
                this.ui.ty.prop('disabled', true)
                this.draw()
            } else {
                this.ui.ty.prop('disabled', false)
                this.draw()
            }
        },

        changeElement: function() {
            this.draw()
        },

        populateXFM: function() {
            if (!this.xfm.get('data').length) return
            this.ui.xfm.show()

            var opts = _.map(_.unique(_.pluck(this.xfm.get('data'), 'ELEMENT')), function(e) {
                return '<option value="'+e+'">'+e+'</option>'
            })
            this.ui.el.html(opts.join())
        },

        getModel: function() {
            var m = this.getOption('imagestatuses').findWhere({ ID: this.getOption('ID') })
            if (m.get('SNS').length)
                if (m.get('SNS')[2] && this.hasSnapshot == false) {
                this.snapshot.load(app.apiurl+'/image/id/'+this.getOption('ID')+'/f/1')
                //this.draw()
            }
        },

        snapshotLoaded: function() {
            console.log('snapshot loaded')
            this.hasSnapshot = true
            this.draw()
        },

        onRender: function() {
            this.ui.xfm.hide()
        },


        onDomRefresh: function() {
            this.canvas = this.ui.canvas[0]
            this.ctx = this.canvas.getContext('2d')

            this.canvas.width = this.$el.parent().width()
            this.canvas.height = this.$el.parent().height()

            this.heatmap = new HeatMap.create({ 
                container: this.$el[0],
                maxOpacity: .4,
            })
        },


        draw: function() {
            console.log('draw', this.ctx, this.hasSnapshot)
            if (!this.ctx || !this.gridFetched) return

            var bw = 1000*this.grid.get('DX_MM')/this.grid.get('PIXELSPERMICRONX')
            var bh = 1000*this.grid.get('DY_MM')/this.grid.get('PIXELSPERMICRONY')

            var radius = bw * 1.1

            this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)

            // plot cropped snapshot
            if (this.hasSnapshot) {
                var scalef = this.snapshot.width/1024

                var stx = this.grid.get('SNAPSHOT_OFFSETXPIXEL')*scalef
                var sty = this.grid.get('SNAPSHOT_OFFSETYPIXEL')*scalef

                var w = bw*this.grid.get('STEPS_X')*scalef
                var h = bh*this.grid.get('STEPS_Y')*scalef

                var cvratio = this.canvas.width / this.canvas.height
                var snratio = w/h
                
                if (cvratio < snratio) {
                    this.offset_h = (w/cvratio)-h
                } else {
                    this.offset_w = (cvratio*h)-w
                }

                this.scale = this.canvas.width/(w+this.offset_w)

                this.ctx.globalAlpha = 1
                this.ctx.drawImage(this.snapshot, stx-this.offset_w/2, sty-this.offset_h/2, w+this.offset_w, h+this.offset_h, 0, 0, this.canvas.width, this.canvas.height)
            }

            var d = []
            if (this.ui.flu.is(':checked')) {
                var tmp = _.where(this.xfm.get('data'), { ELEMENT: this.ui.el.val() })
                _.each(tmp, function(r) {
                    d.push([r.IMAGENUMBER, r.COUNTS])
                })
                this.heatmap.configure({ maxOpacity: .4, gradient: { 0: 'rgba(0,0,0,0)', 1: 'rgb('+tmp[0]['R']+','+tmp[0]['G']+','+tmp[0]['B']+')' } })
            } else {
                if (this.distl.get('data')) d = this.distl.get('data')[this.type] 
{'fraction_non_alphanumeric': 0.15617072078794209, 'fraction_numerical': 0.008207730189523952, 'mean_word_length': 1.6065733177751849, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2256624', 'n_tokens_mistral': 4353, 'n_tokens_neox': 4118, 'n_words': 670}