Giter VIP home page Giter VIP logo

apexcharts-card's Introduction

License HACS Supported Downloads GitHub Activity Stable Beta Community Forum

ApexCharts Card by @RomRider

Header

This is higly customizable graph card for Home-Assistant's Lovelace UI.

It is based on ApexCharts.js and offers most of the features of the library.

It is also inspired by the great mini-graph-card by @kalkih

However, some things might be broken 😁

Table of Content

Installation

HACS (recommended)

This card is available in HACS (Home Assistant Community Store). HACS is a third party community store and is not included in Home Assistant out of the box.

Manual install

  1. Download and copy apexcharts-card.js from the latest release into your config/www directory.

  2. Add the resource reference as decribed below.

CLI install

  1. Move into your config/www directory.

  2. Grab apexcharts-card.js:

$Β wget https://github.com/RomRider/apexcharts-card/releases/download/v2.1.2/apexcharts-card.js
  1. Add the resource reference as decribed below.

Add resource reference

If you configure Lovelace via YAML, add a reference to apexcharts-card.js inside your configuration.yaml:

resources:
  - url: /local/apexcharts-card.js?v=2.1.2
    type: module

Else, if you prefer the graphical editor, use the menu to add the resource:

  1. Make sure, advanced mode is enabled in your user profile (click on your user name to get there)
  2. Navigate to Configuration -> Lovelace Dashboards -> Resources Tab. Hit orange (+) icon
  3. Enter URL /local/apexcharts-card.js and select type "JavaScript Module".
  4. Restart Home Assistant.

Data processing steps

This diagrams shows how your data goes through all the steps allowed by this card:

data_processing_steps

Using the card

Main Options

⚠️ Since this card is in its debuts, you should expect breaking changes moving forward. ⚠️

The card stricly validates all the options available (but not for the apex_config object). If there is an error in your configuration, it will tell you where and display a red error card.

βœ… means required.

Name Type Default Since Description
βœ… type string v1.0.0 custom:apexcharts-card
βœ… series array v1.0.0 See series
config_templates array v1.6.0 Define a configuration once and reuse it multiple times. See config_templates
color_list array v1.6.0 Define the array of colors applied to the series. Will be overriden by each serie's color if defined. Usefull for config_templates mainly.
all_series_config object v1.6.0 If something is defined here it will apply this config to all the series. It accepts the same options as a serie minus entity. It is useful to avoid repetition but the same thing can be achieve in each serie individually. See series and all_series_config for an example
chart_type string line v1.4.0 See chart_type
update_interval string v1.1.0 By default the card updates on every state change. Setting this overrides the behaviour. Valid values are any time string, eg: 1h, 12min, 1d, 1h25, 10sec, ...
update_delay string 1500ms v1.4.0 If the chart doesn't display the last state but the one before, you'll want to increase this value, don't go over 10s, it's not necessary. You'll also want to increase this value if you are using attribute in the series. Valid values are any time strings. This is because of how Home-Assistant works with history, see here
graph_span string 24h v1.1.0 The span of the graph as a time interval. Valid values are any time string, eg: 1h, 12min, 1d, 1h25, 10sec, ...
span object v1.2.0 See span
show object v1.0.0 See show
hours_12 boolean v1.8.0 If undefined, it will follow Home-Assistant's user time format. If true, it will force time to be displayed in 12h format. If false it will force the time to be displayed in 24h format.
cache boolean true v1.0.0 Use in-browser data caching to reduce the load on Home Assistant's server
stacked boolean false v1.0.0 Enable if you want the data to be stacked on the graph
layout string v1.0.0 See layouts
header object v1.0.0 See header
now object v1.5.0 See now
y_axis_precision number 1 v1.2.0 DEPRECATED since v1.10.0 The float precision used to display numbers on the Y axis. Only works if yaxis is undefined.
yaxis array v1.9.0 See yaxis
apex_config object v1.0.0 Apexcharts API 1:1 mapping. You call see all the options here --> Options (Reference) in the Menu. See Apex Charts
experimental object v1.6.0 See experimental
locale string v1.7.0 Default is to inherit from Home-Assistant's user configuration. This overrides it and forces the locale. Eg: en, or fr. Reverts to en if locale is unknown.
brush object v1.8.0 See brush

series Options

Name Type Default Since Description
βœ… entity string v1.0.0 The entity_id of the sensor to display
attribute string v1.4.0 Instead of retrieving the state, it will retrieve an attribute of the entity. Make sure you increase update_delay if the chart doesn't reflect the last value of the attribute
name string v1.0.0 Override the name of the entity
stack_group string v2.1.0 When stacked is true, groups the different series with the name stack_group together. Only works for type: column. All series' names need to be be unique because of a bug in apexcharts.js
color string v1.1.0 Color of the serie. Supported formats: yellow, #aabbcc, rgb(128, 128, 128) or var(--css-color-variable)
opacity number 0.7 for area
else 1
v1.6.0 The opacity of the line or filled area, between 0 and 1
stroke_width number 5 v1.6.0 Change the width of the line. Only works for area and line
stroke_dash number 0 v2.1.0 Creates a dashed line. The higher the number, the bigger the dash.
type string line v1.0.0 line, area or column are supported for now
curve string smooth v1.0.0 smooth (nice curve), straight (direct line between points) or stepline (flat line until next point then straight up or down), monotoneCubic (create a monotone cubic spline)
extend_to_end boolean true v1.0.0 DEPRECATED since v2.0.0 If the last data is older than the end time displayed on the graph, setting to true will extend the value until the end of the timeline. Only works for line and area types.
extend_to boolean or string end v2.0.0 If value is end, it will extend the line/area to the end of the chart. With now, it will extend it to the current time (usefull for chart showing current and future data). If false it will not do anything. Only available for line and area types.
unit string v1.0.0 Override the unit of the sensor
float_precision number 1 v1.2.0 The precision used to display data in the legend and the tooltip. It doesn't impact how the data is displayed on the graph
fill_raw string 'null' v1.5.0 If there is any missing value in the history, last will replace them with the last non-empty state, zero will fill missing values with 0, 'null' will fill missing values with null. This is applied before group_by options
group_by object v1.0.0 See group_by
invert boolean false v1.2.0 Negates the data (1 -> -1). Usefull to display opposites values like network in (standard)/out (inverted)
transform string v1.5.0 Transform your raw data in any way you like. See transform
data_generator string v1.2.0 See data_generator
statistics object v2.0.0 Use HA statistical data (long-term). See statistics
offset string v1.3.0 This is different from the main offset parameter. This is at the series level. It is only usefull if you want to display data from for eg. yesterday on top of the data from today for the same sensor and compare the data. The time displayed in the tooltip will be wrong as will the x axis information. Valid values are any negative time string, eg: -1h, -12min, -1d, -1h25, -10sec, ... month (365.25 days / 12) and year (365.25 days) as unit will generate inconsistent result, you should use days instead.
time_delta string v2.0.0 This applies a time delta to all the datapoints of your chart after fetching them. You can cumulate it with offset. Valid values are any time strings starting with + or -, eg: -30min, +2h, -2d, ...
min number 0 v1.4.0 Only used when chart_type = radialBar, see chart_type. Used to convert the value into a percentage. Minimum value of the sensor
max number 100 v1.4.0 Only used when chart_type = radialBar, see chart_type. Used to convert the value into a percentage. Maximum value of the sensor
color_threshold object v1.6.0 See experimental
yaxis_id string v1.9.0 The identification name of the y-axis which this serie should be associated to. See yaxis
show object v1.3.0 See serie's show options
header_actions object v1.10.0 See header_actions

series' show Options

Name Type Default Since Description
legend_value boolean true v1.3.0 Show/Hide the state in the legend. Will still display the name
as_duration string v1.3.0 Will pretty print the states as durations. Doesn't affect the graph, only the tooltip/legend/header display. You provide the source unit of your sensor. Valid values are millisecond, second, minute, hour, day, week, month, year.
Eg: if the state is 345 and as_duration is set to minute then it would display 5h 45m
in_header boolean or string true v1.4.0 If show_states is enabled, this would show/hide this specific serie in the header. If set to raw (introduced in v1.7.0), it would display the latest raw state of the entity in the header bypassing any grouping/transformation done by the card. If the graph spans into the future (using data_generator): before_now would display the value just before the current time and after_now would display the value just after the current time (Introduced in v1.8.0)
name_in_header boolean true v1.8.0 Only valid if in_header: true. If false, it will hide the name of the serie under the its state in the header
header_color_threshold boolean false v1.7.0 If true and color_threshold experimental mode is enabled, it will colorize the header's state based on the threshold (ignoring opacity).
in_chart boolean true v1.4.0 If false, hides the serie from the chart
datalabels boolean or string false v1.5.0 If true will show the value of each point for this serie directly in the chart. Don't use it if you have a lot of points displayed, it will be a mess. If you set it to total (introduced in v1.7.0), it will display the stacked total value (only works when stacked: true). If you set it to percent, it will display the percentage of the serie instead of the value in the case of a pie or donut chart.
hidden_by_default boolean false v1.6.0 See experimental
extremas boolean or string false v1.7.0 If true, will show the min and the max of the serie in the chart. If the value is time, it will display also the time of the min/max value on top of the value. From v2.0.0, min or max will display the min or the max only and min+time or max+time will display the time of the min or the max. Displaying the time doesn't work with stacked: true.
in_brush boolean false v1.8.0 See brush
offset_in_name boolean true v1.8.0 If true, appends the offset information to the name of the serie. If false, it doesn't

header_actions or title_actions options

Name Type Default Since Description
tap_action object v1.10.0 Action to perform on tap. See action options
hold_action object v1.10.0 Action to perform on hold. See action options
double_tap_action object v1.10.0 Action to perform on double tap. See action options

*_action options

Name Type Default Since Description
action string more-info v1.10.0 Action to perform. Valid values are: more-info, toggle, call-service, none, navigate, url
entity string v1.10.0 Only valid for more-info. Overrides the more-info target entity. Default is to use the serie's entity
navigation_path string v1.10.0 Path to navigate to (e.g. /lovelace/0/) when action is navigate
url_path string v1.10.0 URL to open on click when action is url. The URL will open in a new tab
service string v1.10.0 Any valid Home-Assistant service
service_data object v1.10.0 Service data to include (e.g. entity_id: media_player.bedroom) when action defined as call-service
confirmation object v1.10.0 Display a confirmation popup. See confirmation

Example:

type: custom:apexcharts-card
series:
  - entity: sensor.indoor_temperature
    header_actions:
      tap_action:
        action: call-service
        service: climate.turn_on
        service_data:
          entity_id: climate.heater

confirmation options

This will popup a dialog box before running the action.

Name Type Default Since Description
text string v1.10.0 This text will be displayed in the popup
exemptions array v1.10.0 Any user declared in this list will not see the confirmation dialog. Format user: USER_ID

Example:

type: custom:apexcharts-card
series:
  - entity: sensor.indoor_temperature
    header_actions:
      tap_action:
        action: call-service
        service: script.toggle_climate
        service_data:
          entity: climate.heater
        confirmation:
          text: Are you sure?
          exemptions:
            - user: befc8496799848bda1824f2a8111e30a

statistics options

Name Type Default Since Description
type string mean v2.0.0 Type of long term statistic to pull. Can be one of min, max, mean, sum state or change
period string hour v2.0.0 Period of statistics to pull. Can be one of 5minute, hour, day, week or month
align string middle v2.0.0 Align the data points to the start, end or middle of the period of the statistics

Main show Options

Name Type Default Since Description
loading boolean true v1.0.0 Displays a spinning icon while the data is loading/updating
last_updated boolean false v1.10.0 Show the last time the chart was updated on the bottom right

header Options

Name Type Default Since Description
show boolean false v1.0.0 Show or hide the header
title string v1.1.0 The title of the chart you want to display
title_actions object v2.0.0 Actions to perform while tapping the title of the chart. See title_actions
floating boolean false v1.0.0 Makes the header float above the graph. Positionning will be supported later
show_states boolean false v1.1.0 Show or hide the states in the header
colorize_states boolean false v1.1.0 Colorize the states based on the color of the serie
standard_format boolean false v1.8.0 Display the title using the standard Home-Assistant card format
disable_actions boolean false v1.10.0 If true, disable all header actions

now Options

The position of the marker will only update when the card updates (state change or update_interval).

Name Type Default Since Description
show boolean false v1.5.0 Shows a vertical marker for the current time on the graph. Only useful if displaying data from the future
color string var(--primary-color) v1.5.0 Color of the marker. The color of the text is computed automatically.
label string v1.5.0 Text to display on the label. No label if not defined

now_marker

group_by Options

Name Type Default Since Description
func string raw v1.0.0 See func
duration string 1h v1.0.0 If func is not raw only. It builds buckets of states over duration period of time. Doesn't work for months. Eg of valid values: 2h, 1d, 10s, 25min, 1h30, ...
fill string last v1.0.0 If func is not raw only. If there is any missing value in the buckets of history data (grouped by duration), last will replace them with the last non-empty state, zero will fill missing values with 0, 'null' will fill missing values with null
start_with_last boolean false v1.8.0 If true, each bucket of data will start with the last value from the previous bucket of data. Mostly useful only with func: diff

func Options

Name Since Description
raw v1.0.0 Displays all the state history as known by Home Assistant
avg v1.0.0 Will return the average of all the states in each bucket
min v1.0.0 Will return the smallest state of each bucket
max v1.0.0 Will return the biggest state of each bucket
last v1.0.0 Will return the last state of each bucket
first v1.0.0 Will return the first state of each bucket
sum v1.0.0 Will return the sum of all the states in each bucket
median v1.0.0 Will return the median of all the states in each bucket
delta v1.0.0 Will return the delta between the biggest and smallest state in each bucket
diff v1.4.0 Will return the difference between the last and the first entry in the bucket

chart_type Options

Name Since Description
line v1.0.0 This is the default and will show a timeline. It is compatible with series.type = column, line and area
scatter v1.4.0 Displays a cloud of points without a line between the values
pie v1.4.0 This will display a pie chart with the last value computed of each sensor
donut v1.4.0 This will display a donut chart with the last value computed of each sensor, same as pie but with a hole in the center
radialBar v1.4.0 This will display a radial bar chart with the last value computed of each sensor. The value is represented in percentage only. It is required to provide min and max for each series displayed as it requires to convert the value into percentage. The default value for min is 0 and for max it is 100. This graph works well if you want to display sensors natively in percentages

Charts Type

span Options

Name Since Description
start v1.2.0 Display the graph from the begining of the minute, day, hour, week, month, year, isoWeek. isoWeek is the start of the week according to ISO 8601
end v1.2.0 Display the graph from the end of the minute, day, hour, week, month, year, isoWeek. isoWeek is the end of the week according to ISO 8601
offset v1.2.0 Offset the graph by an amount of time. To offset in the past, start with -. Eg. of valid values: -1day, -12h, 12h, 30min, ... month (365.25 days / 12) and year (365.25 days) as unit will generate inconsistent result, you should use days instead.

Span enables you to:

  • Offset the graph by an amount of time
  • start: Display the graph from the begining of the minute, day, hour, week, month, year. In this case, graph_span should be in most cases <= to 1 unit of the unit defined in start.
  • end: Display the graph from the end of the minute, day, hour, week, month, year
  • Combined with group_by in a serie, the group will begin at the tick of the start unit (+/- offset if defined)
  • Only one of start or end is supported at the same time
graph_span: If start is defined, it should be <= to 1 unit of the one defined in `start`
span:
  start: minute, day, hour, week, month or year
  end: minute, day, hour, week, month or year
  offset: To offset in the past, prefix with `-` Timerange like 1day, 12h, 10min, -12h, -1d, ...

Eg:

  • Display 24h from the start of the current day (00:00 -> 23:59)
    type: custom:apexcharts-card
    graph_span: 24h
    span:
      start: day
  • Display 24h from the start of the previous day (00:00 -> 23:59, -1 day)
    type: custom:apexcharts-card
    graph_span: 24h
    span:
      start: day
      offset: -1d
  • Display 12h between 06:00 and 18:00 of the current day
    type: custom:apexcharts-card
    graph_span: 12h
    span:
      start: day
      offset: +6h
  • Display the last 7 days, the end of the graph is the end of the current day
    type: custom:apexcharts-card
    graph_span: 7d
    span:
      end: day

transform Option

With transform, you can modify raw data comming from Home-Assistant's history using a javascript function.

Some of the things you can do:

  • Transform any state into a number (for eg. for binary_sensors)
  • Apply a different scale to your data (eg: divide by 1024 to convert bits into Kbits)
  • Do anything that javascript allows with the value

Your javascript code will receive:

  • x: a state or a value of the attribute if you defined one (it can be a string, null or a number depending on the entity type you've assigned)
  • hass: the full hass object (hass.states['other.entity'] to get the state object of another entity for eg.)
  • entity: the full state object of the entity from the history entry currently being transformed

And should return a number, a float or null.

Some examples:

  • Convert binary_sensor to numbers (1 is on, 0 is off)

    type: custom:apexcharts-card
    update_delay: 3s
    update_interval: 1min
    series:
      - entity: binary_sensor.heating
        transform: "return x === 'on' ? 1 : 0;"
  • Scale a sensor:

    type: custom:apexcharts-card
    update_delay: 3s
    update_interval: 1min
    series:
      - entity: sensor.bandwidth
        transform: "return x / 1024;"

data_generator Option

Before we start, to learn javascript, google is your friend or ask for help on the forum πŸ™‚

data_generator is an advanced feature. It enables you to build your own data out of the last state of a sensor. It completely bypasses the history retrieval and caching mecanism.

You'll need to write a javascript function which returns a [timestamp, value][]:

  • timestamp is the timestamp of the data in ms
  • value is the value of the data as a number or a float, make sure you parse it if it's a string.

Inside your javascript code, you'll have access to those variables:

  • entity: the entity object
  • start (Date object): the start Date object of the graph currently displayed
  • end (Date object): the end Date object of the graph currently displayed
  • hass: the complete hass object
  • moment: the Moment.JS object to help you manipulate time and dates

Let's take this example:

  • My sensor (sensor.test) has this state as its last state:

    FirstPeak: High
    PeakTimes:
      - '2021-01-27 03:43:00'
      - '2021-01-27 10:24:00'
      - '2021-01-27 16:02:00'
      - '2021-01-27 22:38:00'
      - '2021-01-28 04:21:00'
      - '2021-01-28 11:06:00'
      - '2021-01-28 16:40:00'
      - '2021-01-28 23:18:00'
      - '2021-01-29 05:00:00'
      - '2021-01-29 11:45:00'
      - '2021-01-29 17:19:00'
      - '2021-01-29 23:58:00'
      - '2021-01-30 05:39:00'
      - '2021-01-30 12:25:00'
      - '2021-01-30 17:59:00'
    PeakHeights:
      - 4.99
      - 1.41
      - 4.96
      - 1.33
      - 5.22
      - 1.19
      - 5.15
      - 1.14
      - 5.42
      - 1.01
      - 5.3
      - 0.99
      - 5.57
      - 0.87
      - 5.39
    unit_of_measurement: m
    friendly_name: Tides
  • This is data in the future, but I want to display them so I need to build them myself using data_generator:

    type: custom:apexcharts-card
    graph_span: 4d # I have 4 days worth of data in the future in the attributes
    span:
      start: hour # I want to display from the start of the current hours 4 days into the future
    series:
      - entity: sensor.test
        data_generator: | # This is what builds the data
          return entity.attributes.PeakTimes.map((peak, index) => {
            return [new Date(peak).getTime(), entity.attributes.PeakHeights[index]];
          });

    The result of this function call would be something like:
    [[1611718980000, 4.99], [1611743040000, 1.41], [1611763320000, 4.96], ...]

  • And this is all you need πŸŽ‰

yaxis Options. Multi-Y axis

⚠️ If this option is used, you can't define yaxis in the main apex_config option as it will be overriden.

You can have as many y-axis as there are series defined in your configuration or less.

Name Type Default Since Description
id string v1.9.0 Required if you define multiple yaxis. The identification name of the yaxis used to map it to a serie. Needs to be unique.
show boolean true v1.9.0 Whether to show or not the axis on the chart
opposite boolean false v1.9.0 If true, the axis will be shown on the right side of the chart
min auto, number or string auto v1.9.0 If undefined or auto, the min of the yaxis will be automatically calculated based on the min value of all the series associated to this axis. See below for other formats.
max auto, number or string auto v1.9.0 If undefined or auto, the min of the yaxis will be automatically calculated based on the max value of all the series associated to this axis. See below for other formats.
decimals number 1 v1.10.0 Number of decimals to show on this y-axis
apex_config object v1.9.0 Any configuration from https://apexcharts.com/docs/options/yaxis/, except min, max, show and opposite
align_to number v1.10.0 Aligns the yaxis extremas to the closest multiple of align_to. Only valid if min or max are not fixed values.

Min/Max Format

min and max support multiple types of format:

  • not set or auto (this is the default): if it is set to auto, the min or max will be automatically calculated
  • any number: if a number is set, the min or max will be fixed on the y-axis
  • ~90: if the format is ~ followed by a number, the min or max will be defined as a soft bounds
    • min: ~90 and the min of the data in the series is 120: the y-axis min value will be 90
    • min: ~90 and the min of the data in the series is 60: the y-axis min value will be 60
  • '|+20|' or '|-20|': This will add/remove the value between | | from the min/max
    • min: '|-20|': The min of the data in the series is 32, the y-axis min will be 12 (= 32 - 20)
    • max: '|+10|': The max of the data in the series is 32, the y-axis max will be 42 (= 32 + 10)

Examples

  • Simple example with one y-axis:

    type: custom:apexcharts-card
    header:
      show: true
      title: Max Soft Bounds + Min Fixed Bound
    graph_span: 20min
    series:
      - entity: sensor.random0_100
    yaxis: # only 1 yaxis, no need for id or yaxis_id
      - min: 0
        # if the sensor doesn't go above 50, the max of the axis will be 50
        # else the max will be the maximum value of the sensor
        max: ~50
        decimals: 0
        apex_config:
          tickAmount: 4
  • In this example, we have 2 sensors:

    • sensor.random0_100: goes from 0 to 100
    • sensor.random_0_1000: goes from 0 to 1000

    The min and max of both y-axis are auto calculated based on the spread of the data associated with each axis.

    multi_y_axis

    type: custom:apexcharts-card
    graph_span: 20min
    yaxis:
      - id: first # identification name of the first y-axis
        decimals: 0
        apex_config:
          tickAmount: 4
      - id: second # identification name of the second y-axis
        opposite: true # make it show on the right side
        decimals: 0
        apex_config:
          tickAmount: 4
    all_series_config:
      stroke_width: 2
    series:
      - entity: sensor.random0_100
        yaxis_id: first # this serie will be associated to the 'id: first' axis.
      - entity: sensor.random_0_1000
        yaxis_id: second # this serie will be associated to the 'id: second' axis.
      - entity: sensor.random0_100
        yaxis_id: first # this serie will be associated to the 'id: first' axis.
        transform: 'return Number(x) + 30;' # We make it go fom 30 to 130
      - entity: sensor.random0_100
        yaxis_id: first # this serie will be associated to the 'id: first' axis.
        transform: 'return Number(x) - 30;' # We make it go from -30 to 70

Apex Charts Options Example

This is how you could change some options from ApexCharts as described on the Options (Reference) menu entry.

Hundreds of options are available and it is not possible to describe them all here so check over there and ask on the forum if you need help with using them.

  • ⚠️ Some options might not work in the context of this card.
  • ⚠️ Everything which is available through the default config of this card shouldn't be defined in apex_config. If you do, it might break.
type: custom:apexcharts-card
series:
  - ...
apex_config:
  dataLabels:
    enabled: true
    dropShadow:
      enabled: true

Some options in ApexCharts can take a javascript function as an argument. To make this possible, you'll have to prefix your function with EVAL:.

⚠️ While using this EVAL: feature, there is no safeguard so use at your own risk.

Here is an example:

apex_config:
  yaxis:
    labels:
      formatter: |
        EVAL:function(value) {
          return "42";
        }

Layouts

For now, only minimal is supported: It will remove the grid, the axis and display the legend at the top. But you can use the apex_config to do whatever you want.

  • minimal

    minimal

For code junkies, you'll find the default options I use in src/apex-layouts.ts

Configuration Templates

General

  • Define your config template in the main lovelace configuration and then use it in your cards. This will avoid a lot of repetitions! It's basically YAML anchors, but without using YAML anchors and is very useful if you split your config in multiple files πŸ˜„

  • You can overload any parameter with a new one

  • Arrays will be merged by matching the index

  • You can also inherit another template from within a template.

  • You can inherit multiple templates at once by making it an array. In this case, the templates will be merged together with the current configuration in the order they are defined. This happens recursively.

    type: custom:apexcharts-card
    config_templates:
      - template1
      - template2
    # or
    type: custom:apexcharts-card
    config_templates: template1

The card templates will be applied in the order they are defined: template2 will be merged with template1 and then the local config will be merged with the result. You can still chain templates together (ie. define template in a apexcharts-card template. It will follow the path recursively).

Make sure which type of lovelace dashboard you are using before changing the main lovelace configuration:

  • managed changes are managed by lovelace UI - add the template configuration to configuration in raw editor
    • go to your dashboard
    • click three dots and Edit dashboard button
    • click three dots again and click Raw configuration editor button
  • yaml - add template configuration to your dashboard file (ui-lovelace.yaml for eg.)

Note: Templates have to be defined in all dashboards, they are not shared.

To give you an idea where to put those (in your dashboard file/RAW editor):

apexcharts_card_templates:
  default:
    color_list: ['red', 'green', 'blue']

  bandwidth_chart:
    graph_span: 24h
    config_templates: default
    header:
      show: true
      show_states: true
      colorize_states: true
    all_series_config:
      stroke_width: 2
      opacity: 0.3
      type: area

views:
  - title: Main
    panel: true
    cards:
      [...]

And then where you define your card, you can consume those templates, and/or overload it:

- type: custom:apexcharts-card
  config_templates: bandwidth_chart
  header:
    title: WAN Bandwidth
  series:
    - entity: sensor.wan_download
    - entity: sensor.wan_upload
      invert: true

In the end, this would produce the same result as but it's shorter and you can reuse that template elsewhere:

- type: custom:apexcharts-card
  graph_span: 24h
  header:
    title: WAN Bandwidth
    show: true
    show_states: true
    colorize_states: true
  all_series_config:
    stroke_width: 2
    opacity: 0.3
    type: area
  color_list: ['red', 'green', 'blue']
  series:
    - entity: sensor.wan_download
    - entity: sensor.wan_upload
      invert: true

all_series_config options

This will allow you to apply some settings to all the series avoiding repetition. It's just syntaxic sugar and doesn't add more features.

Eg:

- type: custom:apexcharts-card
  graph_span: 24h
  all_series_config:
    stroke_width: 2
    type: area
    transform: return x / 1024;
    unit: Mb/s
  series:
    - entity: sensor.wan_download
    - entity: sensor.wan_upload
      invert: true

Generates the same result as repeating the configuration in each series:

- type: custom:apexcharts-card
  graph_span: 24h
  series:
    - entity: sensor.wan_download
      stroke_width: 2
      type: area
      transform: return x / 1024;
      unit: Mb/s
    - entity: sensor.wan_upload
      invert: true
      stroke_width: 2
      type: area
      transform: return x / 1024;
      unit: Mb/s

Experimental features

⚠️ You enter the danger zone ⚠️

Configuration options

Name Type Default Since Description
color_threshold boolean false v1.6.0 Will enable the color threshold feature. See color_threshold
disable_config_validation boolean false v1.6.0 If true, will disable the config validation. Useful if you have cards adding parameters to this one. Use at your own risk.
hidden_by_default boolean false v1.6.0 Will allow you to use the hidden_by_default option. See hidden_by_default
brush boolean false v1.8.0 Will display a brush which allows you to select a portion time to display on the main chart. See brush

color_threshold experimental feature

color_threshold is an experimental feature for now since enabling it will break some other default features.

If enabled, it might:

  • display the wrong serie color in the tooltip in some cases (series with datapoints not aligned mostly)
  • display thin columns instead of the standard size
  • completely render apex_config.fill options unusable, and if you do, it will break the card

Now that you are warned, it works with:

  • chart_type: radialBar, line, pie, donut
  • series's type: column, area, line

Some notes:

  • For series's type: column, the full bar will be of the color defined. Gradient is not possible
  • For series's type: area:
    • only the filled area will be displayed with the gradient. It is not possible to do so for the line.
    • It works better with stroke_width: 1 or stroke_width: 0
  • If using invert: true, the values in color_threshold should stay the same as with invert: false.

And this is how to use it:

type: custom:apexcharts-card
experimental:
  color_threshold: true
series:
  - entity: sensor.temperature
    color_threshold:
      - value: -10
        # color can be a color name, rgb(r, g, b), '#0000ff' or var(--color-variable)
        # default is: the default color of the serie
        color: blue
        # optional opacity, value from 0 to 1.
        # only for line and area
        # Default is 1 for 'type: line' and 0.7 for `type: area`
        opacity: 1
      - value: 0
        color: cyan
      - value: 15
        color: green
      - value: 25
        color: orange

color_threshold

hidden_by_default experimental feature

Enabling this experimental feature might/will break the auto-scaling and auto-column width feature. Don't open an issue for that. It only works if all the series have a unique name.

This option is useful if you want to hide a serie from the chart by default when it's loaded as if you had clicked on the legend to disable this serie.

This is how to use it:

type: custom:apexcharts-card
experimental:
  hidden_by_default: true
series:
  - entity: sensor.temperature
    show:
      hidden_by_default: true
  - entity: sensor.temperature_office

brush experimental feature

brush will allow you to display a small chart on the bottom of the card to select a time frame to display on the main chart.

brush_image

Things to know:

  • You might have some glitches if you are using colums in either the top or the bottom of the chart. There's nothing I can do about it.
  • All the features from normal series can be applied to the brush series
  • You can configure the bottom chart the way you want with another specific apex_config also
  • It might be compute heavy and slow with a lot of history data points
  • It is recommended to not show too much data on the bottom chart for the sake of lisibility

Here is how to use it (this represents the chart above):

type: custom:apexcharts-card
experimental:
  color_threshold: true
  brush: true # This is required
graph_span: 2h # This will represent the span of the brush
brush:
  # selection_span: optional
  # defines the default selected span in the brush
  # Defaults to 1/4 of the `graph_span`
  selection_span: 10m
  # apex_config: optional
  apex_config:
    # Any ApexCharts settings you want to apply to the brush
    # Same as the standard apex_config
series:
  - entity: sensor.random0_100
    color: blue
    type: area
    stroke_width: 1
    color_threshold:
      - value: 0
        color: red
      - value: 50
        color: yellow
      - value: 100
        color: green
  - entity: sensor.random0_100
    color: blue
    stroke_width: 1
    float_precision: 0
    show:
      # in_brush: set it to true and the serie will show up in the brush
      in_brush: true
      # add this also if you want your serie to only show up in the brush
      in_chart: false

Known issues

  • Sometimes, if smoothing is used alongside area and there is missing data in the chart, the background will be glitchy. See apexcharts.js/#2180
  • binary_sensor is not yet supported.
  • Bars will span left and right of the data point. Not so great if you use func to aggregate your data. See apexcharts.js/#1688

Roadmap

Not ordered by priority:

  • Support more types of charts (pie, radial, polar area at least)
  • Support for binary_sensors
  • Support for aggregating data with exact boundaries (ex: aggregating data with 1h could aggregate from 2:00:00am to 2:59:59am then 3:00:00am to 3:59:59 exactly, etc...)
  • Display the graph from start of day, week, month, ... with support for "up to now" or until the "end of the period"
  • Support for any number of Y-axis
  • Support for logarithmic
  • Support for state mapping for non-numerical state sensors
  • Support for simple color threshold (easier to understand/write than the ones provided natively by ApexCharts)
  • Support for graph configuration templates Γ  la button-card

Examples

Simple graph

type: custom:apexcharts-card
series:
  - entity: sensor.temperature

Multiple Types of Graphs

multi-graph

type: custom:apexcharts-card
graph_span: 6h
header:
  show: false
series:
  - entity: sensor.humidity
    type: line
    name: Outside Humidity
    group_by:
      func: avg
      duration: 30min
  - entity: sensor.random0_100
    type: column
    name: Office Humidity
    group_by:
      func: avg
      duration: 30min

Aggregating data

aggregating_data

type: custom:apexcharts-card
graph_span: 1h
header:
  show: false
series:
  - entity: sensor.random0_100
    name: AVG
    curve: smooth
    type: line
    group_by:
      duration: 10min
      func: avg
  - entity: sensor.random0_100
    curve: smooth
    name: MIN
    type: line
    group_by:
      duration: 10min
      func: min
  - entity: sensor.random0_100
    curve: smooth
    name: MAX
    type: line
    group_by:
      duration: 10min
      func: max
  - entity: sensor.random0_100
    curve: smooth
    name: LAST
    type: line
    group_by:
      duration: 10min
      func: last
  - entity: sensor.random0_100
    curve: smooth
    name: FIRST
    type: line
    group_by:
      duration: 10min
      func: first

Compare data from today with yesterday

type: custom:apexcharts-card
graph_span: 1d
span:
  start: day
header:
  show: false
series:
  # data from today
  - entity: sensor.temperature
  # data from yesterday offsetted to be displayed today
  - entity: sensor.temperature
    offset: -1d

Change the line thickness

  • Change all lines thickness

    type: custom:apexcharts-card
    graph_span: 1d
    all_series_config:
      stroke_width: 2
    series:
      - entity: sensor.temperature
      - entity: sensor.humidity
  • Selective line thickness modification

    type: custom:apexcharts-card
    graph_span: 1d
    series:
      - entity: sensor.temperature
        stroke_width: 2
      - entity: sensor.humidity
        stroke_width: 6

Use apexcharts-card with auto-entities

This requires the auto-entities card

type: custom:auto-entities
filter:
  include:
    - entity_id: sensor.temperature*
      options:
        entity: this.entity_id
card:
  type: custom:apexcharts-card

Change the height of the graph

This is described in the ApexCharts.js documentation here where you can find way more options.

type: custom:apexchart-card
apex_config:
  chart:
    height: 250px
series:
  - entity: sensor.temperature

apexcharts-card's People

Contributors

dependabot[bot] avatar koying avatar lukasztackowiak avatar ondras12345 avatar romrider avatar semantic-release-bot avatar tefracky avatar testuser7 avatar thibaultmol avatar wesley-vos avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

apexcharts-card's Issues

Style attribute

The style attribute is apparently not recognized by the card. The following config returns a value.style is extraneous error:

  - type: 'custom:apexcharts-card'
    graph_span: 8d
    span:
      start: hour
    series:
      - entity: weather.openweathermap
        data_generator: |
          return.entity.attributes.datetime.map((time, index) => {
            return [new Date(time), entity.attributes.precipitation[index]];
          });
    style:
      left: 50%
      top: 65%
      width: 90%

In header: display real latest value instead of grouped one

Checklist

  • I am running the latest version of the card
  • I checked if there isn't another feature request opened with the same request
  • I checked that the feature is not already available in the dev branch

Is your feature request related to a problem? Please describe.

If group_by is enabled – currently value displayed in the header is last one from grouping values.

Describe the solution you'd like

It should display latest raw value.

Describe alternatives you've considered

Cannot imagine any.

Additional context

None.

mini-graph-card theme like

I would like share the config to get a "mini-graph-card" like graph theme.

immagine

apex_config:
  chart:
    height: 130%
  stroke:
    width: 3
  fill:
    type: solid
    opacity: 0.2

group-by and current data

Using group_by, with max function, duration 1 day and graph_span 7 days I can display series along 7 days grouped by day by day.

Anyway I cannot got the current day data, I missing something?

Thanks

declaration of 'unit' in radialBar graph

I am a huge fan of your apexchart-card and I want to switch all my old standard gauges and graphs over to your implementation.

So far I succeeded with most of the cards but I am struggling with building a gauge for anything other than percentages.

For percentages they look perfectly fine:
image

But when it comes to gauges for temperatures they are not so handy because of the forced 'percentage sign' after the value.

I found out, that you can change the unit in the radialBar apex options:
dataLabels -> values -> formatter
But it only accepts javascript which is quite difficult to add there (at least for me)

Maybe you can implement the 'unit' keyword in the yaml so we can specify the unit in there.
This would make the gauges so much more useful :-)

Thanks in advance and keep up the good work!

Hide serie in legend completely

There already is an option to hide the value of a serie in the legend, but it would be nice to completely hide it (so the serie is visible in the chart, but not in the legend). I could use this since I have a 0-value sensor to emphasize the 0 value on the y-axis.

For a 0-value, I could use the following:

legend:
  showForZeroSeries: false

But for any other fixed sensor that would not work

Problem with 'offset: -1month' plot, incorrect chart x-axis origin v1.5.0

I'm not sure if this a February related issue or what, trying to chart current day starting at midnight, -1 month starting at midnight, -2 months starting at midnight.

In the attached picture, the graph for -1 month is appears to be using the time the chart was executed as the x-axis origin, the current day and -2 months charts appear to correctly start x-axis at midnight.

1st picture: problem as generated by yaml below
2nd picture: correct plot for -1 month data in matplotlib
3rd picture: chrome javascript console

attached zip file, full data set for 3 months, more than you need ;-)

Thanks for your help and great work!

# test 13
title: T13 Multiple Bar History
panel: true
cards:
- type: vertical-stack
  cards:



  - type: custom:apexcharts-card
    header:
      show: false
    series: 
    - entity: sensor.backyard_atc_mi_temperature
      color: blue
      # offset: -1month
      type: line
    update_interval: 5m
    graph_span: 24h
    span:
      start: day
    cache: true
    apex_config:
      chart:
        height: 400
      title:
        text: 'Backyard Temperature Current'

  - type: custom:apexcharts-card
    header:
      show: false
    series: 
    - entity: sensor.backyard_atc_mi_temperature
      color: blue
      offset: -1month
      type: line
    update_interval: 5m
    graph_span: 24h
    span:
      start: day
    cache: true
    apex_config:
      chart:
        height: 400
      title:
        text: 'Backyard Temperature -1month'

  - type: custom:apexcharts-card
    header:
      show: false
    series: 
    - entity: sensor.backyard_atc_mi_temperature
      color: blue
      offset: -2month
      type: line
    update_interval: 5m
    graph_span: 24h
    span:
      start: day
    cache: true
    apex_config:
      chart:
        height: 400
      title:
        text: 'Backyard Temperature -2month'

apexcharts version:

user@ubuntu-macmini2012:~/homeassistant/www/custom-lovelace/apexcharts$ grep -o -P '.{0,20}1\.5\..{0,20}' apexcharts-card.js
-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5V11h1V5.5c
-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5z"/>\n</sv
ate,i.card_version="1.5.0",0!==i.data.length
hSpan,card_version:"1.5.0",last_fetched:new
pan:0,card_version:"1.5.0",last_fetched:new
APEXCHARTS-CARD %c v1.5.0 ","color: orange;
th("-raw")?t:ae(t);"1.5.0"!==i.card_version&

minus-one-problem-00

minus-one-problem-02

minus-one-problem-01

atc-mi-backyard.csv.zip

Be able the configure the amount of decimals to show with the data.

There is a hard limit on 1 decimal behind the dot now, in a lot of cases 2 decimals are very useful to have, for example if you graph costs: $10,00 instead of $10.0

would be great to have a option to configure this.
for example:
0,1,2 or so same concet as this:

yaxis:
decimalsInFloat: 0

Feature Request: Show current time as a bar/thin line in the chart

Would it be possible to add an option to show the current time as a bar or thin line in a chart? I may be useful when you have time series spanning past and current times, i.e span.end is in the future. Maybe as a global/main option where you can specify the width and color?

Feature Request : Cumulative bar

Thanks for this very good extension, one feature could be insterested
In case, we have a value that is calculate by the adding of two, have the detail could be interessed like this
image

Choose default toggle configuration

Hello,
First of all, thank you, because this card is just awesome !!!!

Now, I would like to be able to do something like that:
image

Meaning, by default (when opening screen), to be able to choose which of the series are toggled on (ExtΓ©rieur and Garage in the image above) and which of the series are toggled off (Salon in the image above).

I found a way to completely hide a series (which I don't understand because then, why add it in the first place ?) but not to do this.
Did I miss this possibility in the docs ? If no, do you know if this could be implemented ?
Thanks !!

question : best practice to determine version of apexcharts-card downloaded and running in browser

This is probably only a problem for 'stuck in mud' folks like me that do things on command line. However, what is best practice to check the version of apexcharts-card that is downloaded to HA server and running in current browser?

I currently use a combo of:

user@ubuntu-macmini2012:~/homeassistant/www/custom-lovelace/apexcharts$ grep -o -P '.{0,20}1\.4\..{0,20}' apexcharts-card.js
ate,i.card_version="1.4.0",0!==i.data.length
hSpan,card_version:"1.4.0",last_fetched:new
pan:0,card_version:"1.4.0",last_fetched:new
APEXCHARTS-CARD %c v1.4.0 ","color: orange;
th("-raw")?t:ae(t);"1.4.0"!==i.card_version&

and check the chrome javascript console. But as is shown in the console out, again probably only for old fart yaml editors such as I, need to make sure the yaml is updated (see picture below), clear the browser cache, exit chrome, restart chrome, reload resource in HA and yeah! I am current.

Tips? other than I am candidate for HomeKit? ;-)

If there was a clear unique version value to grep for in .js file, that would be a helpful tip.

Thanks for your great work, so useful!

apex-version

graph_span logic at entity level to compare data over period

Question/enhancement :

It seems like graph_span is at chart level only, would it possible to enable something similar at series/entity level? The specific use case I am looking at would be to graph the same entity over 2 or more periods. Compare last 24 hours to prior 24 hours for example.

Thanks! Keep up the great work!

enhancement header size

thanks for adding the header to the card
could add the h1 tag so that it picks up the standard Lovelace card size

Display non-historical data

I have a use case where I am looking to graph future events - specifically tides and have my own custom component that retrieves the forthcoming tide data into an array.

It would be great to be able to display this data rather than simply the historical data of a sensor. The data can be formatted in a similar manner as a sensor.

At the moment I can fudge this (using mini-graph card) by setting the 'current' value as the value 2 days into the future and therefore when 2 days worth of data is displayed the graph line is accurate, but of course all the timing information is incorrect.

Thanks for considering.

Opacity being overwritten by default

Checklist

  • [ x] I updated the card to the latest version available
  • [ x] I cleared the cache of my browser
  • [ x] I verified that I'm really running the lastest version in my browser console
  • [ x] I checked if there is another issue opened with the same problem

Describe the bug
A clear and concise description of what the bug is.
as per https://community.home-assistant.io/t/apexcharts-card-a-highly-customizable-graph-card/272877/255?u=davidfw1960
and Romrider comment Ah right, I forgot I override the values in the code. πŸ˜‘
Might want to open a bug :slight_smile:
Version of the card
Version: 1.5

To Reproduce
This is the configuration I used:

  fill:
    type: solid
    opacity:
      - 0.2
      - 0.2

Screenshots
If applicable, add screenshots to help explain your problem.
as per forum link
Expected behavior
A clear and concise description of what you expected to happen.

Desktop (please complete the following information):

  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional context
Add any other context about the problem here.

hovering popup disapear on graph refresh

Checklist

  • I updated the card to the latest version available
  • I cleared the cache of my browser
  • I verified that I'm really running the lastest version in my browser console
  • I checked if there is another issue opened with the same problem

Describe the bug
When hovering cursor over graph, values valid for point under cursor are displayed in popup.
However when card refreshes the data (manifested by reload indicator), the popup disappears.

See animation in screenshot section

Version of the card
Version: 1.5.0

To Reproduce
This is the configuration I used:

type: 'custom:apexcharts-card'
graph_span: 1h
span:
  end: minute
apex_config:
  stroke:
    width: 2
series:
  - entity: sensor.isp1_ping
    name: google (max)
    curve: smooth
    type: line
    color: 'rgb(200, 60, 60)'
    group_by:
      duration: 1m
      func: max
  - entity: sensor.isp1_ping
    name: google (avg)
    curve: smooth
    type: area
    color: 'rgb(255, 160, 160)'
    group_by:
      duration: 1m
      func: avg
  - entity: sensor.isp2_ping
    name: 39-1 (max)
    curve: smooth
    type: line
    color: 'rgb(60, 60, 150)'
    group_by:
      duration: 1m
      func: max
  - entity: sensor.isp2_ping
    name: 39-1 (avg)
    curve: smooth
    type: area
    color: 'rgb(160, 160, 250)'
    group_by:
      duration: 1m
      func: avg
  - entity: sensor.isp3_ping
    group_by:
      duration: 1m
      func: max
    name: 192.168.100.1

Screenshots
graph3

Expected behavior
The popup should remain until mouse cursor is moved out from the graph. Graph data refresh shouldn't affect it's appearance

Desktop (please complete the following information):

  • Firefox
  • 85.0.1

Smartphone (please complete the following information):

  • N/A

Additional context
N/A

Feature Request: Show extremas (min, max)

Would it be possible to add an option to the main show option to show the extremas, mix/max values, below the legend? Similiar to what you can do int the mini-graph card:

Mini Graph card screenshot

Way to load additional locales

Checklist

  • I am running the latest version of the card
  • I checked if there isn't another feature request opened with the same request
  • I checked that the feature is not already available in the dev branch

Is your feature request related to a problem? Please describe.

No way to define custom locales for dashboards that are not in english.

Describe the solution you'd like

Way to import and load locales for Apexcharts.js.

Describe alternatives you've considered

Currently using everywhere custom labels that do no use "February" like strings. ;)

Additional context

None.

tap_action

Checklist

  • I am running the latest version of the card
  • I checked if there isn't another feature request opened with the same request
  • I checked that the feature is not already available in the dev branch

I'd like to be able to define a tap_action for the card, similar to what can be done with the mini-graph-card. I use graphs in various places in my config and a tap_action to call a popup via browser_mod.

offset not working in data_generator

I want to use the same data to compare with previous 7 days.
Changing offset of a series to any value other than 0 makes the series stop displaying.
Also tried changing graph_span and span.offset data but no luck.
Am I doing it correctly?

v1.4.0-dev.4
offset

type: 'custom:apexcharts-card'
series:
  - entity: sensor.daily_energy
    name: A
    type: column
    offset: '-0day'
    data_generator: |
      return entity.attributes.json.map((entry) => {
        return [new Date(entry.d), entry.s];
      });
  - entity: sensor.daily_energy
    name: B
    type: column
    offset: '+0day'
    data_generator: |
      return entity.attributes.json.map((entry) => {
        return [new Date(entry.d), entry.s];
      });
graph_span: 20day
span:
  start: day
  offset: '-20day'
apex_config:
  plotOptions:
    bar:
      columnWidth: 70%
  dataLabels:
    enabled: false

I am using https://github.com/crowbarz/ha-sql_json to fetch the data from sql

Thanks for making a great addon.

Animation when the card shows up for the first time

Checklist

  • I am running the latest version of the card
  • I checked if there isn't another feature request opened with the same request
  • I checked that the feature is not already available in the dev branch

Is your feature request related to a problem? Please describe.
No not a problem but a cool useless nice to have! There is already a spinning icon but having an animation of lines (e.g. left to right drawing) would be the cherry on the cake

Describe the solution you'd like
Each line is drawn slowly, one after each other, and each pixel of a line is displayed from left to right until the display is complete

Describe alternatives you've considered
Well, when you never saw it, you don't consider. But when you already saw, too late, you cannot live without! I do not see something else which can enhance a nice introduction of graphs
BTW there are some animations when you select/deselect a line on a plot, but maybe too fast and the kind of zoom/translation/bouncing is not as pleasant as a speed constant and peaceful point after point line drawing

Additional context
like the animation parameter on mini-graph card

Bug with height in combination with minus values

First of all. Thanks for a great card. I could finally get rid of my mini-graph cards and get something usable 😍

Now, to the bug :-)

I have a card with the following config:

type: 'custom:apexcharts-card'
graph_span: 24h
update_interval: 1min
header:
  show: true
  show_states: true
  colorize_states: true
  title: KΓΆket - Temperatur
series:
  - entity: sensor.temperature_21
    curve: smooth
    type: line
  - entity: sensor.temperature_23
    curve: smooth
    type: line
apex_config:
  legend:
    show: false
  chart:
    height: 300

It seems as when the value is -20.3 (too long?) it wraps the line and therefore the height of this card differs compared to the card next to it which also has "height: 300" configured. See picture below:

image

I get the same issue with, for example, height 350 for both.

Title for graphs

When showing multiple line graphs, would be nice to have a title for them. Same as your Traffic Sources title on one of your examples on the forum

Formatting of tooltip bug

I have a graph for the forthcoming year and have used

xaxis:
  labels:
    format: 'MMM'

which displays the date as Jan/Feb/Mar etc along the x axis.

However when mouse overing the graph the tooltips comes out as

Feb 1st, 00:00:00

I’d like to change the format of the tooltip to simply Feb in this case. Using the below does not appear to work.

tooltip:
  x:
    format: 'MMM'

Date with offset option

Checklist

  • [x ] I am running the latest version of the card
  • [x ] I checked if there isn't another feature request opened with the same request
  • [ x] I checked that the feature is not already available in the dev branch

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like
add an offset for the date/time

Describe alternatives you've considered
I have a sensor that's containts date, but the data is only available 2 days after the real data, so the timestamp is wrong, can we have an option with an offset to resynchronize data and graph date

Additional context
Add any other context or screenshots about the feature request here.

Color value inherit into states

Checklist

  • [ X] I am running the latest version of the card
  • [ X] I checked if there isn't another feature request opened with the same request
  • [ X] I checked that the feature is not already available in the dev branch

Is it possible to inherit the actual color of the value in the states as well? I’ve defined the color values within color_threshold, but I guess it could an interesting feature anyway.

Documentation for Pie and Donut chart

Thanks a lot for creating this card, I love it!

However, I'm missing some documentation for the usage of pie and donut charts. Unfortuantely my donut and pie charts are not beeing plot with config:

- type: custom:apexcharts-card
  chart_type: donut
  header:
    show: true
  series:
    - entity: sensor.stocks_cloudflare_total
      name: Cloudflare
    - entity: sensor.funds_technology_fidelity_total
      name: Global Fidelity

image

Thanks

transform would get supercharged with access to history item

Good stuff @RomRider. Thanks for putting this together.

I have a use case where I am trying to chart daily usage of my xfinity internet service. I am trying to create a bar chart of daily usage for a given 'month so far' and an indication if I am on track to stay under my bandwidth cap (1229 GB/mo). I have sensors that have a daily history of usage as well as an array of 6 prior months total usage.

So, for any given day/datapoint, I need to:

  • calculate the perday bandwidth amount (bandwidth_cap/days_in_the_month)
  • determine what day of the current cycle this data represents (data_timestamp is timestamp of when data was recorded)
  • calculate thresholds of usage based on (number of days * perday)
  • color a bar or line segment with red, yellow, or green based on say under 70% (green), 70-90% (yellow), and >90% red.
  • I need to calculate this for every historical point.

The result should be a set of colorized bars that would show each day individually based on the day into the period. Note that day 1 could be over but day 2 could be under so the bars would be red then green if day 1 was a busy day and day 2 wasn't.

I have the config-template-card which allows me to use scripting over the entire apexcharts-card, however, this is only good for the current (today) instantiation of the entity.

I am looking at the transform option to provide this info, however, there is no access to the actual history item, instead, we get the historical 'x' value which is the state of the item and full access to the hass.states['sensor.xfinity_usage'] object, but this is again the current value, not the actual item that is being pulled from the history.

I think if there were an option to directly access the object structure item being transformed it would allow this capability.

So this line and this one

I think would just need to pass in the current working item to make it available as a named entity as 'x' or 'hass'.

Here is what a sample graph would look like, ideally the green bars would show based on that data points current usage not the usage as of the day it is being displayed. The following yaml was attempting to draw a line graph overlay that would show the 70% and 90% threshold lines, but it became clear that data isn't available. Note, this example is setting color based on the current state, not previous state.

image

using:

type: 'custom:config-template-card'
variables:
  THIS: 'states[''sensor.xfinity_usage'']'
  tthold: |
    (thresh,THIS) => {
      const date = new Date(THIS.attributes.raw.usageMonths[6].endDate);
      console.log(date);
      const daysmon = date.getDate();
      console.log("daysmon="+daysmon)
      console.log(THIS.attributes.data_timestamp);
      const today = new Date(THIS.attributes.data_timestamp * 1000).getDate();
      console.log(">>" + today);
      const daysleft = daysmon - today ;
      const perday = 1229/daysmon;
      console.log("usage= "+THIS.state);
      return today * perday * thresh;
    }
entities:
  - sensor.xfinity_usage
card:
  type: 'custom:apexcharts-card'
  header:
    show: true
    title: 'Xfinity Usage'
    show_states: false
    colorize_states: true
  update_interval: 12h
  experimental:
    hidden_by_default: true
    color_threshold: true
  apex_config:
    xaxis:
      labels:
        format: M/d
    yaxis:
      min: 0
      max: '${tthold(1,THIS)}'
    legend:
      show: false
    hidden_by_default: true
    color_threshold: true
  span:
    start: day
    offset: '-5d'
  graph_span: 7d
  series:
    - entity: sensor.xfinity_usage
      type: column
      name: Current
      extend_to_end: false
      fill_raw: last
      group_by:
        func: last
        duration: 1d
      show:
        legend_value: false
        datalabels: true
      color_threshold:
        - color: Red
          value: '${tthold(0.9,THIS)}'
        - color: Yellow
          value: '${tthold(0.7,THIS)}'
        - color: Green
          value: 0
    - entity: sensor.xfinity_usage
      transform: "
      console.log('this='+Object.keys(this));
      var THIS = hass.states['sensor.xfinity_usage']; 
      const thresh = 0.7;
      console.log('entity='+THIS.attributes.data_timestamp);
      const date = new Date(THIS.attributes.raw.usageMonths[6].endDate);
      console.log(date);
      const daysmon = date.getDate();
      console.log('daysmon='+daysmon);
      console.log(THIS.attributes.data_timestamp);
      const today = new Date(THIS.attributes.data_timestamp * 1000).getDate();
      console.log('>>' + today);
      const daysleft = daysmon - today ;
      const perday = 1229/daysmon;
      console.log('perday='+perday); 
      console.log('today='+today);
      console.log('thresh='+thresh);
      console.log('x='+x);
      
      return x * today * perday * thresh;
      "
      type: line
      name: Current
      extend_to_end: false
      fill_raw: last
      group_by:
        func: last
        duration: 1d 
      show:
        legend_value: false
        datalabels: true

As a reference, here what the xfinity_usage sensor looks like, there is essentially some data in the outer block like data_timestamp, usage, and total and then there are 6 months of past usage summaries with usageMonths[6] being this month so far and also contains the start/end date of the current period.

{'data_timestamp': 1612890369,
              'friendly_name': 'Xfinity Usage',
              'raw': {'courtesyAllowed': 1,
                      'courtesyRemaining': 1,
                      'courtesyUsed': 0,
                      'displayUsage': True,
                      'inPaidOverage': False,
                      'usageMonths': [{'additionalBlocksUsed': 0.0,
                                       'additionalCostPerBlock': 10.0,
                                       'additionalIncluded': 0.0,
                                       'additionalPercentUsed': 0.0,
                                       'additionalRemaining': 0.0,
                                       'additionalUnitsPerBlock': 50.0,
                                       'additionalUsed': 0.0,
                                       'allowableUsage': 1229.0,
                                       'billableOverage': 0.0,
                                       'currentCreditAmount': 0,
                                       'devices': [{'id': 'B0:39:56:99:E4:E1',
                                                    'usage': 931.0}],
                                       'displayUsage': True,
                                       'endDate': '08/31/2020',
                                       'homeUsage': 931.0,
                                       'maxCreditAmount': 0,
                                       'overageCharges': 0.0,
                                       'overageUsed': 0.0,
                                       'policy': 'limited',
                                       'policyName': '1.2 Terabyte Data Plan',
                                       'startDate': '08/01/2020',
                                       'totalUsage': 931.0,
                                       'unitOfMeasure': 'GB',
                                       'wifiUsage': 0.0},
                                      {'additionalBlocksUsed': 0.0,
                                       'additionalCostPerBlock': 10.0,
                                       'additionalIncluded': 0.0,
                                       'additionalPercentUsed': 0.0,
                                       'additionalRemaining': 0.0,
                                       'additionalUnitsPerBlock': 50.0,
                                       'additionalUsed': 0.0,
                                       'allowableUsage': 1229.0,
                                       'billableOverage': 0.0,
                                       'currentCreditAmount': 0,
                                       'devices': [{'id': 'B0:39:56:99:E4:E1',
                                                    'usage': 987.0}],
                                       'displayUsage': True,
                                       'endDate': '09/30/2020',
                                       'homeUsage': 987.0,
                                       'maxCreditAmount': 0,
                                       'overageCharges': 0.0,
                                       'overageUsed': 0.0,
                                       'policy': 'limited',
                                       'policyName': '1.2 Terabyte Data Plan',
                                       'startDate': '09/01/2020',
                                       'totalUsage': 987.0,
                                       'unitOfMeasure': 'GB',
                                       'wifiUsage': 0.0},
                                      {'additionalBlocksUsed': 0.0,
                                       'additionalCostPerBlock': 10.0,
                                       'additionalIncluded': 0.0,
                                       'additionalPercentUsed': 0.0,
                                       'additionalRemaining': 0.0,
                                       'additionalUnitsPerBlock': 50.0,
                                       'additionalUsed': 0.0,
                                       'allowableUsage': 1229.0,
                                       'billableOverage': 0.0,
                                       'currentCreditAmount': 0,
                                       'devices': [{'id': 'B0:39:56:99:E4:E1',
                                                    'usage': 730.0}],
                                       'displayUsage': True,
                                       'endDate': '10/31/2020',
                                       'homeUsage': 730.0,
                                       'maxCreditAmount': 0,
                                       'overageCharges': 0.0,
                                       'overageUsed': 0.0,
                                       'policy': 'limited',
                                       'policyName': '1.2 Terabyte Data Plan',
                                       'startDate': '10/01/2020',
                                       'totalUsage': 730.0,
                                       'unitOfMeasure': 'GB',
                                       'wifiUsage': 0.0},
                                      {'additionalBlocksUsed': 0.0,
                                       'additionalCostPerBlock': 10.0,
                                       'additionalIncluded': 0.0,
                                       'additionalPercentUsed': 0.0,
                                       'additionalRemaining': 0.0,
                                       'additionalUnitsPerBlock': 50.0,
                                       'additionalUsed': 0.0,
                                       'allowableUsage': 1229.0,
                                       'billableOverage': 0.0,
                                       'currentCreditAmount': 0,
                                       'devices': [{'id': 'B0:39:56:99:E4:E1',
                                                    'usage': 850.0}],
                                       'displayUsage': True,
                                       'endDate': '11/30/2020',
                                       'homeUsage': 850.0,
                                       'maxCreditAmount': 0,
                                       'overageCharges': 0.0,
                                       'overageUsed': 0.0,
                                       'policy': 'limited',
                                       'policyName': '1.2 Terabyte Data Plan',
                                       'startDate': '11/01/2020',
                                       'totalUsage': 850.0,
                                       'unitOfMeasure': 'GB',
                                       'wifiUsage': 0.0},
                                      {'additionalBlocksUsed': 0.0,
                                       'additionalCostPerBlock': 10.0,
                                       'additionalIncluded': 0.0,
                                       'additionalPercentUsed': 0.0,
                                       'additionalRemaining': 0.0,
                                       'additionalUnitsPerBlock': 50.0,
                                       'additionalUsed': 0.0,
                                       'allowableUsage': 1229.0,
                                       'billableOverage': 0.0,
                                       'currentCreditAmount': 0,
                                       'devices': [{'id': 'B0:39:56:99:E4:E1',
                                                    'usage': 882.0}],
                                       'displayUsage': True,
                                       'endDate': '12/31/2020',
                                       'homeUsage': 882.0,
                                       'maxCreditAmount': 0,
                                       'overageCharges': 0.0,
                                       'overageUsed': 0.0,
                                       'policy': 'limited',
                                       'policyName': '1.2 Terabyte Data Plan',
                                       'startDate': '12/01/2020',
                                       'totalUsage': 882.0,
                                       'unitOfMeasure': 'GB',
                                       'wifiUsage': 0.0},
                                      {'additionalBlocksUsed': 0.0,
                                       'additionalCostPerBlock': 10.0,
                                       'additionalIncluded': 0.0,
                                       'additionalPercentUsed': 0.0,
                                       'additionalRemaining': 0.0,
                                       'additionalUnitsPerBlock': 50.0,
                                       'additionalUsed': 0.0,
                                       'allowableUsage': 1229.0,
                                       'billableOverage': 0.0,
                                       'currentCreditAmount': 0,
                                       'devices': [{'id': 'B0:39:56:99:E4:E1',
                                                    'usage': 1099.0}],
                                       'displayUsage': True,
                                       'endDate': '01/31/2021',
                                       'homeUsage': 1099.0,
                                       'maxCreditAmount': 0,
                                       'overageCharges': 0.0,
                                       'overageUsed': 0.0,
                                       'policy': 'limited',
                                       'policyName': '1.2 Terabyte Data Plan',
                                       'startDate': '01/01/2021',
                                       'totalUsage': 1099.0,
                                       'unitOfMeasure': 'GB',
                                       'wifiUsage': 0.0},
                                      {'additionalBlocksUsed': 0.0,
                                       'additionalCostPerBlock': 10.0,
                                       'additionalIncluded': 0.0,
                                       'additionalPercentUsed': 0.0,
                                       'additionalRemaining': 0.0,
                                       'additionalUnitsPerBlock': 50.0,
                                       'additionalUsed': 0.0,
                                       'allowableUsage': 1229.0,
                                       'billableOverage': 0.0,
                                       'currentCreditAmount': 0,
                                       'devices': [{'id': 'B0:39:56:99:E4:E1',
                                                    'usage': 205.0}],
                                       'displayUsage': True,
                                       'endDate': '02/28/2021',
                                       'homeUsage': 205.0,
                                       'maxCreditAmount': 0,
                                       'overageCharges': 0.0,
                                       'overageUsed': 0.0,
                                       'policy': 'limited',
                                       'policyName': '1.2 Terabyte Data Plan',
                                       'startDate': '02/01/2021',
                                       'totalUsage': 205.0,
                                       'unitOfMeasure': 'GB',
                                       'wifiUsage': 0.0}]},
              'total': 1229.0,
              'unit_of_measurement': 'GB',
              'units': 'GB',
              'used': 205.0
}

Thanks in advance
-Fred

error when trying to integrate the card in the prototype lovelace drag and drop

Checklist

  • [X ] I am running the latest version of the card
  • [ X] I checked if there isn't another feature request opened with the same request
  • [ X] I checked that the feature is not already available in the dev branch

Is your feature request related to a problem? Please describe.
the new prototype drag and drop Lovelace editor stops the card from working
because it appends another value pair to the card that your syntax checker does not like

Describe the solution you'd like
ignore extra value pairs that other custom integration may add

Describe alternatives you've considered
not checking extra value pairs at the base level

Additional context
sorry bit long - relevant code lines

    type: 'custom:grid-dnd
        type: 'custom:apexcharts-card'
        layout:
          key: b99d9004-f09e-4299-bb37-137c53ca0c97

  - title: test2
    path: test2
    type: 'custom:grid-dnd
    cards:
      - entities:
          - entity: climate.wiser_back_room
          - entity: climate.wiser_front_room
          - entity: climate.wiser_hall
          - entity: climate.wiser_old_kitchen
          - entity: climate.wiser_mum_bedroom
          - entity: climate.wiser_mums_bath_room
          - entity: climate.wiser_middle_toilet
          - entity: climate.wiser_back_bedroom
          - entity: climate.wiser_top_bath_room
          - entity: climate.wiser_top_floor
        show_header_toggle: false
        title: Room Heating Temperatures
        type: entities
        state_color: true
        layout:
          key: 25a9ed14-9875-47b8-a75d-9168d7dd3df4
      - header:
          show: true
          title: .
          floating: false
          show_states: true
          colorize_states: true
        now:
          show: true
        graph_span: 7d
        span:
          start: minute
          offset: '-7d'
        series:
          - entity: sensor.wiser_itrv_back_room_2
            attribute: device_reception_RSSI
            color: 'rgb(128, 0, 128)'
            group_by:
              duration: 5min
              func: avg
            name: Device RSSI
            curve: stepline
            show:
              in_header: false
          - entity: sensor.wiser_itrv_back_room_2
            attribute: controller_reception_RSSI
            color: 'rgb(0, 128, 128)'
            group_by:
              duration: 5min
              func: avg
            name: Controller RSSI
            curve: stepline
            show:
              in_header: false
          - entity: climate.wiser_back_room
            attribute: percentage_demand
            color: 'rgb(0, 0, 255)'
            group_by:
              duration: 5min
              func: max
            name: Demand
            fill_raw: zero
            unit: '%'
          - entity: climate.wiser_back_room
            attribute: temperature
            color: 'rgb(0, 255, 0)'
            name: Target
            group_by:
              duration: 5min
              func: max
            curve: stepline
            unit: ℃
          - entity: climate.wiser_back_room
            attribute: current_temperature
            color: 'rgb(255, 0, 0)'
            group_by:
              duration: 5min
              func: max
            name: Current
            unit: ℃
          - entity: sensor.outdoor_temperature
            color: 'rgb(128, 128, 128)'
            group_by:
              duration: 10min
              func: avg
            name: Outdoor
        y_axis_precision: 0
        apex_config:
          stroke:
            width:
              - 2
              - 2
              - 3
              - 3
              - 3
              - 3
          yaxis:
            - show: false
              decimalsInFloat: 0
              min: -125
              max: 0
            - show: false
              decimalsInFloat: 0
              min: -125
              max: 0
            - show: true
              opposite: true
              min: -25
              max: 100
              decimalsInFloat: 0
            - show: true
              decimalsInFloat: 0
              min: -7
              max: 30
            - show: false
              decimalsInFloat: 0
              min: -7
              max: 30
            - show: false
              decimalsInFloat: 0
              min: -7
              max: 30
          xaxis:
            type: datetime
            zoom:
              type: x
              enabled: true
              autoScaleYaxis: true
          chart:
            type: line
            stacked: false
            height: 350
            zoom:
              type: x
              enabled: true
              autoScaleYaxis: true
            toolbar:
              show: true
              offsetX: -40
              offsetY: 0
              tools:
                download: true
                selection: true
                zoom: true
                zoomin: false
                zoomout: false
                pan: true
                reset: true
              autoSelected: zoom
          grid:
            borderColor: 'rgb(40, 40, 40)'
            strokeDashArray: 0
            position: back
            row:
              colors:
                - 'rgb(60, 60, 60)'
                - transparent
              opacity: 0.1
            column:
              colors:
                - 'rgb(60, 60, 60)'
                - transparent
              opacity: 0.1
            xaxis:
              lines:
                show: true
            padding:
              top: 5
              right: 4
              bottom: 10
              left: 4
          title:
            text: Back Room Heating
            align: centre
            margin: 0
            offsetX: 5
            offsetY: -75
            floating: true
            style:
              fontSize: 22px
              fontWeight: normal
              fontFamily: undefined
              color: 'rgb(255, 255, 255)'
        show:
          loading: false
        type: 'custom:apexcharts-card'
        layout:
          key: b99d9004-f09e-4299-bb37-137c53ca0c97

Screenshot 2021-02-05 003037

the red part should look like

Screenshot 2021-02-05 010032

Throttle refresh?

The bottom chart in this picture, two of the entities have a fair number of points about 30k each and are updating subsecond. The graph show the 'spinner' updating a lot. Is there a way to throttle updates, perhaps an option to set an update period in seconds, also to only plot every x values? On a 3.2 ghz i7 mac mini in chrome the lag shows, worried that charts in your tool will be very heavy. Thanks for your work!


  - type: custom:apexcharts-card
    series: 
    - entity: sensor.backyard_sensor_temperature
    cache: true

  - type: custom:apexcharts-card
    series: 
    - entity: sensor.backyard_govee_temperature
    - entity: sensor.backyard_sensor_temperature
    - entity: sensor.backyard_atc_mi_temperature
    cache: true

temp-plot

Stacked option, y-axis : v1.1.0-dev.1

In v1.1.0-dev.1, I'm not sure if I am using the 'stacked' option correctly, the y-axis seems to odd:

  - type: custom:apexcharts-card
    series: 
    - entity: sensor.backyard_govee_temperature
    - entity: sensor.backyard_sensor_temperature
    - entity: sensor.backyard_atc_mi_temperature
    update_interval: 15s
    hours_to_show: 24
    cache: true
    stacked: true

stacked

Add total datalabel on stacked charts

Hello,

With a bar graph like this one:
image

I would like to know if it would be possible to display the total datalabel per column instead of the label for each element in the stack.
So for column 1 display only 18.4, column 2 display only 23.7, ...
I think that's what they discuss here apexcharts/apexcharts.js#450 but I'm not sure if have access to formatter here ?

Title card

May can you add the option to set a card's title?

Charts disappear after HA update or restart

OK some weirdness I noticed yesterday. Just installed latest beta of HA and it’s zeroed out (most) all of my graphs:
image
The entities are in recorder and I can see states graphed for the entity eg:
image
Latest 1.4 version

Selective Stacking

Thank you and great job!

I guess it would be better to choose what series stacking together instead all for graph.

Add func options: last not null and/or last > 0

Hello,
Regarding this:
image

Would it be possible to have a function quite equivalent to last, but that would take the last not null/empty or even the last > 0 value ?

Usecase is that we can have a value that is evaluated by a WS. Sometimes, the WS fails and the value is not returned or is evaluated to zero. In this case, the last function isn't working and shows zero instead of a previous correct value.

Feature request: dynamic y-axis upper/lower across multiple charts based on HA entity

Your thoughts on an idea for dynamic y-axis based on some entity and formula.

Being able to have a fixed upper and lower limit on the y-axis lets you show the detail and subtleties of data. But two frustrations often occur.

First, you have multiple graphic panels with fixed axis values. You want to change them all to a different common set of values. It's a search and replace in YAML, and since I do not use GUI to manage my Lovelace, I don't know how you would do this in GUI.

Second, if you have a y-scale that can either move up and down or expand and contract based on some dynamic input. For example, outdoor temperatures can range from very low (below 32 or 0) to very high ( 100+ or 40+) . Having the whole range in this all the time, yields charts without detail. So being able to set the upper and lower y-axis value based on some formula on a Home Assistant entity, would allow for this. For example, month of year, a lagging moving average, or any other entity that you could expose in HA with a formula applied.

The issue with a fixed 'min' and 'max' option is that, 1st you cannot have a common one across charts, and 2nd this is not a really good way to understand change if your y scale is changing without your control.

It seems like ApexCharts allows a formula for the min and max values, but I am still trying to figure it out. And, if possible at all, some kind of 'decorator' to bring in a Home Assistant 'input_number' or 'entity' to a ApexCharts 'function' would be needed for what I am trying to describe.

min: Number || Function
Lowest number to be set for the y-axis. The graph drawing beyond this number will be clipped off
You can also pass a function here which should return a number. The function accepts an argument which by default is the smallest value in the y-axis. function(min) { return min }

Thanks for your thoughts.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.