Skip to content

Charts

Bar charts

  • January

    • Value label: 74kwh
  • February

    • Value label: 49kwh
  • March

    • Value label: 141kwh

January

Your HTML here

February

Your HTML here

March

Your HTML here

April

Your HTML here

Bar charts short

  • Jan.

    • Value label: 74kwh
  • Feb.

    • Value label: 49kwh
  • Mar.

    • Value label: 141kwh
  • Apr.

    • Value label: 77kwh
  • May

    • Value label: 40kwh
  • Jun.

    • Value label: 41kwh
  • Jul.

    • Value label: 112kwh
  • Aug.

    • Value label: 132kwh
  • Sep.

    • Value label: 148kwh
  • Oct.

    • Value label: 121kwh
  • Nov.

    • Value label: 111kwh
  • Dec.

    • Value label: 143kwh

January

Your HTML here

February

Your HTML here

March

Your HTML here

April

Your HTML here

May

Your HTML here

June

Your HTML here

July

Your HTML here

August

Your HTML here

September

Your HTML here

October

Your HTML here

November

Your HTML here

December

Your HTML here

Barchart empty

    Bar charts with horizontal scroll

    • January

      • Value label: 74kwh
    • February

      • Value label: 49kwh
    • March

      • Value label: 141kwh
    • April

      • Value label: 77kwh
    • May

      • Value label: 40kwh
    • June

      • Value label: 41kwh
    • July

      • Value label: 112kwh
    • August

      • Value label: 132kwh
    • September

      • Value label: 148kwh
    • October

      • Value label: 121kwh
    • November

      • Value label: 111kwh
    • December

      • Value label: 143kwh

    January

    Your HTML here

    February

    Your HTML here

    March

    Your HTML here

    April

    Your HTML here

    May

    Your HTML here

    June

    Your HTML here

    July

    Your HTML here

    August

    Your HTML here

    September

    Your HTML here

    October

    Your HTML here

    November

    Your HTML here

    December

    Your HTML here

    html
    <div class="barChart">
        <div class="barChart__graphContainer">
            <ul class="barChart__graph">
                <li class="barChart__group" data-info="january">
                    <p class="barChart__label">January</p>
                    <button class="barChart__toggle">Open January</button>
                    <ul class="barChart__bars">
                        <li class="barChart__bar pat--line bg--primary" data-value="74">
                            Value label: 74kwh
                        </li>
                    </ul>
                </li>
                <!-- More `barChart__group` li -->
            </ul>
        </div>
        <div class="barChart__infos">
            <div class="barChart__info" id="january">
                <div class="barChart__infoContainer">
                    <p>January</p>
                    <p>Your HTML here</p>
                </div>
            </div>
            <!-- More `barChart__info` divs -->
        </div>
    </div>

    Here is a more complex one, the only difference is the number of barChart__bar

    • January

      • Value label: 74kwh
      • Value label: 138kwh
      • Value label: 51kwh
      • Value label: 94kwh
    • February

      • Value label: 49kwh
      • Value label: 149kwh
      • Value label: 28kwh
      • Value label: 119kwh
    • March

      • Value label: 141kwh
      • Value label: 113kwh
      • Value label: 37kwh
      • Value label: 132kwh
    • April

      • Value label: 77kwh
      • Value label: 87kwh
      • Value label: 95kwh
      • Value label: 71kwh
    • May

      • Value label: 40kwh
      • Value label: 80kwh
      • Value label: 49kwh
      • Value label: 88kwh
    • June

      • Value label: 41kwh
      • Value label: 117kwh
      • Value label: 98kwh
      • Value label: 134kwh
    • July

      • Value label: 112kwh
      • Value label: 123kwh
      • Value label: 123kwh
      • Value label: 70kwh
    • August

      • Value label: 132kwh
      • Value label: 95kwh
      • Value label: 67kwh
      • Value label: 110kwh
    • September

      • Value label: 148kwh
      • Value label: 109kwh
      • Value label: 141kwh
      • Value label: 127kwh
    • October

      • Value label: 121kwh
      • Value label: 121kwh
      • Value label: 117kwh
      • Value label: 134kwh
    • November

      • Value label: 111kwh
      • Value label: 89kwh
      • Value label: 51kwh
      • Value label: 80kwh
    • December

      • Value label: 143kwh
      • Value label: 79kwh
      • Value label: 59kwh
      • Value label: 76kwh

    January

    Your HTML here

    February

    Your HTML here

    March

    Your HTML here

    April

    Your HTML here

    May

    Your HTML here

    June

    Your HTML here

    July

    Your HTML here

    August

    Your HTML here

    September

    Your HTML here

    October

    Your HTML here

    November

    Your HTML here

    December

    Your HTML here

    html
    <div class="barChart">
        <div class="barChart__graphContainer">
            <ul class="barChart__graph">
                <li class="barChart__group" data-info="january">
                    <p class="barChart__label">January</p>
                    <button class="barChart__toggle">Open January</button>
                    <ul class="barChart__bars">
                        <li class="barChart__bar pat--line bg--primary" data-value="74">
                            Value label: 74kwh
                        </li>
                        <li class="barChart__bar  pat--thinLine bg--primary" data-value="138">
                            Value label: 138kwh
                        </li>
                        <li class="barChart__bar pat--dot bg--accent" data-value="51">
                            Value label: 51kwh
                        </li>
                        <li class="barChart__bar pat--square bg--accent" data-value="94">
                            Value label: 94kwh
                        </li>
                    </ul>
                </li>
                <!-- More `barChart__group` li -->
            </ul>
        </div>
        <div class="barChart__infos">
            <div class="barChart__info" id="january">
                <div class="barChart__infoContainer">
                    <p>January</p>
                    <p>Your HTML here</p>
                </div>
            </div>
            <!-- More `barChart__info` divs -->
        </div>
    </div>

    Javascript

    js
    // $barChart is a '.barChart' html element
    /**
     * Get bars and all data related to it that can be usefull
     */
    function buildBars() {
        return Array.from($barChart.querySelectorAll('.barChart__bar')).map(
            ($bar) => {
                return {
                    el: $bar,
                    value: Number($bar.dataset.value),
                }
            },
        )
    }
    
    /**
     * Get bar groups and all data related to it that can be usefull
     */
    function buildBarGroups() {
        const $barGroups = Array.from(
            $barChart.querySelectorAll('.barChart__group'),
        )
    
        return $barGroups.map(($barGroup) => {
            const info = $barGroup.dataset.info
                ? $barChart.querySelector(`#${$barGroup.dataset.info}`)
                : null
    
            return {
                el: $barGroup,
                toggle: $barGroup.querySelector('.barChart__toggle'),
                info,
            }
        })
    }
    
    /**
     * Get the bar with the highest value
     */
    function getHighestBar(aBars) {
        return aBars.reduce((oCarry, oBar) => {
            if (oCarry) {
                return oBar.value > oCarry.value ? oBar : oCarry
            }
    
            return oBar
        }, null)
    }
    
    /**
     * Get the percentage of a bar relative to another one
     */
    function getRelativeHeight(oBar, oReference) {
        return (oBar.value / oReference.value) * 100
    }
    
    /**
     * Manage the component rendering by setting bars height as css variable
     * to use it in out stylesheet
     */
    function render(aBars) {
        const oReference = getHighestBar(aBars)
    
        aBars.forEach((oBar) => {
            oBar.el.style.setProperty(
                '--percentage',
                `${getRelativeHeight(oBar, oReference)}%`,
            )
        })
    }
    
    /**
     * Manage the modifier responsible of the white gradient on the right if the content overflows
     */
    function manageOverflow($control) {
        const $graph = $barChart.querySelector('.barChart__graph')
        const $graphContainer = $barChart.querySelector(
            '.barChart__graphContainer',
        )
    
        if ($graph.scrollWidth > $graphContainer.offsetWidth) {
            if (!document.body.contains($control)) {
                $graphContainer.insertAdjacentElement('afterbegin', $control)
            }
        } else {
            $control.remove()
        }
    
        $barChart.classList.toggle(
            'barChart--overflow',
            $graph.scrollWidth > $graphContainer.offsetWidth,
        )
    }
    
    /**
     * Allows to open the corresponding info, uiseful to have a nice vertical transition
     * Having no information is not a crashing
     */
    function open(oCurrentBarGroup, aBarGroups) {
        aBarGroups.forEach((oBarGroup) => {
            oBarGroup.info?.classList.toggle(
                CLASS_ACTIVE,
                oCurrentBarGroup === oBarGroup,
            )
    
            oBarGroup.el.classList.toggle(
                CLASS_ACTIVE,
                oCurrentBarGroup === oBarGroup,
            )
        })
    
        return oCurrentBarGroup
    }
    
    const aBarGroups = buildBarGroups()
    const aBars = buildBars()
    let oCurrentBar = open(aBarGroups[0], aBarGroups)
    const $control = createElement({
        tag: 'button',
        innerHTML: 'Next',
        attributes: {
            class: 'barChart__control',
        },
    })
    
    window.addEventListener('resize', () => manageOverflow($control))
    
    aBarGroups.forEach((oBarGroup) =>
        oBarGroup.toggle.addEventListener('click', () => {
            oCurrentBar = open(oBarGroup, aBarGroups)
        }),
    )
    
    $control?.addEventListener('click', (e) => {
        e.preventDefault()
        const iCurrentIndex = aBarGroups.findIndex(
            (oBarGroup) => oBarGroup === oCurrentBar,
        )
    
        const iNextIndex =
            iCurrentIndex + 1 >= aBarGroups.length ? 0 : iCurrentIndex + 1
    
        oCurrentBar = open(aBarGroups[iNextIndex], aBarGroups)
        aBarGroups[iNextIndex].el.scrollIntoView({
            behaviour: 'smooth',
            inline: 'center',
            block: 'center',
        })
    })
    
    manageOverflow($control)
    render(aBars)

    Line chart

    html
    <div class="box">
        <canvas class="dsChart" data-type="line"></canvas>
    </div>
    js
    new Chartjs.Chart($chart, {
        data: {
            labels: [
                'January',
                'February',
                'March',
                'April',
                'May',
                'June',
                'July',
                'August',
                'September',
                'October',
                'November',
                'December',
            ],
            datasets: [
                // Default dataset example for temperatures.
                {
                    label: 'Line chart',
                    type: 'line',
                    data: [
                        227, 411, 442, 483, 609, 562, 427, 735, 458,
                        205, 611, 688,
                    ],
                    backgroundColor: (context) => {
                        if (context.chart.chartArea) {
                            const {
                                ctx,
                                chartArea: { top, bottom },
                            } = context.chart
                            const oGradienBg =
                                ctx.createLinearGradient(
                                    0,
                                    top,
                                    0,
                                    bottom,
                                )
                            oGradienBg.addColorStop(
                                0,
                                `${oColors.PRIMARY}40`,
                            )
                            oGradienBg.addColorStop(
                                1,
                                `${oColors.WHITE}FFF40`,
                            )
                            return oGradienBg
                        }
                        return [oColors.PRIMARY]
                    },
                    borderColor: [oColors.PRIMARY],
                    fill: true,
                    yAxisID: 'y',
                    tension: 0,
                    order: 1,
                },
            ],
        },
        options: {
            scales: {
                y: {
                    grace: '5%',
                    ticks: {
                        callback: (value) => {
                            return `${value} kWh`
                        },
                    },
                },
            },
            plugins: {
                legend: {
                    position: 'bottom',
                },
            },
        },
    })

    doughnut chart

    html
    <div class="box">
        <canvas class="dsChart" width="1" height="1" data-type="doughnut"></canvas>
    </div>
    js
    new Chartjs.Chart($chart, {
        data: {
            datasets: [
                // Default dataset example for temperatures.
                {
                    label: 'Doughnut chart',
                    type: $chart.dataset.type,
                    data: [227, 411, 688, 227, 411, 688],
                    backgroundColor: [
                        oColors.BLACK,
                        oColors.GREY,
                        oColors.GREY_OVERLAY,
                        oColors.GREY_LIGHT,
                        oColors.GREY_LIGHTER,
                        oColors.GREY_LIGHTEST,
                    ],
                },
            ],
        },
        options: {
            responsive: true,
            plugins: {
                legend: {
                    display: false,
                },
            },
        },
    })