The <activity-graph>
web component visualizes activity data. It is a simple way to display activity over time, similar to GitHub's contribution graph. It is built with accessibility, flexibility and especially client and server side rendering (SSR) in mind.
- 📦 0 dependencies
- 🎉 flexible usage via attributes
- 🎨 easily stylable via LightDOM and CSS variables
- 🖥️ supports Client and Server Side Rendering
<script
type="module"
src="https://cdn.jsdelivr.net/npm/@mariohamann/activity-graph/dist/activity-graph.min.js"
></script>
<activity-graph></activity-graph>
npm install @mariohamann/activity-graph
import "@mariohamann/activity-graph";
<activity-graph></activity-graph>
<activity-graph
range-start="2021-01-01"
range-end="2021-12-31"
activity-data="2021-01-01,2021-01-02,2021-01-03"
activity-levels="0,1,2,3,5"
first-day-of-week="1"
lang="de"
i18n='{"activities": "Aktivitäten", "less": "Weniger", "more": "Mehr"}'
></activity-graph>
range-start
(optional): The start date of the activity graph. Defaults to 1 year ago in client side rendering.range-end
(optional): The end date of the activity graph. Defaults to today in client side rendering.activity-data
: The activity data as a comma separated list of dates, e. g.2021-01-01,2021-01-02,2021-01-03
. By setting dates multiple times the activity level can be increased. See Progressive Enhancement as an alternative for client side rendering.activity-levels
(optional): The numbers define the threshold for each level. Defaults to0,1,2,3,4
. The first number is the lowest level, the last number is the highest level. The number of levels is the length of the list.0,2,4
would show a graph with three levels, where the second level has a threshold of2
and the third level has a threshold of4
first-day-of-week
: The first day of the week. Defaults to0
(Sunday).1
would be Monday,6
would be Saturday.lang
: The language of the graph. Defaults to the browser's language. The language is used for date formattingi18n
: The internationalization of the graph. Defaults to English. The object can contain the keysactivities
,less
andmore
for the respective labels.
The component uses LightDOM and where()
selectors to be easily stylable.
It supports Light and Dark Mode and uses Light Mode as default. The following classes are available to influence the mode:
.activity-graph-light
: sets the color scheme to light (default).activity-graph-dark
: sets the color scheme to dark.activity-graph-auto
: sets the color scheme to the user's system preference
To theme the graph, you can use the following CSS variables (showing their default values for Light Mode):
activity-graph {
--activity-graph-rounded: 2px;
--activity-graph-text-weight: 400;
--activity-graph-font-size: 12px;
--activity-graph-level-0-bg: #161b22;
--activity-graph-text-color: #24292e;
--activity-graph-level-0-bg: #ebedf0;
--activity-graph-level-0-border: rgba(27, 31, 35, 0.06);
--activity-graph-level-1-bg: #9be9a8;
--activity-graph-level-1-border: rgba(27, 31, 35, 0.06);
--activity-graph-level-2-bg: #40c463;
--activity-graph-level-2-border: rgba(27, 31, 35, 0.06);
--activity-graph-level-3-bg: #30a14e;
--activity-graph-level-3-border: rgba(27, 31, 35, 0.06);
--activity-graph-level-4-bg: #216e39;
--activity-graph-level-4-border: rgba(27, 31, 35, 0.06);
--activity-graph-disabled-bg: transparent;
--activity-graph-disabled-border: rgba(27, 31, 35, 0.06);
}
Tip
Target activity-graph
or activity-graph.activity-graph-dark
etc. to easily override styles.
The web component supports to progressively enhance your content. For that you can "slot" your activity-data
e. g. in a list. The web component will then take the data from every element's data-activity
and render the graph instead of the content. This way you can provide a fallback for users with JavaScript disabled.
Warning
This is the preferred implementation for client side rendering and only works there.
<activity-graph>
<ul>
<li data-activity="2024-01-03">Activity on 2024-01-03</li>
<li data-activity="2024-01-04">Activity on 2024-01-04</li>
<li data-activity="2024-01-05">Activity on 2024-01-05</li>
<li data-activity="2024-01-06">Activity on 2024-01-06</li>
</ul>
</activity-graph>
activity-graph
is provided as a pure function to be used with @enhance/ssr
for Server Side Rendering. See Official docs or NPM for more information.
Tip
There's no client-side JavaScript required.
import ActivityGraph from "@mariohamann/activity-graph/element";
import enhance from "@enhance/ssr";
const html = enhance({
elements: {
"activity-graph": ActivityGraph, // Activity Graph expects to be defined with the tag `activity-graph`
},
});
console.log(html`<activity-graph></activity-graph>`);
activity-graph
is provided as a pure function to be used with enhance-ssr-wasm. This allows you to use the component in "any language that Extism has an SDK for including Python, Ruby, .NET, Rust, Go, PHP, Java and more".
Tip
There's no client-side JavaScript required.
For implementation details see the examples by the Enhance team:
he JavaScript runtime of Extism's JavaScript PDK (which is used to compile enhance-ssr-wasm
) doesn't support any locales for Date formatting. To overcome this problem activity-graph-wasm
bundles dayjs for date formatting. As this extensively raises processing time for SSR, there are different bundles available:
dist/activity-graph-wasm(.min).js
: includes all locales of dayjs – use the most aggressive caching possible!dist/activity-graph-wasm/en(.min).js
: includes onlyen
dist/activity-graph-wasm/{locale}(.min).js
: includes only {locale} +en
Caution
Make sure to use the smallest appropriate bundle to reduce processing time.
The smallest file is dist/activity-graph-wasm/en.min.js
and is therefore recommended for testing purposes.
The component heavily relies on proper semantics, e. g. the usage of figure
, figcaption
, table
, colspan
, colgroup
etc. If you have any concerns regarding the implementation, please file an issue.