nonoのポートフォリオサイト

dashboard

構成要素

サンプルコード

dashboard.py


    """
    This app creates a simple sidebar layout using inline style arguments and the
    dbc.Nav component.
    
    dcc.Location is used to track the current location, and a callback uses the
    current location to render the appropriate page content. The active prop of
    each NavLink is set automatically according to the current pathname. To use
    this feature you must install dash-bootstrap-components >= 0.11.0.
    
    For more details on building multi-page Dash applications, check out the Dash
    documentation: https://dash.plot.ly/urls
    """
    import dash
    import dash_bootstrap_components as dbc
    from dash import Input, Output, State, dcc, ctx, html
    import plotly.express as px
    import plotly.graph_objects as go
    
    import pandas as pd
    import os
    import datetime
    
    import graph_views
    
    #get date
    dt_now = datetime.datetime.now()
    print(dt_now.year, dt_now.month, dt_now.day)
    print(type(dt_now.year))
    
    # set select items
    area_list = ['ライセンス','長崎流体機','高砂流体機','神戸流体機']
    items_license = ['NASTRAN','Abaqus','Fluent','CFX']
    items_nagasaki = ['Sandybridge','Ivybridge', 'Ivybridge2', 'Haswell', 'Broadwell', 'Skylake']
    items_takasago = ['R5_Ivybridge', 'R5_Haswell2', 'R5_Broadwell', 'R5_Broadwell2', 'R5_Skylake']
    items_kobe = ['Cascadelake', 'Milan']
    
    year_list =[item for item in range(2020, dt_now.year+1)]
    year_list.append('-')
    month_list = [item for item in range(1,13)]
    month_list.append('-')
    # for item in year_list:
    #     print(item)
    # for item in month_list:
    #     print(item)
    
    #import datasets
    datasets = graph_views.fetch_dataset(dt_now.year, dt_now.month)
    #initial graph
    figure_datasets = graph_views.create_figure(datasets, items_license, area_list[0])
    fig1 = figure_datasets.create_figure(0,100)
    figure_datasets = graph_views.create_figure(datasets, items_nagasaki, area_list[1])
    fig2 = figure_datasets.create_figure(0,100)
    figure_datasets = graph_views.create_figure(datasets, items_takasago, area_list[2])
    fig3 = figure_datasets.create_figure(0,100)
    figure_datasets = graph_views.create_figure(datasets, items_kobe ,area_list[3])
    fig4 = figure_datasets.create_figure(0,100)
    
    del datasets,figure_datasets
    
    app = dash.Dash(external_stylesheets=[dbc.themes.BOOTSTRAP],suppress_callback_exceptions=True)
    app.css.config.serve_locally = True
    app.scripts.config.serve_locally = True
    
    
    # the style arguments for the sidebar. We use position:fixed and a fixed width
    SIDEBAR_STYLE = {
        # "position": "fixed",
        "top": 0,
        "left": 0,
        "bottom": 0,
        # "width": "20rem",
        "padding": "2rem 1rem",
        # "color":"#fff",
        # "background-color": "#f8f9fa",
    }
    
    # the styles for the main content position it to the right of the sidebar and
    # add some padding.
    CONTENT_STYLE = {
        "margin-left": "18rem",
        "margin-right": "2rem",
        "padding": "2rem 1rem",
    }
    
    sidebar = html.Div(
        [
            html.H4("Settings", className="display-7"),
            html.Hr(),
            # html.P(
            #     "Please select license or area", className="lead"
            # ),
            # html.Label('最新の24時間のみ表示する'),
            dcc.Checklist(
                options=[{'label':'最新の1日のみ表示する', 'value': 'True'}],
                id='selected-24-hours', className="text-warning"),
            html.Hr(),
            html.Label('年'),
            html.Div([
                dcc.Dropdown(
                    year_list,
                    dt_now.year,
                    id='year-select'
                ),
            ], style={'width': '98%', 'display': 'inline-block'}),
            # html.Hr(),
            html.Label('月'),
            html.Div([
                dcc.Dropdown(
                    month_list,
                    dt_now.month,
                    id='month-select',
                ),
            ], style={'width': '98%', 'display': 'inline-block'}),
            html.Hr(),
            html.Label('ライセンス'),
            dcc.Dropdown(items_license,
                         items_license,
                         id='selected-license',
                         multi=True),
            html.Label('長崎流体機'),
            dcc.Dropdown(items_nagasaki,
                         items_nagasaki,
                         id='selected-nagasaki',
                         multi=True),
            html.Label('高砂流体機'),
            dcc.Dropdown(items_takasago,
                         items_takasago,
                         id='selected-takasago',
                         multi=True),
            html.Label('神戸流体機'),
            dcc.Dropdown(items_kobe,
                         items_kobe,
                         id='selected-kobe',
                         multi=True),
            html.Hr(),
            # dbc.Button("Draw Graph", id='draw', color="primary", className="me-1"),
            # dbc.Button("Rest Graph", id='reset', color="success", className="me-1"),
        ],
        style=SIDEBAR_STYLE,
    )
    
    content = html.Div([
        html.H6("Availability status of trend data."),
        dcc.Graph(id='graph_1',figure=fig1),
        dcc.Graph(id='graph_2',figure=fig2),
        dcc.Graph(id='graph_3',figure=fig3),
        dcc.Graph(id='graph_4',figure=fig4),
    ])
    # app.layout = dbc.Container(
    app.layout = html.Div(
        [
            dbc.Row(
                [
                    dbc.Col(sidebar, width=4, className='bg-secondary'),
                    dbc.Col(content, width=8, className='bg-white')
                ]
            )
        ]
    )
    @app.callback(
        Output(component_id='graph_1', component_property='figure'),
        # Input('draw', 'n_clicks'),
        # State('selected-license','value'),
        Input('selected-24-hours','value'),
        Input('selected-license','value'),
        Input('year-select','value'),
        Input('month-select','value'),
        prevent_initial_call=True
    )
    # def update_graph(draw,items,year,month):
    def update_graph(flg,items,year,month):
        # print(flg)
        # triggered_id = ctx.triggered_id
        # print(items)
        # if triggered_id == 'draw':
        #     print('*** draw ***')
        #     return draw_graph(items, year, month)
        return draw_graph(flg,items, year, month)
    def draw_graph(flg,items, year, month):
        datasets = graph_views.fetch_dataset(year, month)
        figure_datasets = graph_views.create_figure(datasets, items ,'ライセンス', flg)
        fig1 = figure_datasets.create_figure(0,100)
        del datasets,figure_datasets
        return fig1
    def reset_graph():
        return go.Figure()
    
    @app.callback(
        Output(component_id='graph_2', component_property='figure'),
        Input('selected-24-hours','value'),
        Input('selected-nagasaki','value'),
        Input('year-select','value'),
        Input('month-select','value'),
        prevent_initial_call=True
    )
    def update_graph2(flg,items,year,month):
        return draw_graph2(flg,items, year, month)
    def draw_graph2(flg, items, year, month):
        datasets = graph_views.fetch_dataset(year, month)
        figure_datasets = graph_views.create_figure(datasets, items, '長崎流体機', flg)
        fig2 = figure_datasets.create_figure(0,100)
        del datasets,figure_datasets
        return fig2
    
    @app.callback(
        Output(component_id='graph_3', component_property='figure'),
        Input('selected-24-hours','value'),
        Input('selected-takasago','value'),
        Input('year-select','value'),
        Input('month-select','value'),
        prevent_initial_call=True
    )
    def update_graph3(flg,items,year,month):
        return draw_graph3(flg,items, year, month)
    def draw_graph3(flg,items, year, month):
        datasets = graph_views.fetch_dataset(year, month)
        figure_datasets = graph_views.create_figure(datasets, items, '高砂流体機', flg)
        fig3 = figure_datasets.create_figure(0,100)
        del datasets,figure_datasets
        return fig3
    
    @app.callback(
        Output(component_id='graph_4', component_property='figure'),
        Input('selected-24-hours','value'),
        Input('selected-kobe','value'),
        Input('year-select','value'),
        Input('month-select','value'),
        prevent_initial_call=True
    )
    def update_graph4(flg,items,year,month):
        return draw_graph4(flg,items, year, month)
    def draw_graph4(flg, items, year, month):
        datasets = graph_views.fetch_dataset(year, month)
        figure_datasets = graph_views.create_figure(datasets, items, '神戸流体機', flg)
        fig4 = figure_datasets.create_figure(0,100)
        del datasets,figure_datasets
        return fig4
    
    if __name__ == "__main__":
        app.run_server(port=8000)

graph_view.py


    import plotly.express as px
    import plotly.graph_objects as go
    
    from abc import ABC, abstractclassmethod
    import pandas as pd
    import os
    import datetime
    import calendar
    
    
    class datasets(ABC):
        @abstractclassmethod
        def _fetch_dataset(self):
            pass
    
    
    class create(ABC):
        @abstractclassmethod
        def _setting_datasets(self):
            pass
    
    
    class fetch_dataset(datasets):
        def __init__(self, year='2023', month='3'):
            self._df = None
            self._year = year
            self._month = month
            self._fetch_dataset()
    
        def _fetch_dataset(self):
            dir_name = os.getcwd()
            if int(self._month) < 10:
                set_month = '0' + str(self._month)
            file_name = str(self._year) + set_month + '.csv'
            assets_file = dir_name + '/' + file_name
            self._df = pd.read_csv(assets_file)
    
        def __str__(self):
            return 'datasets'
    
    
    class create_figure(create):
        # def __init__(self, datasets: datasets, area='長崎流体機', year='2023', month='01'):
        def __init__(self, datasets: datasets, items ,area, flag=[]):
            self._area = area
            self._year = datasets._year
            self._month = datasets._month
            self._title = items
            self._dates = []
            self._values = []
            self._flag = flag
            # print(flag)
            self._setting_datasets(datasets)
    
        def _setting_datasets(self, datasets):
            for _date in datasets._df['Date']:
                date = datetime.datetime.strptime(_date, '%Y-%m-%d %H:%M:%S')
                self._dates.append(date)
    
            for item in self._title:
                if item !='':
                    self._values.append(datasets._df[str(item)].values)
                else:
                    self._values=[]
    
        def create_figure(self, d_min, d_max):
            fig = go.Figure()
            # print(self._flag)
            if self._flag == ['True']:
                print(self._flag)
                dt_now = datetime.datetime.now()
                set_year = dt_now.year
                set_month = dt_now.month
                last_day = dt_now.day
                start_day = last_day - 1
            else:
                set_year = int(self._year)
                set_month = int(self._month)
                start_day = 1
                last_day = calendar.monthrange(set_year, set_month)[1]
            for index,value in enumerate(self._values):
                # fig.add_trace(go.Scatter(x=self._dates, y=value,
                #                       name=self._title[index],
                #                       opacity=0.9,mode='lines+markers'))
                fig.add_trace(go.Bar(x=self._dates, y=value,
                                      name=self._title[index],
                                      opacity=0.9))
                fig.update_xaxes(title='time',range=(datetime.date(set_year, set_month, start_day),
                                        datetime.date(set_year, set_month, last_day)))
                # fig.update_yaxes(title='availability', range=[d_min, d_max],showgrid=False)
                fig.update_yaxes(title='availability', range=[d_min, d_max])
                fig.update_layout(barmode='overlay')
                fig.update_layout(bargap=0)
            fig.update_layout(hovermode='closest')
            fig.update_layout(title=dict(text=f'{self._year} 年 {self._month} 月 {self._area} 稼働率',font_color='green'))
            # fig.update_traces(marker_color='rgb(95, 158, 160)', marker_line_color='green',
            #         marker_line_width=1.5, opacity=0.6,name=self._title)
            return fig
    
        def __str__(self):
            return self._values
    
    
    if __name__ == '__main__':
    
        datasets = fetch_dataset()