amcharts / amcharts5

The newest, fastest, and most advanced amCharts charting library for JavaScript and TypeScript apps.
Other
348 stars 92 forks source link

Unable to make the legend markers as circular in shape for the stacked bar chart demo #1763

Open r-niyati opened 1 day ago

r-niyati commented 1 day ago

Bug description

I have tried to reuse the following demo:

https://www.amcharts.com/demos/stacked-column-chart/

Aim is to create the legend markers circular in shape. I have tried using marker template but it still returns legends in square shape. Here's my code:

function getJsonData(chartId) { // Create root element var root = am5.Root.new(chartId);

    // Set themes
    root.setThemes([
        am5themes_Animated.new(root)
    ]);

    // Create chart
    var chart = root.container.children.push(am5xy.XYChart.new(root, {
        panX: false,
        panY: false,
        wheelX: "panX",
        wheelY: "zoomX",
        paddingLeft: 10,
        layout: root.verticalLayout
    }));

    // Add scrollbar
    chart.set("scrollbarX", am5.Scrollbar.new(root, {
        orientation: "horizontal"
    }));

    var data = toolData[chartId];
    data = data.map((i) => ({
        market: i.market,
        atc: parseFloat(i.atc),
        allowances: parseFloat(i.allowances),
        abs: parseFloat(i.abs)
    }));

    // Create axes
    var xRenderer = am5xy.AxisRendererX.new(root, {
        minorGridEnabled: true,
        minGridDistance: 30,
        cellStartLocation: 0.1,
        cellEndLocation: 0.9,
        strokeOpacity: 1,
        strokeWidth: 1,
        stroke: am5.color(0xDADADA)
    });
    var xAxis = chart.xAxes.push(am5xy.CategoryAxis.new(root, {
        categoryField: "market",
        renderer: xRenderer
    }));

    // Rotate the labels
    xAxis.get("renderer").labels.template.setAll({
        rotation: 275,
        fontSize: 16,
        fontWeight: 500,
        fontFamily: "NotoSans-Regular",
        fill: am5.color(0x002c77),
        centerY: am5.p50,
        centerX: am5.p100
    });

    xRenderer.grid.template.setAll({
        location: 1,
        visible: false
    });

    xAxis.data.setAll(data);
    var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
        min: 0,
        renderer: am5xy.AxisRendererY.new(root, {
            strokeOpacity: 0
        })
    }));

    var yRenderer = yAxis.get("renderer");
    yRenderer.grid.template.setAll({
        strokeOpacity: 0,
        strokeWidth: 0
    });

    yRenderer.labels.template.setAll({
        fill: am5.color(0x002c77),
        fontSize: "0"
    });

    // Add series
    function makeSeries(name, fieldName, color) {
        var series = chart.series.push(am5xy.ColumnSeries.new(root, {
            name: name,
            stacked: true,
            xAxis: xAxis,
            yAxis: yAxis,
            valueYField: fieldName,
            categoryXField: "market",
            clustered: false,
            fill: color,
            stroke: color
        }));

        series.data.setAll(data);

        // Set tooltip properties directly on the columns
        series.columns.template.setAll({
            tooltipText: "{name}: [bold]{valueY}",
            width: am5.percent(70),
            fontFamily: "NotoSans-Regular",
            tooltip: am5.Tooltip.new(root, {
                fill: am5.color(0xffffff), // Set the tooltip background color
                stroke: am5.color(0xff0000), // Set the stroke color to red
                strokeWidth: 2, // Set the stroke width
                fontFamily: "NotoSans-Regular",
                fontSize: 14
            })
        });

        // Make stuff animate on load
        series.appear();
    }

    makeSeries("ABS", "abs", am5.color(0x00AC41));
    makeSeries("Allowances", "allowances", am5.color(0x009DE0));
    makeSeries("ATC", "atc", am5.color(0xFFFFFF));

    // Create legend
    var legend = chart.children.push(am5.Legend.new(root, {
        centerX: am5.p50,
        x: am5.p50,
        layout: root.horizontalLayout
    }));

    // Set legend labels properties
    legend.labels.template.setAll({
        fontSize: 16,
        lineHeight: 1.4,
        fontFamily: "NotoSans-Regular",
        fill: am5.color(0x002c77),
        truncate: false // Ensure labels are not truncated
    });

    // Set value labels properties
    legend.valueLabels.template.setAll({
        fill: am5.color(0x002c77)
    });

    // Customize the legend markers
    legend.markers.template.setAll({
        width: 20,
        height: 20,
        fill: am5.color(0xFFFFFF), // Default fill color
        strokeWidth: 2
    });

    // Create circular markers
    legend.markers.template.set("template", am5.Circle.new(root, {
        radius: 10, // Set radius for circular markers
        fill: am5.color(0xFFFFFF), // Default fill color
        stroke: am5.color(0xdadada), // Stroke color
        strokeWidth: 2 // Stroke width
    }));

    // Add series to legend
    legend.data.setAll(chart.series.values);

    // Make stuff animate on load
    chart.appear(1000, 100);

    return root;
}
martynasma commented 10 hours ago

The easiest way to make markers circular in shape is like this:

legend.markerRectangles.template.setAll({
  cornerRadiusTR: 20,
  cornerRadiusBR: 20,
  cornerRadiusTL: 20,
  cornerRadiusBL: 20
});
r-niyati commented 9 hours ago

This code worked. However, unable to add stroke width and shadow to tooltip as well not able to add stroke to the legend markers.

image
martynasma commented 8 hours ago

Since markers inherit stroke and fill information from the related series, you can only override it with an adapter:

legend.markerRectangles.template.adapters.add("stroke", function() {
  return am5.color(0x000000);
});
r-niyati commented 8 hours ago

Thanks this worked as well. Is there a way to add hand cursor to legends?

martynasma commented 7 hours ago

Legend uses pointer symbol over legends by default.