Exemplo n.º 1
0
def data_viewer(dataset, tables, columns_per_table, **widget_args):
    """Show all data in a downloadable table"""

    formatters = {
        "ng_vsh40_pct": NumberFormatter(format="0 %"),
        "thickness_mtvd": NumberFormatter(format="0.0"),
        "top_depth_mtvd": NumberFormatter(format="0.0"),
        "base_depth_mtvd": NumberFormatter(format="0.0"),
    }

    def get_filename(table):
        return f"{dataset}-{table}.xlsx"

    def get_data(table_name):
        columns = columns_per_table.get(table_name, {})
        return (readers.read_all(
            config.app.apps.reader, dataset,
            table_name).loc[:, columns.keys()].sort_values(
                by="ng_vsh40_pct", ascending=False).reset_index(drop=True))

    table_name = pn.widgets.Select(
        name="Choose table",
        options={t.title(): t
                 for t in tables},
        value=tables[0],
        size=1,
    )
    filename = pn.widgets.TextInput(name="File name",
                                    value=get_filename(table_name.value))

    @pn.depends(table_name.param.value)
    def table(table_name):
        data = get_data(table_name).assign(
            ng_vsh40_pct=lambda d: d.ng_vsh40_pct / 100  # Show N:G as percent
        )

        return pn.widgets.Tabulator(
            data,
            disabled=True,
            titles=columns_per_table[table_name],
            formatters=formatters,
            layout="fit_data_table",
            **widget_args,
        )

    @pn.depends(table_name.param.value, watch=True)
    def update_filename(table_name):
        filename.value = get_filename(table_name)

    def download_file():
        """Download data as an Excel file"""
        output_bytes = io.BytesIO()

        # Write data as Excel
        excel_writer = pd.ExcelWriter(output_bytes, engine="xlsxwriter")
        get_data(table_name.value).to_excel(
            excel_writer, sheet_name=table_name.value.title(), index=False)
        excel_writer.save()

        # Reset output stream and return it
        output_bytes.seek(0)
        return output_bytes

    @pn.depends(filename.param.value)
    def download_button(filename):
        return pn.widgets.FileDownload(callback=download_file,
                                       filename=filename,
                                       button_type="success")

    return pn.Row(
        pn.Column(
            table_name,
            filename,
            download_button,
        ),
        pn.Column(table, sizing_mode="stretch_width"),
    )
Exemplo n.º 2
0
def load_app(config_file):
    pn.config.sizing_mode = 'stretch_both'

    impact_hour_data = read_impact_hour_data()

    # TECH
    t = TECH(
        total_impact_hours=impact_hour_data['Assumed IH'].sum(),
        impact_hour_data=impact_hour_data, total_cstk_tokens=1000000,
        config=config_file['tech'])

    # DandelionVoting
    dandelion = DandelionVoting(17e6, config=config_file['dandelion_voting'])

    updating_results = pn.widgets.Button(name="Updating", disabled=True)

    # Share Button
    comments_tech = pn.widgets.TextAreaInput(
                                        name='What is your Hatch Strategy?',
                                        max_length=1024,
                                        placeholder='Tell us why you configured the Hatch this way')
    comments_dandelion = pn.widgets.TextAreaInput(
                                        name='What is your Dandelion Voting strategy?',
                                        max_length=1024,
                                        placeholder='What intended effects will your Dandelion Voting Parameters have?')
    share_button = pn.widgets.Button(name='Submit Hatch Config Proposal',
                                     button_type='primary',
                                     disabled=True)
    url = pn.widgets.TextInput(name='URL', value='')
    share_button.js_on_click(args={'target': url},
                             code='window.open(target.value)')
    results_button = pn.widgets.Button(name='See your results',
                                       button_type='success')

    # Run buttons
    run_dandelion = pn.widgets.Button(name='Run simulation',
                                      button_type='success')
    run_impact_hours = pn.widgets.Button(name='Run simulation',
                                         button_type='success')

    def update_params_by_url_query():
        queries = curdoc().session_context.request.arguments
        queries = {i: j[0] for i, j in queries.items()}
        if queries:
            if 'ihminr' in queries:
                t.min_raise = int(queries['ihminr'])
            if 'ihmaxr' in queries:
                t.max_raise = int(queries['ihmaxr'])
            if 'tgihr' in queries:
                t.impact_hour_rate_at_target_goal = float(queries['tgihr'])
            if 'maxihr' in queries:
                t.maximum_impact_hour_rate = float(queries['maxihr'])
            if 'ihtr' in queries:
                t.target_raise = int(queries['ihtr'])
            if 'hor' in queries:
                t.hatch_oracle_ratio = float(queries['hor'])
            if 'hpd' in queries:
                t.hatch_period_days = int(queries['hpd'])
            if 'her' in queries:
                t.hatch_exchange_rate = float(queries['her'])
            if 'ht' in queries:
                t.hatch_tribute_percentage = int(queries['ht'])
            if 'sr' in queries:
                dandelion.support_required_percentage = int(queries['sr'])
            if 'maq' in queries:
                dandelion.minimum_accepted_quorum_percentage = int(queries['maq'])
            if 'vdd' in queries:
                dandelion.vote_duration_days = int(queries['vdd'])
            if 'vbh' in queries:
                dandelion.vote_buffer_hours = int(queries['vbh'])
            if 'rqh' in queries:
                dandelion.rage_quit_hours = int(queries['rqh'])
            if 'tfx' in queries:
                dandelion.tollgate_fee_xdai = float(queries['tfx'])

            t.param.trigger('action')  # Update dashboard
            dandelion.param.trigger('action')

    @pn.depends(updating_results)
    def update_input_output_pane(results_button_on):
        if results_button_on:
            input_output_pane = pn.pane.GIF('media/inputs_outputs.gif')
        else:
            input_output_pane = pn.pane.Markdown('')

        return input_output_pane

    @pn.depends(updating_results)
    def update_output_scenarios(results_button_on):
        if results_button_on:
            output_scenarios = pn.panel(t.output_scenarios_view()
                                         .hvplot.table())
        else:
            output_scenarios = pn.pane.Markdown('')

        return output_scenarios

    @pn.depends(updating_results)
    def update_result_score(results_button_on):
        if results_button_on:
            t.param.trigger('action')  # Update dashboard
            dandelion.param.trigger('action')
            data_table = {
                'Parameters': [
                    "Target Goal (wxDai)",
                    "Maximum Goal (wxDai)",
                    "Minimum Goal (wxDai)",
                    "Impact Hour Rate at Target Goal (wxDai/IH)",
                    "Impact Hour Rate at Infinity (wxDai/IH)",
                    "Hatch Membership Ratio (wxDai/CSTK)",
                    "Hatch Period (days)",
                    "Hatch Minting rate (TECH/wxDai)",
                    "Hatch Tribute (%)",
                    "Support Required (%)",
                    "Minimum Quorum (%)",
                    "Vote Duration (days)",
                    "Vote Buffer (hours)",
                    "Ragequit Delay (hours)",
                    "Tollgate Fee (wxDai)"],
                'Values': [
                    int(t.target_raise),
                    int(t.max_raise),
                    int(t.min_raise),
                    t.impact_hour_rate_at_target_goal,
                    t.maximum_impact_hour_rate,
                    t.hatch_oracle_ratio,
                    t.hatch_period_days,
                    t.hatch_exchange_rate,
                    t.hatch_tribute_percentage,
                    dandelion.support_required_percentage,
                    dandelion.minimum_accepted_quorum_percentage,
                    dandelion.vote_duration_days,
                    dandelion.vote_buffer_hours,
                    dandelion.rage_quit_hours,
                    dandelion.tollgate_fee_xdai]
                }
            df = pd.DataFrame(data=data_table)

            # Define output pane
            output_pane = pn.Row(pn.Column(t.impact_hours_plot,
                                           t.redeemable_plot),
                                 pn.Column(dandelion.vote_pass_view,
                                           t.pie_charts_view))
            output_pane.save('output.html')
            pn.panel(t.output_scenarios_view()
                      .hvplot.table()).save('out_scenarios.html')

            scenarios = codecs.open("out_scenarios.html", 'r')
            charts = codecs.open("output.html", 'r')

            data_charts = {
                'html': charts.read(),
                'css': ".box { color: white; background-color: #0f79b9; padding: 10px; font-family: Roboto }",
                'google_fonts': "Roboto"}
            data_scenarios = {
                'html': scenarios.read(),
                'css': ".box { color: white; background-color: #0f79b9; padding: 10px; font-family: Roboto }",
                'google_fonts': "Roboto"}

            charts = requests.post(url=HCTI_API_ENDPOINT,
                                   data=data_charts,
                                   auth=(HCTI_API_USER_ID, HCTI_API_KEY))
            scenarios = requests.post(url=HCTI_API_ENDPOINT,
                                      data=data_scenarios,
                                      auth=(HCTI_API_USER_ID, HCTI_API_KEY))
            # Parameters string
            url_fork = '{url}?ihminr={ihf_minimum_raise}&tgihr={impact_hour_rate_at_target_goal}&maxihr={maximum_impact_hour_rate}&ihtr={ihf_target_raise}&ihmaxr={ifh_maximum_raise}&hor={hatch_oracle_ratio}&hpd={hatch_period_days}&her={hatch_exchange_rate}&ht={hatch_tribute_percentage}&sr={support_required}&maq={minimum_accepted_quorum}&vdd={vote_duration_days}&vbh={vote_buffer_hours}&rqh={rage_quit_hours}&tfx={tollgate_fee_xdai}"'.format(tollgate_fee_xdai=dandelion.tollgate_fee_xdai,
            vote_duration_days=dandelion.vote_duration_days,
            rage_quit_hours=dandelion.rage_quit_hours,
            ihf_minimum_raise=int(t.min_raise),
            impact_hour_rate_at_target_goal=t.impact_hour_rate_at_target_goal,
            maximum_impact_hour_rate=t.maximum_impact_hour_rate,
            ihf_target_raise=t.target_raise,
            ifh_maximum_raise=int(t.max_raise),
            hatch_oracle_ratio=t.hatch_oracle_ratio,
            hatch_period_days=t.hatch_period_days,
            hatch_exchange_rate=t.hatch_exchange_rate,
            hatch_tribute_percentage=t.hatch_tribute_percentage,
            support_required=dandelion.support_required_percentage,
            minimum_accepted_quorum=dandelion.minimum_accepted_quorum_percentage,
            vote_buffer_hours=dandelion.vote_buffer_hours,
            max_wxdai_ratio=int(1125*t.hatch_oracle_ratio),
            total_votes_per_year=int(24/dandelion.vote_buffer_hours*365),
            single_tech_mint=float(1/t.hatch_exchange_rate),
            url=config_file['url'])

            # Title
            title = '## Check out my proposal for the Hatch! <a href="' + url_fork + ' target="_blank">Click here to preload the Hatch Configuration Dashboard with my parameters if you think you can do better</a>.'
            meme_image = """

![image](https://i.imgflip.com/57zyrl.jpg)
"""
            graphical_summary = """
# Graphical Summary

![image]({image_charts})
""".format(image_charts=charts.json()['url'])


            graph_descriptions = """
## Graph Descriptions

- Top Left, **Impact Hour Rate vs wxDai Collected**: The Impact Hour Rate determines the Minting Rate for Builders, making 1 Impact Hour equivalent to sending this amount of wxDai to the Hatch.
- Top Right, **Proposal Acceptance Criteria**: Shows the range of possibilities for DAO vote outcomes and whether they succeed or not given the Support Required & Minimum Quorum I chose.
- Bottom Left, **Backer's Rage Quit % vs wxDai Collected**: The Backer's Rage Quit % is the percent of wxDai that the Backers sent to the Hatch that would be returned if they decide to Ragequit.
- Bottom Right, **Redeem-ability of the DAO's wxDai**: Shows who has rights to the wxDai held by the DAO. All of the DAO's funds are collectively governed but some can be withdrawn if token holders Ragequit. This shows the results of my parameter choices at the 3 different goals.
"""
            simulated_outcomes = """
# Simulated Outcomes

![image]({image_scenarios})
            """.format(image_scenarios=scenarios.json()['url'])

            parameters_data = """
# My Hatch Configuration

| Parameter|Value|
|:-|-:|
|Target Goal (wxDai)|{target_goal:,}|
|Maximum Goal (wxDai)|{max_goal:,}|
|Minimum Goal (wxDai)|{min_goal:,}|
|Impact Hour Rate at Target Goal (wxDai/IH)|{ih_rate_tg_goal:,}|
|Impact Hour Rate at Infinity (wxDai/IH)|{ih_rate_infinity:,}|
|Hatch Membership Ratio (wxDai/CSTK)|{hatch_membership_ratio:,}|
|Hatch Period (days)|{hatch_period_days}|
|Hatch Minting rate (TECH/wxDai)|{hatch_minting_rate:,}|
|Hatch Tribute (%)|{hatch_tribute}|
|Support Required (%)|{support_required}|
|Minimum Quorum (%)|{minimum_quorum}|
|Vote Duration (days)|{vote_duration_days}|
|Vote Buffer (hours)|{vote_buffer_hours}|
|Ragequit (hours)|{ragequit}|
|Tollgate Fee (wxDai)|{tollgate_fee:,}|</a>""".format(target_goal=t.target_raise,
           max_goal=t.max_raise,
           min_goal=t.min_raise,
           ih_rate_tg_goal=t.impact_hour_rate_at_target_goal,
           ih_rate_infinity=t.maximum_impact_hour_rate,
           hatch_membership_ratio=t.hatch_oracle_ratio,
           hatch_period_days=t.hatch_period_days,
           hatch_minting_rate=t.hatch_exchange_rate,
           hatch_tribute=t.hatch_tribute_percentage,
           support_required=dandelion.support_required_percentage,
           minimum_quorum=dandelion.minimum_accepted_quorum_percentage,
           vote_duration_days=dandelion.vote_duration_days,
           vote_buffer_hours=dandelion.vote_buffer_hours,
           ragequit=dandelion.rage_quit_hours,
           tollgate_fee=dandelion.tollgate_fee_xdai)

            results_header = """
# Summary
"""

            default_comment = "To use the defaults... Technocracy for the win"
            if not comments_tech.value: 
                print(comments_tech.value)
                comment_tech = default_comment
            else:
                comment_tech = comments_tech.value
            
            if not comments_dandelion.value: 
                comment_dandelion = default_comment
            else:
                comment_dandelion = comments_dandelion.value

            string_comments_tech = """
## Hatch Strategy

<p>{comments}</p>
            """.format(comments=comment_tech)

            string_comments_dandelion = """
## DAO Strategy

<p>{comments}</p>
            """.format(comments=comment_dandelion)

            string_data = """
  <h2>Hatch Details</h2>

- Trusted Seed members can send wxDai to the Hatch for {hatch_period_days} days.

- The target goal will be {ihf_target_raise} wxDai, with a minimum of {ihf_minimum_raise} wxDai necessary for the TEC Hatch DAO to be launched and a cap at {ifh_maximum_raise} wxDai.

- Backers will need to send in {single_tech_mint} wxDai to mint 1 TECH.

- The membership ratio is set at {hatch_oracle_ratio} wxDai/CSTK, so a Trusted Seed member with the minimum CSTK Score of 1125 CSTK can send up to {max_wxdai_ratio}  wxDai to the Hatch.

<h2>TEC Hatch DAO Voting Details</h2>

- Proposals will be voted on for {vote_duration_days} days. They will require at least {support_required}% support, and a minimum of {minimum_accepted_quorum}% of the TECH Tokens will have to vote yes for a proposal to pass.

- TECH token holders will have {rage_quit_hours} hours to exit the DAO if they don't like the result of a vote (as long as they didn't vote yes) before it is executed.

- There will be a minimum of {vote_buffer_hours} hours between proposals so people always have time to exit safely if they voted yes on a previous vote, this means we can have at most {total_votes_per_year} votes per year.

- To prevent griefing attacks, it will cost {tollgate_fee_xdai} wxDai to make a proposal.

If you have Impact Hours, you can see how much money you will get with my configuration <a href="{url}?ihminr={ihf_minimum_raise}&tgihr={impact_hour_rate_at_target_goal}&maxihr={maximum_impact_hour_rate}&ihtr={ihf_target_raise}&ihmaxr={ifh_maximum_raise}&hor={hatch_oracle_ratio}&hpd={hatch_period_days}&her={hatch_exchange_rate}&ht={hatch_tribute_percentage}&sr={support_required}&maq={minimum_accepted_quorum}&vdd={vote_duration_days}&vbh={vote_buffer_hours}&rqh={rage_quit_hours}&tfx={tollgate_fee_xdai}" target="_blank">here, just check out the Impact Hour Results table.
            """.format(tollgate_fee_xdai=dandelion.tollgate_fee_xdai,
            vote_duration_days=dandelion.vote_duration_days,
            rage_quit_hours=dandelion.rage_quit_hours,
            ihf_minimum_raise=int(t.min_raise),
            impact_hour_rate_at_target_goal=t.impact_hour_rate_at_target_goal,
            maximum_impact_hour_rate=t.maximum_impact_hour_rate,
            ihf_target_raise=t.target_raise,
            ifh_maximum_raise=int(t.max_raise),
            hatch_oracle_ratio=t.hatch_oracle_ratio,
            hatch_period_days=t.hatch_period_days,
            hatch_exchange_rate=t.hatch_exchange_rate,
            hatch_tribute_percentage=t.hatch_tribute_percentage,
            support_required=dandelion.support_required_percentage,
            minimum_accepted_quorum=dandelion.minimum_accepted_quorum_percentage,
            vote_buffer_hours=dandelion.vote_buffer_hours,
            max_wxdai_ratio=int(1125*t.hatch_oracle_ratio),
            total_votes_per_year=int(24/dandelion.vote_buffer_hours*365),
            single_tech_mint=float(1/t.hatch_exchange_rate),
            url=config_file['url'])

            markdown_panel = pn.pane.Markdown(parameters_data +
                                              string_comments_tech +
                                              string_comments_dandelion +
                                              results_header +
                                              string_data +
                                              graphical_summary)
            markdown_panel = pn.pane.Markdown(title +
                                              meme_image +
                                              graphical_summary +
                                              graph_descriptions +
                                              simulated_outcomes +
                                              string_comments_tech +
                                              string_comments_dandelion +
                                              results_header +
                                              string_data +
                                              parameters_data)
            body = urllib.parse.quote(markdown_panel.object, safe='')
            url.value = (config_file['repo'] +
                         "/issues/new?title=Vote%20for%20My%20Params&labels=" +
                         config_file['label'] + "&body=" + body)
            results_button.name = "Update your results"
            markdown_panel = pn.pane.Markdown(results_header + string_data)
            return markdown_panel

    pn.state.onload(update_params_by_url_query)

    def help_icon(href, text):
        return """
        <style>
        .tooltip {{
            position: relative;
            display: inline-block;
            align-self: flex-end;
        }}

        .tooltip .tooltiptext {{
            visibility: hidden;
            width: 200px;
            background-color: #555;
            color: #fff;
            text-align: center;
            border-radius: 6px;
            padding: 10px;
            position: absolute;
            z-index: 1;
            bottom: 125%;
            left: 50%;
            margin-left: -110px;
            opacity: 0;
            transition: opacity 0.3s;
        }}

        .tooltip .tooltiptext::after {{
            content: "";
            position: absolute;
            top: 100%;
            left: 50%;
            margin-left: -5px;
            border-style: solid;
            border-color: #555 transparent transparent transparent;
        }}

        .tooltip:hover .tooltiptext {{
            visibility: visible;
            opacity: 1;
        }}

        .icon {{
            width: 24px;
            height: 24px;
        }}

        .flex {{
            height: 100%;
            display: flex;
            justify-content: center;
        }}
        </style>
        <div class="flex">
            <div class="tooltip">
                <a href="{href}" target="_blank">
                    <img class="icon" src="http://cdn.onlinewebfonts.com/svg/img_295214.png" />
                </a>
                <span class="tooltiptext">{text}</span>
            </div>
        </div>
        """.format(href=href, text=text)

    def param_with_tooltip(param, tooltip, height=50):
        return pn.Row(pn.Column(param, sizing_mode="stretch_width"),
                      pn.pane.HTML(help_icon(tooltips[tooltip]['href'],
                                   tooltips[tooltip]['text']),
                                   sizing_mode="fixed",
                                   width=30, height=height, align="end"))

    def run_simulation_dandelion(event):
        dandelion.param.trigger('action')

    def run_simulation_impact_hours(event):
        t.param.trigger('action')
    
    def update_results(event):
        results_button.disabled = True
        share_button.disabled = True
        updating_results.value = True
        share_button.disabled = False
        results_button.disabled = False
        updating_results.value = False

    results_button.on_click(update_results)
    run_dandelion.on_click(run_simulation_dandelion)
    run_impact_hours.on_click(run_simulation_impact_hours)

    # Front-end
    tmpl = pn.Template(template=template)
    tmpl.add_variable('app_title', config_file['title'])
    tmpl.add_panel('B', pn.Column(
        param_with_tooltip(
            t.param.min_raise,
            tooltip='min_raise'),
        param_with_tooltip(
            t.param.max_raise,
            tooltip='max_raise'),
        param_with_tooltip(
            t.param.target_raise,
            tooltip='target_raise'),
        param_with_tooltip(
            t.param.impact_hour_rate_at_target_goal,
            tooltip='impact_hour_rate_at_target_goal'),
        param_with_tooltip(
            t.param.maximum_impact_hour_rate,
            tooltip='maximum_impact_hour_rate', height=40),
        param_with_tooltip(
            t.param.hatch_tribute_percentage,
            tooltip='hatch_tribute_percentage'),
        param_with_tooltip(
            t.param.hatch_oracle_ratio,
            tooltip='hatch_oracle_ratio'),
        param_with_tooltip(
            t.param.hatch_period_days,
            tooltip='hatch_period_days'),
        param_with_tooltip(
            t.param.hatch_exchange_rate,
            tooltip='hatch_exchange_rate'),
        run_impact_hours
    ))
    tmpl.add_panel('C', t.outputs_overview_view)
    tmpl.add_panel('E', t.payout_view)
    tmpl.add_panel('D', pn.Column(t.redeemable_plot, t.impact_hours_plot))
    tmpl.add_panel('M', t.trigger_unbalanced_parameters)
    tmpl.add_panel('F', t.pie_charts_view)
    tmpl.add_panel('V', pn.Column(
        param_with_tooltip(
            pn.Column(dandelion.param.support_required_percentage),
            tooltip='support_required_percentage', height=40),
        param_with_tooltip(
            dandelion.param.minimum_accepted_quorum_percentage,
            tooltip='minimum_accepted_quorum_percentage', height=40),
        param_with_tooltip(
            dandelion.param.vote_buffer_hours,
            tooltip='vote_buffer_hours'),
        param_with_tooltip(
            dandelion.param.tollgate_fee_xdai,
            tooltip='tollgate_fee_xdai'),
        param_with_tooltip(
            dandelion.param.vote_duration_days,
            tooltip='vote_duration_days'),
        param_with_tooltip(
            dandelion.param.rage_quit_hours,
            tooltip='rage_quit_hours'),
        run_dandelion
    ))
    tmpl.add_panel('W', dandelion.vote_pass_view)
    tmpl.add_panel('G', update_input_output_pane)
    tmpl.add_panel('R', update_result_score)
    tmpl.add_panel('CO', pn.Column(comments_tech, comments_dandelion))
    tmpl.add_panel('BU', pn.Column(results_button, share_button, url))
    tmpl.add_panel('OU', update_output_scenarios)
    tmpl.servable(title=config_file['title'])
Exemplo n.º 3
0
Arquivo: utils.py Projeto: erdc/pyuit
    def statuses_panel(self):
        statuses_table = pn.widgets.DataFrame.from_param(self.param.statuses, width=1300) \
            if self.statuses is not None else pn.pane.Alert('No status information available.', alert_type='info')

        if self.disable_update:
            buttons = None
        else:
            update_btn = pn.widgets.Button.from_param(self.param.update,
                                                      button_type='primary',
                                                      width=100)
            terminate_btn = pn.widgets.Button.from_param(
                self.param.terminate_btn, button_type='danger', width=100)
            yes_btn = pn.widgets.Button.from_param(self.param.yes_btn,
                                                   button_type='danger',
                                                   width=100)
            cancel_btn = pn.widgets.Button.from_param(self.param.cancel_btn,
                                                      button_type='success',
                                                      width=100)

            yes_btn.visible = False
            cancel_btn.visible = False

            msg = pn.indicators.String(
                value=
                'Are you sure you want to terminate the job. This cannot be undone.',
                css_classes=['bk', 'alert', 'alert-danger'],
                default_color='inherit',
                font_size='inherit',
                visible=False,
            )

            terminate_confirmation = pn.Column(
                msg,
                pn.Row(yes_btn, cancel_btn, margin=20),
                background='#ffffff',
            )

            args = {
                'update_btn': update_btn,
                'terminate_btn': terminate_btn,
                'statuses_table': statuses_table,
                'msg': msg,
                'yes_btn': yes_btn,
                'cancel_btn': cancel_btn,
                'term_col': terminate_confirmation
            }
            terminate_code = 'update_btn.disabled=true; terminate_btn.visible=false; ' \
                             'msg.visible=true; yes_btn.visible=true; cancel_btn.visible=true; ' \
                             'term_col.css_classes=["panel-widget-box"]'
            cancel_code = 'update_btn.disabled=false; terminate_btn.visible=true; ' \
                          'msg.visible=false; yes_btn.visible=false; cancel_btn.visible=false; term_col.css_classes=[]'

            terminate_btn.js_on_click(args=args, code=terminate_code)
            cancel_btn.js_on_click(args=args, code=cancel_code)

            code = 'btn.css_classes.push("pn-loading", "arcs"); btn.properties.css_classes.change.emit(); ' \
                   'other_btn.disabled=true; ' \
                   'statuses_table.push("pn-loading", "arcs"); statuses_table.properties.css_classes.change.emit();'

            update_btn.js_on_click(
                args={
                    'btn': update_btn,
                    'other_btn': terminate_btn,
                    'statuses_table': statuses_table
                },
                code=code,
            )
            yes_btn.js_on_click(
                args={
                    'btn': terminate_btn,
                    'other_btn': update_btn,
                    'statuses_table': statuses_table
                },
                code=code,
            )

            buttons = pn.Row(update_btn, terminate_btn, terminate_confirmation)

        return pn.Column(
            statuses_table,
            buttons,
            sizing_mode='stretch_width',
        )
Exemplo n.º 4
0
def plot_rgb(dataset,
             bands=['blue', 'green', 'red'],
             dims=['x', 'y'],
             height=700,
             width=700,
             clims=None,
             norm='eq_hist',
             cmap=['black', 'white'],
             nodata=1):
    """Interactive RGB visualization of a xarray time series

    Description
    ----------
    Takes an xarray time dataset and creates an interactive panel which allows to inspect the different data variables at different time steps

    Parameters
    ----------
    dataset : xarray.Dataset
        A multi-dimensional array with x,y and time dimensions and one or more data variables.
    bands: int, str
        A list of names defining the data variables used for the red, green and blue band
    dim : list, str
        A list containing the names of the x and y dimension.
    height: int
        Height of the created plot specified in pixels.
    width: int
        Width of the created plot specified in pixels.
    clims: int,float
        Min and max data values to use for colormap interpolation.
    norm :
        The normalization operation applied before colormapping. Valid options include 'linear', 'log', 'eq_hist', 'cbrt'.
    cmap : list, str
        Used for the colormap of single-layer datashader output.
    nodata: int
        Value defining the nodata value for the dataset

    """

    pn.extension()

    list_vars = []
    time_list = []

    for ts in dataset.time.values:
        ts = pd.Timestamp(ts).to_pydatetime("%Y-%M-%D")
        time_list.append(ts)

    for var in dataset.data_vars:
        list_vars.append(var)

    r_select = pn.widgets.Select(name='R', value='red', options=list_vars)
    g_select = pn.widgets.Select(name='G', value='green', options=list_vars)
    b_select = pn.widgets.Select(name='B', value='blue', options=list_vars)
    time_select = pn.widgets.Select(name='Time',
                                    value=time_list[0],
                                    options=time_list)

    def combine_bands(r, g, b, time):
        xs, ys = dataset[r].sel(time=time)[dims[0]], dataset[r].sel(
            time=time)[dims[1]]
        r, g, b = [
            ds.utils.orient_array(img)
            for img in (dataset[r].sel(time=time), dataset[g].sel(time=time),
                        dataset[b].sel(time=time))
        ]
        a = (np.where(np.logical_or(np.isnan(r), r <= nodata), 0,
                      255)).astype(np.uint8)
        r = (normalize_data(r)).astype(np.uint8)
        g = (normalize_data(g)).astype(np.uint8)
        b = (normalize_data(b)).astype(np.uint8)
        return regrid(hv.RGB(
            (xs, ys[::-1], r, g, b, a),
            vdims=list('RGBA'))).redim(x=dims[0],
                                       y=dims[1]).opts(width=width,
                                                       height=height)

    def on_r_select(event):
        var = event.obj.value
        col[-1] = combine_bands(r=r_select.value,
                                b=b_select.value,
                                g=g_select.value,
                                time=time_select.value)

    def on_b_select(event):
        var = event.obj.value
        col[-1] = combine_bands(r=r_select.value,
                                b=b_select.value,
                                g=g_select.value,
                                time=time_select.value)

    def on_g_select(event):
        var = event.obj.value
        col[-1] = combine_bands(r=r_select.value,
                                b=b_select.value,
                                g=g_select.value,
                                time=time_select.value)

    def on_time_select(event):
        time = event.obj.value
        col[-1] = combine_bands(r=r_select.value,
                                b=b_select.value,
                                g=g_select.value,
                                time=time_select.value)

    r_select.param.watch(on_r_select, parameter_names=['value'])
    g_select.param.watch(on_r_select, parameter_names=['value'])
    b_select.param.watch(on_r_select, parameter_names=['value'])
    time_select.param.watch(on_time_select, parameter_names=['value'])

    col = pn.Row(
        pn.Column(pn.WidgetBox(r_select, g_select, b_select, time_select)),
        combine_bands(r=r_select.value,
                      b=b_select.value,
                      g=g_select.value,
                      time=time_select.value))
    return col
Exemplo n.º 5
0
 def generate_chart(self):
     self.chart = pn.Column(self.content, sizing_mode="stretch_both")
Exemplo n.º 6
0
 def __init__(self, cats=None, logo=True):
     self.source = SourceGUI()
     self.cat = CatGUI(cats=cats, done_callback=self.done_callback)
     self.panel = pn.Column(name='GUI', width_policy='max', max_width=MAX_WIDTH)
     self.visible = True
     self.logo = logo
Exemplo n.º 7
0
 def submit_view(self):
     return pn.Column(
         self.view,
         self.action_button,
         name='Submit',
     )
Exemplo n.º 8
0
from bokeh.models.formatters import DatetimeTickFormatter

data = {
    "x": [
        pd.Timestamp("2020-01-01"),
        pd.Timestamp("2020-01-02"),
        pd.Timestamp("2020-01-03")
    ],
    "y": [2, 4, 5],
}
XFORMATTER = DatetimeTickFormatter(days=["%m %d, %Y"],
                                   hours=["%Y-%m-%d %H:%M"])
s1 = bk.plotting.figure(plot_width=500, plot_height=250, title=None)
s1.scatter(source=data)
s1.xaxis.formatter = XFORMATTER
s2 = bk.plotting.figure(plot_width=500,
                        plot_height=250,
                        title=None,
                        x_range=s1.x_range)
s2.vbar(
    x="x",
    top="y",
    bottom=0,
    source=data,
)
s2.xaxis.formatter = XFORMATTER

p = bk.layouts.gridplot([[s1], [s2]])

pn.Column(p).servable()
Exemplo n.º 9
0
    ],
    value='all',
)
# -


@pn.depends(alpha=alpha_slider.param.value,
            time=time_slider.param.value,
            concentration=concentration_slider.param.value)
def plot_overlaid_ecdfs_pn(alpha, time, concentration):
    return plot_overlaid_ecdfs(alpha, time, concentration)


widgets = pn.Column(pn.Spacer(width=30),
                    alpha_slider,
                    time_slider,
                    concentration_slider,
                    width=500)
panel = pn.Column(plot_overlaid_ecdfs_pn, widgets)
panel.save('interactive', embed=True, max_opts=40)


def main():
    p = plot_overlaid_ecdfs(2, 1 / .005, 'all')
    bokeh.io.show(p)

    return True


if __name__ == '__main__':
    main()
Exemplo n.º 10
0
 def getDebugPanel(self):
     self.debugPanel = pn.Column(self.param)
     return self.debugPanel
Exemplo n.º 11
0
Arquivo: base.py Projeto: vt100/intake
class Base(object):
    """
    Base class for composable panel objects that make up the GUI.

    Parameters
    ----------
    children: list of panel objects
        children that will be used to populate the panel when visible
    panel: panel layout object
        instance of a panel layout (row or column) that contains children
        when visible
    watchers: list of param watchers
        watchers that are set on children - cleaned up when visible
        is set to false.
    visible: bool
        whether or not the instance should be visible. When not visible
        ``panel`` is empty.
    logo : bool, opt
        whether to show the intake logo in a panel to the left of the main
        panel. Default is False
    """
    children = None
    panel = None
    watchers = None
    visible_callback = None
    logo_panel = pn.Column(pn.pane.PNG(ICONS['logo'], align='center'),
                           margin=(25, 0, 0, 0),
                           width=50)
    logo = False

    def __init__(self, visible=True, visible_callback=None, logo=False):
        self.visible = visible
        self.visible_callback = visible_callback
        self.logo = logo

    @property
    def panel(self):
        if not self.logo:
            return self._panel
        return pn.Row(self.logo_panel, self._panel, margin=0)

    @panel.setter
    def panel(self, panel):
        self._panel = panel

    def servable(self, *args, **kwargs):
        return self.panel.servable(*args, **kwargs)

    def show(self, *args, **kwargs):
        return self.panel.show(*args, **kwargs)

    def __repr__(self):
        """Print output"""
        return self.panel.__repr__()

    def _repr_mimebundle_(self, *args, **kwargs):
        """Display in a notebook or a server"""
        try:
            return self.panel._repr_mimebundle_(*args, **kwargs)
        except:
            raise NotImplementedError("Panel does not seem to be set "
                                      "up properly")

    def setup(self):
        """Should instantiate widgets, set ``children``, and set watchers"""
        raise NotImplementedError

    @property
    def visible(self):
        """Whether or not the instance should be visible."""
        return self._visible

    @visible.setter
    def visible(self, visible):
        """When visible changed, do setup or unwatch and call visible_callback"""
        self._visible = visible
        if visible and len(self._panel.objects) == 0:
            self.setup()
            self._panel.extend(self.children)
        elif not visible and len(self._panel.objects) > 0:
            self.unwatch()
            self._panel.clear()
        if self.visible_callback:
            self.visible_callback(visible)

    def unwatch(self):
        """Get rid of any lingering watchers and remove from list"""
        if self.watchers is not None:
            unwatched = []
            for watcher in self.watchers:
                watcher.inst.param.unwatch(watcher)
                unwatched.append(watcher)
            self.watchers = [w for w in self.watchers if w not in unwatched]

    def __getstate__(self):
        """Serialize the current state of the object"""
        return {'visible': self.visible}

    def __setstate__(self, state):
        """Set the current state of the object from the serialized version.
        Works inplace. See ``__getstate__`` to get serialized version and
        ``from_state`` to create a new object."""
        self.visible = state.get('visible', True)
        return self

    @classmethod
    def from_state(cls, state):
        """Create a new object from a serialized exising object.

        Example
        -------
        original = cls()
        copy = cls.from_state(original.__getstate__())
        """
        return cls().__setstate__(state)
Exemplo n.º 12
0
def serve_dashboard():
    dashboard = pn.Column("# My Async Dashboard")
    return dashboard.servable()
Exemplo n.º 13
0
        dashboard = build_dashboard_google_trends_btc(
                                                        price_curve_btc,
                                                        cumulative_return_curve_btc, 
                                                        
                                                        google_predicted_positive_return_curve_btc, 
                                                        google_cumulative_return_plot_btc
                                                    )
    
    
    # Return the dashboard
    return dashboard


# Make interactive drop-down lists which users can choose a social source and crypto
user_input = interact_manual(
                                analyse, 
                                Source=['Select Source', 'Elon Musk Tweets', 'Google Trends Data'], 
                                Ticker=['Select Ticker', 'Bitcoin', 'Dogecoin']
                            )

# Make the upper half interface in the app
interface = pn.Column(
                        '# SillyCon App',
                        '## Analyse correlations between Social Sources and Crypto Prices',
                        '### Select a Source and Crypto Ticker, then press Run Interact', 
                        user_input
                    )

# Launch the app in browser
interface.servable()
interface.show()
Exemplo n.º 14
0
def multiple_choice(param, popup_label=None):
    """Create a multiple choice widget"""
    return pn.Column(
        headline(param.label, popup_label=popup_label),
        pn.widgets.RadioBoxGroup.from_param(param),
    )
Exemplo n.º 15
0
 def _open(self):
     self.__panel = pn.Column(sizing_mode='stretch_width')
Exemplo n.º 16
0
 def on_gsr_dataframe_btn(self):
     if self.gsr_dataframe_btn.clicks == 0: return
     df = self.robot.get_dataframe(with_geo=True)
     return pn.Column(self._df(df), sizing_mode='stretch_width')
Exemplo n.º 17
0
 def panel(self):
     return pn.Column(
         pn.panel(self.param, expand_button=False, show_name=False),
         self.view)
Exemplo n.º 18
0
import panel as pn
import plotly.express as px

data = {
    "Day": [
        "Sunday",
        "Monday",
        "Tuesday",
        "Wednesday",
        "Thursday",
        "Friday",
        "Saturday",
    ],
    "Orders": [
        15539,
        21345,
        18483,
        24003,
        23489,
        24092,
        12034,
    ],
}
dataframe = pd.DataFrame(data)
app = pn.Column(
    dataframe,
    sizing_mode="stretch_width",
    background="gray",
)
app.servable()
Exemplo n.º 19
0
select_gene = pn.widgets.Select(name='Select gene',
                                options=list(outdict.keys()))
select_growth = pn.widgets.Select(name='Select growth',
                                  options=list(
                                      outdict[select_gene.value].keys()))


def plot_infoshift(gene='aphA', growth='arabinose'):
    plt.clf()
    plt.cla()
    s = outdict[gene][growth]

    colorinputs = np.zeros((160))
    for i in range(160):
        if s[i] < 0:
            colorinputs[i] = 0.0
        else:
            colorinputs[i] = 1.0
    fig, ax = plt.subplots(figsize=(10, 2))
    shiftcolors = plt.cm.bwr(colorinputs)
    s_abs = np.abs(s)
    ax.bar(range(160), np.abs(s), color=shiftcolors)
    #fig = plt.bar(range(160),np.abs(s),color=shiftcolors)
    plt.close(fig)
    return fig


m = pn.interact(plot_infoshift, gene=select_gene, growth=select_growth)
mout = pn.Row(pn.Column(m[0]), pn.Column(m[1])).servable()
mout.save('/home/bill/test.html')
# +
artists_points = create_artists_points(artists)
albums_points = create_albums_points(x=x_select.value,
                                     y=y_select.value,
                                     color=color_select.value,
                                     data=albums)

layout = pn.Column(pn.Row(
    pn.Column(
        pn.Pane(title, width=400),
        pn.Pane(instruction, width=400),
    ),
    pn.Pane(artists_points),
),
                   pn.Row(
                       pn.Column(
                           decade_box,
                           axes_box,
                           width=400,
                       ),
                       pn.Pane(albums_points),
                   ),
                   width_policy="max",
                   height_policy="max")

# -

# ### Interactivity and selections


# +
Exemplo n.º 21
0
def data_explorer_app(doc):
    tmpl = pn.Template('')

    # Load the modules we want.
    obs_explorer = ObservationsExplorer(name='Search Observations')
    stats = Stats(name='Overall Stats')

    def _stat_card(label, value):
        return pn.pane.HTML(f'''
        <div class="card">
            <div class="card-body">
                <h1><span class="badge badge-info">{value}</span></h1>
                <h3>{label}</h3>
            </div>
        </div>
        ''')

    stats_row = pn.Row(
        pn.Column(
            pn.Row(
                _stat_card('Hours Exptime',
                           int(stats.df['Total Hours'].sum())),
                _stat_card('Total Images', int(stats.df['Images'].sum())),
            ),
            pn.Row(
                _stat_card('Observations',
                           int(stats.df['Observations'].sum())),
                _stat_card('Contributing Units',
                           len(stats.df['Unit'].unique())),
            )),
        stats.widget_box,
        stats.plot,
        sizing_mode='stretch_both',
    )

    obs_widget_box = pn.WidgetBox(pn.Param(
        obs_explorer.param,
        widgets={
            'unit_id': pn.widgets.MultiChoice,
            'search_name': {
                "type": pn.widgets.TextInput,
                "placeholder": "Lookup RA/Dec by object name",
            },
        },
        disabled=True),
                                  sizing_mode='stretch_both',
                                  max_width=320)

    observations_row = pn.Column(
        pn.panel('#### Observations'),
        pn.Row(
            obs_widget_box,
            obs_explorer.table,
            pn.Column(
                obs_explorer.selected_title,
                obs_explorer.image_preview,
                # obs_explorer.image_table,
                obs_explorer.table_download_button,
                obs_explorer.sources_download_button),
            sizing_mode='stretch_both',
        ))

    main_layout = pn.Column(stats_row, observations_row)

    tmpl.add_panel('mainArea', main_layout)

    return tmpl.server_doc(doc=doc)
Exemplo n.º 22
0
                                              title='Correlation Histogram')
    dig_dist_his = hv.Histogram(
        (dig_dist_edges, dig_dist_freq)).opts(xlabel='Distance',
                                              height=300,
                                              width=400,
                                              title='Distance Histogram')

    dash = (dig_corr_img + dig_corr_his + dig_dist_img + dig_dist_his).opts(
        opts.Layout(shared_axes=False)).cols(2)  # Dashboard of all plots

    return dash


# Display all digits data plots and widgets
# -----------------------------------------
pn.Column(dig_CorrRange, dig_plots)

# ***
# ## Fashion Data
#
# The MNIST fashion data is loaded from https://github.com/zalandoresearch/fashion-mnist. The data set consists of a training set of 60,000 images and a test set of 10,000 images. Each image is a 28x28 grayscale image, associated with a label from 10 classes.
# * Number of samples: 10,000 (test only)
# * Number of features: 784 (28x28)
# * Number of groups: 10
# * Pixle value range: 0-255
#
# | Label | Description | Number of Samples |
# | :---: | :---: | :---: |
# | 0 | T-shirt/top | 1000 |
# | 1 | Trouser | 1000 |
# | 2 | Pullover | 1000 |
Exemplo n.º 23
0
def plot_band(dataset,
              dims=['x', 'y'],
              height=500,
              width=500,
              clims=None,
              norm='eq_hist',
              cmap=['black', 'white'],
              nodata=1):
    """Interactive visualization of xarray time series

    Description
    ----------
    Takes an xarray time dataset and creates an interactive panel which allows to inspect the different data variables at different time steps

    Parameters
    ----------
    dataset : xarray.Dataset
        A multi-dimensional array with x,y and time dimensions and one or more data variables.
    dim : list, str
        A list containing the names of the x and y dimension.
    height: int
        Height of the created plot specified in pixels.
    width: int
        Width of the created plot specified in pixels.
    clims: int,float
        Min and max data values to use for colormap interpolation.
    norm :
        The normalization operation applied before colormapping. Valid options include 'linear', 'log', 'eq_hist', 'cbrt'.
    cmap : list, str
        Used for the colormap of single-layer datashader output.
    nodata: int
        Value defining the nodata value for the dataset

    """

    pn.extension()

    list_vars = []
    time_list = []

    for ts in dataset.time.values:
        ts = pd.Timestamp(ts).to_pydatetime("%Y-%M-%D")
        time_list.append(ts)

    for var in dataset.data_vars:
        list_vars.append(var)

    bands_select = pn.widgets.Select(name='Band',
                                     value=list_vars[0],
                                     options=list_vars)
    time_select = pn.widgets.Select(name='Time',
                                    value=time_list[0],
                                    options=time_list)

    def one_band(band, time):
        xs, ys = dataset[band].sel(time=time)[dims[0]], dataset[band].sel(
            time=time)[dims[1]]
        b = ds.utils.orient_array(dataset[band].sel(time=time))
        a = (np.where(np.logical_or(np.isnan(b), b <= nodata), 0,
                      255)).astype(np.uint8)
        return shade(regrid(
            hv.RGB((xs, ys[::-1], b, b, b, a), vdims=list('RGBA'))),
                     cmap=cmap,
                     clims=clims,
                     normalization=norm).redim(x=dims[0],
                                               y=dims[1]).opts(width=width,
                                                               height=height)

    def on_var_select(event):
        var = event.obj.value
        col[-1] = one_band(band=bands_select.value, time=time_select.value)
        print(time=time_select.value)

    def on_time_select(event):
        time = event.obj.value
        col[-1] = one_band(band=bands_select.value, time=time_select.value)
        print(time_select.value)

    bands_select.param.watch(on_var_select, parameter_names=['value'])
    time_select.param.watch(on_time_select, parameter_names=['value'])
    col = pn.Row(pn.Column(pn.WidgetBox(bands_select, time_select)),
                 one_band(band=bands_select.value, time=time_select.value))

    return col
Exemplo n.º 24
0
 def __init__(self, columns):
     super().__init__()
     self.columns = columns
     self.panel = pn.Column(name='Fields')
     self._register(None, "changed")
Exemplo n.º 25
0
    def update_result_score(results_button_on):
        if results_button_on:
            t.param.trigger('action')  # Update dashboard
            dandelion.param.trigger('action')
            data_table = {
                'Parameters': [
                    "Target Goal (wxDai)",
                    "Maximum Goal (wxDai)",
                    "Minimum Goal (wxDai)",
                    "Impact Hour Rate at Target Goal (wxDai/IH)",
                    "Impact Hour Rate at Infinity (wxDai/IH)",
                    "Hatch Membership Ratio (wxDai/CSTK)",
                    "Hatch Period (days)",
                    "Hatch Minting rate (TECH/wxDai)",
                    "Hatch Tribute (%)",
                    "Support Required (%)",
                    "Minimum Quorum (%)",
                    "Vote Duration (days)",
                    "Vote Buffer (hours)",
                    "Ragequit Delay (hours)",
                    "Tollgate Fee (wxDai)"],
                'Values': [
                    int(t.target_raise),
                    int(t.max_raise),
                    int(t.min_raise),
                    t.impact_hour_rate_at_target_goal,
                    t.maximum_impact_hour_rate,
                    t.hatch_oracle_ratio,
                    t.hatch_period_days,
                    t.hatch_exchange_rate,
                    t.hatch_tribute_percentage,
                    dandelion.support_required_percentage,
                    dandelion.minimum_accepted_quorum_percentage,
                    dandelion.vote_duration_days,
                    dandelion.vote_buffer_hours,
                    dandelion.rage_quit_hours,
                    dandelion.tollgate_fee_xdai]
                }
            df = pd.DataFrame(data=data_table)

            # Define output pane
            output_pane = pn.Row(pn.Column(t.impact_hours_plot,
                                           t.redeemable_plot),
                                 pn.Column(dandelion.vote_pass_view,
                                           t.pie_charts_view))
            output_pane.save('output.html')
            pn.panel(t.output_scenarios_view()
                      .hvplot.table()).save('out_scenarios.html')

            scenarios = codecs.open("out_scenarios.html", 'r')
            charts = codecs.open("output.html", 'r')

            data_charts = {
                'html': charts.read(),
                'css': ".box { color: white; background-color: #0f79b9; padding: 10px; font-family: Roboto }",
                'google_fonts': "Roboto"}
            data_scenarios = {
                'html': scenarios.read(),
                'css': ".box { color: white; background-color: #0f79b9; padding: 10px; font-family: Roboto }",
                'google_fonts': "Roboto"}

            charts = requests.post(url=HCTI_API_ENDPOINT,
                                   data=data_charts,
                                   auth=(HCTI_API_USER_ID, HCTI_API_KEY))
            scenarios = requests.post(url=HCTI_API_ENDPOINT,
                                      data=data_scenarios,
                                      auth=(HCTI_API_USER_ID, HCTI_API_KEY))
            # Parameters string
            url_fork = '{url}?ihminr={ihf_minimum_raise}&tgihr={impact_hour_rate_at_target_goal}&maxihr={maximum_impact_hour_rate}&ihtr={ihf_target_raise}&ihmaxr={ifh_maximum_raise}&hor={hatch_oracle_ratio}&hpd={hatch_period_days}&her={hatch_exchange_rate}&ht={hatch_tribute_percentage}&sr={support_required}&maq={minimum_accepted_quorum}&vdd={vote_duration_days}&vbh={vote_buffer_hours}&rqh={rage_quit_hours}&tfx={tollgate_fee_xdai}"'.format(tollgate_fee_xdai=dandelion.tollgate_fee_xdai,
            vote_duration_days=dandelion.vote_duration_days,
            rage_quit_hours=dandelion.rage_quit_hours,
            ihf_minimum_raise=int(t.min_raise),
            impact_hour_rate_at_target_goal=t.impact_hour_rate_at_target_goal,
            maximum_impact_hour_rate=t.maximum_impact_hour_rate,
            ihf_target_raise=t.target_raise,
            ifh_maximum_raise=int(t.max_raise),
            hatch_oracle_ratio=t.hatch_oracle_ratio,
            hatch_period_days=t.hatch_period_days,
            hatch_exchange_rate=t.hatch_exchange_rate,
            hatch_tribute_percentage=t.hatch_tribute_percentage,
            support_required=dandelion.support_required_percentage,
            minimum_accepted_quorum=dandelion.minimum_accepted_quorum_percentage,
            vote_buffer_hours=dandelion.vote_buffer_hours,
            max_wxdai_ratio=int(1125*t.hatch_oracle_ratio),
            total_votes_per_year=int(24/dandelion.vote_buffer_hours*365),
            single_tech_mint=float(1/t.hatch_exchange_rate),
            url=config_file['url'])

            # Title
            title = '## Check out my proposal for the Hatch! <a href="' + url_fork + ' target="_blank">Click here to preload the Hatch Configuration Dashboard with my parameters if you think you can do better</a>.'
            meme_image = """

![image](https://i.imgflip.com/57zyrl.jpg)
"""
            graphical_summary = """
# Graphical Summary

![image]({image_charts})
""".format(image_charts=charts.json()['url'])


            graph_descriptions = """
## Graph Descriptions

- Top Left, **Impact Hour Rate vs wxDai Collected**: The Impact Hour Rate determines the Minting Rate for Builders, making 1 Impact Hour equivalent to sending this amount of wxDai to the Hatch.
- Top Right, **Proposal Acceptance Criteria**: Shows the range of possibilities for DAO vote outcomes and whether they succeed or not given the Support Required & Minimum Quorum I chose.
- Bottom Left, **Backer's Rage Quit % vs wxDai Collected**: The Backer's Rage Quit % is the percent of wxDai that the Backers sent to the Hatch that would be returned if they decide to Ragequit.
- Bottom Right, **Redeem-ability of the DAO's wxDai**: Shows who has rights to the wxDai held by the DAO. All of the DAO's funds are collectively governed but some can be withdrawn if token holders Ragequit. This shows the results of my parameter choices at the 3 different goals.
"""
            simulated_outcomes = """
# Simulated Outcomes

![image]({image_scenarios})
            """.format(image_scenarios=scenarios.json()['url'])

            parameters_data = """
# My Hatch Configuration

| Parameter|Value|
|:-|-:|
|Target Goal (wxDai)|{target_goal:,}|
|Maximum Goal (wxDai)|{max_goal:,}|
|Minimum Goal (wxDai)|{min_goal:,}|
|Impact Hour Rate at Target Goal (wxDai/IH)|{ih_rate_tg_goal:,}|
|Impact Hour Rate at Infinity (wxDai/IH)|{ih_rate_infinity:,}|
|Hatch Membership Ratio (wxDai/CSTK)|{hatch_membership_ratio:,}|
|Hatch Period (days)|{hatch_period_days}|
|Hatch Minting rate (TECH/wxDai)|{hatch_minting_rate:,}|
|Hatch Tribute (%)|{hatch_tribute}|
|Support Required (%)|{support_required}|
|Minimum Quorum (%)|{minimum_quorum}|
|Vote Duration (days)|{vote_duration_days}|
|Vote Buffer (hours)|{vote_buffer_hours}|
|Ragequit (hours)|{ragequit}|
|Tollgate Fee (wxDai)|{tollgate_fee:,}|</a>""".format(target_goal=t.target_raise,
           max_goal=t.max_raise,
           min_goal=t.min_raise,
           ih_rate_tg_goal=t.impact_hour_rate_at_target_goal,
           ih_rate_infinity=t.maximum_impact_hour_rate,
           hatch_membership_ratio=t.hatch_oracle_ratio,
           hatch_period_days=t.hatch_period_days,
           hatch_minting_rate=t.hatch_exchange_rate,
           hatch_tribute=t.hatch_tribute_percentage,
           support_required=dandelion.support_required_percentage,
           minimum_quorum=dandelion.minimum_accepted_quorum_percentage,
           vote_duration_days=dandelion.vote_duration_days,
           vote_buffer_hours=dandelion.vote_buffer_hours,
           ragequit=dandelion.rage_quit_hours,
           tollgate_fee=dandelion.tollgate_fee_xdai)

            results_header = """
# Summary
"""

            default_comment = "To use the defaults... Technocracy for the win"
            if not comments_tech.value: 
                print(comments_tech.value)
                comment_tech = default_comment
            else:
                comment_tech = comments_tech.value
            
            if not comments_dandelion.value: 
                comment_dandelion = default_comment
            else:
                comment_dandelion = comments_dandelion.value

            string_comments_tech = """
## Hatch Strategy

<p>{comments}</p>
            """.format(comments=comment_tech)

            string_comments_dandelion = """
## DAO Strategy

<p>{comments}</p>
            """.format(comments=comment_dandelion)

            string_data = """
  <h2>Hatch Details</h2>

- Trusted Seed members can send wxDai to the Hatch for {hatch_period_days} days.

- The target goal will be {ihf_target_raise} wxDai, with a minimum of {ihf_minimum_raise} wxDai necessary for the TEC Hatch DAO to be launched and a cap at {ifh_maximum_raise} wxDai.

- Backers will need to send in {single_tech_mint} wxDai to mint 1 TECH.

- The membership ratio is set at {hatch_oracle_ratio} wxDai/CSTK, so a Trusted Seed member with the minimum CSTK Score of 1125 CSTK can send up to {max_wxdai_ratio}  wxDai to the Hatch.

<h2>TEC Hatch DAO Voting Details</h2>

- Proposals will be voted on for {vote_duration_days} days. They will require at least {support_required}% support, and a minimum of {minimum_accepted_quorum}% of the TECH Tokens will have to vote yes for a proposal to pass.

- TECH token holders will have {rage_quit_hours} hours to exit the DAO if they don't like the result of a vote (as long as they didn't vote yes) before it is executed.

- There will be a minimum of {vote_buffer_hours} hours between proposals so people always have time to exit safely if they voted yes on a previous vote, this means we can have at most {total_votes_per_year} votes per year.

- To prevent griefing attacks, it will cost {tollgate_fee_xdai} wxDai to make a proposal.

If you have Impact Hours, you can see how much money you will get with my configuration <a href="{url}?ihminr={ihf_minimum_raise}&tgihr={impact_hour_rate_at_target_goal}&maxihr={maximum_impact_hour_rate}&ihtr={ihf_target_raise}&ihmaxr={ifh_maximum_raise}&hor={hatch_oracle_ratio}&hpd={hatch_period_days}&her={hatch_exchange_rate}&ht={hatch_tribute_percentage}&sr={support_required}&maq={minimum_accepted_quorum}&vdd={vote_duration_days}&vbh={vote_buffer_hours}&rqh={rage_quit_hours}&tfx={tollgate_fee_xdai}" target="_blank">here, just check out the Impact Hour Results table.
            """.format(tollgate_fee_xdai=dandelion.tollgate_fee_xdai,
            vote_duration_days=dandelion.vote_duration_days,
            rage_quit_hours=dandelion.rage_quit_hours,
            ihf_minimum_raise=int(t.min_raise),
            impact_hour_rate_at_target_goal=t.impact_hour_rate_at_target_goal,
            maximum_impact_hour_rate=t.maximum_impact_hour_rate,
            ihf_target_raise=t.target_raise,
            ifh_maximum_raise=int(t.max_raise),
            hatch_oracle_ratio=t.hatch_oracle_ratio,
            hatch_period_days=t.hatch_period_days,
            hatch_exchange_rate=t.hatch_exchange_rate,
            hatch_tribute_percentage=t.hatch_tribute_percentage,
            support_required=dandelion.support_required_percentage,
            minimum_accepted_quorum=dandelion.minimum_accepted_quorum_percentage,
            vote_buffer_hours=dandelion.vote_buffer_hours,
            max_wxdai_ratio=int(1125*t.hatch_oracle_ratio),
            total_votes_per_year=int(24/dandelion.vote_buffer_hours*365),
            single_tech_mint=float(1/t.hatch_exchange_rate),
            url=config_file['url'])

            markdown_panel = pn.pane.Markdown(parameters_data +
                                              string_comments_tech +
                                              string_comments_dandelion +
                                              results_header +
                                              string_data +
                                              graphical_summary)
            markdown_panel = pn.pane.Markdown(title +
                                              meme_image +
                                              graphical_summary +
                                              graph_descriptions +
                                              simulated_outcomes +
                                              string_comments_tech +
                                              string_comments_dandelion +
                                              results_header +
                                              string_data +
                                              parameters_data)
            body = urllib.parse.quote(markdown_panel.object, safe='')
            url.value = (config_file['repo'] +
                         "/issues/new?title=Vote%20for%20My%20Params&labels=" +
                         config_file['label'] + "&body=" + body)
            results_button.name = "Update your results"
            markdown_panel = pn.pane.Markdown(results_header + string_data)
            return markdown_panel
Exemplo n.º 26
0
import panel as pn

ABOUT = """\
# About

[Panel](https://panel.pyviz.org/) is a powerful framework for building awesome-analytics apps in [Python](https://www.python.org/).

The purpose of this app is to test that a **multi-page Dashboard Layout** similar to the [bootstrap dashboard template](https://getbootstrap.com/docs/4.3/examples/dashboard/) from [getboostrap.com](https://getbootstrap.com/) can be implemented in [Panel](https://panel.pyviz.org/).
"""

IMAGE = "https://getbootstrap.com/docs/4.4/assets/img/examples/dashboard.png"

INFO = """\
Navigate to the **Dashboard Page** via the **Sidebar** to see the result.
Or Navigate to the **Limitations Page** to learn of some of the limitations of Panel that
I've experienced."""

about = pn.layout.Row(pn.pane.Markdown(ABOUT))
image = pn.pane.PNG(IMAGE)
info = pn.layout.Row(pn.pane.Markdown(
    INFO,
    background="#d1ecf1",
))
app = pn.Column(
    about,
    image,
    info,
)
app.servable()
Exemplo n.º 27
0
 def param_with_tooltip(param, tooltip, height=50):
     return pn.Row(pn.Column(param, sizing_mode="stretch_width"),
                   pn.pane.HTML(help_icon(tooltips[tooltip]['href'],
                                tooltips[tooltip]['text']),
                                sizing_mode="fixed",
                                width=30, height=height, align="end"))
Exemplo n.º 28
0
 def __init__(self):
     self.panel = pn.Column(pn.Spacer())
     self.dirty = True  # don't use kwargs until source is set
Exemplo n.º 29
0
        bounds=(
            start,
            end,
        ),
    )
    number = param.Number(
        default=0,
        bounds=(
            -5.0,
            5.0,
        ),
    )


view = pn.Param(
    CustomExample.param,
    widgets={
        "select_string": pn.widgets.RadioButtonGroup,
        "date": pn.widgets.DatePicker,
        "number": pn.widgets.FloatSlider,
    },
)

app = pn.Column(
    __doc__,
    view,
    pn.pane.Markdown("# Stand Alone Widget"),
    width=1000,
)
app.servable()
Exemplo n.º 30
0
    chopiness * Chopiness_offset_4SRad,
    color="green",
    line_alpha=0.5,
    legend_label=data.WSPD.name,
)

p4.grid.grid_line_alpha = 0.3
p4.xaxis.axis_label = "Date"
p4.yaxis.axis_label = '"Chopiness" f(Wave Height, Wave separation, Wind Gusts)'
p4.legend.location = "top_left"
p4.name = "Solar"

button = pn.widgets.Button(
    name=
    "Update Data (station updates every 30 min at bottom and top of the hour)")
button.on_click(import_data)
bar_width = 300
big_bar_width = 3 * bar_width + 40
pn.Column(
    pn.Tabs(p1, p2, p3, p4),
    pn.layout.HSpacer(),
    pn.pane.Markdown('## How safe is it to go out? (based on "chopiness") '),
    pn.widgets.Progress(
        active=True,
        width=big_bar_width,
        bar_color=bar_color,
        value=int(curr_chopiness),
    ),
    # button,
).servable()