mirror of
https://github.com/FlipsideCrypto/eth_activity.git
synced 2026-02-06 10:46:46 +00:00
make it look like a timecard!
This commit is contained in:
parent
166c92e91c
commit
ec5e52c768
BIN
eoa/data.RData
Normal file
BIN
eoa/data.RData
Normal file
Binary file not shown.
305
eoa/global.R
305
eoa/global.R
@ -1,4 +1,3 @@
|
||||
|
||||
library(shinyjs)
|
||||
library(ggplot2)
|
||||
library(dplyr)
|
||||
@ -9,6 +8,11 @@ library(shroomDK)
|
||||
# gitignored - get your own ShroomDK key from Flipside Crypto!
|
||||
api_key <- readLines("api_key.txt")
|
||||
|
||||
|
||||
#423E75 # dark purple
|
||||
#CECBF5 # light purple
|
||||
#0D0C1C # black background
|
||||
|
||||
# EOA Daily History (query updates DAILY) ----
|
||||
|
||||
eoa_daily_history <- fromJSON(
|
||||
@ -29,7 +33,7 @@ eoa_daily_history <- eoa_daily_history %>%
|
||||
# FUNCTIONS ----
|
||||
|
||||
get_tx_by_day <- function(eoa_address, api_key = api_key, ttl = 0){
|
||||
|
||||
|
||||
withProgress(message = "Querying...", detail = "", expr = {
|
||||
|
||||
query <- {
|
||||
@ -47,7 +51,7 @@ get_tx_by_day <- function(eoa_address, api_key = api_key, ttl = 0){
|
||||
x = query, fixed = TRUE)
|
||||
|
||||
incProgress(amount = 0.1,
|
||||
detail = "Query Created")
|
||||
detail = "Query Created")
|
||||
|
||||
query_token <- create_query_token(query = query,
|
||||
api_key = api_key,
|
||||
@ -69,7 +73,7 @@ get_tx_by_day <- function(eoa_address, api_key = api_key, ttl = 0){
|
||||
df <- clean_query(res)
|
||||
|
||||
incProgress(0.5,
|
||||
detail = "Done!")
|
||||
detail = "Done!")
|
||||
|
||||
return(df)
|
||||
})
|
||||
@ -78,157 +82,206 @@ get_tx_by_day <- function(eoa_address, api_key = api_key, ttl = 0){
|
||||
|
||||
plot_eoa <- function(eoadh = eoa_daily_history,
|
||||
user_bar = NULL,
|
||||
title = "ETH Accounts by their Historic Days Active"){
|
||||
|
||||
title = "") {
|
||||
|
||||
eoadh <- eoadh %>% group_by(eoa_bucket) %>%
|
||||
summarise(sum_eoa = sum(EOA_FREQ))
|
||||
|
||||
if(is.null(user_bar)){
|
||||
|
||||
eoa_plotly <- eoadh %>% plot_ly(x = ~eoa_bucket,
|
||||
y = ~sum_eoa/1e6,
|
||||
color = I("#1C6DB8"),
|
||||
type = "bar",
|
||||
hoverinfo = 'text',
|
||||
hovertext = ~paste0(
|
||||
"Days Active: ", eoa_bucket,
|
||||
"\nAddresses: ",
|
||||
scales::label_comma(accuracy = 1)(sum_eoa)))
|
||||
|
||||
} else {
|
||||
# if(is.null(user_bar)){
|
||||
#
|
||||
# eoa_plotly <- eoadh %>%
|
||||
# plot_ly(x = ~eoa_bucket,
|
||||
# y = ~sum_eoa/1e6,
|
||||
# color = I("#696286"),
|
||||
# type = "bar",
|
||||
# hoverinfo = 'text',
|
||||
# hovertext = ~paste0(
|
||||
# "Days Active: ", eoa_bucket,
|
||||
# "\nAddresses: ",
|
||||
# scales::label_comma(accuracy = 1)(sum_eoa)))
|
||||
#
|
||||
# urhere <- list(
|
||||
# x = 0,
|
||||
# y = 0,
|
||||
# text = "",
|
||||
# xref = "x",
|
||||
# yref = "y",
|
||||
# showarrow = FALSE
|
||||
# )
|
||||
#
|
||||
# } else {
|
||||
|
||||
eoadh$lab <- c("Others")
|
||||
eoadh$lab[eoadh$eoa_bucket == user_bar] <- "You"
|
||||
eoadh$lab <- as.factor(eoadh$lab)
|
||||
|
||||
eoa_plotly <- eoadh %>% plot_ly(x = ~eoa_bucket,
|
||||
y = ~sum_eoa/1e6,
|
||||
type = 'bar',
|
||||
color = ~lab,
|
||||
colors = c("#1C6DB8","#d99d45"),
|
||||
hoverinfo = 'text',
|
||||
hovertext = ~paste0(
|
||||
"Days Active: ", eoa_bucket,
|
||||
"\nAddresses: ",
|
||||
scales::label_comma(accuracy = 1)(sum_eoa)))
|
||||
}
|
||||
eoa_plotly <- eoadh %>%
|
||||
plot_ly(x = ~eoa_bucket,
|
||||
y = ~sum_eoa/1e6,
|
||||
type = 'bar',
|
||||
color = ~lab,
|
||||
colors = rev(c("#696286","#9288BA")),
|
||||
hoverinfo = 'text',
|
||||
hovertext = ~paste0(
|
||||
"Days Active: ", eoa_bucket,
|
||||
"\nAddresses: ",
|
||||
scales::label_comma(accuracy = 1)(sum_eoa)))
|
||||
|
||||
urhere <- list(
|
||||
x = user_bar,
|
||||
y = eoadh$sum_eoa[eoadh$lab == "You"]/1000000 + 10,
|
||||
text = "You\n↓",
|
||||
xref = "x",
|
||||
yref = "y",
|
||||
showarrow = FALSE
|
||||
)
|
||||
# }
|
||||
|
||||
|
||||
eoa_plotly <- eoa_plotly %>%
|
||||
layout(title = title,
|
||||
eoa_plotly <-
|
||||
eoa_plotly %>%
|
||||
layout(annotations = urhere,
|
||||
title = title,
|
||||
font = list(
|
||||
family = "Inter",
|
||||
color = 'white'),
|
||||
family = "Roboto Mono",
|
||||
color = '#423E75'),
|
||||
showlegend = FALSE,
|
||||
margin = list(l=35, r=0, b=35, t=0, autoexpand = FALSE),
|
||||
yaxis = list(title = "# Addresses (Millions)",
|
||||
showgrid = FALSE,
|
||||
color = "#FFF"),
|
||||
color = "#423E75"),
|
||||
xaxis = list(title = "Days Active",
|
||||
showticklabels = TRUE,
|
||||
color = "#FFF"),
|
||||
color = "#423E75"),
|
||||
plot_bgcolor = "transparent",
|
||||
paper_bgcolor = "transparent",
|
||||
legend = list(font = list(color = '#FFFFFF')),
|
||||
hovermode = 'x') %>%
|
||||
plotly::config(scrollZoom = FALSE,
|
||||
displayModeBar = FALSE,
|
||||
displaylogo = FALSE)
|
||||
displayModeBar = FALSE,
|
||||
displaylogo = FALSE)
|
||||
|
||||
return(eoa_plotly)
|
||||
|
||||
}
|
||||
|
||||
plot_tx <- function(eoa_tx){
|
||||
|
||||
maxdate <- Sys.Date()
|
||||
mindate <- Sys.Date() - 391
|
||||
|
||||
d <- data.frame(
|
||||
dates_in_year = seq.Date(mindate, maxdate, by = 'day')
|
||||
plot_tx <- function(eoa_tx) {
|
||||
|
||||
maxdate <- Sys.Date()
|
||||
mindate <- Sys.Date() - 391
|
||||
|
||||
d <- data.frame(
|
||||
date = seq.Date(mindate, maxdate, by = 'day')
|
||||
)
|
||||
|
||||
d$month <- format(d$date, '%b')
|
||||
d$day <- weekdays(d$date)
|
||||
|
||||
# start on Monday
|
||||
d <- d[which(d$day == "Monday")[1]:length(d$day), ]
|
||||
d$week <- ceiling(nrow(d)/7) # fill last week number *
|
||||
# infill previous weeks (1,1,1,1,1,1,1,2,2,2,2,2,2,2,.... N,N,N,N,N,N,N,*)
|
||||
fillweek = floor(nrow(d)/7)*7
|
||||
d$week[1:fillweek] <- unlist(lapply(1:(nrow(d)/7), replicate, n = 7))
|
||||
|
||||
|
||||
data <- merge(d, eoa_tx, by = "date", all.x = TRUE)
|
||||
data <- data[, c("date","week","month", "day", "NUM_TX")]
|
||||
data$NUM_TX[is.na(data$NUM_TX)] <- 0
|
||||
|
||||
monthlabel = data %>%
|
||||
group_by(month) %>%
|
||||
summarise(w1 = first(week)) %>%
|
||||
dplyr::arrange(w1)
|
||||
|
||||
data$day <- toupper(substr(data$day, 1, 3))
|
||||
data$day <- ordered(data$day,
|
||||
levels = c("MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"),
|
||||
labels = c("Mon", "Tues", "Wed", "Thurs", "Fri", "Sat", "Sun"))
|
||||
|
||||
|
||||
#colfunc <- colorRampPalette(c("#C8B1F2", "#696286"))
|
||||
colfunc <- colorRampPalette(c("#C8B1F2", "#4F4A59"))
|
||||
|
||||
data[data$NUM_TX == 0,]$NUM_TX <- 0.01
|
||||
|
||||
hline <- function(y = 0, color = "grey") {
|
||||
list(
|
||||
type = "line",
|
||||
x0 = 0,
|
||||
x1 = 1,
|
||||
xref = "paper",
|
||||
y0 = y,
|
||||
y1 = y,
|
||||
line = list(color = color, width = 0.5)
|
||||
)
|
||||
|
||||
d$month <- format(d$dates_in_year, '%b')
|
||||
d$day <- weekdays(d$dates_in_year)
|
||||
|
||||
# start on Monday
|
||||
d <- d[which(d$day == "Monday")[1]:length(d$day), ]
|
||||
d$week <- ceiling(nrow(d)/7) # fill last week number *
|
||||
# infill previous weeks (1,1,1,1,1,1,1,2,2,2,2,2,2,2,.... N,N,N,N,N,N,N,*)
|
||||
fillweek = floor(nrow(d)/7)*7
|
||||
d$week[1:fillweek] <- unlist(lapply(1:(nrow(d)/7), replicate, n = 7))
|
||||
|
||||
|
||||
data <- merge(d, eoa_tx, by.x = "dates_in_year", by.y = "date", all.x = TRUE)
|
||||
data <- data[, c("dates_in_year","week","month", "day", "NUM_TX")]
|
||||
data$NUM_TX[is.na(data$NUM_TX)] <- 0
|
||||
|
||||
monthlabel = data %>%
|
||||
group_by(month) %>%
|
||||
summarise(w1 = first(week)) %>%
|
||||
dplyr::arrange(w1)
|
||||
|
||||
p <- plot_ly(data = data)
|
||||
p <- add_heatmap(p = p, x = ~week,
|
||||
y = ~day,
|
||||
z = ~NUM_TX*5, # scale up for better coloring
|
||||
text = paste0(
|
||||
data$day,", ",
|
||||
data$dates_in_year,
|
||||
"\nTransactions:",
|
||||
data$NUM_TX
|
||||
),
|
||||
colors = 'Blues',
|
||||
zauto = FALSE,
|
||||
zmax = 50,
|
||||
zmin = 0,
|
||||
hoverinfo = 'text',
|
||||
xgap = 3,
|
||||
ygap = 3,
|
||||
showscale = FALSE)
|
||||
|
||||
p %>% layout(title = "Year in Review",
|
||||
font = list(
|
||||
family = "Inter",
|
||||
color = 'white'),
|
||||
plot_bgcolor = "transparent",
|
||||
paper_bgcolor = "transparent",
|
||||
yaxis=list(
|
||||
showline = FALSE,
|
||||
color = "#FFF",
|
||||
showgrid = FALSE,
|
||||
zeroline = FALSE,
|
||||
tickmode="array",
|
||||
ticktext=data$day[1:7],
|
||||
tickvals=c(0,1,2,3,4,5,6),
|
||||
title="",
|
||||
autorange = 'reversed'
|
||||
),
|
||||
xaxis= list(
|
||||
showline = FALSE,
|
||||
showgrid = FALSE,
|
||||
zeroline = FALSE,
|
||||
color = "#FFF",
|
||||
ticktext = c(monthlabel$month,monthlabel$month[1]),
|
||||
tickvals = c(monthlabel$w1, max(monthlabel$w1)+4),
|
||||
title = ""
|
||||
)) %>%
|
||||
plotly::config(scrollZoom = FALSE,
|
||||
displayModeBar = FALSE,
|
||||
displaylogo = FALSE)
|
||||
}
|
||||
|
||||
plot_ly(data,
|
||||
x = ~week,
|
||||
y = ~day,
|
||||
marker = list(size = ~NUM_TX*5,
|
||||
color = "#423E75",
|
||||
line = list(width = 0, color = "#423E75")
|
||||
),
|
||||
#name = ~address_name,
|
||||
text = paste0(
|
||||
data$day,", ",
|
||||
data$date,
|
||||
"\nTransactions:",
|
||||
round(data$NUM_TX)
|
||||
),
|
||||
hoverinfo = 'text',
|
||||
type = 'scatter', mode = "markers") %>%
|
||||
layout(
|
||||
shapes = list(hline(-0.5), hline(0.5), hline(1.5), hline(2.5), hline(3.5), hline(4.5), hline(5.5), hline(6.5)),
|
||||
font = list(
|
||||
family = "Roboto Mono",
|
||||
color = "#423E75"),
|
||||
plot_bgcolor = "transparent",
|
||||
paper_bgcolor = "transparent",
|
||||
margin = list(l=20, r=0, b=20, t=0, autoexpand = FALSE),
|
||||
yaxis=list(
|
||||
showline = FALSE,
|
||||
ticklen = 0,
|
||||
tickwidth = 0,
|
||||
color = "#423E75",
|
||||
showgrid = FALSE,
|
||||
zeroline = FALSE,
|
||||
tickmode="array",
|
||||
#tickvals=c(0,1,2,3,4,5,6),
|
||||
title="",
|
||||
autorange = 'reversed',
|
||||
tickangle = 270
|
||||
),
|
||||
xaxis= list(
|
||||
showline = FALSE,
|
||||
showgrid = FALSE,
|
||||
zeroline = FALSE,
|
||||
color = "#423E75",
|
||||
ticklen = 0,
|
||||
tickwidth = 0,
|
||||
ticktext = c(monthlabel$month,monthlabel$month[1]),
|
||||
tickvals = c(monthlabel$w1, max(monthlabel$w1)+4),
|
||||
title = ""
|
||||
)) %>%
|
||||
plotly::config(scrollZoom = FALSE,
|
||||
displayModeBar = FALSE,
|
||||
displaylogo = FALSE)
|
||||
|
||||
}
|
||||
|
||||
card_eoa <- function(card_value, card_label){
|
||||
# Creates a card using html
|
||||
HTML(
|
||||
paste0(
|
||||
'<div class="card">
|
||||
# Creates a card using html
|
||||
HTML(
|
||||
paste0(
|
||||
'<div class="card">
|
||||
<div class="card-body">
|
||||
<p class="card-value">',
|
||||
card_value,
|
||||
'</p><p class="card-label">',
|
||||
card_label,
|
||||
'</p></div></div>'
|
||||
card_value,
|
||||
'</p><p class="card-label">',
|
||||
card_label,
|
||||
'</p></div></div>'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
127
eoa/server.R
127
eoa/server.R
@ -2,81 +2,96 @@ library(shiny)
|
||||
source("global.R")
|
||||
# Define server logic
|
||||
shinyServer(function(input, output, session) {
|
||||
|
||||
results <- eventReactive(input$submit, {
|
||||
|
||||
results <- reactiveValues()
|
||||
|
||||
onclick(id = "go-button", expr = {
|
||||
|
||||
if(nchar(input$address) != 42 | !grepl("^0x", input$address)){
|
||||
stop("Double check address is a valid ETH address (not ENS)")
|
||||
|
||||
} else {
|
||||
x <- get_tx_by_day(eoa_address = input$address,
|
||||
x <- get_tx_by_day(eoa_address = input$address,
|
||||
api_key = readLines("api_key.txt"),
|
||||
ttl = 0)
|
||||
x$date <- as.Date(x$DAY_)
|
||||
return(x)
|
||||
x$date <- as.Date(x$DAY_)
|
||||
results$table <- x
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
observe({
|
||||
rr <<- results()
|
||||
})
|
||||
|
||||
|
||||
eoa_stats <- reactive({
|
||||
|
||||
da <- length(unique(results()$date))
|
||||
|
||||
eoa_activity <- list(
|
||||
"Transactions" = sum(results()$NUM_TX),
|
||||
"Days Active" = da,
|
||||
"Total Tx Fees" = paste0(round(sum(results()$FEES_PAID),2), ' Ξ')
|
||||
"txn" = sum(results$table$NUM_TX),
|
||||
"days" = length(unique(results$table$date)),
|
||||
"fees" = paste0(round(sum(results$table$FEES_PAID),2), ' Ξ')
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
output$title <- renderUI({
|
||||
|
||||
da <- eoa_stats()[["Days Active"]]
|
||||
|
||||
percent <- {
|
||||
round(
|
||||
100*(eoa_daily_history[eoa_daily_history$UNIQUE_DAYS == da, "eoa_cumprop"]),
|
||||
2)
|
||||
}
|
||||
|
||||
tagList(
|
||||
div(class = 'chart-title', span(
|
||||
paste0("You're more active than ", percent, "% of ETH users!")
|
||||
)))
|
||||
|
||||
output$ntxn <- renderText(ifelse(eoa_stats()$txn > 0, eoa_stats()$txn, ""))
|
||||
output$days <- renderText(ifelse(eoa_stats()$days > 0, eoa_stats()$days, ""))
|
||||
output$fees <- renderText(ifelse(eoa_stats()$fees != '0 Ξ', eoa_stats()$fees, ""))
|
||||
|
||||
|
||||
output$median_days <- renderText(ifelse(eoa_stats()$txn > 0, "<1 day", ""))
|
||||
output$percentile <- renderText({
|
||||
round(
|
||||
100*(eoa_daily_history[eoa_daily_history$UNIQUE_DAYS == eoa_stats()$days, "eoa_cumprop"]),
|
||||
2)
|
||||
})
|
||||
|
||||
output$compare <- renderUI({
|
||||
tagList(
|
||||
lapply(names(eoa_stats()),
|
||||
FUN = function(x){card_eoa(eoa_stats()[[x]], x)})
|
||||
)
|
||||
})
|
||||
# output$title <- renderUI({
|
||||
#
|
||||
# da <- eoa_stats()$days
|
||||
#
|
||||
# percent <- {
|
||||
# round(
|
||||
# 100*(eoa_daily_history[eoa_daily_history$UNIQUE_DAYS == da, "eoa_cumprop"]),
|
||||
# 2)
|
||||
# }
|
||||
#
|
||||
# tagList(
|
||||
# div(class = 'chart-title', span(
|
||||
# paste0("You've shown up more than ", percent, "% of ETH users")
|
||||
# )))
|
||||
#
|
||||
# })
|
||||
|
||||
# output$compare <- renderUI({
|
||||
# tagList(
|
||||
# lapply(names(eoa_stats()),
|
||||
# FUN = function(x){card_eoa(eoa_stats()[[x]], x)})
|
||||
# )
|
||||
# })
|
||||
|
||||
# plot_ <- reactive({
|
||||
#
|
||||
# if(input$submit == 0){
|
||||
# plot_eoa(eoadh = eoa_daily_history)
|
||||
#
|
||||
# } else {
|
||||
#
|
||||
# x = cut(as.numeric(eoa_stats()[["Days Active"]]),
|
||||
# breaks = c(0, 1,10,100,1000, Inf),
|
||||
# labels = c("1","2-10","11-100","101-1000","1001+"))
|
||||
#
|
||||
# plot_eoa(eoadh = eoa_daily_history, x)
|
||||
# }
|
||||
# })
|
||||
|
||||
plot_ <- reactive({
|
||||
|
||||
if(input$submit == 0){
|
||||
plot_eoa(eoadh = eoa_daily_history)
|
||||
|
||||
} else {
|
||||
|
||||
x = cut(as.numeric(eoa_stats()[["Days Active"]]),
|
||||
breaks = c(0, 1,10,100,1000, Inf),
|
||||
labels = c("1","2-10","11-100","101-1000","1001+"))
|
||||
|
||||
plot_eoa(eoadh = eoa_daily_history, x)
|
||||
}
|
||||
})
|
||||
|
||||
output$main_plot <- renderPlotly({
|
||||
plot_()
|
||||
x = cut(as.numeric(eoa_stats()$txn),
|
||||
breaks = c(0, 1,10,100,1000, Inf),
|
||||
labels = c("1","2-10","11-100","101-1000","1001+"))
|
||||
plot_eoa(eoadh = eoa_daily_history, user_bar = x)
|
||||
})
|
||||
|
||||
output$heatmap <- renderUI({
|
||||
renderPlotly(plot_tx(results()))
|
||||
})
|
||||
|
||||
output$heatmap <- renderPlotly(plot_tx(results$table))
|
||||
|
||||
# output$heatmap <- renderUI({
|
||||
# renderPlotly(plot_tx(results()))
|
||||
# })
|
||||
|
||||
})
|
||||
|
||||
223
eoa/ui.R
223
eoa/ui.R
@ -4,104 +4,135 @@ source("global.R")
|
||||
# Define UI -------
|
||||
|
||||
shinyUI(fluidPage(
|
||||
title = 'ETH Activity',
|
||||
useShinyjs(),
|
||||
|
||||
tags$head(
|
||||
tags$link(rel = 'stylesheet', type = 'text/css', href = 'styles.css'),
|
||||
tags$link(rel = 'stylesheet', href = 'https://fonts.googleapis.com/css?family=Roboto+Mono'),
|
||||
tags$link(rel = 'stylesheet', href = 'https://fonts.googleapis.com/css?family=Inter')
|
||||
),
|
||||
tags$head(tags$script(src = 'rudderstack.js')),
|
||||
tags$style(type='text/css',
|
||||
'.shiny-output-error { visibility: hidden; }',
|
||||
'.shiny-output-error:before { visibility: hidden; }'
|
||||
),
|
||||
|
||||
withTags({
|
||||
header(class='top-banner',
|
||||
section(
|
||||
a(class='fs-logo', href='https://www.flipsidecrypto.com',
|
||||
'Powered by Flipside Crypto', onclick = 'rudderstack.track("ntr-click-flipside-icon")'),
|
||||
section(class='socials',
|
||||
a(class='twitter', href='https://twitter.com/flipsidecrypto',
|
||||
'Twitter', onclick = 'rudderstack.track("ntr-click-twitter-icon")'),
|
||||
a(class='linkedin', href='https://www.linkedin.com/company/flipside-crypto',
|
||||
'LinkedIn', onclick = 'rudderstack.track("ntr-click-linkedin-icon")'),
|
||||
a(class='discord', href='https://flipsidecrypto.com/discord',
|
||||
'Discord', onclick = 'rudderstack.track("ntr-click-discord-icon")'),
|
||||
a(href='https://app.flipsidecrypto.com/auth/signup/', # redirects to xyz signup
|
||||
'Sign Up', onclick = 'rudderstack.track("ntr-click-signup-icon")')
|
||||
)
|
||||
title = 'Ethereum Dedication',
|
||||
useShinyjs(),
|
||||
|
||||
tags$head(
|
||||
tags$link(rel = 'stylesheet', type = 'text/css', href = 'styles.css'),
|
||||
tags$link(rel = 'stylesheet', href = 'https://fonts.googleapis.com/css?family=Roboto+Mono'),
|
||||
tags$link(rel = 'stylesheet', href = 'https://fonts.googleapis.com/css?family=Inter'),
|
||||
tags$link(rel = 'stylesheet', href = 'https://fonts.googleapis.com/css?family=Architects+Daughter')
|
||||
),
|
||||
tags$head(tags$script(src = 'rudderstack.js')),
|
||||
tags$style(type='text/css',
|
||||
'.shiny-output-error { visibility: hidden; }',
|
||||
'.shiny-output-error:before { visibility: hidden; }'
|
||||
),
|
||||
|
||||
withTags({
|
||||
header(class='top-banner',
|
||||
section(
|
||||
a(class='fs-logo', href='https://www.flipsidecrypto.com',
|
||||
'Powered by Flipside Crypto', onclick = 'rudderstack.track("ntr-click-flipside-icon")'),
|
||||
section(class='socials',
|
||||
a(class='twitter', href='https://twitter.com/flipsidecrypto',
|
||||
'Twitter', onclick = 'rudderstack.track("ntr-click-twitter-icon")'),
|
||||
a(class='linkedin', href='https://www.linkedin.com/company/flipside-crypto',
|
||||
'LinkedIn', onclick = 'rudderstack.track("ntr-click-linkedin-icon")'),
|
||||
a(class='discord', href='https://flipsidecrypto.com/discord',
|
||||
'Discord', onclick = 'rudderstack.track("ntr-click-discord-icon")'),
|
||||
a(href='https://app.flipsidecrypto.com/auth/signup/', # redirects to xyz signup
|
||||
'Sign Up', onclick = 'rudderstack.track("ntr-click-signup-icon")')
|
||||
)
|
||||
)
|
||||
}),
|
||||
|
||||
# APP LABEL HERE -----------------------------------
|
||||
|
||||
withTags({
|
||||
section(class='hero',
|
||||
h1(
|
||||
class='header',
|
||||
'ETH Activity',
|
||||
),
|
||||
p('Search your address to get stats on your activity'),
|
||||
)
|
||||
}),
|
||||
|
||||
# APP START HERE -----------------------------------
|
||||
|
||||
div(class = 'chart-block',
|
||||
fluidRow(
|
||||
column(10,
|
||||
textInput(inputId = "address", label = "",
|
||||
placeholder = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
|
||||
width = '90%')),
|
||||
column(2, class = 'eoa-btn',
|
||||
actionButton("submit", label = "Search", width = '90%'))
|
||||
)
|
||||
),
|
||||
|
||||
div(
|
||||
class = 'chart-container',
|
||||
div(
|
||||
class = 'chart-block',
|
||||
div(class = 'chart',
|
||||
conditionalPanel("input.submit > 0",
|
||||
uiOutput('title')
|
||||
),
|
||||
fluidRow(
|
||||
column(3,
|
||||
conditionalPanel("input.submit > 0",
|
||||
div(class = 'eoa-tbl',
|
||||
uiOutput('compare'))
|
||||
)),
|
||||
column(9,
|
||||
div(class = 'heat',
|
||||
conditionalPanel("input.submit > 0",
|
||||
uiOutput('heatmap'))
|
||||
)
|
||||
)
|
||||
),
|
||||
br(),
|
||||
plotlyOutput("main_plot")
|
||||
)
|
||||
)
|
||||
),
|
||||
div(class = "about",
|
||||
h3("About"),
|
||||
br(),
|
||||
HTML(
|
||||
paste0(
|
||||
"Built w/ ❤️ by the team at Flipside Crypto. Powered by ",
|
||||
"<u><a href = 'https://sdk.flipsidecrypto.xyz/shroomdk'>ShroomDK</a></u>"
|
||||
)),
|
||||
p("Have a feature request, or want to build using Flipside's free data?"),
|
||||
HTML(
|
||||
paste0("Join us in ","<u><a href = 'https://flipsidecrypto.com/discord'>Discord</a></u>")
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
}),
|
||||
|
||||
div(class = "timecard-holder",
|
||||
fluidRow(class='solid',
|
||||
div(class='title', 'Ethereum Dedication'),
|
||||
div(class = "subtitle", 'Your Onchain Timecard'),
|
||||
),
|
||||
br(),
|
||||
fluidRow(class = "address-row",
|
||||
column(9, class = 'light-left',
|
||||
div(style = "height: 60px", # sorry for the inline styling, it's just easier this way :crying:
|
||||
"Address",
|
||||
textInput(inputId = "address",
|
||||
label = NULL,
|
||||
#value = default.address,
|
||||
placeholder = "enter a full address (non-ens)",
|
||||
width = '400px'))
|
||||
),
|
||||
column(3, class = 'light-right', id = "go-button",
|
||||
div(style = "height: 60px; width: 100%",
|
||||
"Fill",
|
||||
div(id = "click", "CLICK"))
|
||||
#actionButton("submit", label = "FILL"))
|
||||
) # close column 3
|
||||
), # close row
|
||||
|
||||
fluidRow(
|
||||
column(4, class = 'light-left',
|
||||
div(style = "height: 60px; width: 100%",
|
||||
"# Txn.", div(class = "show-result", textOutput("ntxn")))),
|
||||
column(4, class = 'light-left',
|
||||
div(style = "height: 60px; width: 100%",
|
||||
"Days Active", div(class = "show-result", textOutput("days")))),
|
||||
column(4, class = 'light-left',
|
||||
div(style = "height: 60px; width: 100%",
|
||||
"Fees Ξ", div(class = "show-result", textOutput("fees"))))
|
||||
),
|
||||
|
||||
fluidRow(
|
||||
column(12,class = "light-left",
|
||||
div(style = "width: 100%",
|
||||
div("Daily Punchcard"), br(),
|
||||
plotlyOutput('heatmap', width = "100%", height = "300px")
|
||||
), br(),
|
||||
)
|
||||
),
|
||||
fluidRow(class='solid',
|
||||
div(class = "subtitle", 'You vs. Everyone Else'),
|
||||
),
|
||||
|
||||
fluidRow(
|
||||
column(6, class = 'light-left',
|
||||
div(style = "height: 60px; width: 100%",
|
||||
"Days Active: Chain Median", div(class = "show-result", textOutput("median_days")))),
|
||||
column(6, class = 'light-left',
|
||||
div(style = "height: 60px; width: 100%",
|
||||
"Your Percentile", div(class = "show-result", textOutput("percentile"))))
|
||||
),
|
||||
|
||||
fluidRow(
|
||||
column(12,class = "light-left",
|
||||
div(style = "width: 100%",
|
||||
div("Active Days"),
|
||||
plotlyOutput('main_plot', width = "100%", height = "300px")
|
||||
),
|
||||
br()
|
||||
)
|
||||
),
|
||||
|
||||
fluidRow(class='solid',
|
||||
div(class = "subtitle", 'About this Timecard'),
|
||||
),
|
||||
fluidRow(
|
||||
column(6, class = 'light-left',
|
||||
div(style = "height: 60px; width: 100%",
|
||||
HTML(
|
||||
paste0(
|
||||
"Built w/ ❤️ by the team at Flipside Crypto. Powered by ",
|
||||
"<u><a href = 'https://sdk.flipsidecrypto.xyz/shroomdk'>ShroomDK</a></u>"
|
||||
))
|
||||
)),
|
||||
column(6, class = 'light-right',
|
||||
div(style = "height: 60px; width: 100%",
|
||||
p("Part 1 of our mission to clock you onchain. What do you want to know about yourself?"),
|
||||
))
|
||||
),
|
||||
fluidRow(
|
||||
column(12, class = 'light-left',
|
||||
div(style = "height: 60px; width: 100%, text-align: center",
|
||||
HTML(
|
||||
paste0("Join us in ","<u><a href = 'https://flipsidecrypto.com/discord'>Discord</a></u>")
|
||||
)
|
||||
))
|
||||
)
|
||||
|
||||
) # close timecard-holder div
|
||||
|
||||
) # end FluidPage
|
||||
) # end shinyUI
|
||||
|
||||
|
||||
@ -3,54 +3,90 @@
|
||||
/*PUT CUSTOM CLASSES HERE*/
|
||||
/*******************/
|
||||
|
||||
.row {
|
||||
margin: 0;
|
||||
}
|
||||
.timecard-holder {
|
||||
background-color: #CECBF5;
|
||||
margin-top: 30px;
|
||||
width: 100%;
|
||||
}
|
||||
.solid {
|
||||
background-color: #423E75;
|
||||
color: #CECBF5;
|
||||
}
|
||||
|
||||
.light-left {
|
||||
color: #423E75;
|
||||
border-style: solid;
|
||||
border-color: #423E75;
|
||||
border-width: 1px 1px 1px 1px;
|
||||
}
|
||||
|
||||
.light-right {
|
||||
color: #423E75;
|
||||
border-style: solid;
|
||||
border-color: #423E75;
|
||||
border-width: 1px 1px 1px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: #CECBF5;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
text-align: center;
|
||||
color: #CECBF5;
|
||||
font-size: 1.2em;
|
||||
font-family: 'Roboto Mono', sans-serif;
|
||||
}
|
||||
|
||||
#address::placeholder {
|
||||
color: #62616D;
|
||||
}
|
||||
#go-button {
|
||||
cursor: pointer;
|
||||
}
|
||||
#click {
|
||||
text-align: center;
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
|
||||
.show-result {
|
||||
text-align: center;
|
||||
font-family: Architects Daughter, sans-serif;
|
||||
font-size: 2em;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.heatmap {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.about {
|
||||
margin: auto;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: #03FFFF;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.about {
|
||||
margin: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.eoa-tbl {
|
||||
margin-top: 30%;
|
||||
}
|
||||
|
||||
.eoa-btn {
|
||||
padding-right: 30px;
|
||||
}
|
||||
|
||||
#submit {
|
||||
background: #000000;
|
||||
color: #FFFFFF;
|
||||
border: 1px solid #03FFFF;
|
||||
margin: 20px 0px 0px 0px;
|
||||
.chart-title {
|
||||
font-family: Inter;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-size: 20px;
|
||||
line-height: 150%;
|
||||
color: white;
|
||||
padding: 32px 32px 20px;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
width: 90%;
|
||||
height: 90%;
|
||||
background-color: #1C6DB8;
|
||||
border-radius: 4px;
|
||||
margin: 3px;
|
||||
margin-bottom: 10px;
|
||||
padding: 3px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.card-value {
|
||||
text-align: center;
|
||||
font-size: 25px;
|
||||
}
|
||||
.card-label {
|
||||
text-align: center;
|
||||
font-size: 15px;
|
||||
.chart {
|
||||
border-radius: 4px;
|
||||
padding: 0 32px 14px;
|
||||
background: rgb(60,47,110);
|
||||
background: linear-gradient(180deg, rgba(60,47,110,1) 0%, rgba(13,12,28,1) 67%);
|
||||
}
|
||||
|
||||
|
||||
@ -59,14 +95,14 @@ text-align: center;
|
||||
/*******************/
|
||||
|
||||
body {
|
||||
background-color: #10151A;
|
||||
background-color: #0D0C1C;
|
||||
background-attachment:fixed;
|
||||
background-size: auto 100%;
|
||||
background-position: center;
|
||||
padding-left: 10%;
|
||||
padding-right: 10%;
|
||||
font-family: 'Inter';
|
||||
color: #FFFFFF;
|
||||
font-family: 'Roboto Mono';
|
||||
color: #423E75;
|
||||
padding-bottom: 6rem;
|
||||
}
|
||||
|
||||
@ -77,20 +113,99 @@ a {
|
||||
|
||||
hr {
|
||||
margin: 2%;
|
||||
background: #10151A;
|
||||
background: #0D0C1C;
|
||||
opacity: 0.5;
|
||||
border: 1px solid #637381;
|
||||
border: 1px solid #AB9AE8;
|
||||
}
|
||||
|
||||
.container-fluid {
|
||||
background-color: #10151A;
|
||||
max-width: 1000px;
|
||||
background-color: #0D0C1C;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
height: 100%;
|
||||
padding-top: 48px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
|
||||
/*****************/
|
||||
/* GENERAL Forms */
|
||||
/*****************/
|
||||
|
||||
|
||||
.form-control {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
box-shadow: inset 0 0 0 rgb(0 0 0 / 0%);
|
||||
color: black;
|
||||
|
||||
}
|
||||
.form-group {
|
||||
margin: 0;
|
||||
}
|
||||
input::-webkit-box-shadow {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
input::-webkit-outer-spin-button,
|
||||
input::-webkit-inner-spin-button {
|
||||
|
||||
margin: 0;
|
||||
}
|
||||
input[type=number] {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/******************/
|
||||
/* REACTABLE Tables */
|
||||
/******************/
|
||||
|
||||
.rt-page-button-current {
|
||||
color: #FFF;
|
||||
}
|
||||
.rt-thead {
|
||||
background-color: #0D0C1C;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.ReactTable {
|
||||
background-color: #171e25;
|
||||
color: #C4CDD5;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.rt-th {
|
||||
border: 0px solid #000000 !important;
|
||||
padding-top: 15px;
|
||||
padding-bottom: 15px;
|
||||
font-weight: 400;
|
||||
font-family: Inter;
|
||||
}
|
||||
.rt-tr {
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
.rt-pagination {
|
||||
margin: 0;
|
||||
background: #171e25;
|
||||
opacity: 0.5;
|
||||
border-bottom: 1px solid #C4CDD5;
|
||||
border-top: 1px solid #C4CDD5;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/******************/
|
||||
/* Header Bar */
|
||||
/******************/
|
||||
@ -154,120 +269,4 @@ hr {
|
||||
.discord {
|
||||
background: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10.2354 11.1801C10.0175 11.1617 9.79902 11.2095 9.60868 11.3172C9.41833 11.425 9.26496 11.5877 9.16863 11.7841C9.07229 11.9804 9.0375 12.2013 9.06879 12.4178C9.10008 12.6343 9.19601 12.8363 9.34401 12.9973C9.492 13.1584 9.68518 13.271 9.89825 13.3205C10.1113 13.3699 10.3344 13.3539 10.5382 13.2744C10.742 13.195 10.917 13.0559 11.0405 12.8753C11.1639 12.6948 11.2299 12.4811 11.2299 12.2624C11.2358 12.126 11.2147 11.9898 11.1678 11.8616C11.121 11.7334 11.0493 11.6157 10.957 11.5151C10.8646 11.4146 10.7533 11.3333 10.6295 11.2758C10.5057 11.2184 10.3718 11.1858 10.2354 11.1801ZM13.7942 11.1801C13.5762 11.1617 13.3578 11.2095 13.1674 11.3172C12.9771 11.425 12.8237 11.5877 12.7274 11.7841C12.631 11.9804 12.5962 12.2013 12.6275 12.4178C12.6588 12.6343 12.7548 12.8363 12.9028 12.9973C13.0508 13.1584 13.2439 13.271 13.457 13.3205C13.6701 13.3699 13.8931 13.3539 14.0969 13.2744C14.3007 13.195 14.4758 13.0559 14.5992 12.8753C14.7226 12.6948 14.7887 12.4811 14.7887 12.2624C14.7945 12.126 14.7734 11.9898 14.7266 11.8616C14.6797 11.7334 14.6081 11.6157 14.5157 11.5151C14.4234 11.4146 14.3121 11.3333 14.1883 11.2758C14.0645 11.2184 13.9306 11.1858 13.7942 11.1801Z' fill='%23F4F6F8'/%3E%3Cpath d='M18.5325 3H5.46751C5.20438 3.00063 4.94396 3.05308 4.70111 3.15436C4.45826 3.25564 4.23774 3.40376 4.05213 3.59027C3.86653 3.77678 3.71948 3.99802 3.61939 4.24136C3.51929 4.4847 3.46811 4.74538 3.46876 5.0085V18.1905C3.46811 18.4536 3.51929 18.7143 3.61939 18.9576C3.71948 19.201 3.86653 19.4222 4.05213 19.6087C4.23774 19.7952 4.45826 19.9434 4.70111 20.0446C4.94396 20.1459 5.20438 20.1984 5.46751 20.199H16.524L16.0073 18.3953L17.2553 19.5555L18.435 20.6475L20.5313 22.5V5.0085C20.5319 4.74538 20.4807 4.4847 20.3806 4.24136C20.2805 3.99802 20.1335 3.77678 19.9479 3.59027C19.7623 3.40376 19.5418 3.25564 19.2989 3.15436C19.0561 3.05308 18.7956 3.00063 18.5325 3ZM14.769 15.7335C14.769 15.7335 14.418 15.3142 14.1255 14.9437C14.8322 14.7774 15.4573 14.3664 15.8903 13.7835C15.5394 14.017 15.1633 14.21 14.769 14.3588C14.3154 14.5524 13.8411 14.693 13.3553 14.778C12.5202 14.9317 11.6638 14.9284 10.83 14.7682C10.3405 14.6725 9.86073 14.5321 9.39676 14.349C9.15219 14.255 8.91437 14.1442 8.68501 14.0175C8.65576 13.998 8.62651 13.9882 8.59726 13.9688C8.58259 13.9614 8.56937 13.9515 8.55826 13.9395C8.38276 13.842 8.28526 13.7738 8.28526 13.7738C8.70251 14.3444 9.30604 14.7514 9.99151 14.9242C9.69901 15.2948 9.33826 15.7335 9.33826 15.7335C8.75909 15.7491 8.18497 15.6221 7.66642 15.3636C7.14787 15.1052 6.70078 14.7233 6.36451 14.2515C6.39616 12.2749 6.87623 10.3313 7.76851 8.56725C8.55372 7.95055 9.51103 7.59283 10.5083 7.5435L10.6058 7.6605C9.66755 7.89268 8.79203 8.32877 8.04151 8.93775C8.04151 8.93775 8.25601 8.82075 8.61676 8.655C9.3176 8.33509 10.0645 8.12779 10.83 8.04075C10.8846 8.02945 10.94 8.02293 10.9958 8.02125C11.6491 7.93613 12.3103 7.92958 12.9653 8.00175C13.9952 8.11938 14.9922 8.43735 15.9 8.93775C15.1875 8.3578 14.36 7.93574 13.4723 7.6995L13.6088 7.5435C14.606 7.59283 15.5633 7.95055 16.3485 8.56725C17.2408 10.3313 17.7209 12.2749 17.7525 14.2515C17.4135 14.7229 16.9645 15.1043 16.4446 15.3625C15.9246 15.6208 15.3494 15.7482 14.769 15.7335Z' fill='%23F4F6F8'/%3E%3C/svg%3E%0A") no-repeat center center;
|
||||
}
|
||||
.hero {
|
||||
margin: 1.5em 0;
|
||||
text-align: center;
|
||||
}
|
||||
.hero > p {
|
||||
color: #E5E5E5;
|
||||
font-size: 20px;
|
||||
margin-top: 1em;
|
||||
}
|
||||
.header {
|
||||
margin: 0;
|
||||
color: #03FFFF;
|
||||
font-family: 'Inter', sans-serif;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
/*****************/
|
||||
/* GENERAL Forms */
|
||||
/*****************/
|
||||
|
||||
|
||||
.form-control {
|
||||
background: #000000;
|
||||
border: 1px solid #03FFFF;
|
||||
border-radius: 4px;
|
||||
margin-left: 20px;
|
||||
font-family: Roboto Mono !important;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
input::-webkit-outer-spin-button,
|
||||
input::-webkit-inner-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
input[type=number] {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
|
||||
|
||||
/******************/
|
||||
/* GENERAL Charts */
|
||||
/******************/
|
||||
.chart-block {
|
||||
background: #171E25;
|
||||
border: 2px solid rgba(45, 109, 135, 0.5);
|
||||
border-radius: 16px;
|
||||
}
|
||||
.chart-block > .row > .col-sm-6 {
|
||||
padding: 0;
|
||||
}
|
||||
.col-sm-6 > .chart {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.chart-title {
|
||||
font-family: Inter;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-size: 20px;
|
||||
line-height: 150%;
|
||||
color: white;
|
||||
padding: 32px 32px 20px;
|
||||
}
|
||||
.chart {
|
||||
border-bottom-left-radius: 14px;
|
||||
border-bottom-right-radius: 14px;
|
||||
padding: 0 32px 14px;
|
||||
background: linear-gradient(
|
||||
360deg
|
||||
, rgba(0, 204, 255, 0.3) 0%
|
||||
, rgba(0, 204, 255, 0.3) 10%
|
||||
, rgba(0, 204, 255, 0) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
|
||||
/******************/
|
||||
/* REACTABLE Tables */
|
||||
/******************/
|
||||
|
||||
.rt-page-button-current {
|
||||
color: #FFF;
|
||||
}
|
||||
.rt-thead {
|
||||
background-color: #10151A;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.ReactTable {
|
||||
background-color: #171e25;
|
||||
color: #C4CDD5;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.rt-th {
|
||||
border: 0px solid #000000 !important;
|
||||
padding-top: 15px;
|
||||
padding-bottom: 15px;
|
||||
font-weight: 400;
|
||||
font-family: Inter;
|
||||
}
|
||||
.rt-tr {
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
.rt-pagination {
|
||||
margin: 0;
|
||||
background: #171e25;
|
||||
opacity: 0.5;
|
||||
border-bottom: 1px solid #C4CDD5;
|
||||
border-top: 1px solid #C4CDD5;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user