How To: Work with Code View
The Code View is provided to let you customize your visualizations using JavaScript. Please use this feature responsibly.
Do not attempt to run or insert malicious code.
All actions in Code View are logged and monitored. Misuse may result in loss of access.
Purpose
Code View lets you go beyond standard edits by writing custom JavaScript (preferably using Highcharts, but any valid React/JS code works). You can:
Write your own chart logic,
Copy/paste from examples, or
Ask an AI chatbot to generate or fix the code for you.
Steps to Create a Custom Visualization (Example: Calendar Heatmap)
Open the Edit Menu
On the top-right of a visualization, click the three dots (⋮) → Edit → Code View.
Select Columns
Choose the Date column and the Metric column you want to display.
Example:
date
andcost
.
Paste or Write Code
You can:
Paste an example (like the Calendar Heatmap below),
Write your own JavaScript, or
Ask an AI chatbot to generate a chart in JavaScript using Highcharts.
If using AI, share details like “I want a calendar heatmap with my
date
andcost
columns.”
Fix Errors with AI Help
If you see an error message in Code View, copy it.
Paste the error into the prompt bar or an AI chatbot and ask how to fix it.
Example: “Highcharts error #17” → paste into AI → it will suggest the right config.
Save & Preview
Click Save to apply your changes.
If the chart doesn’t look right, refine your code or prompt again.
Example: Calendar Heatmap by Day (Plain JS/React)
Paste this entire component into Code View, then update:
dateColumn
→ your date field (expects MM/DD/YYYY)metricColumn
→ the metric you want to displaymetricPrefix
→'$'
for currency or''
for non-currency
function CalendarHeatmapByDay({ data = [] }) {
const dateColumn = 'date';
const metricColumn = 'cost';
const metricPrefix = '$';
const byDate = new Map();
const yearsSet = new Set();
data.forEach(item => {
if (!item[dateColumn]) return;
const [mm, dd, yyyy] = item[dateColumn].split("/").map(s => s.padStart(2, "0"));
const iso = `${yyyy}-${mm}-${dd}`;
yearsSet.add(yyyy);
const v = Number(item[metricColumn]) || 0;
byDate.set(iso, (byDate.get(iso) || 0) + v);
});
const years = [...yearsSet].sort((a, b) => Number(a) - Number(b));
const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
const maxCost = byDate.size === 0 ? 0 : Math.max(...byDate.values());
const GREENS = [
"#e5f5e0", "#c7e9c0", "#a1d99b", "#74c476", "#41ab5d",
"#238b45", "#006d2c", "#00441b"
];
const costs = Array.from(byDate.values()).filter(v => v > 0).sort((a, b) => a - b);
const median = costs.length ? (costs[Math.floor((costs.length - 1) / 2)] + costs[Math.ceil((costs.length - 1) / 2)]) / 2 : 0;
const absDevs = costs.map(v => Math.abs(v - median)).sort((a, b) => a - b);
const mad = absDevs.length ? (absDevs[Math.floor((absDevs.length - 1) / 2)] + absDevs[Math.ceil((absDevs.length - 1) / 2)]) / 2 : 0;
let scale = mad * 1.4826;
if (!scale) {
const min = costs.length ? costs[0] : 0;
const max = costs.length ? costs[costs.length - 1] : 0;
scale = (max - min) / 6 || 1;
}
const clamp = (x, lo, hi) => Math.max(lo, Math.min(hi, x));
const colorFor = cost => {
if (cost <= 0 || !isFinite(cost)) return "#f0f0f0";
const z = (cost - median) / scale;
const zClamped = clamp(z, -2.5, 2.5);
const t = (zClamped + 2.5) / 5;
const idx = Math.round(t * (GREENS.length - 1));
return GREENS[idx];
};
const daysInMonth = (y, m) => new Date(y, m + 1, 0).getDate();
const firstDow = (y, m) => new Date(y, m, 1).getDay();
const weeksInMonth = (y, m) => Math.ceil((firstDow(y, m) + daysInMonth(y, m)) / 7);
const baseLabelCol = 18;
const dim = 18;
const dayGap = 4;
var showWeekdayLabels = true;
const showTooltip = (e, text) => {
const tooltip = document.createElement('div');
tooltip.style.position = 'fixed';
tooltip.style.background = 'rgba(0,0,0,0.75)';
tooltip.style.color = '#fff';
tooltip.style.padding = '3px 6px';
tooltip.style.borderRadius = '3px';
tooltip.style.fontSize = '11px';
tooltip.style.pointerEvents = 'none';
tooltip.style.zIndex = '1000';
tooltip.innerHTML = text;
document.body.appendChild(tooltip);
const rect = e.target.getBoundingClientRect();
tooltip.style.top = `${rect.top - tooltip.offsetHeight - 4}px`;
tooltip.style.left = `${rect.left + rect.width / 2 - tooltip.offsetWidth / 2}px`;
e.target._tooltip = tooltip;
};
const hideTooltip = (e) => {
if (e.target._tooltip) {
document.body.removeChild(e.target._tooltip);
e.target._tooltip = null;
}
};
return React.createElement("div", { style: { padding: 12 } },
React.createElement("div", { style: { marginBottom: 8, fontSize: 16, fontWeight: 700 } }, "Media Spend by Day"),
years.length === 0
? React.createElement("div", { style: { color: "#666" } }, "No data.")
: years.map(yyyy =>
React.createElement("div", { key: yyyy, style: { marginBottom: 12 } },
React.createElement("div", { style: { fontWeight: 700, fontSize: 14, marginBottom: 4 } }, yyyy),
React.createElement("div", {
style: {
display: "grid",
gridTemplateColumns: "repeat(auto-fill, 160px)",
justifyContent: "start",
gap: 8,
alignItems: "start",
gridAutoFlow: "row dense"
}
},
Array.from({ length: 12 }).map((_, mIndex0) => {
const monthLabel = monthNames[mIndex0];
const weeks = weeksInMonth(Number(yyyy), mIndex0);
const firstDay = firstDow(Number(yyyy), mIndex0);
const tiles = [];
const totalDays = daysInMonth(Number(yyyy), mIndex0);
let hasData = false;
const labelCol = showWeekdayLabels ? baseLabelCol : 0;
const tileColStart = showWeekdayLabels ? 2 : 1;
for (let d = 1; d <= totalDays; d++) {
const dt = new Date(Number(yyyy), mIndex0, d);
const dow = dt.getDay();
const week = Math.floor((firstDay + (d - 1)) / 7);
const mm = String(mIndex0 + 1).padStart(2, "0");
const dd = String(d).padStart(2, "0");
const iso = `${yyyy}-${mm}-${dd}`;
const cost = byDate.get(iso) || 0;
if (cost > 0) hasData = true;
tiles.push(
React.createElement("div", {
key: iso,
style: {
gridRow: dow + 2,
gridColumn: week + tileColStart,
width: dim,
height: dim,
borderRadius: 3,
background: colorFor(cost),
cursor: cost > 0 ? "pointer" : "default"
},
onMouseEnter: (e) => showTooltip(e, `${monthLabel} ${d}, ${yyyy} — ${metricPrefix}${cost.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`),
onMouseLeave: hideTooltip
})
);
}
if (!hasData) return null;
const weekdayLabels = showWeekdayLabels
? ["S", "M", "T", "W", "T", "F", "S"].map((lbl, i) =>
React.createElement("div", {
key: lbl,
style: {
gridRow: i + 2,
gridColumn: 1,
width: baseLabelCol,
textAlign: "right",
paddingRight: 2,
fontSize: 9,
color: "#888",
alignSelf: "center",
justifySelf: "end",
lineHeight: `${dim}px`
}
}, lbl)
)
: [];
showWeekdayLabels = false;
return React.createElement("div", {
key: `${yyyy}-${mIndex0}`,
style: {
maxWidth: "160px",
borderRadius: 8,
padding: 4,
background: "#fff"
}
},
React.createElement("div", {
style: { fontWeight: 600, fontSize: 12, marginBottom: 4, textAlign: "center" }
}, monthLabel),
React.createElement("div", {
style: {
display: "grid",
gridTemplateColumns: `${showWeekdayLabels ? baseLabelCol + 'px ' : ''}repeat(${weeks}, ${dim}px)`,
gridTemplateRows: `12px repeat(7, ${dim}px)`,
gap: dayGap,
alignItems: "center",
justifyContent: "start"
}
},
showWeekdayLabels ? React.createElement("div", { style: { gridRow: 1, gridColumn: 1 } }) : null,
...Array.from({ length: weeks }).map((_, w) =>
React.createElement("div", {
key: `w-${w}`,
style: {
gridRow: 1,
gridColumn: w + tileColStart,
fontSize: 9,
color: "#aaa",
justifySelf: "center"
}
})
),
...weekdayLabels,
...tiles
)
);
})
)
)
),
React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 4, marginTop: 6 } },
React.createElement("span", { style: { fontSize: 11, color: "#666" } }, "Less"),
...GREENS.map((c, i) =>
React.createElement("div", { key: i, style: { width: 12, height: 12, borderRadius: 3, background: c } })
),
React.createElement("span", { style: { fontSize: 11, color: "#666" } }, "More")
)
);
}
Tips & Best Practices
DIY or AI: You can hand-code or prompt an AI chatbot to generate the chart code for you.
Error-driven debugging: Use Code View error messages as input for the AI to fix your code.
Highcharts reference: For advanced visualizations, check the Highcharts API docs.
One viz at a time: Code edits only affect the visualization you’re editing, not the full dashboard.