Scatter Chart
Examples
(6)Properties
(66)Playground
Loading demo…
import
{
ScatterChart
}
from
'@platform-blocks/charts'
;
import
{
QUADRANTS
,
SERIES
}
from
'./data'
;
const
describeQuadrant
=
(
x
:
number
,
y
:
number
)
=>
{
const
labels
=
QUADRANTS
.
labels
;
if
(
!
labels
)
return
null
;
const
isRight
=
x
>=
QUADRANTS
.
x
;
const
isTop
=
y
>=
QUADRANTS
.
y
;
if
(
isRight
&&
isTop
)
return
labels
.
topRight
??
null
;
if
(
!
isRight
&&
isTop
)
return
labels
.
topLeft
??
null
;
if
(
isRight
&&
!
isTop
)
return
labels
.
bottomRight
??
null
;
return
labels
.
bottomLeft
??
null
;
}
;
export
function
Demo
(
)
{
return
(
<ScatterChart
title
=
"API error rate vs. request volume"
subtitle
=
"Each point represents a service, sized by throughput"
height
=
{
360
}
data
=
{
SERIES
.
flatMap
(
(
serie
)
=>
serie
.
data
)
}
series
=
{
SERIES
}
quadrants
=
{
QUADRANTS
}
pointOpacity
=
{
0.9
}
enableCrosshair
multiTooltip
liveTooltip
grid
=
{
{
show
:
true
}
}
legend
=
{
{
show
:
true
,
position
:
'bottom'
}
}
xScaleType
=
"log"
xAxis
=
{
{
show
:
true
,
title
:
'Requests per minute (thousands)'
,
labelFormatter
:
(
value
:
number
)
=>
`${Math.round(value)}k`
,
}
}
yAxis
=
{
{
show
:
true
,
title
:
'Error rate (%)'
,
labelFormatter
:
(
value
:
number
)
=>
`${value.toFixed(1)}%`
,
}
}
tooltip
=
{
{
show
:
true
,
backgroundColor
:
'#12263A'
,
textColor
:
'#F4F6FB'
,
formatter
:
(
point
)
=>
{
const
quadrantNote
=
describeQuadrant
(
point
.
x
,
point
.
y
)
;
const
lines
=
[
point
.
label
??
'Service'
,
`Volume ${Math.round(point.x)}k rpm · Errors ${point.y.toFixed(1)}%`
,
]
;
if
(
quadrantNote
)
{
lines
.
push
(
quadrantNote
)
;
}
return
lines
.
join
(
'\n'
)
;
}
,
}
}
/>
)
;
}
Loading demo…
import
{
ScatterChart
}
from
'@platform-blocks/charts'
;
import
{
SERIES
}
from
'./data'
;
export
function
Demo
(
)
{
return
(
<ScatterChart
title
=
"Spend vs. qualified leads"
subtitle
=
"Campaign cohort"
height
=
{
340
}
data
=
{
SERIES
.
flatMap
(
(
serie
)
=>
serie
.
data
)
}
series
=
{
SERIES
}
showTrendline
=
"per-series"
enableCrosshair
enablePanZoom
zoomMode
=
"both"
multiTooltip
liveTooltip
xAxis
=
{
{
show
:
true
,
title
:
'Spend (USD thousands)'
,
labelFormatter
:
(
value
)
=>
`$${value}`
,
}
}
yAxis
=
{
{
show
:
true
,
title
:
'Qualified leads'
,
}
}
grid
=
{
{
show
:
true
}
}
legend
=
{
{
show
:
true
,
position
:
'bottom'
}
}
tooltip
=
{
{
show
:
true
,
formatter
:
(
point
)
=>
`${point.x}k spend → ${point.y} leads`
,
}
}
/>
)
;
}
Loading demo…
import
{
ScatterChart
}
from
'@platform-blocks/charts'
;
import
{
QUADRANTS
,
SERIES
}
from
'./data'
;
const
resolveAction
=
(
x
:
number
,
y
:
number
)
=>
{
const
labels
=
QUADRANTS
.
labels
;
if
(
!
labels
)
return
null
;
const
right
=
x
>=
QUADRANTS
.
x
;
const
top
=
y
>=
QUADRANTS
.
y
;
if
(
!
right
&&
top
)
return
labels
.
topLeft
??
null
;
if
(
right
&&
top
)
return
labels
.
topRight
??
null
;
if
(
!
right
&&
!
top
)
return
labels
.
bottomLeft
??
null
;
return
labels
.
bottomRight
??
null
;
}
;
export
function
Demo
(
)
{
return
(
<ScatterChart
title
=
"Campaign spend vs. attributed revenue"
subtitle
=
"Ad set performance, each marker sized by budget grouping"
height
=
{
360
}
data
=
{
SERIES
.
flatMap
(
(
serie
)
=>
serie
.
data
)
}
series
=
{
SERIES
}
quadrants
=
{
QUADRANTS
}
pointOpacity
=
{
0.86
}
showTrendline
=
"per-series"
enableCrosshair
multiTooltip
liveTooltip
grid
=
{
{
show
:
true
}
}
legend
=
{
{
show
:
true
,
position
:
'bottom'
}
}
xAxis
=
{
{
show
:
true
,
title
:
'Spend (USD thousands)'
,
labelFormatter
:
(
value
:
number
)
=>
`$${value}k`
,
}
}
yAxis
=
{
{
show
:
true
,
title
:
'Attributed revenue (USD thousands)'
,
labelFormatter
:
(
value
:
number
)
=>
`$${value}k`
,
}
}
tooltip
=
{
{
show
:
true
,
backgroundColor
:
'#0B1220'
,
textColor
:
'#F1F5F9'
,
formatter
:
(
point
)
=>
{
const
action
=
resolveAction
(
point
.
x
,
point
.
y
)
;
const
lines
=
[
point
.
label
??
'Ad set'
,
`Spend $${point.x}k · Revenue $${point.y}k`
,
]
;
if
(
action
)
{
lines
.
push
(
action
)
;
}
return
lines
.
join
(
'\n'
)
;
}
,
}
}
/>
)
;
}
Loading demo…
import
{
ScatterChart
}
from
'@platform-blocks/charts'
;
import
{
QUADRANTS
,
SERIES
}
from
'./data'
;
const
resolveQuadrantLabel
=
(
x
:
number
,
y
:
number
)
=>
{
const
horizontal
=
x
>=
QUADRANTS
.
x
?
'Right'
:
'Left'
;
const
vertical
=
y
>=
QUADRANTS
.
y
?
'Top'
:
'Bottom'
;
const
labels
=
QUADRANTS
.
labels
;
if
(
!
labels
)
return
null
;
if
(
horizontal
===
'Left'
&&
vertical
===
'Top'
)
return
labels
.
topLeft
??
null
;
if
(
horizontal
===
'Right'
&&
vertical
===
'Top'
)
return
labels
.
topRight
??
null
;
if
(
horizontal
===
'Left'
&&
vertical
===
'Bottom'
)
return
labels
.
bottomLeft
??
null
;
if
(
horizontal
===
'Right'
&&
vertical
===
'Bottom'
)
return
labels
.
bottomRight
??
null
;
return
null
;
}
;
export
function
Demo
(
)
{
return
(
<ScatterChart
title
=
"Customer LTV vs. Acquisition Cost"
subtitle
=
"Segment performance across recent cohorts"
height
=
{
360
}
data
=
{
SERIES
.
flatMap
(
(
serie
)
=>
serie
.
data
)
}
series
=
{
SERIES
}
quadrants
=
{
QUADRANTS
}
pointOpacity
=
{
0.9
}
showTrendline
=
"per-series"
enableCrosshair
multiTooltip
liveTooltip
grid
=
{
{
show
:
true
}
}
legend
=
{
{
show
:
true
,
position
:
'bottom'
}
}
xAxis
=
{
{
show
:
true
,
title
:
'Acquisition cost (USD thousands)'
,
labelFormatter
:
(
value
:
number
)
=>
`$${value}k`
,
}
}
yAxis
=
{
{
show
:
true
,
title
:
'Lifetime value (USD thousands)'
,
labelFormatter
:
(
value
:
number
)
=>
`$${value}k`
,
}
}
tooltip
=
{
{
show
:
true
,
backgroundColor
:
'#101218'
,
textColor
:
'#F8FAFC'
,
formatter
:
(
point
)
=>
{
const
quadrantLabel
=
resolveQuadrantLabel
(
point
.
x
,
point
.
y
)
;
const
lines
=
[
point
.
label
??
'Segment'
,
`CAC $${point.x}k · LTV $${point.y}k`
,
]
;
if
(
quadrantLabel
)
{
lines
.
push
(
quadrantLabel
)
;
}
return
lines
.
join
(
'\n'
)
;
}
,
}
}
/>
)
;
}
Loading demo…
import
{
ScatterChart
}
from
'@platform-blocks/charts'
;
import
{
SERIES
}
from
'./data'
;
export
function
Demo
(
)
{
return
(
<ScatterChart
title
=
"Feature usage vs. satisfaction"
subtitle
=
"Weekly feature interactions mapped to CSAT by cohort"
height
=
{
360
}
data
=
{
SERIES
.
flatMap
(
(
serie
)
=>
serie
.
data
)
}
series
=
{
SERIES
}
pointOpacity
=
{
0.85
}
showTrendline
=
"per-series"
enableCrosshair
multiTooltip
liveTooltip
grid
=
{
{
show
:
true
}
}
legend
=
{
{
show
:
true
,
position
:
'bottom'
,
align
:
'center'
}
}
xAxis
=
{
{
show
:
true
,
title
:
'Weekly feature uses'
,
labelFormatter
:
(
value
:
number
)
=>
`${value}x`
,
}
}
yAxis
=
{
{
show
:
true
,
title
:
'Customer satisfaction (1-10)'
,
labelFormatter
:
(
value
:
number
)
=>
value
.
toFixed
(
1
)
,
}
}
tooltip
=
{
{
show
:
true
,
formatter
:
(
point
)
=>
`${point.label ?? 'Cohort'}\nUsage ${point.x.toFixed(1)}x | CSAT ${point.y.toFixed(1)}`
,
}
}
/>
)
;
}
Loading demo…
import
{
ScatterChart
}
from
'@platform-blocks/charts'
;
import
{
SERIES
}
from
'./data'
;
export
function
Demo
(
)
{
return
(
<ScatterChart
title
=
"Performance rating vs. tenure"
subtitle
=
"Team-by-team view with marker size scaled to total compensation (USD thousands)"
height
=
{
360
}
data
=
{
SERIES
.
flatMap
(
(
serie
)
=>
serie
.
data
)
}
series
=
{
SERIES
}
pointOpacity
=
{
0.88
}
showTrendline
=
"per-series"
enableCrosshair
multiTooltip
liveTooltip
grid
=
{
{
show
:
true
}
}
legend
=
{
{
show
:
true
,
position
:
'bottom'
}
}
xAxis
=
{
{
show
:
true
,
title
:
'Tenure (years)'
,
labelFormatter
:
(
value
:
number
)
=>
`${value.toFixed(1)} yrs`
,
}
}
yAxis
=
{
{
show
:
true
,
title
:
'Performance rating (1-5)'
,
labelFormatter
:
(
value
:
number
)
=>
value
.
toFixed
(
1
)
,
}
}
tooltip
=
{
{
show
:
true
,
formatter
:
(
point
)
=>
{
const
compensation
=
point
.
data
?
.
compensation
;
const
compensationText
=
typeof compensation
===
'number'
?
`$${compensation}k`
:
'n/a'
;
return
`${point.label ?? 'Team member'}\nRating ${point.y.toFixed(1)} | Tenure ${point.x.toFixed(1)} yrs\nComp ${compensationText}`
;
}
,
}
}
/>
)
;
}
</>
react-ui-library
100+ accessible, themeable components that work seamlessly across iOS, Android, and Web.
A Platform Blocks product.
Quick Links
Resources