Histogram Chart

Distribution of continuous data split into bins.

Interaction highlights

Emits HistogramBinSummary via onBinFocus / onBinBlur so external UI can react to the active bin.

Pointer metadata now includes cumulative counts, density ratios, and percentile—ideal for shared popovers.

Loading demo…

import

 

{

 

HistogramChart

 

}

 

from

 

'@platform-blocks/charts'

;

 

import

 

{

SESSION_DURATIONS

}

 

from

 

'./data'

;

 

export

 

function

 

Demo

(

)

 

{

  

return

 

(

    

<HistogramChart

      

title

=

"Session duration distribution"

      

subtitle

=

"Product analytics cohort"

      

height

=

{

280

}

      

data

=

{

SESSION_DURATIONS

}

      

bins

=

{

10

}

      showDensity

      

densityThickness

=

{

3

}

      

densityColor

=

"#12B886"

      

barGap

=

{

0.15

}

      

tooltip

=

{

{

        show

:

 

true

,

        formatter

:

 

(

bin

)

 

=>

 

`${bin.count} sessions between ${bin.start}-${bin.end} min`

,

      

}

}

      

valueFormatter

=

{

(

count

,

bin

)

 

=>

 

`${count} • ${bin.density.toFixed(2)} pdf`

}

      enableCrosshair

      liveTooltip

    

/>

  

)

;

}

Loading demo…

import

 

{

 

HistogramChart

 

}

 

from

 

'@platform-blocks/charts'

;

 

import

 

{

CONTRACT_LENGTHS

,

median

}

 

from

 

'./data'

;

 

export

 

function

 

Demo

(

)

 

{

  

return

 

(

    

<HistogramChart

      

title

=

"Customer contract length distribution"

      

subtitle

=

"Used to calibrate retention and renewal strategy"

      

height

=

{

320

}

      

data

=

{

CONTRACT_LENGTHS

}

      

bins

=

{

12

}

      

binMethod

=

"sturges"

      

density

=

{

false

}

      

showDensity

=

{

false

}

      

barOpacity

=

{

0.82

}

      

rangeHighlights

=

{

[

{

id

:

 

'core-subscription'

,

start

:

 

12

,

end

:

 

24

,

color

:

 

'#22C55E'

,

opacity

:

 

0.14

 

}

]

}

      

annotations

=

{

[

        

{

          id

:

 

'one-year'

,

          shape

:

 

'vertical-line'

,

          x

:

 

12

,

          color

:

 

'#22C55E'

,

          label

:

 

'1 year'

,

        

}

,

        

{

          id

:

 

'two-year'

,

          shape

:

 

'vertical-line'

,

          x

:

 

24

,

          color

:

 

'#15803D'

,

          label

:

 

'2 years'

,

        

}

,

        

{

          id

:

 

'median'

,

          shape

:

 

'vertical-line'

,

          x

:

median

,

          color

:

 

'#F97316'

,

          label

:

 

`Median ${median} mo`

,

        

}

,

      

]

}

      

xAxis

=

{

{

        title

:

 

'Contract length (months)'

,

      

}

}

      

yAxis

=

{

{

        title

:

 

'Customer accounts'

,

        labelFormatter

:

 

(

value

)

 

=>

 

`${value.toFixed(0)}`

,

      

}

}

      

grid

=

{

{

show

:

 

true

 

}

}

      

tooltip

=

{

{

        show

:

 

true

,

        formatter

:

 

(

bin

)

 

=>

 

`${bin.count} accounts between ${bin.start.toFixed(0)}–${bin.end.toFixed(0)} months`

,

      

}

}

      

valueFormatter

=

{

(

count

)

 

=>

 

`${count} customers`

}

    

/>

  

)

;

}

Loading demo…

import

 

{

 

HistogramChart

 

}

 

from

 

'@platform-blocks/charts'

;

 

import

 

{

TENURE_YEARS

,

medianTenure

}

 

from

 

'./data'

;

 

export

 

function

 

Demo

(

)

 

{

  

return

 

(

    

<HistogramChart

      

title

=

"Employee tenure distribution"

      

subtitle

=

"Helps spot retention risks and succession depth"

      

height

=

{

320

}

      

data

=

{

TENURE_YEARS

}

      

bins

=

{

12

}

      

binMethod

=

"sqrt"

      showDensity

      

densityThickness

=

{

2.5

}

      

densityColor

=

"#22C55E"

      

barOpacity

=

{

0.8

}

      

rangeHighlights

=

{

[

        

{

id

:

 

'new-hires'

,

start

:

 

0

,

end

:

 

1.5

,

color

:

 

'#FACC15'

,

opacity

:

 

0.18

 

}

,

        

{

id

:

 

'veterans'

,

start

:

 

8

,

end

:

 

15

,

color

:

 

'#22C55E'

,

opacity

:

 

0.12

 

}

,

      

]

}

      

annotations

=

{

[

        

{

          id

:

 

'median-tenure'

,

          shape

:

 

'vertical-line'

,

          x

:

 

Number

(

medianTenure

.

toFixed

(

2

)

)

,

          color

:

 

'#F97316'

,

          label

:

 

`Median ${medianTenure.toFixed(1)} yrs`

,

        

}

,

      

]

}

      

xAxis

=

{

{

        title

:

 

'Tenure (years)'

,

        labelFormatter

:

 

(

value

)

 

=>

 

`${value.toFixed(1)} yrs`

,

      

}

}

      

yAxis

=

{

{

        title

:

 

'Probability density'

,

        labelFormatter

:

 

(

value

)

 

=>

value

.

toFixed

(

2

)

,

      

}

}

      

grid

=

{

{

show

:

 

true

 

}

}

      

tooltip

=

{

{

        show

:

 

true

,

        formatter

:

 

(

bin

)

 

=>

 

`${bin.count} teammates between ${bin.start.toFixed(1)}–${bin.end.toFixed(1)} years`

,

      

}

}

      

valueFormatter

=

{

(

count

,

bin

)

 

=>

 

`${count} people · pdf ${bin.density.toFixed(3)}`

}

    

/>

  

)

;

}

Loading demo…

import

 

{

useState

}

 

from

 

'react'

;

import

 

{

 

View

,

 

Text

 

}

 

from

 

'react-native'

;

import

 

{

 

HistogramChart

,

 

HistogramBinSummary

 

}

 

from

 

'@platform-blocks/charts'

;

 

import

 

{

AVERAGE_LOAD

,

LOAD_TIMES

,

SLO_TARGET

}

 

from

 

'./data'

;

 

export

 

function

 

Demo

(

)

 

{

  

const

 

[

focusedBin

,

setFocusedBin

]

 

=

useState

<HistogramBinSummary

 

|

 

null

>

(

null

)

;

 

  

return

 

(

  

<View

>

      

<HistogramChart

        

title

=

"Page load time distribution"

        

subtitle

=

"Week after performance optimization rollout"

        

height

=

{

340

}

        

data

=

{

LOAD_TIMES

}

        

bins

=

{

14

}

        

binMethod

=

"fd"

        showDensity

        

densityThickness

=

{

3

}

        

barOpacity

=

{

0.78

}

        

densityColor

=

"#12B886"

        

rangeHighlights

=

{

[

{

id

:

 

'slo-window'

,

start

:

 

0

,

end

:

SLO_TARGET

,

color

:

 

'#38BDF8'

,

opacity

:

 

0.12

 

}

]

}

        

annotations

=

{

[

          

{

            id

:

 

'slo-target'

,

            shape

:

 

'vertical-line'

,

            x

:

SLO_TARGET

,

            color

:

 

'#0EA5E9'

,

            label

:

 

'SLO 2.5s'

,

          

}

,

          

{

            id

:

 

'avg-load'

,

            shape

:

 

'vertical-line'

,

            x

:

 

Number

(

AVERAGE_LOAD

.

toFixed

(

2

)

)

,

            color

:

 

'#F97316'

,

            label

:

 

`Avg ${AVERAGE_LOAD.toFixed(2)}s`

,

          

}

,

        

]

}

        

xAxis

=

{

{

          title

:

 

'Page load time (seconds)'

,

          labelFormatter

:

 

(

value

)

 

=>

 

`${value.toFixed(1)}s`

,

        

}

}

        

yAxis

=

{

{

          title

:

 

'Probability density'

,

          labelFormatter

:

 

(

value

)

 

=>

value

.

toFixed

(

2

)

,

        

}

}

        

grid

=

{

{

show

:

 

true

 

}

}

        

tooltip

=

{

{

          show

:

 

true

,

          formatter

:

 

(

bin

)

 

=>

 

`${bin.count} page views between ${bin.start.toFixed(1)}–${bin.end.toFixed(1)}s`

,

        

}

}

        

valueFormatter

=

{

(

count

,

bin

)

 

=>

 

`${count} views · pdf ${bin.density.toFixed(3)}`

}

        

onBinFocus

=

{

(

summary

)

 

=>

 

setFocusedBin

(

summary

)

}

        

onBinBlur

=

{

(

)

 

=>

 

setFocusedBin

(

null

)

}

      

/>

  

<View

 

style

=

{

{

paddingHorizontal

:

 

4

,

marginTop

:

 

12

 

}

}

>

        

{

focusedBin

?

 

(

          

<Text

 

style

=

{

{

fontSize

:

 

13

,

color

:

 

'#3F3F46'

 

}

}

>

            

{

`${focusedBin.count} loads between ${focusedBin.start.toFixed(2)}–${focusedBin.end.toFixed(2)}s · percentile ${(focusedBin.percentile * 100).toFixed(1)}% · cumulative ${(focusedBin.cumulativeDensityRatio * 100).toFixed(1)}% density`

}

          

</Text

>

        

)

 

:

 

(

          

<Text

 

style

=

{

{

fontSize

:

 

13

,

color

:

 

'#52525B'

 

}

}

>

            

Hover

a bar to highlight its percentile and cumulative share of traffic

.

          

</Text

>

        

)

}

      

</View

>

    

</View

>

  

)

;

}

Loading demo…

import

 

{

 

HistogramChart

 

}

 

from

 

'@platform-blocks/charts'

;

 

import

 

{

BATTERY_VOLTAGES

,

REPLACEMENT_THRESHOLD

,

TARGET_VOLTAGE

}

 

from

 

'./data'

;

 

export

 

function

 

Demo

(

)

 

{

  

return

 

(

    

<HistogramChart

      

title

=

"Sensor battery voltage after firmware upgrade"

      

subtitle

=

"Monitoring pack health across deployed field units"

      

height

=

{

320

}

      

data

=

{

BATTERY_VOLTAGES

}

      

bins

=

{

12

}

      

binMethod

=

"sturges"

      showDensity

      

densityThickness

=

{

2.8

}

      

densityColor

=

"#34D399"

      

barOpacity

=

{

0.78

}

      

rangeHighlights

=

{

[

        

{

id

:

 

'low-voltage'

,

start

:

 

3.0

,

end

:

REPLACEMENT_THRESHOLD

,

color

:

 

'#EF4444'

,

opacity

:

 

0.14

 

}

,

        

{

id

:

 

'target-band'

,

start

:

TARGET_VOLTAGE

,

end

:

 

4.1

,

color

:

 

'#22C55E'

,

opacity

:

 

0.12

 

}

,

      

]

}

      

annotations

=

{

[

        

{

          id

:

 

'replacement-line'

,

          shape

:

 

'vertical-line'

,

          x

:

REPLACEMENT_THRESHOLD

,

          color

:

 

'#DC2626'

,

          label

:

 

'Replace below 3.5V'

,

        

}

,

        

{

          id

:

 

'target-line'

,

          shape

:

 

'vertical-line'

,

          x

:

TARGET_VOLTAGE

,

          color

:

 

'#16A34A'

,

          label

:

 

'Target 3.9V+'

,

        

}

,

      

]

}

      

xAxis

=

{

{

        title

:

 

'Voltage (V)'

,

        labelFormatter

:

 

(

value

)

 

=>

 

`${value.toFixed(2)}V`

,

      

}

}

      

yAxis

=

{

{

        title

:

 

'Probability density'

,

        labelFormatter

:

 

(

value

)

 

=>

value

.

toFixed

(

2

)

,

      

}

}

      

grid

=

{

{

show

:

 

true

 

}

}

      

tooltip

=

{

{

        show

:

 

true

,

        formatter

:

 

(

bin

)

 

=>

 

`${bin.count} sensors between ${bin.start.toFixed(2)}–${bin.end.toFixed(2)}V`

,

      

}

}

      

valueFormatter

=

{

(

count

,

bin

)

 

=>

 

`${count} sensors · pdf ${bin.density.toFixed(3)}`

}

    

/>

  

)

;

}

Loading demo…

import

 

{

 

HistogramChart

 

}

 

from

 

'@platform-blocks/charts'

;

 

import

 

{

REVIEW_THRESHOLD

,

TRANSACTION_AMOUNTS

}

 

from

 

'./data'

;

 

export

 

function

 

Demo

(

)

 

{

  

return

 

(

    

<HistogramChart

      

title

=

"Transaction amount distribution"

      

subtitle

=

"Identifying anomalous high-value purchases"

      

height

=

{

320

}

      

data

=

{

TRANSACTION_AMOUNTS

}

      

bins

=

{

16

}

      

binMethod

=

"fd"

      showDensity

      

barOpacity

=

{

0.76

}

      

densityColor

=

"#0EA5E9"

      

rangeHighlights

=

{

[

        

{

id

:

 

'high-risk-window'

,

start

:

 

900

,

end

:

 

1400

,

color

:

 

'#EF4444'

,

opacity

:

 

0.12

 

}

,

      

]

}

      

annotations

=

{

[

        

{

          id

:

 

'manual-review'

,

          shape

:

 

'vertical-line'

,

          x

:

REVIEW_THRESHOLD

,

          color

:

 

'#DC2626'

,

          label

:

 

'Manual review starts'

,

        

}

,

      

]

}

      

xAxis

=

{

{

        title

:

 

'Transaction amount (USD)'

,

        labelFormatter

:

 

(

value

)

 

=>

 

`$${value.toFixed(0)}`

,

      

}

}

      

yAxis

=

{

{

        title

:

 

'Probability density'

,

        labelFormatter

:

 

(

value

)

 

=>

value

.

toFixed

(

3

)

,

      

}

}

      

grid

=

{

{

show

:

 

true

 

}

}

      

tooltip

=

{

{

        show

:

 

true

,

        formatter

:

 

(

bin

)

 

=>

 

`${bin.count} orders between $${bin.start.toFixed(0)}–$${bin.end.toFixed(0)}`

,

      

}

}

      

valueFormatter

=

{

(

count

,

bin

)

 

=>

 

`${count} orders · pdf ${bin.density.toFixed(3)}`

}

    

/>

  

)

;

}

Scan to open this page on your phonereact-ui-library.com/components/HistogramChart

</>

react-ui-library

100+ accessible, themeable components that work seamlessly across iOS, Android, and Web.

A Platform Blocks product.