chart icon indicating copy to clipboard operation
chart copied to clipboard

Support for timestamp labels

Open benmccann opened this issue 7 years ago • 4 comments

Data specifies labels as a List<String>. However, the labels that I have are of type long representing milliseconds since the epoch for use in a time scale.

Here's an example of what I'm trying to do: http://www.chartjs.org/samples/latest/scales/time/financial.html

I'm not sure if the solution is to change labels to a List<?> or to add a type parameter to Data specifying the label type.

benmccann avatar Oct 24 '17 02:10 benmccann

That's something I haven't seen documented yet, but it does appear that Chart.js accepts more than just strings:

The labels on the page you link are moments, which I assume have their own serialization so that they can simply be substituted for Strings.

	var dateFormat = 'MMMM DD YYYY';
	var date = moment('April 01 2017', dateFormat);
	var data = [randomBar(date, 30)];
	var labels = [date];
	while (data.length < 60) {
		date = date.clone().add(1, 'd');
		if (date.isoWeekday() <= 5) {
			data.push(randomBar(date, data[data.length - 1].y));
			labels.push(date);
		}
	}

	var ctx = document.getElementById("chart1").getContext("2d");
	ctx.canvas.width = 1000;
	ctx.canvas.height = 300;
	var cfg = {
		type: 'bar',
		data: {
			labels: labels,
			datasets: [{
				label: "CHRT - Chart.js Corporation",
				data: data,
				type: 'line',
				pointRadius: 0,
				fill: false,
				lineTension: 0,
				borderWidth: 2
			}]
		},

That having been said, I'm not entirely sure this is something that can be easily accommodated, as an external JS library is used to get the desired effect.

One possible way forward could be to allow specifying custom formatter, perhaps as functional interface. We could have a method with a the following signature:

public <T> Data addLabel(T label, Formatter<T> formatter);

where Formatter would be an interface that looks like this:

public interface Formatter<T> {
    public String format(T t);
}

I do note that the library currently is targeted at >= Java 6, so no Java 8 syntax in the library itself without a major version bump.

Looking at all that though, I'm thinking that's something that might as well just be taken care of before calling addLabel(String label).

Any thoughts on this?

mdewilde avatar Oct 24 '17 18:10 mdewilde

You're right. I didn't look closely enough. The labels there are moments. I wouldn't expect that to be supported by this library since moments are a non-primitive type defined by a javascript library.

However, you can change that example so that it does indeed have labels as numbers as I originally thought. In my code I actually do have numbers and would still like to see them supported.

All the other libraries I use moved to Java 8 long ago, so I would have no issues dropping Java 6 support. Though I'm not sure that will be necessary with the clarification that I want to use numbers and not moments.

benmccann avatar Oct 27 '17 15:10 benmccann

To be honest, I'm not 100% clear on what is required. We could add a method along the lines of

public D addLabel(Object o) {
    this.labels.add(String.valueOf(o));
    return (D) this;
}

That would allow you to add any object as label. However, I'm not entirely sure on what the advantage would be. In the case of the timestamps, you don't want to simply have a stringified long, you want date formatting applied. I'd suggest that the best place to do that formatting would be before you add the label.

mdewilde avatar Nov 14 '17 20:11 mdewilde

I don't think there should be a String.valueOf because that would convert it from a number to a string and then it would no longer be handled correctly.

The problem with formatting before adding the label is that you then need to define a formatting function both in Java and in JavaScript. By using longs you can have the formatting function only on the client side.

benmccann avatar Nov 15 '17 03:11 benmccann