mariusmuntean / ChartJs.Blazor

Brings Chart.js charts to Blazor
https://www.iheartblazor.com/
MIT License
692 stars 152 forks source link

OnClick handler not working on BarChart #55

Closed taylorjimbo closed 4 years ago

taylorjimbo commented 4 years ago

The defined OnClick handler is not being fired when the bar is click, but when the legend is clicked

Code example

@page "/test"

@using ChartJs.Blazor.Charts @using ChartJs.Blazor.ChartJS.Common.Properties @using ChartJs.Blazor.Util @using ChartJs.Blazor.ChartJS.BarChart @using ChartJs.Blazor.ChartJS.BarChart.Axes @using ChartJs.Blazor.ChartJS.Common.Axes @using ChartJs.Blazor.ChartJS.Common.Wrappers @using ChartJs.Blazor.ChartJS.Common.Axes.Ticks @using ChartJs.Blazor.ChartJS.Common.Handlers.OnClickHandler @using Newtonsoft.Json

<ChartJsBarChart @ref="barChartJs" Config="@_config" Height="250" />


<button type="button" class="btn btn-outline-danger" @onclick="OnClear">Clear
<textarea rows="@Rows" @bind-value="@EventArgs" @bind-value:event="oninput" style="width: 100%; resize: both; height:auto ">

@code {

private ChartJsBarChart barChartJs;
private BarConfig _config;
public int Rows { get; set; } = 3;
private BarDataset<DoubleWrapper> _barDataSet;

public string EventArgs { get; set; } = "";

protected override void OnInitialized()
{
    _config = new BarConfig()
    {

        Options = new BarOptions
        {
            Title = new OptionsTitle
            {
                Display = true,
                Text = "Simple Bar Chart"
            },
            Scales = new BarScales
            {
                XAxes = new List<CartesianAxis>
            {
                    new BarCategoryAxis
                    {
                        BarPercentage = 0.5,
                        BarThickness = BarThickness.Flex
                    }
                },
                YAxes = new List<CartesianAxis>
            {
                    new BarLinearCartesianAxis
                    {
                        Ticks = new LinearCartesianTicks
                        {
                            BeginAtZero = true
                        }
                    }
                }
            },

            OnClick = new DotNetInstanceClickHandler(OnClickHandler),
            MaintainAspectRatio = false,
            Responsive = true
        }
    };

    _config.Data.Labels.AddRange(new[] { "A", "B", "C", "D" });

    _barDataSet = new BarDataset<DoubleWrapper>
    {
        Label = "My double dataset",
        BackgroundColor = new[] { ColorUtil.RandomColorString(), ColorUtil.RandomColorString(), ColorUtil.RandomColorString(), ColorUtil.RandomColorString() },
        BorderWidth = 0,
        HoverBackgroundColor = ColorUtil.RandomColorString(),
        HoverBorderColor = ColorUtil.RandomColorString(),
        HoverBorderWidth = 1,
        BorderColor = "#ffffff"
    };

    _barDataSet.AddRange(new double[] { 8, 5, 3, 7 }.Wrap());
    _config.Data.Datasets.Add(_barDataSet);

}

[JSInvokable]
public void OnClickHandler(object sender, object args)
{
    EventArgs += JsonConvert.SerializeObject(JsonConvert.DeserializeObject($"{Environment.NewLine}{args}"), Formatting.Indented);
    Rows = Math.Max(3, EventArgs.Split(new[] { Environment.NewLine }, StringSplitOptions.None).Length + 1);
    StateHasChanged();
}

private void OnClear()
{
    EventArgs = string.Empty;
    StateHasChanged();
}

}`

mariusmuntean commented 4 years ago

@taylorjimbo this is odd. I will look into this during the weekend. Is this an urgent issue for you right now?

taylorjimbo commented 4 years ago

Not urgent. Thanks for the quick response.

taylorjimbo commented 4 years ago

I don't know if this is related, but I also noticed that for Bar Charts you can only display a single Label and not a Legend.

I add the following and left the Label in the BarDataset empty, but the Legend was not displayed.

Options = new BarOptions { Legend = new Legend { Position = Position.Left, Labels = new LegendLabelConfiguration { UsePointStyle = true }, Display = true },

taylorjimbo commented 4 years ago

I have changed some of my Bar Charts to doughnut/pie charts and I noticed that whenever I call the Chart Update method that I lose the On Click Handler.

_doughnutChartJs.Update();

mariusmuntean commented 4 years ago

Hi there

I think you saw two different bugs. One had to do with the Update() method wiping out any registered click/hover handlers (Issue 54) and the other is a serialization exception while marshaling the click/hover event args from the JS Runtime to Mono.

The second bug was caused by a circular reference which broke the serialization.

Both should be fixed and I just released a new NuGet package.

As always, please feel free to open the issue again if you believe the problem isn't really fixed.

taylorjimbo commented 4 years ago

Sweet! Just tested on the bar charts and the On Click works.

Another issue in the same area is that the On Click handler args from TimeBarChart does not have a label in the _model or _view. This makes is impossible to know which bar they clicked on.

image

taylorjimbo commented 4 years ago

Update: It is NOT impossible to know which bar they clicked on in a TimeBarChart. It is just a little extra work.

I had to reference it by the Index in the args.