Hello,
I would like to make a few suggestions to improve the way formatters are used in jqPlot.
I would be happy to contribute code, but I would like to get your opinions (more specifically Chris's, of course) first.
The overall goal would be to make formatters easier to customise, by passing them more contextual data.
Although this doesn't seem to be documented in the main options, it's already possible to change a tickRenderer formatter by passing a custom function to the 'formatter' parameter, as mentioned in this thread:
https://groups.google.com/forum/?fromgroups#!searchin/jqplot-users/formatter/jqplot-users/E_oPzn7Im9k/72LzsBQVEVgJThe formatter function only takes two parameters: formatString and value.
This is fine for simple cases, but in some cases, it's also useful to be able to get more context about the plot that is being rendered (series, index, displayed range, ...).
As far as I can tell, there are already a couple of places where this is used: the nice intervals in the DateAxisRenderer and the highlighter's tooltipContentEditor.
By default, without any specific formatString, the DateAxisRenderer adapts automatically to display only the relevant parts of the date depending on how far you zoom in. It will only display the hours and minutes if it's meaningful for the displayed range (e.g. over a day, but not over a year). This is fine if you want to use the date formats pre-set for this purpose within the DateAxisRenderer (niceFormatStrings and niceIntervals).
However, if you want to use a different date format (let's say "%e-%b-%Y" for the dates), it seems this can only be done by changing the entire formatString, which affects all the formatted strings, regardless of the zooming level and displayed range.
A recent addition to the highlighter plugin also seems to reflect a similar need for contextual information, via the tooltipContentEditor. This parameter expects a function that takes (str, seriesIndex, pointIndex, plot) where str is is the original string produced by the formatter in place. This function could in fact be the formatter, instead of tweaking the formatter's output.
What I would like to suggest is a more harmonised usage of formatters across the rest of the code, by passing it more contextual information, in a similar way to what tooltipContentEditor does. (The whole "nice intervals" logic would also be moved within the formatter itself, instead of being a special case in the DateAxisFormatter.)
There seems to be two broad categories of formatter usages: for a specific data point and for a specific axis.
- The data point usages would be:
- highlighter
- cursor
- point labels
What's currently done with tooltipContentEditor in the highlighter plugin could indeed equally apply to the cursor and the point labels. In all cases, the label refers to a specific data point.
Perhaps the formatters could be extended with something like this:
formatter(options, value, seriesIndex, pointIndex, plot)
(options could be the formatterString or an object with more parameters perhaps, if the formatter can be configured more extensively, perhaps with an additional formatterOptions).)
- The axis usages would be all the tick renderers.
In this case, it doesn't make much sense to use a pointIndex. The seriesIndex might be relevant, also this should indirectly be linked from the axis used by a specific series instead. Perhaps something like this could be used:
formatter(options, value, axis, plot)
(axis, would be one of 'xaxis', 'yaxis', 'y2axis', ... perhaps.)
Perhaps we could also have a single function signature applicable to both usages generally speaking, maybe something along the lines of:
formatter(formatString, value, plot, formatterOptions, formatterArgs) where formatterArgs would be an object with fields seriesIndex, pointIndex and/or axis when applicable.
I'm not quite sure what the cleanest way to proceed with this would be. Some of this may change the API, and it would be better not to break existing code.
Any thoughts on this? These are merely early suggestions of course. Perhaps I've missed something and what I'm trying to do can already be done. I'm not sure whether there would be more general interest for this.
Best wishes,
Bruno.