Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce scriptable options (bubble chart) #4671

Merged
merged 3 commits into from Aug 24, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/SUMMARY.md
Expand Up @@ -10,6 +10,7 @@
* [Interactions](general/interactions/README.md)
* [Events](general/interactions/events.md)
* [Modes](general/interactions/modes.md)
* [Options](general/options.md)
* [Colors](general/colors.md)
* [Fonts](general/fonts.md)
* [Configuration](configuration/README.md)
Expand All @@ -34,7 +35,7 @@
* [Category](axes/cartesian/category.md)
* [Linear](axes/cartesian/linear.md)
* [Logarithmic](axes/cartesian/logarithmic.md)
* [Time](axes/cartesian/time.md)
* [Time](axes/cartesian/time.md)
* [Radial](axes/radial/README.md)
* [Linear](axes/radial/linear.md)
* [Labelling](axes/labelling.md)
Expand Down
68 changes: 48 additions & 20 deletions docs/charts/bubble.md
@@ -1,6 +1,6 @@
# Bubble Chart

A bubble chart is used to display three dimensions of data at the same time. The location of the bubble is determined by the first two dimensions and the corresponding horizontal and vertical axes. The third dimension is represented by the size of the individual bubbles.
A bubble chart is used to display three dimensions of data at the same time. The location of the bubble is determined by the first two dimensions and the corresponding horizontal and vertical axes. The third dimension is represented by the size of the individual bubbles.

{% chartjs %}
{
Expand Down Expand Up @@ -38,34 +38,60 @@ var myBubbleChart = new Chart(ctx,{

The bubble chart allows a number of properties to be specified for each dataset. These are used to set display properties for a specific dataset. For example, the colour of the bubbles is generally set this way.

All properties, except `label` can be specified as an array. If these are set to an array value, the first value applies to the first bubble in the dataset, the second value to the second bubble, and so on.
| Name | Type | [Scriptable](../general/options.md#scriptable-options) | [Indexable](../general/options.md#indexable-options) | Default
| ---- | ---- | :----: | :----: | ----
| [`backgroundColor`](#styling) | [`Color`](../general/colors.md) | Yes | Yes | `'rgba(0,0,0,0.1)'`
| [`borderColor`](#styling) | [`Color`](../general/colors.md) | Yes | Yes | `'rgba(0,0,0,0.1)'`
| [`borderWidth`](#styling) | `Number` | Yes | Yes | `3`
| [`data`](#data-structure) | `Object[]` | - | - | **required**
| [`hoverBackgroundColor`](#interactions) | [`Color`](../general/colors.md) | Yes | Yes | `undefined`
| [`hoverBorderColor`](#interactions) | [`Color`](../general/colors.md) | Yes | Yes | `undefined`
| [`hoverBorderWidth`](#interactions) | `Number` | Yes | Yes | `1`
| [`hoverRadius`](#interactions) | `Number` | Yes | Yes | `4`
| [`hitRadius`](#interactions) | `Number` | Yes | Yes | `1`
| [`label`](#labeling) | `String` | - | - | `undefined`
| [`pointStyle`](#styling) | `String` | Yes | Yes | `circle`
| [`radius`](#styling) | `Number` | Yes | Yes | `3`

| Name | Type | Description
| ---- | ---- | -----------
| `label` | `String` | The label for the dataset which appears in the legend and tooltips.
| `backgroundColor` | `Color/Color[]` | The fill color for bubbles.
| `borderColor` | `Color/Color[]` | The border color for bubbles.
| `borderWidth` | `Number/Number[]` | The width of the point bubbles in pixels.
| `hoverBackgroundColor` | `Color/Color[]` | Bubble background color when hovered.
| `hoverBorderColor` | `Color/Color[]` | Bubble border color when hovered.
| `hoverBorderWidth` | `Number/Number[]` | Border width of point when hovered.
| `hoverRadius` | `Number/Number[]` | Additional radius to add to data radius on hover.
### Labeling

## Config Options
`label` defines the text associated to the dataset and which appears in the legend and tooltips.

The bubble chart has no unique configuration options. To configure options common to all of the bubbles, the [point element options](../configuration/elements.md#point-configuration) are used.
### Styling

The style of each bubble can be controlled with the following properties:

| Name | Description
| ---- | ----
| `backgroundColor` | bubble background color
| `borderColor` | bubble border color
| `borderWidth` | bubble border width (in pixels)
| `pointStyle` | bubble [shape style](../configuration/elements#point-styles)
| `radius` | bubble radius (in pixels)

All these values, if `undefined`, fallback to the associated [`elements.point.*`](../configuration/elements.md#point-configuration) options.

### Interactions

The interaction with each bubble can be controlled with the following properties:

| Name | Description
| ---- | -----------
| `hoverBackgroundColor` | bubble background color when hovered
| `hoverBorderColor` | bubble border color hovered
| `hoverBorderWidth` | bubble border width when hovered (in pixels)
| `hoverRadius` | bubble **additional** radius when hovered (in pixels)
| `hitRadius` | bubble **additional** radius for hit detection (in pixels)

All these values, if `undefined`, fallback to the associated [`elements.point.*`](../configuration/elements.md#point-configuration) options.

## Default Options

We can also change the default values for the Bubble chart type. Doing so will give all bubble charts created after this point the new defaults. The default configuration for the bubble chart can be accessed at `Chart.defaults.bubble`.

## Data Structure

For a bubble chart, datasets need to contain an array of data points. Each point must implement the [bubble data object](#bubble-data-object) interface.

### Bubble Data Object

Data for the bubble chart is passed in the form of an object. The object must implement the following interface. It is important to note that the radius property, `r` is **not** scaled by the chart. It is the raw radius in pixels of the bubble that is drawn on the canvas.
Bubble chart datasets need to contain a `data` array of points, each points represented by an object containing the following properties:

```javascript
{
Expand All @@ -75,7 +101,9 @@ Data for the bubble chart is passed in the form of an object. The object must im
// Y Value
y: <Number>,

// Radius of bubble. This is not scaled.
// Bubble radius in pixels (not scaled).
r: <Number>
}
```

**Important:** the radius property, `r` is **not** scaled by the chart, it is the raw radius in pixels of the bubble that is drawn on the canvas.
31 changes: 8 additions & 23 deletions docs/charts/line.md
Expand Up @@ -6,11 +6,11 @@ A line chart is a way of plotting data points on a line. Often, it is used to sh
"type": "line",
"data": {
"labels": [
"January",
"February",
"March",
"April",
"May",
"January",
"February",
"March",
"April",
"May",
"June",
"July"
],
Expand Down Expand Up @@ -62,7 +62,7 @@ All point* properties can be specified as an array. If these are set to an array
| `pointBorderColor` | `Color/Color[]` | The border color for points.
| `pointBorderWidth` | `Number/Number[]` | The width of the point border in pixels.
| `pointRadius` | `Number/Number[]` | The radius of the point shape. If set to 0, the point is not rendered.
| `pointStyle` | `String/String[]/Image/Image[]` | Style of the point. [more...](#pointstyle)
| `pointStyle` | `String/String[]/Image/Image[]` | Style of the point. [more...](../configuration/elements#point-styles)
| `pointHitRadius` | `Number/Number[]` | The pixel size of the non-displayed point that reacts to mouse events.
| `pointHoverBackgroundColor` | `Color/Color[]` | Point background color when hovered.
| `pointHoverBorderColor` | `Color/Color[]` | Point border color when hovered.
Expand All @@ -75,29 +75,14 @@ All point* properties can be specified as an array. If these are set to an array
### cubicInterpolationMode
The following interpolation modes are supported:
* 'default'
* 'monotone'.
* 'monotone'.

The 'default' algorithm uses a custom weighted cubic interpolation, which produces pleasant curves for all types of datasets.

The 'monotone' algorithm is more suited to `y = f(x)` datasets : it preserves monotonicity (or piecewise monotonicity) of the dataset being interpolated, and ensures local extremums (if any) stay at input data points.

If left untouched (`undefined`), the global `options.elements.line.cubicInterpolationMode` property is used.

### pointStyle
The style of point. Options are:
* 'circle'
* 'cross'
* 'crossRot'
* 'dash'.
* 'line'
* 'rect'
* 'rectRounded'
* 'rectRot'
* 'star'
* 'triangle'

If the option is an image, that image is drawn on the canvas using [drawImage](https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/drawImage).

### Stepped Line
The following values are supported for `steppedLine`:
* `false`: No Step Interpolation (default)
Expand Down Expand Up @@ -127,7 +112,7 @@ Chart.defaults.line.spanGaps = true;

## Data Structure

The `data` property of a dataset for a line chart can be passed in two formats.
The `data` property of a dataset for a line chart can be passed in two formats.

### Number[]
```javascript
Expand Down
18 changes: 17 additions & 1 deletion docs/configuration/elements.md
Expand Up @@ -18,14 +18,30 @@ Global point options: `Chart.defaults.global.elements.point`
| Name | Type | Default | Description
| -----| ---- | --------| -----------
| `radius` | `Number` | `3` | Point radius.
| `pointStyle` | `String` | `circle` | Point style.
| [`pointStyle`](#point-styles) | `String` | `circle` | Point style.
| `backgroundColor` | `Color` | `'rgba(0,0,0,0.1)'` | Point fill color.
| `borderWidth` | `Number` | `1` | Point stroke width.
| `borderColor` | `Color` | `'rgba(0,0,0,0.1)'` | Point stroke color.
| `hitRadius` | `Number` | `1` | Extra radius added to point radius for hit detection.
| `hoverRadius` | `Number` | `4` | Point radius when hovered.
| `hoverBorderWidth` | `Number` | `1` | Stroke width when hovered.

### Point Styles

The following values are supported:
- `'circle'`
- `'cross'`
- `'crossRot'`
- `'dash'`
- `'line'`
- `'rect'`
- `'rectRounded'`
- `'rectRot'`
- `'star'`
- `'triangle'`

If the value is an image, that image is drawn on the canvas using [drawImage](https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/drawImage).

## Line Configuration
Line elements are used to represent the line in a line chart.

Expand Down
13 changes: 7 additions & 6 deletions docs/general/README.md
@@ -1,9 +1,10 @@
# General Chart.js Configuration
# General Configuration

These sections describe general configuration options that can apply elsewhere in the documentation.
These sections describe general configuration options that can apply elsewhere in the documentation.

* [Colors](./colors.md) defines acceptable color values
* [Font](./fonts.md) defines various font options
* [Interactions](./interactions/README.md) defines options that reflect how hovering chart elements works
* [Responsive](./responsive.md) defines responsive chart options that apply to all charts.
* [Device Pixel Ratio](./device-pixel-ratio.md) defines the ratio between display pixels and rendered pixels
* [Device Pixel Ratio](./device-pixel-ratio.md) defines the ratio between display pixels and rendered pixels.
* [Interactions](./interactions/README.md) defines options that reflect how hovering chart elements works.
* [Options](./options.md) scriptable and indexable options syntax.
* [Colors](./colors.md) defines acceptable color values.
* [Font](./fonts.md) defines various font options.
48 changes: 48 additions & 0 deletions docs/general/options.md
@@ -0,0 +1,48 @@
# Options

## Scriptable Options

Scriptable options also accept a function which is called for each data and that takes the unique argument `context` representing contextual information (see [option context](options.md#option-context)).

Example:

```javascript
color: function(context) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I initially implemented scriptable options as a function taking 2 arguments: an index and the context (see the datalabels plugin) - index being the dataset index if the option is resolved for a dataset element (line of a line chart) or the data index if the option is for a data element (point of a line chart).

Having the index as first argument would allow to integrate with external functions (e.g. returning a color for a given index (return index % size)). After discussing with @etimberg, we agreed to remove that first argument and keep only the context.

Thoughts?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To illustrate my previous message: let's say a third party library provides the following function:

function colorize(i) {
	return color_palette[i % color_palette.length];
}

Then, if index is provided, it's easy to plug an option to that function:

point: {
    color: colorize
}

Instead of:

point: {
    color: function(context) {
        return colorize(context.dataIndex);
    }
}

However, not sure how this use case is common or will work as-is most of the time, and having this first index argument might be burden later if we realize it's more confusing than helpful. So I think function(context) is better, just want to be sure we are all on the same page.

return context.data < 0 ? 'red' : // draw negative values in red
index%2 ? 'blue' : 'green'; // else, alternate values in blue and green
}
```

> **Note:** scriptable options are only supported by a few bubble chart options.

## Indexable Options

Indexable options also accept an array in which each item corresponds to the element at the same index. Note that this method requires to provide as many items as data, so, in most cases, using a [function](#scriptable-options) is more appropriated if supported.

Example:

```javascript
color: [
'red', // color for data at index 0
'blue', // color for data at index 1
'green', // color for data at index 2
'black', // color for data at index 3
//...
]
```

## Option Context

The option context is used to give contextual information when resolving options and currently only applies to [scriptable options](#scriptable-options).

The context object contains the following properties:

- `datasetIndex`: index of the current dataset
- `datasetCount`: number of datasets
- `dataset`: dataset at index `datasetIndex`
- `dataIndex`: index of the current data
- `dataCount`: number of data
- `data`: value of the current data
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

data or value? (I picked data to be consistent with dataIndex and dataCount)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like data

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I asked because data can be confusing: could be chart.data, dataset.data or dataset.data[i]

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup, I was thinking about that more. maybe change it to dataValue?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will remove it to expose the minimal set.

- `chart`: the associated chart
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is part of the public API, we need to be sure we want to expose all these properties.

Thoughts?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm OK with these properties

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least, we need to expose chart, datasetIndex and dataIndex properties.

The other values can be retrieved as follow:

  • datasetCount: chart.data.datasets.length
  • dataset: chart.data.datasets[datasetIndex]
  • dataCount: chart.data.datasets[datasetIndex].data.length
  • data: chart.data.datasets[datasetIndex].data[dataIndex]

dataset is always needed to resolve options (since it contains some of them), so it would not cost more to include it to the context. I think most use cases of scriptable options will be to derive the data value, however data is (almost) never required to resolve options, so it's an additional cost to expose it to the context. I'm really not sure about exposing (right now) datasetCount and dataCount.

If we expose only chart, datasetIndex, dataIndex and dataset:

  • datasetCount: chart.data.datasets.length
  • dataCount: dataset.data.length
  • data: dataset.data[dataIndex]

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think chart, datasetIndex, dataIndex and dataset is the minimum. The only reason to include the other properties is to save users code if they want to get those values.

I'm also OK with the minimal set of properties to keep our code smaller.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can start with the minimal set and add more if requested. Like that we limit probabilities of later deprecations.


**Important**: since the context can represent different types of entities (dataset, data, etc.), some properties may be `undefined` so be sure to test any context property before using it.
6 changes: 6 additions & 0 deletions samples/samples.js
Expand Up @@ -167,6 +167,12 @@
title: 'HTML tooltips (points)',
path: 'tooltips/custom-points.html'
}]
}, {
title: 'Scriptable',
items: [{
title: 'Bubble Chart',
path: 'scriptable/bubble.html'
}]
}, {
title: 'Advanced',
items: [{
Expand Down