amcharts / amcharts5

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

Stock Chart Indicator Selector Visual #1676

Closed taylort91 closed 1 month ago

taylort91 commented 1 month ago

Bug description

The formatting of the Indicator selection within am5stock is not showing up correctly as on Amcharts website. Do not see a method of stacking the search bar and selections.

Snipit image

Amcharts Website image

HTML

    <script src="https://cdn.amcharts.com/lib/5/index.js"></script>
    <script src="https://cdn.amcharts.com/lib/5/xy.js"></script>
    <script src="https://cdn.amcharts.com/lib/5/stock.js"></script>
    <script src="https://cdn.amcharts.com/lib/5/themes/Animated.js"></script>
    <div id="chartcontrols" style="height: auto; max-width: 100%; padding: 5px 5px 0 16px;"></div>
    <div id="chartdiv" style="width: 100%; height: 550px;"></div>

Java Script

        am5.ready(function() {
            // create root element
            var root = am5.Root.new("chartdiv");

            const myTheme = am5.Theme.new(root);

            myTheme.rule("Grid", ["scrollbar", "minor"]).setAll({
                visible: false
            });

            root.setThemes([
                am5themes_Animated.new(root),
                myTheme
            ]);

            var stockChart = root.container.children.push(am5stock.StockChart.new(root, {
            }));

            root.numberFormatter.set("numberFormat", "#,###.00");

            var mainPanel = stockChart.panels.push(am5stock.StockPanel.new(root, {
                wheelY: "zoomX",
                panX: true,
                panY: true,
            }));

            mainPanel.get("colors").set("step",2);

            // Create Axes
            var valueAxis = mainPanel.yAxes.push(am5xy.ValueAxis.new(root, {
                renderer: am5xy.AxisRendererY.new(root, {
                }),
                tooltip: am5.Tooltip.new(root, {}),
                numberFormat: "#,###.00",
                extraTooltipPrecision: 2
            }));

            var dateAxis = mainPanel.xAxes.push(am5xy.GaplessDateAxis.new(root, {
                baseInterval: {
                    timeUnit: "day",
                    count: 1
                },
                groupData: true,
                renderer: am5xy.AxisRendererX.new(root, {
                    minorGridEnabled: true
                }),
                tooltip: am5.Tooltip.new(root, {})
            }));

            // Add Series
            var color = root.interfaceColors.get("background");
            var valueSeries = mainPanel.series.push(am5xy.CandlestickSeries.new(root, {
                fill: color,
                clustered: false,
                calculateAggregates: true,
                stroke: color,
                name: '{{ ticker }}',
                xAxis: dateAxis,
                yAxis: valueAxis,
                valueYField: "Close",
                openValueYField: "Open",
                lowValueYField: "Low",
                highValueYField: "High",
                valueXField: "Date",
                lowValueYGrouped: "low",
                highValueYGrouped: "high",
                openValueYGrouped: "open",
                valueYGrouped: "close",
                legendValueText: "Open: {openValueY} Low: {lowValueY} High: {highValueY} Close: {valueY}",
                legendRangeValueText: "{valueYClose}"
            }));

            var valueTooltip = valueSeries.set("tooltip", am5.Tooltip.new(root, {
                getFillFromSprite: false,
                getStrokeFromSprite: true,
                getLabelFillFromSprite: true,
                autoTextColor: false,
                pointerOrientation: "horizontal",
                labelText: "{name}: {valueY} {valueYChangePreviousPercent.formatNumber('[#00ff00]+#,###.##|[#ff0000]#,###.##|[#999999]0')}%"
            }));
            valueTooltip.get("background").set("fill", root.interfaceColors.get("background"));

            var valueLegend = mainPanel.plotContainer.children.push(am5stock.StockLegend.new(root, {
                stockChart: stockChart
            }));

            var volumePanel = stockChart.panels.push(am5stock.StockPanel.new(root, {
                wheelY: "zoomX",
                panX: true,
                panY: true,
                height: am5.percent(30)
            }));

            var volumeValueAxis = volumePanel.yAxes.push(am5xy.ValueAxis.new(root, {
                numberFormat: "#.#a",
                renderer: am5xy.AxisRendererY.new(root, {})
            }));

            var volumeDateAxis = volumePanel.xAxes.push(am5xy.GaplessDateAxis.new(root, {
                baseInterval: {
                    timeUnit: "day",
                    count:1
                },
                groupData: true,
                renderer: am5xy.AxisRendererX.new(root, {
                    minorGridEnabled: true
                })
            }));

            var firstColor = volumePanel.get("colors").getIndex(0);
            var volumeSeries = volumePanel.series.push(am5xy.ColumnSeries.new(root, {
                name: '{{ ticker }}',
                clustered: false,
                fill: firstColor,
                stroke: firstColor,
                valueYField: "Volume",
                valueXField: "Date",
                xAxis: volumeDateAxis,
                yAxis: volumeValueAxis,
                legendValueText: "{valueY.formatNumber('#.#a')}",
                numberFormat: "#.#a"
            }));

            var volumeLegend = volumePanel.plotContainer.children.push(am5stock.StockLegend.new(root, {
                stockChart: stockChart
            }));

            mainPanel.set("cursor", am5xy.XYCursor.new(root, {
                yAxis: valueAxis,
                xAxis: dateAxis,
                snapToSeries: [valueSeries],
                snapToSeriesBy: "y!"
            }));

            volumePanel.set("cursor", am5xy.XYCursor.new(root, {
                yAxis: volumeValueAxis,
                xAxis: volumeDateAxis,
                snapToSeries: [volumeSeries],
                snapToSeriesBy: "y!"
            }));

            var scrollbar = mainPanel.set("scrollbarX", am5xy.XYChartScrollbar.new(root, {
                orientation: "horizontal",
                height: 50
            }));
            stockChart.toolsContainer.children.push(scrollbar);

            var sbDateAxis = scrollbar.chart.xAxes.push(am5xy.GaplessDateAxis.new(root, {
                groupData: true,
                groupIntervals: [{
                    timeUnit: "week",
                    count: 1
                }],
                baseInterval: {
                    timeUnit: "day",
                    count: 1
                },
                renderer: am5xy.AxisRendererX.new(root, {
                    minorGridEnabled: true
                })
            }));

            var sbValueAxis = scrollbar.chart.yAxes.push(am5xy.ValueAxis.new(root, {
                renderer: am5xy.AxisRendererY.new(root, {})
            }));

            var sbSeries = scrollbar.chart.series.push(am5xy.LineSeries.new(root, {
                valueYField: "Close",
                valueXField: "Date",
                xAxis: sbDateAxis,
                yAxis: sbValueAxis
            }));

            sbSeries.fills.template.setAll({
                visible: true,
                fillOpacity: 0.3
            });

            var toolbar = am5stock.StockToolbar.new(root, {
                container: document.getElementById("chartcontrols"),
                stockChart: stockChart,
                controls: [ 
                    am5stock.IndicatorControl.new(root, {
                        stockChart: stockChart,
                        legend: valueLegend
                    }),

                    am5stock.DateRangeSelector.new(root, {
                        stockChart: stockChart
                    }),

                    am5stock.PeriodSelector.new(root, {
                        stockChart: stockChart
                    }),

                    am5stock.DrawingControl.new(root, {
                        stockChart: stockChart
                    }),

                    am5stock.ResetControl.new(root, {
                        stockChart: stockChart
                    }),

                    am5stock.SettingsControl.new(root, {
                        stockChart: stockChart
                    }),                        
                ]
            });

            data = {{ hist_data|safe }};

            valueSeries.data.setAll(data);
            stockChart.set("stockSeries", valueSeries);
            valueLegend.data.setAll([valueSeries]);

            volumeSeries.data.setAll(data);
            stockChart.set("volumeSeries", volumeSeries);
            volumeLegend.data.setAll([volumeSeries]);

            sbSeries.data.setAll(data);

            chart.appear(1000, 100);
        });

Python

interval = "max"
ticker_obj = yf.Ticker(ticker)
hist_df = ticker_obj.history(period=interval)
hist_df = hist_df.reset_index()
hist_data = hist_df.to_json(orient="records")

Environment (if applicable) amCharts 5 Django 4.1.6 yfinance 0.2.41

Additional context

taylort91 commented 1 month ago

Other CSS file caused issue with chart. Removed CSS document and issue went away.