0

在 jupyter notebook 中,当我尝试渲染用 ipywidgets 编写的图形用户界面时,一切正常。 显示在 jupyter notebook 中的图形用户界面

然后,当我使用 Voila 渲染进行渲染时,表格和地图呈现在屏幕宽度之外。Voila 中是否有任何设置可以控制渲染宽度?我基本上需要表格和地图在屏幕宽度内呈现。

附加信息。下面是代码

import ipywidgets 
import glob
import json
import pandas as pd
import qgrid
import folium
from IPython.display import display 

takeawayFolderPath = '/home/hd2900/Documents/Python/POS/takeawayOrders'
class GeoMapping:
    def __init__(self, takeawayFolderPath, homeCoordinate, deliveryRadius):
        self.takeawayFolderPath = takeawayFolderPath
        self.homeCoordinate = homeCoordinate
        self.deliveryRadius = deliveryRadius #The deliver radius is given in meters
        currentSelectedRowNumber = None
        self.refreshJson()
        self.getOrderDataFrame()
        self.buildGUI()
        self.displayTable()
        self.displayMap()
    
    def buildGUI(self):
        self.btn_update = ipywidgets.Button(description = 'Refresh')
        self.btn_update.on_click(self.update_btn)
        self.tableOutput1 = ipywidgets.Output()
        self.btn_orderComplete = ipywidgets.Button(description = 'Complete', button_style = 'danger')
        self.btn_orderComplete.on_click(self.orderComplete)
        self.mapOutput = ipywidgets.Output()
        self.VBox = ipywidgets.VBox([self.btn_update, self.tableOutput1, self.btn_orderComplete, self.mapOutput])
        display(self.VBox)
        
    def displayMap(self):
        with self.mapOutput:
            self.mapOutput.clear_output()
            #Centering the map at home coordinate
            self.map = folium.Map(location= self.homeCoordinate, zoom_start=12)
            
            #Add a red circle marker to show home. This is not the delivery 
            folium.CircleMarker(
                location= self.homeCoordinate,
                radius=5,
                popup= "Home",
                color="#FF0000",
                fill=True,
                fill_color="#FF0000",
                ).add_to(self.map)
            
            #Add delivery radius ring
            folium.Circle(
                radius = self.deliveryRadius,
                location= self.homeCoordinate,
                popup="",
                color="crimson",
                fill=False).add_to(self.map)
            
            #Take time into account and plot the maps in different color. The color order
            for orderid in self.orderDF['Order Id']:
                latitude, longitude, deadline = self.getGeoCoordinateFromOrderId(orderid)
                
                #Plot the coordinates in map
                folium.Marker(
                    [latitude, longitude], popup=f"<h1>{orderid} {deadline}</h1>", tooltip = "more info"
                    ).add_to(self.map)
            
            display(self.map)
        
    def displayTable(self):
        with self.tableOutput1:
            self.tableOutput1.clear_output()
            self.qgrid = qgrid.show_grid(
                self.orderDF, 
                grid_options = {'sortable': False, 'filterable': False, 'maxVisibleRows': 100},
                )
            self.qgrid.observe(self.qgridTableRowSelected)
            display(self.qgrid)
    
    def orderComplete(self,b):
        if not self.currentSelectedRowNumber:
            return
        
        #Get the order id of the selected row
        orderId = self.orderDF['Order Id'][self.currentSelectedRowNumber[0]]
        
        #Find the json file with the order id and write a new key in the dictionary
        filePath = self.getJsonFilePathFromOrderId(orderId)
        
        order = self.readJsonFile(filePath)
        order['Complete'] = True
        
        self.saveJsonFile(order, filePath)
        self.update()
    
    def getJsonFilePathFromOrderId(self, orderId):
        '''
        Given the order Id integer, this method returns the json file full path
        '''
        files = glob.glob(self.takeawayFolderPath + '/*.json')
        for fileName in files:
            order = self.readJsonFile(fileName)
            
            if order['order']['id'] == orderId:
                return fileName
    
    def update_btn(self, b):
        self.update()

    def update(self):
        self.refreshJson()
        self.getOrderDataFrame()
        self.displayTable()
        self.displayMap()
        
    def qgridTableRowSelected(self, change):
        with self.tableOutput1:
            if change['name'] == '_selected_rows' and change['new']:
                self.currentSelectedRowNumber = self.qgrid.get_selected_rows()
        
    def refreshJson(self):
        '''
        Used for refresh all the latest json files
        '''
        files = glob.glob(self.takeawayFolderPath + '/*.json')
        self.orders = list()
        for fileName in files:
            order = self.readJsonFile(fileName)
            
            #Check if the order is a delivery
            if order['order']['delivery']:
                #Check if the key Complete exists 
                if 'Complete' not in order:
                    tmp = dict()
                    tmp['id'] = order['order']['id']
                    tmp['fullName'] = order['order']['fullName']
                    tmp['email'] = order['order']['email']
                    tmp['mobile'] = order['order']['mobile']
                    tmp['deliveryAddress'] = order['order']['deliveryAddress']
                    tmp['latitude'] = order['order']['latitude']
                    tmp['longitude'] = order['order']['longitude']
                    tmp['comments'] = order['order']['comments']
                    tmp['deadline'] = order['order']['deliveryTime']

                    self.orders.append(tmp)
        
    def getOrderDataFrame(self):
        '''
        Convert the content in self.orders into a pandas data frame 
        '''
        #The data frame contain the following columns
        self.orderDF = dict()
        self.orderDF['Order Id'] = list()
        self.orderDF['Name'] = list()
        self.orderDF['Address'] = list()
        self.orderDF['Mobile'] = list()
        self.orderDF['Comments'] = list()
        self.orderDF['Deadline'] = list()
        for order in self.orders:
            self.orderDF['Order Id'].append(order['id'])
            self.orderDF['Name'].append(order['fullName'])
            self.orderDF['Address'].append(order['deliveryAddress'])
            self.orderDF['Mobile'].append(order['mobile'])
            self.orderDF['Comments'].append(order['comments'])
            self.orderDF['Deadline'].append(order['deadline'])
                
        self.orderDF = pd.DataFrame.from_dict(self.orderDF)
    
    def getGeoCoordinateFromOrderId(self, orderId):
        for order in self.orders:
            if order['id'] == orderId:
                latitude = order['latitude']
                longitude = order['longitude']
                deadline = order['deadline']
                return latitude, longitude, deadline
    
    def readJsonFile(self, filePath):
        with open(filePath,'r') as fileId:
            data = json.load(fileId)
        return data
    
    def saveJsonFile(self, dataDict, filePath):
        '''
        Given the dictionary dataDict and the filePath, this method saves it to json file
        '''
        with open(filePath, 'w') as fileId:
            json.dump(dataDict, fileId)

hd2900Coordinate = (55.73228810541183, 12.575497656450752)
deliveryRadius = 8
deliveryRadius = deliveryRadius * 1000       
GeoMap = GeoMapping(takeawayFolderPath, hd2900Coordinate, deliveryRadius)

在此处输入图像描述

4

0 回答 0