Search code examples
javascriptvisualizationamchartsamcharts5

Amcharts5: legend errors in multiline chart


I am using amchart5 to render some multi line data and I have some issues with how the data is being rendered.

  1. I cannot add currency symbols to the labels of the y-axis
  2. I cant turn the labels of the x-axis so they are more vertical rather than horizontal
  3. The preview will not show any lines

How can I resolve this?

See image: enter image description here

Javascript

<script type="text/javascript">
    am5.ready(function() {

    // Create root element
    // https://www.amcharts.com/docs/v5/getting-started/#Root_element
    var root = am5.Root.new("fundChartLine");
    
    root.numberFormatter.setAll({
        numberFormat: "#,###.##00",
    });

    // Set themes
    // https://www.amcharts.com/docs/v5/concepts/themes/
    root.setThemes([
        am5themes_Animated.new(root),
        am5themes_Responsive.new(root),
        Amdg.new(root)
    ]);
    // Create chart
    // https://www.amcharts.com/docs/v5/charts/percent-charts/pie-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);



    // Define data
    var data = {{ line_chart_data| safe }}
    // Create axes
    // https://www.amcharts.com/docs/v5/charts/xy-chart/axes/
    // Create Y-axis
    let yAxis = chart.yAxes.push(
    am5xy.ValueAxis.new(root, {
        renderer: am5xy.AxisRendererY.new(root, {})
    })
    );

    // Create X-Axis
    /*var xAxis = chart.xAxes.push(
    am5xy.CategoryAxis.new(root, {
        maxDeviation: 0.2,
        renderer: am5xy.AxisRendererX.new(root, {}),
        categoryField: "chart_dates"
    })
    );
    xAxis.data.setAll(data);*/

    var xAxis = chart.xAxes.push(
        am5xy.DateAxis.new(root, {
            groupData: true,
            baseInterval: { timeUnit: "day", count: 1 },
            renderer: am5xy.AxisRendererX.new(root, {
            minGridDistance: 30
            })
        })
        );

    xAxis.get("dateFormats")["day"] = "MM/dd";
    xAxis.get("periodChangeDateFormats")["day"] = "MMMM";
    
    xAxis.data.setAll(data);
    // Add series
    // https://www.amcharts.com/docs/v5/charts/xy-chart/series/
    // https://www.amcharts.com/docs/v5/charts/xy-chart/series/line-series/
    function createSeries(name, field) {
    var series = chart.series.push( 
        am5xy.LineSeries.new(root, { 
        name: name,
        xAxis: xAxis, 
        yAxis: yAxis, 
        valueYField: field, 
        categoryXField: "chart_dated_dt",
        stacked: false
        //legendLabelText: "[{fill}]{category}[/]",
        //legendValueYText: "[bold {fill}]ZAR{valueY}[/]"

        })
    );
    
    series.strokes.template.setAll({
        strokeWidth: 2,
        //strokeDasharray: [2,1]
    });
    series.fills.template.setAll({
        fillOpacity: 0.5,
        visible: false
    });
    series.data.setAll(data);
    
    //series.labels.template.set("visible", false);
    //series.ticks.template.set("visible", false);
    
    console.log(series)        
}

    
    chart.topAxesContainer.children.push(am5.Label.new(root, {
        text: "Performance",
        fontSize: 30,
        fontColor: '#e40505',
        fontWeight: "500",
        textAlign: "center",
        x: am5.percent(50),
        centerX: am5.percent(50),
        paddingTop: 0,
        paddingBottom: 20,
    }));



    createSeries("Average Contributions", "average_contrib");
    createSeries("Average Contributions + Interest", "average_totals");
    createSeries("Median Contributions", "median_contrib");
    createSeries("Median Contributions + Interest", "median_totals");
    createSeries("Your Contributions", "user_contrib");
    createSeries("Your Contributions + Interest", "user_totals");

    
    //var legend = chart.children.push(am5.Legend.new(root, {}));
    //legend.data.setAll(chart.series.values);
    var legend = chart.bottomAxesContainer.children.push(am5.Legend.new(root, {
        centerX: am5.percent(50),
        x: am5.percent(50),
        useDefaultMarker: true,
        paddingTop: 10,
        paddingBottom: 20,
        layout: am5.GridLayout.new(root, {
            maxColumns: 3,
            fixedWidthGrid: true
        })
    }));
    legend.data.setAll(chart.series.values);

    // Add scrollbar
    // https://www.amcharts.com/docs/v5/charts/xy-chart/scrollbars/

    /*var scrollbarX = am5.Scrollbar.new(root, {
        orientation: "horizontal"
        });*/

    var scrollbarX = am5xy.XYChartScrollbar.new(root, {
        orientation: "horizontal",
        height: 50
        });
    
    //chart.bottomAxesContainer.children.push(scrollbarX);
    /*let sbxAxis = scrollbarX.chart.xAxes.push(
        am5xy.CategoryAxis.new(root, {
        maxDeviation: 0.2,
        renderer: am5xy.AxisRendererX.new(root, {
            opposite: false,
            strokeOpacity: 0
        }),
        categoryField: "chart_dates"
        })
    );*/
    
    let sbxAxis = scrollbarX.chart.xAxes.push(
        am5xy.DateAxis.new(root, {
            groupData: true,
            groupIntervals: [{ timeUnit: "year", count: 1 }],
            baseInterval: { timeUnit: "day", count: 1 },
            renderer: am5xy.AxisRendererX.new(root, {
                opposite: false,
                strokeOpacity: 0
            })
        })
        );

    let sbyAxis = scrollbarX.chart.yAxes.push(
        am5xy.ValueAxis.new(root, {
            renderer: am5xy.AxisRendererY.new(root, {})
        })
    );

    let sbseries = scrollbarX.chart.series.push(
        am5xy.LineSeries.new(root, {
            xAxis: sbxAxis,
            yAxis: sbyAxis,
            valueYField: "user_totals", 
            valueXField: "chart_dated_dt",
        })
        );
    sbseries.strokes.template.setAll({
        strokeWidth: 2,
        //strokeDasharray: [2,1]
    });
    sbseries.data.setAll(data);
    chart.set("scrollbarX", scrollbarX);
    console.log(sbseries.data.values[0]["user_totals"])
    console.log(sbseries.data.values[0]["chart_dated_dt"])




    // Make stuff animate on load
    // https://www.amcharts.com/docs/v5/concepts/animations/
    root._logo.dispose();
    chart.appear(1000, 100);
    }); // end am5.ready()
I've looked at the docs and at some questions here and still stuck-

Solution

    1. For the currency I added the currency symbol within the number formatter:

      root.numberFormatter.setAll({ numberFormat: "'ZAR '#,###.##00", tooltipNumberFormat: "'ZAR '#,###.##00",

    2. I didn't figure out how to handle the formatting of the legend but what I did instead was change the date data from a Category value with a string to a an actual which allowed me to change the axis into a date one. Amcharts naturally handles the formatting of this in such a way that my problem disappeared and it also fit my long terms data goals for the chart. The category was a story gap.

    3. The preview had isues with my date compile. I noticed in the code when converting the date I was simply making the date object but not actually getting the time. By using the the get_time i was able to properly render the x-axis. This issue aslo affected number 2.

      for (let i = 0; i < data.length; i++) { data[i]["chart_dated_dt"] = new Date(data[i]["chart_dated_dt"]).getTime(); }

    Full code:

    <script type="text/javascript">
        am5.ready(function() {
    
            // Create root element
            // https://www.amcharts.com/docs/v5/getting-started/#Root_element
            var root = am5.Root.new("fundChartLine");
            
            root.numberFormatter.setAll({
                numberFormat: "'ZAR '#,###.##00",
                tooltipNumberFormat: "'ZAR '#,###.##00",
            });
    
            // Set themes
            // https://www.amcharts.com/docs/v5/concepts/themes/
            root.setThemes([
                am5themes_Animated.new(root),
                am5themes_Responsive.new(root),
                Amdg.new(root)
            ]);
            // Create chart
            // https://www.amcharts.com/docs/v5/charts/percent-charts/pie-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);
    
    
    
            // Define data
            var data = {{ line_chart_data| safe }}
            
            for (let i = 0; i < data.length; i++) {
                data[i]["chart_dated_dt"] = new Date(data[i]["chart_dated_dt"]).getTime();
            }
    
            // Create axes
            // https://www.amcharts.com/docs/v5/charts/xy-chart/axes/
            // Create Y-axis
            let yAxis = chart.yAxes.push(
            am5xy.ValueAxis.new(root, {
                maxDeviation: 0.1,
                renderer: am5xy.AxisRendererY.new(root, {})
            })
            );
    
    
            var xAxis = chart.xAxes.push(
                am5xy.DateAxis.new(root, {
                    maxDeviation: 0.1,
                    groupData: true,
                    groupIntervals: [
                        { timeUnit: "month", count: 1 }
                        ],
                    baseInterval: { timeUnit: "day", count: 1 },
                    renderer: am5xy.AxisRendererX.new(root, {
                    }),
                    tooltip: am5.Tooltip.new(root, {})
                })
                );
    
            xAxis.get("dateFormats")["day"] = "MM/dd";
            xAxis.get("periodChangeDateFormats")["day"] = "MMMM";
            
            xAxis.data.setAll(data);
            // Add series
            // https://www.amcharts.com/docs/v5/charts/xy-chart/series/
            // https://www.amcharts.com/docs/v5/charts/xy-chart/series/line-series/
            function createSeries(name, field) {
            var series = chart.series.push( 
                am5xy.LineSeries.new(root, { 
                name: name,
                xAxis: xAxis, 
                yAxis: yAxis,
                valueYField: field, 
                valueXField: "chart_dated_dt",
                stacked: false,
                tooltip: am5.Tooltip.new(root, {
                    pointerOrientation: "horizontal",
                    labelText: "{valueY}",
                    })
    
                })
            );
            
            series.strokes.template.setAll({
                strokeWidth: 2,
                //strokeDasharray: [2,1]
            });
            series.fills.template.setAll({
                fillOpacity: 0.5,
                visible: false
            });
            series.data.setAll(data);
    
            }
            
            chart.topAxesContainer.children.push(am5.Label.new(root, {
                text: "Performance",
                fontSize: 30,
                fontColor: '#e40505',
                fontWeight: "500",
                textAlign: "center",
                x: am5.percent(50),
                centerX: am5.percent(50),
                paddingTop: 0,
                paddingBottom: 20,
            }));
    
            // Add cursor
            // https://www.amcharts.com/docs/v5/charts/xy-chart/cursor/
            var cursor = chart.set("cursor", am5xy.XYCursor.new(root, {
                xAxis: xAxis
                }));
            cursor.lineY.set("visible", false);
    
    
            createSeries("Average Contributions", "average_contrib");
            createSeries("Average Contributions + Interest", "average_totals");
            createSeries("Median Contributions", "median_contrib");
            createSeries("Median Contributions + Interest", "median_totals");
            createSeries("Your Contributions", "user_contrib");
            createSeries("Your Contributions + Interest", "user_totals");
    
            var legend = chart.bottomAxesContainer.children.push(am5.Legend.new(root, {
                centerX: am5.percent(50),
                x: am5.percent(50),
                useDefaultMarker: true,
                paddingTop: 10,
                paddingBottom: 20,
                layout: am5.GridLayout.new(root, {
                    maxColumns: 3,
                    fixedWidthGrid: true
                })
            }));
            legend.data.setAll(chart.series.values);
    
            // Add scrollbar
            // https://www.amcharts.com/docs/v5/charts/xy-chart/scrollbars/
    
            var scrollbarX = am5xy.XYChartScrollbar.new(root, {
                orientation: "horizontal",
                height: 50
                });
            
            let sbxAxis = scrollbarX.chart.xAxes.push(
                am5xy.DateAxis.new(root, {
                    groupData: true,
                    groupIntervals: [
                        { timeUnit: "month", count: 1 }
                        ],
                    baseInterval: { timeUnit: "day", count: 1 },
                    renderer: am5xy.AxisRendererX.new(root, {
                        opposite: false,
                        strokeOpacity: 0
                    })
                })
                );
    
            let sbyAxis = scrollbarX.chart.yAxes.push(
                am5xy.ValueAxis.new(root, {
                    renderer: am5xy.AxisRendererY.new(root, {})
                })
            );
    
            let sbseries = scrollbarX.chart.series.push(
                am5xy.LineSeries.new(root, {
                    xAxis: sbxAxis,
                    yAxis: sbyAxis,
                    valueYField: "user_totals", 
                    valueXField: "chart_dated_dt",
                })
                );
            sbseries.strokes.template.setAll({
                strokeWidth: 2,
                //strokeDasharray: [2,1]
            });
            sbseries.data.setAll(data);
            chart.set("scrollbarX", scrollbarX);
    
    
            // Make stuff animate on load
            // https://www.amcharts.com/docs/v5/concepts/animations/
            
            sbseries.appear(1000, 100);
            console.log(chart.series)
            console
            root._logo.dispose();
            chart.appear(1000, 100);
            }); // end am5.ready()
    </script>