Customizing scrollbar grips
This demo shows how we can completely modify the appearance of scrollbar’s grips.
Open in:New tab
/** * --------------------------------------- * This demo was created using amCharts 5. * * For more information visit: * https://www.amcharts.com/ * * Documentation is available at: * https://www.amcharts.com/docs/v5/ * --------------------------------------- */
// Create root element// https://www.amcharts.com/docs/v5/getting-started/#Root_elementvar root = am5.Root.new("chartdiv");
// Set themes// https://www.amcharts.com/docs/v5/concepts/themes/root.setThemes([am5themes_Animated.new(root)]);
// Create chart// https://www.amcharts.com/docs/v5/charts/xy-chart/var chart = root.container.children.push( am5xy.XYChart.new(root, { panX: true, panY: true, wheelX: "panX", wheelY: "zoomX", pinchZoomX: true }));
// Add cursor// https://www.amcharts.com/docs/v5/charts/xy-chart/cursor/var cursor = chart.set( "cursor", am5xy.XYCursor.new(root, { behavior: "none" }));
cursor.lineY.set("visible", false);
// The datavar data = [ { year: "2001", cars: 1298, motorcycles: 680, bicycles: 101 }, { year: "2002", cars: 1275, motorcycles: 664, bicycles: 97 }, { year: "2003", cars: 1246, motorcycles: 648, bicycles: 93 }, { year: "2004", cars: 1318, motorcycles: 697, bicycles: 111 }, { year: "2005", cars: 1213, motorcycles: 633, bicycles: 87 }, { year: "2006", cars: 1199, motorcycles: 521, bicycles: 145 }, { year: "2007", cars: 1110, motorcycles: 310, bicycles: 91 }, { year: "2008", cars: 1165, motorcycles: 425, bicycles: 120 }, { year: "2009", cars: 1145, motorcycles: 319, bicycles: 102 }, { year: "2010", cars: 1163, motorcycles: 201, bicycles: 145 }, { year: "2011", cars: 1180, motorcycles: 285, bicycles: 100 }, { year: "2012", cars: 1159, motorcycles: 255, bicycles: 122 }];
// Create axes// https://www.amcharts.com/docs/v5/charts/xy-chart/axes/var xAxis = chart.xAxes.push( am5xy.CategoryAxis.new(root, { categoryField: "year", startLocation: 0.5, endLocation: 0.5, renderer: am5xy.AxisRendererX.new(root, { minorGridEnabled: true, minGridDistance: 70 }),
tooltip: am5.Tooltip.new(root, {}) }));
xAxis.data.setAll(data);
var yAxis = chart.yAxes.push( am5xy.ValueAxis.new(root, { renderer: am5xy.AxisRendererY.new(root, {}) }));
// Add scrollbar// https://www.amcharts.com/docs/v5/charts/xy-chart/scrollbars/var scrollbarX = am5xy.XYChartScrollbar.new(root, { orientation: "horizontal", height: 50});
chart.set("scrollbarX", scrollbarX);
var sbxAxis = scrollbarX.chart.xAxes.push( am5xy.CategoryAxis.new(root, { categoryField: "year", startLocation: 0.5, endLocation: 0.5, renderer: am5xy.AxisRendererX.new(root, { minorGridEnabled: true, minGridDistance: 70 }),
tooltip: am5.Tooltip.new(root, {}) }));
sbxAxis.data.setAll(data);
var sbyAxis = scrollbarX.chart.yAxes.push( am5xy.ValueAxis.new(root, { renderer: am5xy.AxisRendererY.new(root, {}) }));
customizeGrip(scrollbarX.startGrip);customizeGrip(scrollbarX.endGrip);
function customizeGrip(grip) { grip.get("background").setAll({ fillOpacity: 0, strokeOpacity: 0 });
grip.get("icon").set("forceHidden", true); grip.children.push( am5.Rectangle.new(root, { fill: am5.color(0x000000), width: 12, height: 12, x: am5.p50, centerX: am5.p50, y: am5.p50, centerY: am5.p50, rotation: 45 }) );
grip.children.push( am5.Rectangle.new(root, { fill: am5.color(0x000000), width: 3, height: scrollbarX.get("height"), x: am5.p50, centerX: am5.p50, y: am5.p50, centerY: am5.p50 }) );
grip.setAll({ maskContent: true });
grip.events.on("pointerdown", function () { console.log("down"); });}
// Add series// https://www.amcharts.com/docs/v5/charts/xy-chart/series/
function createSeries(name, field) { var series = chart.series.push( am5xy.SmoothedXLineSeries.new(root, { name: name, xAxis: xAxis, yAxis: yAxis, valueYField: field, categoryXField: "year", stacked: true, tooltip: am5.Tooltip.new(root, { pointerOrientation: "horizontal", labelText: "[bold]{name}[/]\n{categoryX}: {valueY}" }) }) );
series.strokes.template.setAll({ strokeWidth: 2 });
series.fills.template.setAll({ fillOpacity: 0.5, visible: true });
var sbseries = scrollbarX.chart.series.push( am5xy.LineSeries.new(root, { xAxis: sbxAxis, yAxis: sbyAxis, valueYField: field, categoryXField: "year" }) );
sbseries.data.setAll(data); series.data.setAll(data); series.appear(1000);}
createSeries("Cars", "cars");createSeries("Motorcycles", "motorcycles");createSeries("Bicycles", "bicycles");
// Make stuff animate on load// https://www.amcharts.com/docs/v5/concepts/animations/chart.appear(1000, 100);<div id="chartdiv"></div>body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";}
#chartdiv { width: 100%; height: 95vh;}customizing-scrollbar-gripsHere’s another version:
Open in:New tab
// Create root and chartvar root = am5.Root.new("chartdiv");
var theme = am5.Theme.new(root);
// hides button backgroundtheme.ruleRaw("RoundedRectangle", ["background", "resize", "button"]).setAll({ fillOpacity: 0, strokeOpacity: 0});
// modify the icontheme.ruleRaw("Graphics", ["resize", "button", "icon"]).setAll({ strokeOpacity: 1, strokeWidth: 1, stroke: am5.color(0x3f48cc), fill: am5.color(0x3f48cc), draw: (display) => { display.arc(0, 0, 3, -90, 270); display.moveTo(0, 3); display.lineTo(0, 50); }});
// add custom theme to rootroot.setThemes([am5themes_Animated.new(root), theme]);
var chart = root.container.children.push( am5xy.XYChart.new(root, { panX: true, panY: true, wheelY: "zoomX", layout: root.verticalLayout, pinchZoomX: true }));
// Create Y-axisvar yAxis = chart.yAxes.push( am5xy.ValueAxis.new(root, { maxDeviation: 1, renderer: am5xy.AxisRendererY.new(root, { pan: "zoom" }) }));
// Create X-Axisvar xAxis = chart.xAxes.push( am5xy.DateAxis.new(root, { groupData: true, maxDeviation: 0.5, baseInterval: { timeUnit: "minute", count: 1 }, renderer: am5xy.AxisRendererX.new(root, { minGridDistance: 60, pan: "zoom", minorGridEnabled: true }) }));
// xAxis.get("dateFormats")["day"] = "MM/dd";// xAxis.get("periodChangeDateFormats")["day"] = "MMMM";
// Generate random datafunction generateChartData() { var chartData = []; // current date var firstDate = new Date(); // now set 500 minutes back firstDate.setMinutes(firstDate.getDate() - 500, 0, 0);
// and generate 500 data items var visits = 500; for (var i = 0; i < 500; i++) { var newDate = new Date(firstDate); // each time we add one minute newDate.setMinutes(newDate.getMinutes() + i); // some random number visits += Math.round((Math.random() < 0.5 ? 1 : -1) * Math.random() * 10); // add data item to the array chartData.push({ date: newDate.getTime(), visits: visits }); } return chartData;}var data = generateChartData();
// Create seriesvar series = chart.series.push( am5xy.LineSeries.new(root, { name: "Series", xAxis: xAxis, yAxis: yAxis, valueYField: "visits", valueXField: "date", tooltip: am5.Tooltip.new(root, { pointerOrientation: "horizontal", labelText: "[bold]{name}[/]\n{valueX.formatDate()}: {valueY}" }) }));
series.strokes.template.set("strokeWidth", 2);series.fills.template.setAll({ visible: true, fillOpacity: 0.4});
series.data.setAll(data);
// Pre-zoom X axis to last hourseries.events.once("datavalidated", function (ev, target) { var lastDate = new Date(data[data.length - 1].date); var firstDate = new Date(lastDate.getTime() - 3600000); xAxis.zoomToDates(firstDate, lastDate);});
// Add cursorchart.set( "cursor", am5xy.XYCursor.new(root, { behavior: "none", xAxis: xAxis }));
xAxis.set("tooltip", am5.Tooltip.new(root, {}));
yAxis.set("tooltip", am5.Tooltip.new(root, {}));
var scrollbarX = am5xy.XYChartScrollbar.new(root, { orientation: "horizontal", height: 50});
chart.set("scrollbarX", scrollbarX);chart.bottomAxesContainer.children.push(scrollbarX);
var sbxAxis = scrollbarX.chart.xAxes.push( am5xy.DateAxis.new(root, { baseInterval: { timeUnit: "minute", count: 1 }, renderer: am5xy.AxisRendererX.new(root, { opposite: false, strokeOpacity: 0, minorGridEnabled: true, minGridDistance: 60 }) }));
/// THIS IS THE PART THAT ADDS LABELS TO THE SCROLLBARvar startRange = sbxAxis.axisRanges.push(sbxAxis.makeDataItem({}));var startLabel = startRange.get("label");startLabel.setAll({ maxPosition: 1, minPosition: 0, opacity: 1, paddingLeft: 0, paddingRight: 0, centerX: am5.p100, centerY: 0, fill: am5.color(0x3f48cc)});
scrollbarX.on("start", function (start) { updateRanges();});
// adjust position if label is too close to the edgestartLabel.adapters.add("dx", function (dx) { if (startLabel.x() - startLabel.width() < 0) { return -startLabel.x() + startLabel.width(); }
return 0;});
// all the same for endvar endRange = sbxAxis.axisRanges.push(sbxAxis.makeDataItem({}));var endLabel = endRange.get("label");endLabel.setAll({ maxPosition: 1, minPosition: 0, centerY: 0, opacity: 1, paddingLeft: 0, paddingRight: 0, centerX: 0, fill: am5.color(0x3f48cc)});
scrollbarX.on("end", function (end) { updateRanges();});
// adjust position if label is too close to the edgeendLabel.adapters.add("dx", function (dx) { if (endLabel.x() + endLabel.width() > scrollbarX.width()) { return scrollbarX.width() - endLabel.x() - endLabel.width(); }
return 0;});
function updateRanges() { var start = sbxAxis.positionToValue(scrollbarX.get("start")); var end = sbxAxis.positionToValue(scrollbarX.get("end"));
if (!isNaN(start) && !isNaN(end)) { if (start > end) { [start, end] = [end, start]; }
endRange.set("value", end); endLabel.set("text", sbyAxis.getDateFormatter().format(new Date(end), "YYYY-MM-dd HH:mm"));
startRange.set("value", start); startLabel.set("text", sbyAxis.getDateFormatter().format(new Date(start), "YYYY-MM-dd HH:mm")); }}
// END OF LABELS
var sbyAxis = scrollbarX.chart.yAxes.push( am5xy.ValueAxis.new(root, { renderer: am5xy.AxisRendererY.new(root, {}) }));
var sbseries = scrollbarX.chart.series.push( am5xy.LineSeries.new(root, { xAxis: sbxAxis, yAxis: sbyAxis, valueYField: "visits", valueXField: "date" }));
sbseries.data.setAll(data);<div id="chartdiv"></div>body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";}
#chartdiv { width: 100%; height: 95vh;}customized-scrollbar