parent
20317a5154
commit
449e4cfaf6
@ -0,0 +1,114 @@ |
||||
import $ from 'jquery' |
||||
import Chart from 'chart.js' |
||||
import humps from 'humps' |
||||
import numeral from 'numeral' |
||||
import { formatUsdValue } from '../lib/currency' |
||||
import sassVariables from '../../css/app.scss' |
||||
|
||||
const config = { |
||||
type: 'line', |
||||
responsive: true, |
||||
data: { |
||||
datasets: [] |
||||
}, |
||||
options: { |
||||
legend: { |
||||
display: false |
||||
}, |
||||
scales: { |
||||
xAxes: [{ |
||||
gridLines: { |
||||
display: false, |
||||
drawBorder: false |
||||
}, |
||||
type: 'time', |
||||
time: { |
||||
unit: 'day', |
||||
stepSize: 14 |
||||
}, |
||||
ticks: { |
||||
fontColor: sassVariables.dashboardBannerChartAxisFontColor |
||||
} |
||||
}], |
||||
yAxes: [{ |
||||
id: 'num_transactions', |
||||
gridLines: { |
||||
display: false, |
||||
drawBorder: false |
||||
}, |
||||
ticks: { |
||||
beginAtZero: true, |
||||
callback: (value, index, values) => `$${numeral(value).format('0,0.00')}`, |
||||
maxTicksLimit: 4, |
||||
fontColor: sassVariables.dashboardBannerChartAxisFontColor |
||||
} |
||||
}] |
||||
}, |
||||
tooltips: { |
||||
mode: 'index', |
||||
intersect: false, |
||||
callbacks: { |
||||
label: ({datasetIndex, yLabel}, {datasets}) => { |
||||
const label = datasets[datasetIndex].label |
||||
if (datasets[datasetIndex].yAxisID === 'num_transactions') { |
||||
return `${label}: ${formatUsdValue(yLabel)}` |
||||
} else { |
||||
return yLabel |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
function transformData (marketHistoryData) { |
||||
return marketHistoryData.map( |
||||
({ date, num_transactions }) => ({x: date, y: num_transactions})) |
||||
} |
||||
|
||||
class TransactionHistoryChart { |
||||
constructor (el, transactionHistoryData) { |
||||
this.num_transactions = { |
||||
label: window.localized['Price'], |
||||
yAxisID: 'num_transactions', |
||||
data: transformData(transactionHistoryData), |
||||
fill: false, |
||||
pointRadius: 0, |
||||
backgroundColor: sassVariables.dashboardLineColorPrice, |
||||
borderColor: sassVariables.dashboardLineColorPrice, |
||||
lineTension: 0 |
||||
} |
||||
config.data.datasets = [this.num_transactions] |
||||
this.chart = new Chart(el, config) |
||||
} |
||||
update (transactionHistoryData) { |
||||
this.num_transactions.data = transformData(TransactionHistoryData) |
||||
this.chart.update() |
||||
} |
||||
} |
||||
|
||||
export function createTransactionHistoryChart (el) { |
||||
const dataPath = el.dataset.transaction_history_chart_path |
||||
const $chartLoading = $('[data-chart-loading-message]') |
||||
const $chartError = $('[data-chart-error-message]') |
||||
const chart = new TransactionHistoryChart(el, 0, []) |
||||
$.getJSON(dataPath, {type: 'JSON'}) |
||||
.done(data => { |
||||
const transactionStats = JSON.parse(data.history_data) |
||||
$(el).show() |
||||
chart.update(transactionStats) |
||||
}) |
||||
.fail(() => { |
||||
$chartError.show() |
||||
}) |
||||
.always(() => { |
||||
$chartLoading.hide() |
||||
}) |
||||
return chart |
||||
} |
||||
|
||||
$('[data-chart-error-message]').on('click', _event => { |
||||
$('[data-chart-loading-message]').show() |
||||
$('[data-chart-error-message]').hide() |
||||
createTransactionHistoryChart($('[data-chart="marketHistoryChart"]')[0]) |
||||
}) |
@ -0,0 +1,38 @@ |
||||
defmodule BlockScoutWeb.Chain.TransactionHistoryChartController do |
||||
use BlockScoutWeb, :controller |
||||
|
||||
alias Explorer.Chain.Transaction.History.TransactionStats |
||||
|
||||
def show(conn, _params) do |
||||
with true <- ajax?(conn) do |
||||
[{:history_size, history_size}] = Application.get_env(:block_scout_web, __MODULE__, 30) |
||||
|
||||
latest = Date.utc_today() |
||||
earliest = Date.add(latest, -1 * history_size) |
||||
|
||||
transaction_history_data = TransactionStats.by_date_range(earliest, latest) |
||||
|> extract_history |
||||
|> encode_transaction_history_data |
||||
|
||||
json(conn, %{ |
||||
history_data: transaction_history_data, |
||||
}) |
||||
else |
||||
_ -> unprocessable_entity(conn) |
||||
end |
||||
end |
||||
|
||||
defp extract_history(db_results) do |
||||
Enum.map(db_results, fn row -> |
||||
%{date: row.date, number_of_transactions: row.number_of_transactions} end) |
||||
end |
||||
|
||||
defp encode_transaction_history_data(transaction_history_data) do |
||||
transaction_history_data |
||||
|> Jason.encode() |
||||
|> case do |
||||
{:ok, data} -> data |
||||
_ -> [] |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,48 @@ |
||||
defmodule BlockScoutWeb.Chain.TransactionHistoryChartControllerTest do |
||||
use BlockScoutWeb.ConnCase |
||||
|
||||
alias BlockScoutWeb.Chain.TransactionHistoryChartController |
||||
alias Explorer.Chain.Transaction.History.TransactionStats |
||||
alias Explorer.Repo |
||||
|
||||
describe "GET show/2" do |
||||
test "returns error when not an ajax request" do |
||||
path = transaction_history_chart_path(BlockScoutWeb.Endpoint, :show) |
||||
|
||||
conn = get(build_conn(), path) |
||||
|
||||
assert conn.status == 422 |
||||
end |
||||
|
||||
test "returns ok when request is ajax" do |
||||
path = transaction_history_chart_path(BlockScoutWeb.Endpoint, :show) |
||||
|
||||
conn = |
||||
build_conn() |
||||
|> put_req_header("x-requested-with", "xmlhttprequest") |
||||
|> get(path) |
||||
|
||||
assert json_response(conn, 200) |
||||
end |
||||
|
||||
test "returns appropriate json data" do |
||||
td = Date.utc_today() |
||||
dts = [Date.utc_today(), Date.add(td, -1), Date.add(td, -2)] |
||||
some_transaction_stats = [%{date: Enum.at(dts, 0), number_of_transactions: 10}, |
||||
%{date: Enum.at(dts, 1), number_of_transactions: 20}, |
||||
%{date: Enum.at(dts, 2), number_of_transactions: 30}] |
||||
|
||||
{num, _} = Repo.insert_all(TransactionStats, some_transaction_stats) |
||||
assert num == 3 |
||||
|
||||
conn = |
||||
build_conn() |
||||
|> put_req_header("x-requested-with", "xmlhttprequest") |
||||
|> TransactionHistoryChartController.show([]) |
||||
|
||||
expected = "{\"history_data\":\"[{\\\"date\\\":\\\"2019-07-12\\\",\\\"number_of_transactions\\\":10},{\\\"date\\\":\\\"2019-07-11\\\",\\\"number_of_transactions\\\":20},{\\\"date\\\":\\\"2019-07-10\\\",\\\"number_of_transactions\\\":30}]\"}" |
||||
|
||||
assert conn.resp_body =~ expected |
||||
end |
||||
end |
||||
end |
Loading…
Reference in new issue