Interactive Examples
    • darkGold
    • cyberSpace
    • turquoiseHexagon
    • light
    • lightNature

    Do you like what you see?

    Exit Close Editor
    const lcjs = require('@lightningchart/lcjs')
    const { lightningChart, Themes, emptyFill, PalettedFill, LUT, AxisTickStrategies, AxisScrollStrategies, emptyLine, regularColorSteps } =
        lcjs
    
    const exampleContainer = document.getElementById('chart') || document.body
    if (exampleContainer === document.body) {
        exampleContainer.style.width = '100vw'
        exampleContainer.style.height = '100vh'
        exampleContainer.style.margin = '0px'
    }
    
    const lc = lightningChart()
    
    const temporaryPanelAtStart = lc.UIPanel({
        container: exampleContainer,
        // theme: Themes.darkGold
    })
    const ui = temporaryPanelAtStart.addUIElement().setPadding(12).setText('Click anywhere to start playing audio').setPointerEvents(false)
    temporaryPanelAtStart.background.addEventListener('click', () => startAudioVisualization())
    const theme = temporaryPanelAtStart.getTheme()
    
    const startAudioVisualization = () => {
        temporaryPanelAtStart.dispose()
        const containerChart1 = document.createElement('div')
        const containerChart2 = document.createElement('div')
        exampleContainer.append(containerChart1)
        exampleContainer.append(containerChart2)
        containerChart1.style.width = '100%'
        containerChart1.style.height = '50%'
        containerChart2.style.width = '100%'
        containerChart2.style.height = '50%'
    
        // Loosely based on: https://blog.logrocket.com/audio-visualizer-from-scratch-javascript/
        let audio1 = new Audio()
        audio1.crossOrigin = 'anonymous'
        audio1.src =
            new URL(document.head.baseURI).origin + new URL(document.head.baseURI).pathname + 'examples/assets/0039/alex-productions-noise.mp3'
        const audioCtx = new (window.AudioContext || window.webkitAudioContext)()
        let audioSource = null
        let analyser = null
        audioSource = audioCtx.createMediaElementSource(audio1)
        analyser = audioCtx.createAnalyser()
        audioSource.connect(analyser)
        analyser.connect(audioCtx.destination)
        analyser.fftSize = 128
        audio1.play()
        const bufferLength = analyser.frequencyBinCount
    
        // (1) Frequency visualization
        const chartFrequency = lc
            .ChartXY({
                legend: { visible: false },
                container: containerChart1,
            })
            .setTitle('Alex-Productions - Noise')
            .setTitlePosition('series-right-top')
            .setPadding(30)
            .setUserInteractions(undefined)
        const palette = new PalettedFill({
            lookUpProperty: 'y',
            lut: new LUT({
                interpolate: true,
                steps: regularColorSteps(0, 200, theme.examples.spectrogramColorPalette),
            }),
        })
        const seriesFrequency = chartFrequency
            .addPointLineAreaSeries()
            .setCurvePreprocessing({ type: 'spline', resolution: 10 })
            .setPointFillStyle(emptyFill)
            .setAreaFillStyle(palette)
            .setCursorEnabled(false)
        const axisY = chartFrequency.getDefaultAxisY().setInterval({ start: 0, end: 256 })
        chartFrequency.forEachAxis((axis) => axis.setTickStrategy(AxisTickStrategies.Empty))
    
        // (2) Waveform
        const chartWaveform = lc
            .ChartXY({
                legend: { visible: false },
                container: containerChart2,
            })
            .setTitle('')
            .setPadding(30)
        const seriesWaveform = chartWaveform
            .addLineSeries({
                allowInputModification: false,
            })
            .setMaxSampleCount(100_000)
            .setCursorEnabled(false)
        chartWaveform
            .getDefaultAxisX()
            .setScrollStrategy(AxisScrollStrategies.scrolling)
            .setTickStrategy(AxisTickStrategies.Time)
            .setDefaultInterval((state) => ({
                start: (state.dataMax ?? 0) - 5_000,
                end: state.dataMax,
                stopAxisAfter: false,
            }))
            .fit(false)
        chartWaveform.getDefaultAxisY().setAnimationScroll(false)
        chartWaveform.getDefaultAxisY().setTickStrategy(AxisTickStrategies.Empty)
        chartWaveform.getDefaultAxisX().setTickStrategy(AxisTickStrategies.Time)
    
        //
        const dataArrayFrequency = new Uint8Array(bufferLength)
        const dataArrayTimeDomain = new Float32Array(analyser.fftSize)
        let tPrev = undefined
        const tFirst = performance.now()
        let framesCount = 0
        const title = chartFrequency.getTitle()
        const frame = () => {
            const tNow = performance.now()
            if (tPrev) {
                analyser.getByteFrequencyData(dataArrayFrequency)
                analyser.getFloatTimeDomainData(dataArrayTimeDomain)
                seriesFrequency.clear().appendSamples({
                    yValues: dataArrayFrequency,
                })
                const waveformTimestamps = new Array(dataArrayTimeDomain.length)
                    .fill(0)
                    .map((_, i, arr) => tPrev + ((tNow - tPrev) * (i + 1)) / arr.length)
                seriesWaveform.appendSamples({
                    xValues: waveformTimestamps,
                    yValues: dataArrayTimeDomain,
                })
                chartWaveform.getDefaultAxisX().setStopped(false)
    
                const fps = 1000 / ((tNow - tFirst) / framesCount)
                chartFrequency.setTitle(`${title} - ${fps.toFixed(0)} FPS`)
            }
            requestAnimationFrame(frame)
            tPrev = tNow
            framesCount += 1
        }
        frame()
    }
    

    Real-Time Audio Visualization with JavaScript - LightningChart JS Editor - Editor

    xy axis time line

    High-performance real-time audio visualization JavaScript with LightningChart JS. This example helps visualize MP3s audio files in real-time.


    Noise by Alex-Productions | https://onsound.eu/

    Music promoted by https://www.free-stock-music.com

    Creative Commons / Attribution 3.0 Unported License (CC BY 3.0)

    https://creativecommons.org/licenses/by/3.0/deed.en_US

    API Links

    • LightningChart
    • Automatic tick placement strategies
    • Chart XY
    • Axis XY
    • Line Series XY
    © LightningChart Ltd 2009-2026. All rights reserved.