Search code examples
javascriptc#razorblazortradingview-api

Passing parameters to anonymous javascript function in Blazor


I am building an app that requires the use of the TradingView advanced chart widget but I want to be able to pass a parameter into the options. This is what the code looks like from the website.

<!-- TradingView Widget BEGIN -->
<div class="tradingview-widget-container" style="height:100%;width:100%">
  <div class="tradingview-widget-container__widget" style="height:calc(100% - 32px);width:100%"></div>
  <div class="tradingview-widget-copyright"><a href="https://www.tradingview.com/" rel="noopener nofollow" target="_blank"><span class="blue-text">Track all markets on TradingView</span></a></div>
  <script type="text/javascript" src="https://s3.tradingview.com/external-embedding/embed-widget-advanced-chart.js" async>
  {
  "autosize": true,
  "symbol": "COINBASE:BTCUSD",
  "interval": "D",
  "timezone": "Etc/UTC",
  "theme": "light",
  "style": "1",
  "locale": "en",
  "enable_publishing": false,
  "gridColor": "rgba(255, 255, 255, 0.06)",
  "allow_symbol_change": true,
  "calendar": false,
  "studies": [
    "STD;MACD"
  ],
  "support_host": "https://www.tradingview.com"
}
  </script>
</div>
<!-- TradingView Widget END -->

I want to be able to pass a parameter for the symbol: for example instead of "COINBASE:BTCUSD" i want it to be "COINBASE:+"@symbol+"" so it can be scalable and for some reason it breaks the code every time, and yes I did pay mind to the "" quotes, its just not passing my blazor variable. What can I do here? Here is the link to the widgets in case it helps: https://www.tradingview.com/widget-docs/widgets/charts/advanced-chart/ Any solution which can make these charts scalable across an entire application would be great


Solution

  • If anyone runs into this problem in blazor i solved it like this: Chart.js

    (function() 
    {
        const charting = {
            show: function(symbol, locale, timezone, interval, showDetails, indicators) {
                new TradingView.widget({
                    "autosize": true,
                    "symbol": symbol,
                    "interval": interval,
                    "timezone": timezone,
                    "theme": "light",
                    "style": "8",
                    "locale": locale,
                    "gridColor": "rgba(255, 255, 255, 0.06)",
                    "toolbar_bg": "#f1f3f6",
                    "enable_publishing": false,
                    "hide_top_toolbar": false,
                    "allow_symbol_change": true,
                    "save_image": false,
                    "details": showDetails,
                    "container_id": "tradingview_515f8",
                    "studies": indicators,
                    "studies": [
                        "STD;MACD",
                        "QuantNomad;UT Bot Alerts"
                    ],
                });
            }
        };
    
        if (typeof window !== 'undefined') {
            window.charting = charting; // Make charting available globally if desired (optional)
        } else {
            // Provide module exports for bundlers or other environments (optional)
            module.exports = charting;
        }
    })();
    
    window.scriptLoader = function(sourceUrl, targetElement, innerHtml) {
        if (sourceUrl.Length == 0) {
            console.error("Invalid source URL");
            return;
        }
    
        var tag = document.createElement('script');
        tag.src = sourceUrl;
        tag.type = "text/javascript";
    
        tag.onload = function () {
            console.log("Script loaded successfully");
        }
    
        tag.onerror = function () {
            console.error("Failed to load script");
        }
        tag.innerHTML = innerHtml
        const target = document.querySelector(targetElement);
        target.appendChild(tag);
    };
    
    window.pageLoader = function (sourceUrl) {
        window.location.href = sourceUrl;
    }
    

    ChartService.cs

    using System.ComponentModel;
    using System.Text.Json;
    using Microsoft.JSInterop;
    
    namespace BotTrading.Services;
    
    public class ChartService : IDisposable
    {
        readonly IJSRuntime js;
        public readonly ChartConfig config;
    
        public readonly IEnumerable<string> symbolTypes = new[] { "all", "stock", "futures", "forex", "crypto", "index", "bond", "economic" };
    
        public readonly IEnumerable<string> Indicators = new[] {
            "STD;MACD",
            "UT Bot Alerts-QuantNomad",
        };
    
        public IEnumerable<(string, string)> Intervals = new[]
        {
            ("1", "1m"),
            ("3", "3m"),
            ("5", "5m"),
            ("15", "15m"),
            ("30", "30m"),
            ("60", "1h"),
            ("120", "2h"),
            ("180", "3h"),
            ("240", "4h"),
            ("D", "1d"),
            ("W", "1w"),
        };
    
        public ChartService(IJSRuntime js, ChartConfig config)
        {
            this.js = js;
            this.config = config;
            config.PropertyChanged += DrawChartSync;
        }
    
        private void DrawChartSync(object? sender, PropertyChangedEventArgs e)
        {
            DrawChart();
        }
    
        public async Task DrawChart() => 
            await js.InvokeVoidAsync("charting.show", config.Symbol.Id, config.Locale, config.TimeZone, config.Interval, config.ShowDetails, config.Indicators);
        
        public async Task DisplayChart(string symbol) => 
            await js.InvokeVoidAsync("charting.show", symbol, config.Locale, config.TimeZone, config.Interval, config.ShowDetails, config.Indicators);
    
        public async Task Navigate(Uri uri) => 
            await js.InvokeVoidAsync("pageLoader", uri);
    
        const string technicalAnalysisJsUrl = "https://s3.tradingview.com/external-embedding/embed-widget-technical-analysis.js";
        
        public async Task LoadTechnicalAnalysis(string containerElement) =>
            await js.InvokeVoidAsync("scriptLoader", technicalAnalysisJsUrl, containerElement, JsonSerializer.Serialize(new
            {
                interval = "1m",
                width = "100%",
                height = "100%",
                isTransparent = false,
                symbol = config.Symbol.Symbol,
                showIntervalTabs = false,
                locale = config.Locale,
                colorTheme = "dark",
            }));
    
        // public async Task<IEnumerable<string>> SearchTimeZones(string searchText) =>
        //     TimeZoneConverter.TZConvert
        //         .KnownIanaTimeZoneNames
        //         .Where(tz => tz.ToLower().Contains(searchText.ToLower()))
        //         .OrderBy(tz => tz);
    
        public void Dispose() =>
            config.PropertyChanged -= DrawChartSync;
    }
    

    ChartConfig.cs

    using System.ComponentModel;
    using DevExpress.Mvvm.CodeGenerators;
    
    namespace BotTrading.Services;
    
    [GenerateViewModel]
    public partial class ChartConfig : INotifyPropertyChanged
    {
        [GenerateProperty] ExchangeSymbol symbol = new ExchangeSymbol {Symbol = "XBTUSD"};
        [GenerateProperty] string locale = "en";
        [GenerateProperty] string timeZone = "Etc/UTC";
        [GenerateProperty] string interval = "240";
        [GenerateProperty] bool showDetails = false;
        [GenerateProperty] string[] indicators = Array.Empty<string>();
    
        public event EventHandler OnChartChanged =
            (sender, args) => { };
    
        public void Updated() =>
            OnChartChanged.Invoke(this, new EventArgs());
    
        public event PropertyChangedEventHandler? PropertyChanged;
    }
    
    
    public record ExchangeSymbol
    {
        public string Id => $"{Exchange}:{Symbol}";
        public string Symbol { get; init; }
        public string Description { get; init; }
        public string Type { get; init; }
        public string Exchange { get; init; }
        public string Provider_id { get; init; }
    }