mariusmuntean / ChartJs.Blazor

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

Custom Ticks Format callback #62

Closed netcorefan closed 4 years ago

netcorefan commented 4 years ago

Many times It is necessary to customize ticks in axis and this is normally do it using callback.

https://www.chartjs.org/docs/latest/axes/labelling.html#creating-custom-tick-formats

Joelius300 commented 4 years ago

Thank you for contacting us!

This is a big feature which we should definitely support at some point but we need to be careful on how we implement it otherwise it might be hard to use. Note that in order to implement this, we need a robust system for "delegate-communication" between js and c# (a c# delegate has be callable by js and the return value of the c# delegate has to be sent back to the js-caller). By being careful on how we implement it I meant that we really need to make this system strongly typed and not with a object[] or something like that otherwise it's not going to be enjoyable to use. This might be a challenging task. This robust system is also required for #41 therefore these two issues are very closely related and the hard part (if we do it right) only needs to be done once.

Maybe I have time in the coming days and I'll look over it and try to come up with a good foundation but I can't promise anything. Once we have the foundation the custom tick formats are only one of the many callbacks we want to support (e.g. look at all the tooltip-callbacks).

netcorefan commented 4 years ago

@Joelius300 , thank you for your code. I downloaded the branch to do a test and I realize, after some minutes, that callbacks can't work on server side blazor.

Isn't There any solution to be able to use chartjs callbacks with blazor server side? Would it be able to do it , as work arround (I know it's ugly), to inject javascript funcion in callback as string from c#?

tia!

Joelius300 commented 4 years ago

Unfortunately you've noticed correctly, on server-side callbacks that have a return value can only be implemented with javascript at the moment. You can use JavascriptHandler<T> for this, it works very well.
The reason DelegateHandler<T> doesn't work on server-side is because server-side-blazor only supports async js-calls to C# and not synchronous ones. Since in javascript it's once async, always async (without any Task.Wait() equivalent) you will get a Promise object no matter what. ChartJs isn't promise aware and doesn't await the promise but works with it as if it was the resolved value. If the object you want to return is complex, you'd probably get an error because ChartJs expects a property to be available but isn't since it's still a Promise. If it's a simple type however (like in the filter case which returns a bool) ChartJs might just do a truthy check which will always be true since, like any object, Promises are thruthy and therefore makes your filter entirely useless.

If you're interested, I've already asked SO without much success. The next step is probably asking the blazor team if they'll ever implement synchronous C# interop but to be honest I don't think they will (and maybe they simply can't because of all the underlying stuff).

Also about your comment

Would it be able to do it , as work arround (I know it's ugly), to inject javascript funcion in callback as string from c#?

As far as I can tell this wouldn't help us. Either you'd inject javascript, meaning you'd have to write js-code (which you can already do much easier) or you'd have to call back into C# which will bring us back to the original issue with once async, always async. Or do you have a different idea?

netcorefan commented 4 years ago

hi @Joelius300

Do you think this could help? https://github.com/luciotato/waitfor-ES6

I don't know much javascript either.

Joelius300 commented 4 years ago

As far as I can tell that won't work because you'd have to create a generator which means that instead of having Promise everywhere, we have one Generator object and as you can imagine, its alway truthy. I tried something in a jsfiddle but I'm not sure if I used it correctly.

I'm not good with js so if anyone has an idea or knows how to solve this, please tell us :)
For now it seems like there isn't a solution :/

Joelius300 commented 4 years ago

As far as I understand, this has been implemented in 58870b67d31 and the only point of discussion was the incompatiblity with Server-Side Blazor. It's also used in the sine line sample.

Closing this issue. If I missed something, feel free to comment.