/frontend-mentor-expenses-chart-component-main

Frontend Mentor - Expenses chart component solution

Primary LanguageSCSS

Frontend Mentor - Expenses chart component solution

Code Quality Check Netlify Status

This is a solution to the Expenses chart component challenge on Frontend Mentor. Frontend Mentor challenges help you improve your coding skills by building realistic projects.

Table of contents

Overview

The challenge

Users should be able to:

  • View the bar chart and hover over the individual bars to see the correct amounts for each day
  • See the current day’s bar highlighted in a different colour to the other bars
  • View the optimal layout for the content depending on their device’s screen size
  • See hover states for all interactive elements on the page
  • Bonus: Use the JSON data file provided to dynamically size the bars on the chart

Screenshot

Links

My process

Built with

  • Semantic HTML5 markup
  • CSS custom properties
  • Flexbox
  • CSS Grid
  • Mobile-first workflow
  • Sass - Sass stylesheet language
  • JavaScript - JavasScript language
  • webpack - Static module bundler
  • HtmlWebpackPlugin - HTML file creator (webpack plugin)
  • postcss - CSS transformer with JavScript
  • eslint - Static code analyzer
  • stylelint - Static code analyzer for css/scss
  • prettier - An opinionated code formatter
  • babel - JavaScript compiler

What I learned

I learned to use CSS grid templates with named areas and responsive area, extended code generation.

Using relative heights with CSS Grid and its alignment system. Also I used the attributes to display the day and the amount:

<div class="graph">
    <div class="graph__day" data-label="mon" data-value="$0.00"><div class="rounded-sm"></div></div>
    <div class="graph__day" data-label="tue" data-value="$0.00"><div class="rounded-sm"></div></div>
    <div class="graph__day" data-label="wed" data-value="$0.00"><div class="rounded-sm"></div></div>
    <div class="graph__day" data-label="thu" data-value="$0.00"><div class="rounded-sm"></div></div>
    <div class="graph__day" data-label="fri" data-value="$0.00"><div class="rounded-sm"></div></div>
    <div class="graph__day" data-label="sat" data-value="$0.00"><div class="rounded-sm"></div></div>
    <div class="graph__day" data-label="sun" data-value="$0.00"><div class="rounded-sm"></div></div>
</div>
.graph {
    height: 150px;
    display: grid;
    grid-auto-columns: 1fr;
    grid-auto-flow: column;
    align-items: flex-end;
    // ...

    &__day {
        height: var(--amount-percent, 50%);
        // ...
    }

    // ...

    // displaying attribute values
    &:before {
      content: attr(data-value);
        // ...
    }
    &:after {
        content: attr(data-label);
        // ...
    }
}
/**
 * @typedef {Object} Item
 * @property {string} day
 * @property {number} amount
 *
 * @param {Item[]} items
 */
function applyData(items) {
    // calculate 100%
    const max = items.reduce((carry, item) => Math.max(carry, item.amount), 0);

    // get current day name
    const today = new Date()
        .toLocaleDateString("en-US", { weekday: "short" })
        .toLocaleLowerCase();

    items.forEach((item) => {
        const amountFormatted = `$${item.amount}`;
        const percent = Math.round((item.amount / max) * 100);
        const el = document.querySelector(
            `.graph__day[data-label="${item.day}"]`
        );
        el.setAttribute("data-value", amountFormatted);
        el.toggleAttribute("data-current", item.day === today);
        el.style.setProperty("--amount-percent", `${percent}%`);
    });
}

Continued development

I think for now it's done.

Useful resources

See Build with

Author