[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/hide5stm/python-interface/master/mspy/plot_objects.py [Back]  [Original]

# -------------------------------------------------------------------------
#     Copyright (C) 2005-2013 Martin Strohalm 

#     This program is free software; you can redistribute it and/or modify
#     it under the terms of the GNU General Public License as published by
#     the Free Software Foundation; either version 3 of the License, or
#     (at your option) any later version.

#     This program is distributed in the hope that it will be useful,
#     but WITHOUT ANY WARRANTY; without even the implied warranty of
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#     GNU General Public License for more details.

#     Complete text of GNU GPL can be found in the file LICENSE.TXT in the
#     main directory of the program.
# -------------------------------------------------------------------------

# load libs
import wx
import numpy
import copy

# load modules
import mod_signal
import calculations


# MAIN PLOT OBJECTS
# -----------------

class container:
    """Container to hold plot objects."""
    
    def __init__(self, objects):
        self.objects = objects
    # ----
    
    
    def __additem__(self, obj):
        self.objects.append(obj)
    # ----
    
    
    def __delitem__(self, index):
        del self.objects[index]
    # ----
    
    
    def __setitem__(self, index, obj):
        self.objects[index] = obj
    # ----
    
    
    def __getitem__(self, index):
        return self.objects[index]
    # ----
    
    
    def __len__(self):
        return len(self.objects)
    # ----
    
    
    def getBoundingBox(self, minX=None, maxX=None, absolute=False):
        """Get bounding box coverring all visible objects."""
        
        # init values if no data in objects
        rect = [numpy.array([0, 0]), numpy.array([1, 1])]
        
        # get bouding boxes from objects
        have = False
        for obj in self.objects:
            if obj.properties['visible']:
                oRect = obj.getBoundingBox(minX, maxX, absolute)
                
                if not oRect or not numpy.all(numpy.isfinite(oRect)):
                    continue
                elif have and oRect:
                    rect[0] = numpy.minimum(rect[0], oRect[0])
                    rect[1] = numpy.maximum(rect[1], oRect[1])
                elif oRect:
                    rect = oRect
                    have = True
        
        # check scale
        if rect[0][0] == rect[1][0]:
            rect[0][0] -= 0.5
            rect[1][0] += 0.5
        if rect[0][1] == rect[1][1]:
            rect[1][1] += 0.5
        
        return rect
    # ----
    
    
    def getLegend(self):
        """Get a list of legend names."""
        
        # get names
        names = []
        for obj in self.objects:
            if obj.properties['visible']:
                legend = obj.getLegend()
                if legend and legend[0] != '':
                    names.append(obj.getLegend())
            
        return names
    # ----
    
    
    def getPoint(self, obj, xPos, coord='screen'):
        """Get interpolated Y position for given X."""
        return self.objects[obj].getPoint(xPos, coord)
    # ----
    
    
    def countGels(self):
        """Get number of visible gels."""
        
        count = 0
        for obj in self.objects:
            if obj.properties['visible'] and obj.properties['showInGel']:
                count += 1
        
        return max(count,1)
    # ----
    
    
    def cropPoints(self, minX, maxX):
        """Crop points in all visible objects to selected X range."""
        
        for obj in self.objects:
            if obj.properties['visible']:
                obj.cropPoints(minX, maxX)
    # ----
    
    
    def scaleAndShift(self, scale, shift):
        """Scale and shift all visible objects."""
        
        for obj in self.objects:
            if obj.properties['visible']:
                obj.scaleAndShift(scale, shift)
    # ----
    
    
    def filterPoints(self, filterSize):
        """Filter points in all visible objects."""
        
        for obj in self.objects:
            if obj.properties['visible']:
                obj.filterPoints(filterSize)
    # ----
    
    
    def draw(self, dc, printerScale, overlapLabels, reverse):
        """Draw all visible objects."""
        
        # draw in reverse order
        if reverse:
            self.objects.reverse()
            
        # draw objects
        for obj in self.objects:
            if obj.properties['visible']:
                obj.draw(dc, printerScale)
        
        # draw object's labels
        self.drawLabels(dc, printerScale, overlapLabels)
        
        # reverse back order
        if reverse:
            self.objects.reverse()
    # ----
    
    
    def drawLabels(self, dc, printerScale, overlapLabels):
        """Draw labels for all visible objects."""
        
        # get labels from objects
        annots = []
        labels = []
        for obj in self.objects:
            if obj.properties['visible'] and isinstance(obj, annotations):
                annots += obj.makeLabels(dc, printerScale)
            elif obj.properties['visible']:
                labels += obj.makeLabels(dc, printerScale)
        
        # check labels
        if not annots and not labels:
            return
        
        # sort labels
        annots.sort()
        annots.reverse()
        labels.sort()
        labels.reverse()
        labels = annots + labels
        
        # preset font by first label
        font = labels[0][3]['labelFont']
        colour = labels[0][3]['labelColour']
        bgr = labels[0][3]['labelBgr']
        bgrColour = labels[0][3]['labelBgrColour']
        
        dc.SetFont(_scaleFont(font, printerScale['fonts']))
        dc.SetTextForeground(colour)
        dc.SetTextBackground(bgrColour)
        
        if bgr:
            dc.SetBackgroundMode(wx.SOLID)
        
        # draw labels
        occupied = []
        for label in labels:
            text = label[1]
            textCoords = label[2]
            properties = label[3]
            
            # check limits
            if abs(textCoords[1]) > 10000000:
                continue
            
            # check free space and draw label
            if overlapLabels or self._checkFreeSpace(textCoords, occupied):
                
                # check pen
                if properties['labelFont'] != font:
                    font = properties['labelFont']
                    dc.SetFont(_scaleFont(font, printerScale['fonts']))
                
                if properties['labelColour'] != colour:
                    colour = properties['labelColour']
                    dc.SetTextForeground(colour)
                
                #if properties['labelBgrColour'] != bgrColour:
                #    bgrColour = properties['labelBgrColour']
                #    dc.SetTextBackground(bgrColour)
                
                if properties['labelBgr'] != bgr:
                    bgr = properties['labelBgr']
                    if bgr:
                        dc.SetBackgroundMode(wx.SOLID)
                    else:
                        dc.SetBackgroundMode(wx.TRANSPARENT)
                
                # set angle
                angle = properties['labelAngle']
                if angle == 90 and properties['flipped']:
                    angle = -90
                
                # draw label
                dc.DrawRotatedText(text, textCoords[0], textCoords[1], angle)
                occupied.append(textCoords)
        
        dc.SetBackgroundMode(wx.TRANSPARENT)
    # ----
    
    
    def drawGel(self, dc, gelCoords, gelHeight, printerScale):
        """Draw gel for all allowed objects."""
        
        # draw objects
        for obj in self.objects:
            if obj.properties['visible'] and obj.properties['showInGel']:
                obj.drawGel(dc, gelCoords, gelHeight, printerScale)
                gelCoords[0] += gelHeight
    # ----
    
    
    def append(self, obj):
        self.objects.append(obj)
    # ----
    
    
    def empty(self):
        del self.objects[:]
    # ----
    
    
    def _checkFreeSpace(self, coords, occupied):
        """Check free space for label."""
        
        curX1, curY1, curX2, curY2 = coords
        
        # check occupied space
        for occX1, occY1, occX2, occY2 in occupied:
            if (curX1 < curX2) and ((occX1 

Web Proxy Viewer  |  New URL  |  Original Page