Creating Time-Axis Charts
Working with Temporal Data
Sample Dataset
Here's an example of temporal data we'll use to create a stock price visualization:
Year | High | Low | Close | Open |
---|---|---|---|---|
2001 | 36.85 | 21.44 | 33.125 | 22.062 |
2002 | 34.875 | 20.705 | 25.85 | 33.325 |
2003 | 29.76 | 22.55 | 27.37 | 26.15 |
Setting Up DataModel
1. Define Temporal Schema
For time-based visualizations, you need to specify both the temporal field and its format:
const schema = [
{
name: "Year",
type: "dimension",
subtype: "temporal",
format: "%Y", // DateTime format specification
},
{
name: "Close",
type: "measure",
},
];
DateTime Formats
DataModel supports various DateTime formats. Some common formats:
%Y
: Full year (e.g., 2024)%Y-%m-%d
: ISO date format%d/%m/%Y
: Day/Month/Year format
Check the DataModel API reference for a complete list of supported formats.
2. Initialize DataModel
// Load DataModel class
const DataModel = muze.DataModel;
// Parse data with schema
const parsedData = DataModel.loadDataSync(data, schema);
// Create instance
const dm = new DataModel(parsedData);
Creating the Visualization
1. Set Up Canvas
const canvas = muze.canvas();
canvas.data(dm);
2. Configure Axes
canvas
.rows(["Close"]) // Y-axis: stock prices
.columns(["Year"]); // X-axis: temporal data
Automatic Line Chart
When the x-axis field is temporal, Muze automatically creates a line chart as the default visualization type.
Complete Implementation
Here's a full example including titles and subtitles:
const { muze, getDataFromSearchQuery, env } = viz;
const DataModel = muze.DataModel;
const data = [
{"Year": 1986, "high": 0.145, "low": 0.097, "Close": 0.122, "open": 0.102},
{"Year": 1987, "high": 0.365, "low": 0.125, "Close": 0.242, "open": 0.125},
{"Year": 1988, "high": 0.385, "low": 0.238, "Close": 0.375, "open": 0.245},
{"Year": 1989, "high": 0.522, "low": 0.365, "Close": 0.478, "open": 0.378},
{"Year": 1990, "high": 0.685, "low": 0.442, "Close": 0.615, "open": 0.482},
{"Year": 1991, "high": 1.258, "low": 0.612, "Close": 1.178, "open": 0.622},
{"Year": 1992, "high": 1.875, "low": 1.125, "Close": 1.725, "open": 1.185},
{"Year": 1993, "high": 2.258, "low": 1.685, "Close": 2.125, "open": 1.735},
{"Year": 1994, "high": 2.875, "low": 2.062, "Close": 2.585, "open": 2.142},
{"Year": 1995, "high": 5.258, "low": 2.562, "Close": 5.125, "open": 2.595},
{"Year": 1996, "high": 13.425, "low": 5.125, "Close": 12.812, "open": 5.188},
{"Year": 1997, "high": 19.875, "low": 12.75, "Close": 16.312, "open": 12.875},
{"Year": 1998, "high": 29.125, "low": 14.938, "Close": 27.688, "open": 16.375},
{"Year": 1999, "high": 59.562, "low": 27.375, "Close": 58.375, "open": 27.75},
{"Year": 2000, "high": 60.625, "low": 20.125, "Close": 21.688, "open": 58.5},
{"Year": 2001, "high": 36.852, "low": 21.443, "Close": 33.125, "open": 22.062},
{"Year": 2002, "high": 34.875, "low": 20.705, "Close": 25.85, "open": 33.325},
{"Year": 2003, "high": 29.76, "low": 22.55, "Close": 27.37, "open": 26.15},
{"Year": 2004, "high": 30.20, "low": 24.15, "Close": 26.72, "open": 27.65},
{"Year": 2005, "high": 28.25, "low": 23.82, "Close": 26.15, "open": 26.75},
{"Year": 2006, "high": 31.48, "low": 21.45, "Close": 29.86, "open": 26.25},
{"Year": 2007, "high": 37.20, "low": 27.25, "Close": 35.60, "open": 29.95},
{"Year": 2008, "high": 36.72, "low": 14.87, "Close": 19.44, "open": 35.22},
{"Year": 2009, "high": 31.50, "low": 15.28, "Close": 30.48, "open": 19.52},
{"Year": 2010, "high": 31.58, "low": 22.73, "Close": 27.91, "open": 30.62},
{"Year": 2011, "high": 29.46, "low": 23.65, "Close": 25.96, "open": 28.05},
{"Year": 2012, "high": 32.95, "low": 26.26, "Close": 26.71, "open": 26.05},
{"Year": 2013, "high": 38.98, "low": 26.28, "Close": 37.41, "open": 26.74},
{"Year": 2014, "high": 50.05, "low": 34.63, "Close": 46.45, "open": 37.35},
{"Year": 2015, "high": 56.85, "low": 39.72, "Close": 55.48, "open": 46.66},
{"Year": 2016, "high": 64.10, "low": 48.19, "Close": 62.14, "open": 54.80},
{"Year": 2017, "high": 87.50, "low": 61.95, "Close": 85.54, "open": 62.30},
{"Year": 2018, "high": 115.61, "low": 83.83, "Close": 101.57, "open": 85.95},
{"Year": 2019, "high": 158.96, "low": 97.40, "Close": 157.70, "open": 101.12},
{"Year": 2020, "high": 232.86, "low": 132.52, "Close": 222.42, "open": 158.78}
];
// Define schema with temporal configuration
const schema = [
{
name: "Year",
type: "dimension",
subtype: "temporal",
format: "%Y",
},
{
name: "Close",
type: "measure",
},
];
// Create and configure visualization
const formattedData = DataModel.loadDataSync(data, schema);
const dm = new DataModel(formattedData);
muze
.canvas()
.data(dm)
.rows(["Close"])
.columns(["Year"])
.layers([{
mark: "line",
},
])
.title("MSFT Stocks", {
position: "top",
align: "center",
})
.subtitle("1986 - 2020", {
position: "top",
align: "center",
})
.mount("#chart");
Best Practices for Temporal Charts
-
Data Preparation
- Ensure consistent date formats
- Handle missing dates appropriately
- Consider timezone implications
-
Visualization
- Choose appropriate time intervals
- Consider data density when displaying time ranges
- Use clear date formatting for axis labels
-
Performance
- Aggregate data for large time ranges
- Consider data sampling for dense time series
Common Issues
If you are facing issues with a temporal chart not renderring correctly makre sure you check for the following:
- Incorrect date format specification
- Inconsistent date formats in source data
- Missing or invalid dates