Ejemplo n.º 1
0
    def generate_dashboard(self, title, charts, theme):
        """
        layout 0
        [1]
        """

        tmpl = pn.Template(theme.layout_head + layout_0)
        tmpl.add_panel("title",
                       '<div class="nav-title"> ' + str(title) + "</div>")

        num_of_charts_added = 0

        widgets = pn.Column()

        for chart in charts.values():
            if hasattr(chart, "apply_theme"):
                chart.apply_theme(theme.chart_properties)
            if ("widget" in chart.chart_type
                    or chart.chart_type == "datasize_indicator"):
                chart.chart.sizing_mode = "scale_both"
                chart.chart.width = 280
                widgets.append(chart.view())
                continue
            num_of_charts_added += 1
            if num_of_charts_added == 1:
                chart.chart.sizing_mode = "scale_both"
                chart.width = 1600
                chart.height = int(round(90 * 1.0)) * 10
                tmpl.add_panel("chart1", chart.view())
            else:
                break
        tmpl.add_panel("widgets", widgets)
        return tmpl
Ejemplo n.º 2
0
    def generate_dashboard(self, title, charts, theme):
        """
        layout 7

        [   1   ]
        [2  3  4]
        """

        tmpl = pn.Template(theme.layout_head + layout_7)

        tmpl.add_panel("title",
                       '<div class="nav-title"> ' + str(title) + "</div>")

        num_of_charts_added = 0
        widgets = pn.Column()

        for chart in charts.values():
            if hasattr(chart, "apply_theme"):
                chart.apply_theme(theme.chart_properties)
            if ("widget" in chart.chart_type
                    or chart.chart_type == "datasize_indicator"):
                chart.chart.sizing_mode = "scale_both"
                chart.chart.width = 280
                widgets.append(chart.view())
                continue
            num_of_charts_added += 1
            if num_of_charts_added == 1:
                chart.chart.sizing_mode = "scale_both"
                chart.width = 1600
                chart.height = 600
                tmpl.add_panel("chart1", chart.view())
            elif num_of_charts_added == 2:
                chart.chart.sizing_mode = "scale_both"
                chart.width = int(1600 / 3)
                chart.height = 300
                tmpl.add_panel("chart2", chart.view())
            elif num_of_charts_added == 3:
                chart.chart.sizing_mode = "scale_both"
                chart.width = int(1600 / 3)
                chart.height = 300
                tmpl.add_panel("chart3", chart.view())
            elif num_of_charts_added == 4:
                chart.chart.sizing_mode = "scale_both"
                chart.width = int(1600 / 3)
                chart.height = 300
                tmpl.add_panel("chart4", chart.view())
            else:
                break

        n = 4 - num_of_charts_added

        for i in range(n):
            chart = 4 - i
            tmpl.add_panel("chart" + str(chart), "")

        tmpl.add_panel("widgets", widgets)
        return tmpl
Ejemplo n.º 3
0
 def compose(self, golden_layout: str) -> None:
     """
     Creates a servable template from a golden layout js code string.
     :param golden_layout_string: Result of nesting stacks, columns, rows, and panels
                                  using the methods in this class.
     """
     template = ClientSideCodeStrings.JINJA2_BASE % golden_layout
     self.app = pn.Template(template=template)
     for panel_ID, panel in self.panels.items():
         self.app.add_panel(panel_ID, panel)
Ejemplo n.º 4
0
    def render(self):
        template = pn.Template(self._template)

        template.add_variable("subtitle", "CHIME Daily Validation")
        template.add_variable("app_title", "BON DIA")
        template.add_variable("username", self.current_user)
        template.add_variable("num_unvalidated", 19)
        template.add_variable("root_url", self._root_url)

        return self.populate_template(template)
Ejemplo n.º 5
0
 def compose(self, golden_layout: str) -> None:
     """
     Creates a servable template from a golden layout js code string.
     Any GoldenPanel object needs to call compose exactly once to function as expected.
     :param golden_layout: Result of nesting stacks, columns, rows, and panels
                           using the methods in this class.
     """
     template = ClientSideCodeStrings.JINJA2_BASE % golden_layout
     self.app = pn.Template(template=template)
     for panel_ID, panel in self.panels.items():
         self.app.add_panel(panel_ID, panel)
Ejemplo n.º 6
0
def main():
    pn.config.raw_css.append(CSS)

    app_title = pn.Row(
        pn.layout.HSpacer(),
        pn.pane.Markdown(f"Bootstrap Dashboard"),
        pn.layout.HSpacer(),
        width=SIDEBAR_WIDTH,
        css_classes=["app-title"],
    )
    header = pn.Row(app_title,
                    pn.layout.HSpacer(),
                    sizing_mode="stretch_width",
                    css_classes=["header"])
    sidebar = pn.Column(
        "Sidebar",
        pn.layout.HSpacer(height_policy="max"),
        height_policy="max",
        width=SIDEBAR_WIDTH,
        css_classes=["sidebar"],
    )
    content = pn.Column(width_policy="max",
                        margin=(25, 50, 25, 50),
                        css_classes=["content"])

    about = pn.layout.Row(pn.pane.Markdown(ABOUT))
    image = pn.pane.PNG(IMAGE)
    info = pn.pane.Markdown(INFO, background="#d1ecf1")
    page = pn.Column(about,
                     image,
                     info,
                     sizing_mode="stretch_width",
                     css_classes=["about"])

    content.append(page)

    body = pn.Column(header,
                     pn.Row(sidebar, content),
                     sizing_mode="stretch_width",
                     background="darkgray")

    items = {
        "body": body,
    }
    template = pn.Template(template=TEMPLATE, items=items)
    template.servable()
def build_dashboard(tweets, predictions_streamz_df):
    """Build the dashboard. changes the css, styles and creates empty place holders for tables, tweets and graphs """

    template = """
    {% extends base %}

    <!-- goes in body -->
    {% block postamble %}
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/solar/bootstrap.min.css">
    {% endblock %}

    <!-- goes in body -->
    {% block contents %}
    {{ app_title }}
    <p/>
    <p style="text-align:center;">
    <img src="https://user-images.githubusercontent.com/4336187/87214331-6d9ef280-c2f9-11ea-9c87-231f5c828a4e.png" height='108'>
    </p>
    
    <br>
    <div class="container">
      <div class="row"> 
        <div class="col-sm">
          {{ embed(roots.B) }}
        </div> 
      </div>
    <div class="container">
      <div class="row"> 
        <div class="col-sm">
          {{ embed(roots.C) }}
        </div> 
      </div>
   
      </div>
    </div>
    {% endblock %}
    <div style="background:<%= 
                (function colorfromint(){
                    if(cola > colb ){
                        return("green")}
                    }()) %>; 
                color: black"> 
            <%= value %>
     </div>
    """

    css = '''
    .panel-widget-box {
      background: #f0f0f0;
      border-radius: 5px;
      border: 1px black solid;
    }

     '''

    theme = Theme(
        json={
            'attrs': {
                'Figure': {
                    'background_fill_color': 'black',
                    'border_fill_color': 'black',
                    'outline_line_color': '#444444',
                },
                'Grid': {
                    'grid_line_dash': [6, 4],
                    'grid_line_alpha': .3,
                },
                'Axis': {
                    'major_label_text_color': 'white',
                    'axis_label_text_color': 'white',
                    'major_tick_line_color': 'white',
                    'minor_tick_line_color': 'white',
                    'axis_line_color': "white"
                }
            }
        })

    hv.renderer('bokeh').theme = theme

    dashboard = pn.Template(template)

    tweets_table = pn.Column("##### Live Tweet Sentiments:",
                             tweets.hvplot.table(
                                 columns=[
                                     'created_at', 'user_name', 'tweets',
                                     'sentiments', 'polarity'
                                 ],
                                 backlog=10,
                             ).opts(bgcolor='blue', height=272),
                             css_classes=['panel-widget-box'])

    price = pn.Column(
        "##### Pricing Model",
        predictions_streamz_df.hvplot.line(width=1400,
                                           grid=True,
                                           backlog=500,
                                           title="prices").opts(
                                               bgcolor='black',
                                               legend_position='right'))

    positive_cloud = pn.Column(
        "##### Postive Word Cloud:",
        pn.pane.PNG('Images/postive_sentiments.png', height=272))

    negative_cloud = pn.Column(
        "##### Negative Word Cloud:",
        pn.pane.PNG('Images/negative_sentiments.png', height=272))

    clouds = pn.Row(positive_cloud, negative_cloud)

    sentiments = pn.Row(tweets_table, clouds)

    #     dashboard.add_panel('B',tweets_table)
    dashboard.add_panel('B', sentiments)
    dashboard.add_panel('C', price)

    return dashboard
Ejemplo n.º 8
0
def load_app(config_file):
    pn.config.sizing_mode = 'stretch_both'

    impact_hour_data_1, impact_hour_data_2 = read_impact_hour_data()
    impact_hours_data = ImpactHoursData()

    # ImpactHoursData
    i = ImpactHoursData()

    # TECH
    t = TECH(total_impact_hours=i.total_impact_hours,
             impact_hour_data=impact_hour_data_1,
             total_cstk_tokens=1000000,
             config=config_file['tech'])

    # ImpactHoursFormula
    #impact_hours_rewards = ImpactHoursFormula(i.total_impact_hours, impact_hour_data_1)
    #impact_rewards_view = pn.Column(impact_hours_rewards.impact_hours_rewards,
    # impact_hours_rewards.redeemable,
    # impact_hours_rewards.cultural_build_tribute)

    # Hatch
    cstk_data = read_cstk_data()
    #hatch = Hatch(cstk_data, impact_hours_rewards.target_raise,
    # i.total_impact_hours,
    # impact_hours_rewards.target_impact_hour_rate)

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

    # Import Params Button
    import_params_button = pn.widgets.Button(name='Import params',
                                             button_type='primary')
    import_description = pn.pane.Markdown(
        '<h4>To import the parameters, click on the button below:</h4>')

    # Share Button
    comments = pn.widgets.TextAreaInput(
        name='Comments',
        max_length=1024,
        placeholder='Explain your thoughts on why you choose the params...')
    share_button = pn.widgets.Button(name='Share your results on GitHub!',
                                     button_type='primary')
    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')

    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 'hs' in queries:
                t.impact_hour_slope = float(queries['hs'])
            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

    @pn.depends(results_button)
    def update_result_score(results_button_on):
        data_table = {
            'Parameters': [
                "Target raise (wxDai)", "Maximum raise (wxDai)",
                "Minimum raise (wxDai)", "Impact hour slope (wxDai/IH)",
                "Maximum impact hour rate (wxDai/IH)",
                "Hatch oracle ratio (wxDai/CSTK)", "Hatch period (days)",
                "Hatch exchange rate (TECH/wxDai)", "Hatch tribute (%)",
                "Support required (%)", "Minimum accepted quorum (%)",
                "Vote duration (days)", "Vote buffer (hours)",
                "Rage quit (hours)", "Tollgate fee (wxDai)"
            ],
            'Values': [
                int(t.target_raise),
                int(t.max_raise),
                int(t.min_raise), t.impact_hour_slope,
                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)

        if results_button_on:
            # Define output pane
            output_pane = pn.Row(
                pn.Column(t.impact_hours_view, t.redeemable_plot,
                          t.cultural_build_tribute_plot),
                pn.Column(dandelion.vote_pass_view, t.funding_pool_view))
            output_pane.save('output.html')
            pn.panel(t.output_scenarios_out_issue().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))

            output_data = """

<h1>Output Charts</h1>

![image]({image_charts})

<h1>Output Scenarios</h1>

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

            parameters_data = """

<h1>Parameters</h1>

{params_table}
            """.format(
                params_table=df.to_markdown(index=False, floatfmt=",.2f"))

            string_data = """
<h1>Results</h1>

<p>{comments}</p>

- It costs {tollgate_fee_xdai} wxDAI to make a proposal.

- Votes will be voted on for {vote_duration_days} days.

- 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 don't vote yes).

- There will be a minimum of {vote_buffer_hours} hours between proposals so people can exit safely in weird edge case scenarios.

- A proposal that passes can be executed {proposal_execution_hours} hours after it was proposed.

- A CSTK Token holder that has 2000 CSTK can send a max of {max_wxdai_ratio} wxDai to the Hatch.

Play with my parameters [here]({url}?ihminr={ihf_minimum_raise}&hs={hour_slope}&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(comments=comments.value,
                       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),
                       hour_slope=t.impact_hour_slope,
                       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,
                       proposal_execution_hours=dandelion.vote_buffer_hours +
                       dandelion.rage_quit_hours,
                       max_wxdai_ratio=int(2000 * t.hatch_oracle_ratio),
                       url=config_file['url'])

            markdown_panel = pn.pane.Markdown(parameters_data + string_data +
                                              output_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"

        else:
            string_data = ""
        markdown_panel = pn.pane.Markdown(string_data)
        return pn.Row(df.hvplot.table(), markdown_panel)

    pn.state.onload(update_params_by_url_query)

    # Front-end
    tmpl = pn.Template(template=template)
    tmpl.add_variable('app_title', config_file['title'])
    tmpl.add_panel('A', i.impact_hours_accumulation)
    tmpl.add_panel('B', t)
    tmpl.add_panel('C', t.funding_pool_data_view)
    tmpl.add_panel('E', t.payout_view)
    tmpl.add_panel(
        'D',
        pn.Column(t.impact_hours_view, t.redeemable_plot,
                  t.cultural_build_tribute_plot))
    tmpl.add_panel('M', t.trigger_target_cultural_build_tribute_too_high)
    tmpl.add_panel('F', t.funding_pool_view)
    tmpl.add_panel('V', dandelion)
    tmpl.add_panel('W', dandelion.vote_pass_view)
    tmpl.add_panel('G', pn.pane.GIF('media/inputs_outputs.gif'))

    tmpl.add_panel('R', update_result_score)
    tmpl.add_panel('CO', comments)
    tmpl.add_panel('BU', pn.Column(results_button, share_button, url))
    tmpl.servable(title=config_file['title'])
Ejemplo n.º 9
0
from static.description import description
from static.blockquote import blockquote
from static.extras import extras
from static.returns import returns
from static.js import js
from attributes import Attributes
from correction import Correction
import config as c

settings.resources = 'cdn'
pn.config.raw_css = [
    css,
]

name = 'ufunc-correct'
tmpl = pn.Template(template)
tmpl.add_variable('app_title', name)
tmpl.add_variable('description', description)
tmpl.add_variable('blockquote', blockquote)
tmpl.add_variable('extras', extras)
tmpl.add_variable('returns', returns)
tmpl.add_variable('js', js)


class Interact(param.Parameterized):
    '''

    '''
    def __init__(self):
        super(Interact, self).__init__()
        self.datapath = name + '/data'
Ejemplo n.º 10
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'])
Ejemplo n.º 11
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)
Ejemplo n.º 12
0
    def jinja(self):
        debug("jinja")

        tmpl = pn.Template(dashboard_html_template)

        data_repo_widget = pn.panel(self.param.data_repository, show_labels=False)
        data_repo_widget.width = 300
        data_repo_row = pn.Row(data_repo_widget, self._submit_repository)
        data_repo_row.css_classes = ["data-repo-input"]

        query_filter_widget = pn.panel(self.param.query_filter)
        query_filter_widget.width = 260

        query_filter_active_widget = pn.panel(self.param.query_filter_active)
        query_filter_active_widget.width = 260
        query_filter_active_widget.disabled = True

        new_column_widget = pn.panel(self.param.new_column_expr)
        new_column_widget.width = 260

        datastack_switcher = pn.Row(self._switch_stack)
        datastack_switcher.css_classes = ["stack-switcher"]

        view_switcher = pn.Row(self._switch_view)
        view_switcher.css_classes = ["view-switcher"]

        clear_button_row = pn.Row(self._clear_metrics_button)

        overview_map = self.overview.panel()

        components = [
            ("metrics_clear_button", clear_button_row),
            ("data_repo_path", data_repo_row),
            ("status_message_queue", self.status_message),
            ("adhoc_js", self.adhoc_js),
            ("infobar", self._info),
            ("stack_switcher", datastack_switcher),
            ("view_switcher", view_switcher),
            ("metrics_selectors", self._metric_layout),
            # ('metrics_plots', self._plot_layout),
            # ('plot_top', self._plot_top),
            ("plot_top", None),
            ("metrics_plots", self.detail_plots_layout),
            ("skyplot_metrics_plots", self.skyplot_layout),
            ("overview_plots", overview_map),
            (
                "flags",
                pn.Column(
                    pn.Row(self.flag_filter_select, self.flag_state_select),
                    pn.Row(self.flag_submit),
                    pn.Row(self.flag_filter_selected),
                    pn.Row(self.flag_remove),
                ),
            ),
            (
                "query_filter",
                pn.Column(
                    query_filter_widget,
                    query_filter_active_widget,
                    pn.Row(self.query_filter_clear, self.query_filter_submit),
                ),
            ),
            ("new_column", pn.Column(new_column_widget, pn.Row(self.new_column_submit)),),
        ]

        for l, c in components:
            tmpl.add_panel(l, c)

        return tmpl
Ejemplo n.º 13
0
    def jinja(self):
        from ._jinja2_templates import quicklook
        import holoviews as hv
        tmpl = pn.Template(dashboard_html_template)

        data_repo_widget = pn.panel(self.param.data_repository,
                                    show_labels=False)
        data_repo_widget.width = 300
        #        data_repo_row = pn.Row(pn.panel('Data Repository', align='end'),
        #                               data_repo_widget, self._submit_repository)
        data_repo_row = pn.Row(data_repo_widget, self._submit_repository)
        data_repo_row.css_classes = ['data-repo-input']

        query_filter_widget = pn.panel(self.param.query_filter)
        query_filter_widget.width = 260

        new_column_widget = pn.panel(self.param.new_column_expr)
        new_column_widget.width = 260

        datastack_switcher = pn.Row(self._switch_stack)
        datastack_switcher.css_classes = ['stack-switcher']

        view_switcher = pn.Row(self._switch_view)
        view_switcher.css_classes = ['view-switcher']

        clear_button_row = pn.Row(self._clear_metrics_button)

        components = [
            ('metrics_clear_button', clear_button_row),
            ('data_repo_path', data_repo_row),
            ('status_message_queue', self.status_message),
            ('adhoc_js', self.adhoc_js),
            ('infobar', self._info),
            #            ('view_switcher', switcher_row),
            ('stack_switcher', datastack_switcher),
            ('view_switcher', view_switcher),
            ('metrics_selectors', self._metric_layout),
            ('metrics_plots', self._plot_layout),
            ('skyplot_metrics_plots', self.skyplot_layout),
            ('plot_top', self._plot_top),
            ('flags',
             pn.Column(pn.Row(self.flag_filter_select, self.flag_state_select),
                       pn.Row(self.flag_submit),
                       pn.Row(self.flag_filter_selected),
                       pn.Row(self.flag_remove))),
            (
                'query_filter',
                pn.Column(
                    query_filter_widget,
                    pn.Row(self.query_filter_submit, self.query_filter_clear)),
            ),
            (
                'new_column',
                pn.Column(new_column_widget, pn.Row(self.new_column_submit)),
            ),
        ]

        for l, c in components:
            tmpl.add_panel(l, c)

        return tmpl
Ejemplo n.º 14
0
    def instantiate_button(self):
        '''
        '''
        self.button = pn.widgets.Button(name='Save hist-adjusted tifs to disk')
        self.button.on_click(self._save_on_click)

    @param.depends('rgb_scalar', 'red_scalar', 'grn_scalar', 'blu_scalar')
    def serve_plots(self):
        '''
        '''
        arr = self._adjust_array(arr=self.lowres_arr)
        return self._plot_array(arr, self.hist_kwargs)


bands = ('red', 'grn', 'blu')
sources = [rasterio.open(f"geotiffs/1_toa/center_{b}.tif") for b in bands]

tune = Tune(sources=sources)
tune.instantiate_button()

env = Environment(loader=FileSystemLoader('.'))
jinja_template = env.get_template('templates/tune.html')

tmpl = pn.Template(jinja_template)
tmpl.add_variable('app_title', '<h1>Histogram Reference Generator</h1>')
tmpl.add_panel('A', tune.serve_plots)
tmpl.add_panel('B', tune.param)
tmpl.add_panel('C', tune.button)

tmpl.servable()
Ejemplo n.º 15
0
def load_app(config_file):
    pn.config.sizing_mode = 'stretch_both'

    impact_hour_data = read_impact_hour_data()
    # ImpactHoursData
    i = ImpactHoursData()

    # 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'])


    # ImpactHoursFormula
    #impact_hours_rewards = ImpactHoursFormula(i.total_impact_hours, impact_hour_data_1)
    #impact_rewards_view = pn.Column(impact_hours_rewards.impact_hours_rewards,
    # impact_hours_rewards.redeemable,
    # impact_hours_rewards.cultural_build_tribute)

    # Hatch
    cstk_data = read_cstk_data()
    #hatch = Hatch(cstk_data, impact_hours_rewards.target_raise,
    # i.total_impact_hours,
    # impact_hours_rewards.target_impact_hour_rate)

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

    # Import Params Button
    import_params_button = pn.widgets.Button(name='Import params', button_type = 'primary')
    import_description = pn.pane.Markdown('<h4>To import the parameters, click on the button below:</h4>')

    # Share Button
    comments = pn.widgets.TextAreaInput(name='Comments', max_length=1024, placeholder='Explain your thoughts on why you choose the params...')
    share_button = pn.widgets.Button(name='Share your results on GitHub!', button_type = 'primary')
    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')

    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 'hs' in queries:
                t.impact_hour_slope = float(queries['hs'])
            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(results_button)
    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(results_button)
    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 raise (wxDai)", "Maximum raise (wxDai)", "Minimum raise (wxDai)",
            "Impact hour slope (wxDai/IH)", "Maximum impact hour rate (wxDai/IH)",
            "Hatch oracle ratio (wxDai/CSTK)", "Hatch period (days)",
            "Hatch exchange rate (TECH/wxDai)", "Hatch tribute (%)", "Support required (%)",
            "Minimum accepted quorum (%)", "Vote duration (days)", "Vote buffer (hours)",
            "Rage quit (hours)", "Tollgate fee (wxDai)"],
            'Values': [int(t.target_raise), int(t.max_raise),
            int(t.min_raise), t.impact_hour_slope,
            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_view,
                                        t.redeemable_plot),
            pn.Column(dandelion.vote_pass_view, t.funding_pool_view))
            output_pane.save('output.html')
            pn.panel(t.output_scenarios_out_issue().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))

            output_data = """

<h1>Output Charts</h1>

![image]({image_charts})

<h1>Output Scenarios</h1>

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

            parameters_data = """

<h1>Parameters</h1>

{params_table}
            """.format(params_table=df.to_markdown(index=False, floatfmt=",.2f"))

            string_data = """
<h1>Results</h1>

<p>{comments}</p>

- It costs {tollgate_fee_xdai} wxDai to make a proposal.

- Votes will be voted on for {vote_duration_days} days.

- 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 don't vote yes).

- There will be a minimum of {vote_buffer_hours} hours between proposals so people can exit safely in weird edge case scenarios.

- A proposal that passes can be executed {proposal_execution_hours} hours after it was proposed.

- A CSTK Token holder that has 2000 CSTK can send a max of {max_wxdai_ratio} wxDai to the Hatch.

Play with my parameters [here]({url}?ihminr={ihf_minimum_raise}&hs={hour_slope}&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}).

To see the value of your individual Impact Hours, click [here to go to the Hatch Config Dashboard with these parameters]({url}?ihminr={ihf_minimum_raise}&hs={hour_slope}&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}) and explore the Impact Hour Results table.
            """.format(comments=comments.value,
            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),
            hour_slope=t.impact_hour_slope,
            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,
            proposal_execution_hours=dandelion.vote_buffer_hours+dandelion.rage_quit_hours,
            max_wxdai_ratio=int(2000*t.hatch_oracle_ratio),
            url=config_file['url'])

            markdown_panel = pn.pane.Markdown(parameters_data + string_data + output_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(string_data)
            return pn.Row(df.hvplot.table(),markdown_panel)


    pn.state.onload(update_params_by_url_query)

    def help_icon(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="https://forum.tecommons.org/t/tec-test-hatch-implementation-specification/226" target="_blank">
                    <img class="icon" src="http://cdn.onlinewebfonts.com/svg/img_295214.png" />
                </a>
                <span class="tooltiptext">{text}</span>
            </div>
        </div>
        """.format(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]), sizing_mode="fixed", width=30, height=height, align="end"))

    # 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.target_raise, tooltip='target_raise'), 
        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.hatch_tribute_percentage, tooltip='hatch_tribute_percentage'),
        param_with_tooltip(t.param.maximum_impact_hour_rate, tooltip='maximum_impact_hour_rate', height=40),
        param_with_tooltip(t.param.impact_hour_slope, tooltip='impact_hour_slope', height=40),
        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'),
        t.param.action,
        #t.param.target_impact_hour_rate,
        #t.param.target_redeemable,
        #t.param.target_cultural_build_tribute
    ))
    tmpl.add_panel('C', t.funding_pool_data_view)
    tmpl.add_panel('E', t.payout_view)
    tmpl.add_panel('D', pn.Column(t.impact_hours_view, t.redeemable_plot))
    tmpl.add_panel('M', t.trigger_unbalanced_parameters)
    tmpl.add_panel('F', t.funding_pool_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_duration_days, tooltip='vote_duration_days'),
        param_with_tooltip(dandelion.param.vote_buffer_hours, tooltip='vote_buffer_hours'),
        param_with_tooltip(dandelion.param.rage_quit_hours, tooltip='rage_quit_hours'),
        param_with_tooltip(dandelion.param.tollgate_fee_xdai, tooltip='tollgate_fee_xdai'),
        dandelion.param.action
    ))
    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', comments)
    tmpl.add_panel('BU', pn.Column(results_button, share_button, url))
    tmpl.servable(title=config_file['title'])
Ejemplo n.º 16
0


{% endblock %}
"""


def b(event):
    if fileInput.value is not None:
        fig.object = chart_log(fileInput.value)
    else:
        print('Loading...')


text = pn.pane.Str()
fileInput = pn.widgets.FileInput()

button = pn.widgets.Button(name='Parse', button_type='primary')
button.on_click(b)

fig = pn.pane.Plotly()

tmpl = pn.Template(TEMPLATE)
tmpl.add_panel("file_input", fileInput)
tmpl.add_panel("button", button)
tmpl.add_panel("fig", fig)

tmpl.add_panel('text', text)

tmpl.servable()
Ejemplo n.º 17
0
 def setup_template(self, height=600):
     self.tmpl = pn.Template(template=(template % "server"),
                             nb_template=(template % "notebook"))
     self.tmpl.nb_template.globals["get_id"] = make_globally_unique_id
     self.tmpl.add_variable("height", f"{height}px")