Published
Edited
Mar 11, 2021
Fork of Bounce Rate
4 forks
Importers
Insert cell
Insert cell
Insert cell
Insert cell
highValueUsers(filecoinData, 'IPFS High Value User Volume & Growth Rate', {showTrailing: true})
Insert cell
periodsAgo = 6
Insert cell
highValueUsers = (data, title, options = {}) => {
const highValueGrowthRate = data.reduce((prev, curr, index) => {
if(index === 0) return prev;
const previousValue = data[index - 1].states.high
const currentValue = curr.states.high
return [...prev, Math.floor((currentValue - previousValue) / previousValue * 100)]
}, [])
const { showTrailing } = options;
const trailingData = showTrailing && data.slice(data.length - periodsAgo)
console.log(trailingData)
const trailingLongAgo = trailingData && trailingData[0].states.high
const trailingCurrent = trailingData && trailingData[trailingData.length - 1].states.high
const trailingCompoundAverage = Math.pow(trailingCurrent / trailingLongAgo, 1 / periodsAgo) - 1
const container = html`<canvas></canvas>`;
const [_, ...highData] = data
const myChart = new Chart(container, {
type: 'bar',
data: {
labels: data.slice(1).map((t) => dateDiffToHuman(t.date)),
datasets: [{
type: 'line',
data: highData.map(({ states }) => states.high),
label: 'High-Value User Volume',
yAxisID: 'B',
fill: false,
borderColor: color.green,
lineTension: 0,
borderWidth: 3,
}, {
type: 'bar',
data: highValueGrowthRate,
label: 'High-Value Volume Growth Rate',
yAxisID: 'A',
backgroundColor: color.grey,
}, {
type: 'line',
data: highValueGrowthRate.map(_ => 10),
label: 'High-Value Growth Target',
yAxisID: 'A',
fill: false,
borderColor: d3.color(color.green).darker(2).hex(),
lineTension: 0,
borderWidth: 2,
borderDash: [5, 5],
pointRadius: 0,
}, {
type: 'line',
data: highValueGrowthRate.map(_ => trailingCompoundAverage * 100),
label: 'High-Value Growth (last 12 weeks)',
yAxisID: 'A',
fill: false,
borderColor: d3.color(color.green).brighter(1).hex(),
lineTension: 0,
borderWidth: 2,
borderDash: [5, 5],
pointRadius: 0,
},]
},
options: {
title: {
display: true,
text: title
},
scales: {
yAxes: [{
id: 'B',
ticks: {
min: 0
},
position: 'right',
scaleLabel: {
display: true,
labelString: 'User Volume',
},
gridLines: {
display: false
},
}, {
id: 'A',
ticks: {
callback: (value) => `${value}%`,
},
gridLines: {
zeroLineColor: 'black'
},
scaleLabel: {
display: true,
labelString: 'High-Value User Volume Growth',
},
}],
}
},
});
return container;
}
Insert cell
color = ({
red: d3.schemeTableau10[2],
orange: d3.schemeTableau10[1],
green: d3.schemeTableau10[4],
teal: d3.schemeTableau10[3],
blue: d3.schemeTableau10[0],
grey: d3.schemeTableau10[9],
yellow: d3.schemeTableau10[5]
})
Insert cell
colorMap = ({
'First Time': color.blue,
'Bounced' : color.red,
'Lapsed High-Value': d3.color(color.red).darker().hex(),
'Lapsed Low-Value': d3.color(color.red).brighter().hex(),
'High to Low-Value': d3.color(color.yellow).brighter(0.5).hex(),
'Low-Value': d3.color(color.yellow).darker(0.25).hex(),
'New Low-Value': color.yellow,
'Reactivated Low-Value': d3.color(color.yellow).brighter(0.25).hex(),
'High-Value': d3.color(color.green).darker(0.25).hex(),
'Low to High-Value': d3.color(color.green).brighter(0.75).hex(),
'New High-Value': d3.color(color.green).brighter(0.12).hex(),
'Reactivated High-Value': d3.color(color.green).brighter(1.7).hex()
})
Insert cell
d3 = require('d3')
Insert cell
Insert cell
ipfsData = (await fetch(`${ipfsGetStatesUrl}?start_date=${startDate}`)).json()
Insert cell
filecoinData = (await fetch(`${filecoinGetStatesUrl}?start_date=${startDate}`)).json()
Insert cell
Chart = require('https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js')
Insert cell
moment = require('moment')
Insert cell
import { dateDiffToHuman } from '@protocol/utils'
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more