Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 53 additions & 41 deletions histogram_chart/README.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,56 @@
# Histogram Chart

### Goal

In this guide, we will create a Histogram Chart that subdivides a numerical range into bins, and counts the number of data points within each segment. The resulting bar chart provides a discrete estimate of the probability density function.

![histogram_chart](https://user-images.githubusercontent.com/27631976/198895261-367ac1e3-ceee-4f6b-8b19-f0f501034d4b.png)

### Full code example

```jsx
CustomChart {
fields {
field grain {
type: 'dimension'
}
field metric {
type: 'dimension' // this type can be dimenson or measure depends on the type of field that you want to create the histogram on
}
}
template: @vgl
{
"data": {"values": @{values}},
"transform": [
{"bin": {"maxbins": 40}, "field": @{fields.metric.name}, "as": "binned_price"}
],
"mark": {
"type": "bar",
"tooltip": true
},
"encoding": {
"x": {"field": "binned_price", "type": "quantitative", "bin": {"binned": true, "step": 20}},
"x2": {"field": "binned_price_end"},
"y": {"aggregate": "count"}
}
}
;;
}
```

### Applying the chart

![applying_histogram_custom_chart](https://user-images.githubusercontent.com/27631976/198895642-e79649d7-b790-40c0-8965-d6eb018d8be5.png)
This is an updated and backwards-compatible single-series histogram chart for Holistics, built with Vega-Lite.

It bins a numeric field and counts a dimension per bin using `mark: bar`. Axis labels are dynamically generated based on the selected fields.

---

## ✅ Features

- 📊 Single-series histogram
- 🧮 Configurable number of bins
- 🏷️ Automatic axis labeling:
- X-axis: uses the binned field name
- Y-axis: "Count of {grain field}"
- 🖋 Optional chart title override

---

## 📥 Fields

| Field | Type | Description |
| -------- | -------------------- | ------------------------------------------- |
| `grain` | Dimension | The dimension to count (e.g. Examiner Name) |
| `metric` | Dimension or Measure | The numeric field to bin (e.g. hours/day) |

---

## 🧰 Options

| Option | Type | Default | Description |
| ------------- | ------------ | ------------- | ----------------------- |
| `max_bins` | number-input | `20` | Maximum number of bins |
| `chart_title` | input | `"Histogram"` | Optional title override |

---

## 🔎 Example Output

A simple bar histogram with dynamic binning and axis labels:

- Y-axis: `"Count of Examiner Name"`
- X-axis: `"Median Examiner hr/d binned"`

---

## 📁 Files

- `README.md` – this documentation
- `vgl.aml` – the Holistics CustomChart definition

---

## 🧠 Notes

If you want to compare **multiple series** in a histogram (e.g. by time period or event type), check out [`histogram_multi_series`](../histogram_multi_series).
71 changes: 71 additions & 0 deletions histogram_chart/histogram_chart.vgl.aml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Histogram Chart — Single-Series
//
// Renders a bar histogram with binning on a numeric field.
// Uses the selected fields to dynamically set axis titles.
// Cleaned and compatible with the original implementation, with an optional chart title override.

CustomChart {
fields {
field grain {
label: 'Dimension to count'
type: 'dimension'
}
field metric {
label: "Measure to bin"
type: 'dimension' // this could be either a dimension or measure
}
}

options {
option max_bins {
label: "Max bins"
type: 'number-input'
default_value: 20
}
option chart_title {
label: "Chart title"
type: 'input'
default_value: "Histogram"
}
}

template: @vgl
{
"title": "@{options.chart_title.value}",
"data": {
"values": @{values}
},
"transform": [
{
"bin": {
"maxbins": @{options.max_bins.value}
},
"field": @{fields.metric.name},
"as": "@{fields.metric.name} binned"
}
],
"mark": {
"type": "bar",
"tooltip": true
},
"encoding": {
"x": {
"field": "@{fields.metric.name} binned",
"type": "quantitative",
"title": "@{fields.metric.name} binned"
},
"x2": {
"field": "@{fields.metric.name} binned_end"
},
"y": {
"aggregate": "count",
"title": "Count of @{fields.grain.name}"
},
"tooltip": [
{ "field": "@{fields.metric.name} binned", "type": "quantitative" },
{ "aggregate": "count", "type": "quantitative", "title": "Count" }
]
}
}
;;
}
67 changes: 67 additions & 0 deletions histogram_multi_series/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Histogram: Multi-Series Comparison

This chart renders a histogram of a numeric field across multiple series, using step-interpolated **area charts**. It is ideal for comparing the **shape and distribution** of different categories or time slices.

---

## ✅ Features

- 📊 Step-area histogram using Vega-Lite
- 🔢 Configurable number of bins
- 🏷 Customizable chart title and axis labels
- 🎨 Per-series color encoding
- 🧱 Two comparison modes:
- `"Stacked"`: Percent contribution by series (stacked area)
- `"Overlay"`: Compare distributions side-by-side (overlaid areas)

---

## 📥 Fields

| Field | Type | Description |
| -------- | -------------------- | --------------------------------------------- |
| `grain` | Dimension | Entity to count (e.g. ID, Examiner Name) |
| `metric` | Dimension or Measure | Numeric field to bin (e.g. hours/day) |
| `series` | Dimension | Category to group by (e.g. Event Type, Month) |

---

## 🧰 Options

| Option | Type | Default | Description |
| ------------------- | ------------ | --------------------------- | ------------------------------------------------------- |
| `max_bins` | number-input | `20` | Maximum number of histogram bins |
| `stack_bars` | select | `"none"` | `"stacked"` or `"none"` (overlay) |
| `render_as_percent` | toggle | `false` | If enabled, stacks to 100% per bin (percent comparison) |
| `chart_title` | input | `"Histogram by Series"` | Optional title override |
| `x_axis_label` | input | `"Binned Value"` | Custom X-axis label |
| `y_axis_label` | input | `"Count"` or `"Percentage"` | Custom Y-axis label |

---

## 📊 Output

Renders a normalized area chart with step interpolation. Each series is color-coded and optionally stacked or overlaid.

This chart is especially useful for:

- Comparing durations across phases or time periods
- Viewing distribution shifts over categories

## 🖼 Preview

![Histogram Multi-Series Preview](./histogram_multi_series_chart.png)

---

## 📁 Files

- `README.md` — this file
- `vgl.aml` — the Holistics CustomChart spec

---

## 🧠 Notes

- The `"render_as_percent"` option overrides `stack_bars` and always uses `stack: "normalize"`.
- For a single-series histogram, use the [`histogram_chart`](../histogram_chart) version instead.
116 changes: 116 additions & 0 deletions histogram_multi_series/histogram_multi_series.vgl.aml
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// Custom Histogram by Series Chart for Holistics
//
// Displays a histogram of a numeric metric (e.g. hours/day), grouped by a series (e.g. event type).
// Renders a step-area chart with stacking or overlay mode.
// Axis labels are derived from the selected fields automatically.
//
// Fields:
// - grain: Dimension to count (e.g. ID or name)
// - metric: Numeric field to bin (e.g. duration)
// - series: Categorical grouping field (e.g. event type, date)
//
// Options:
// - max_bins: Number of histogram bins
// - stack_bars: Select between stacked or grouped layout
// - chart_title: Custom title for the chart

CustomChart {
fields {
field grain {
label: 'Dimension to count'
type: 'dimension'
}
field metric {
label: "Measure to bin"
type: 'dimension'
}
field series {
label: "Series (e.g., Event Type)"
type: 'dimension'
}
}

options {
option max_bins {
label: "Max bins"
type: 'number-input'
default_value: 20
}
option stack_bars {
label: "Stacking Mode"
type: 'select'
default_value: "none"
options: [
{ label: "Overlay (Not Stacked)", value: "none" },
{ label: "Stacked", value: "zero" }
]
}
option chart_title {
label: "Chart title"
type: 'input'
default_value: ""
}
}

template: @vgl {
"title": "@{options.chart_title.value}",
"data": {
"values": @{values}
},
"selection": {
"seriesSelector": {
"type": "multi",
"fields": ["@{fields.series.name}"],
"bind": "legend"
}
},
"transform": [
{
"bin": {
"maxbins": @{options.max_bins.value}
},
"field": @{fields.metric.name},
"as": "@{fields.metric.name} binned"
},
{
"filter": {
"selection": "seriesSelector"
}
}
],
"mark": {
"type": "area",
"interpolate": "step",
"opacity": 0.4,
"tooltip": true
},
"encoding": {
"x": {
"field": "@{fields.metric.name} binned",
"type": "quantitative",
"title": "Binned @{fields.metric.name}"
},
"y": {
"aggregate": "count",
"title": "Count of @{fields.grain.name}",
"stack": "@{options.stack_bars.value}"
},
"color": {
"field": @{fields.series.name},
"type": "nominal",
"title": "@{fields.series.name}"
},
"tooltip": [
{ "field": "@{fields.series.name}", "type": "nominal" },
{ "field": "@{fields.metric.name} binned", "type": "quantitative" },
{ "aggregate": "count", "type": "quantitative", "title": "Count" }
]
},
"config": {
"area": {
"line": true
}
}
}
;;
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.