Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exposing isDatasetVisible method on chart object #15

Closed
niekvanderkooy opened this issue Nov 9, 2018 · 9 comments
Closed

Exposing isDatasetVisible method on chart object #15

niekvanderkooy opened this issue Nov 9, 2018 · 9 comments

Comments

@niekvanderkooy
Copy link

ChartJS exposes a chart.isDatasetVisible(index) method, to determine whether the dataset at an index is currently visible. It would be nice to expose this function in Charba.

I am currently using

public native boolean isDatasetVisible(AbstractChart<?, ?> chart, int index)/*-{
    return chart.@org.pepstock.charba.client.AbstractChart::chart.isDatasetVisible(index);
 }-*/;

(This is after checking if the AbstractChart.chart field is not null, since this is not always the case), and I would expect a similar method on maybe org.pepstock.charba.client.items.ChartNode would do the trick?

@niekvanderkooy
Copy link
Author

Ideally, I would be able to call AbstractChart.isDatasetVisible(index), however then there is the issue of what to return if AbstractChart.chart is null.

@stockiNail
Copy link
Contributor

@niekvanderkooy of course we can this method as well.
Anyway there is another method to get if dataset is visible or not, already implemented (we can use it now). The method isDatasetVisible(index) is a shortcut to the following.

The AbstractChart has got the method getDatasetMeta(int index) which returns the metadata of a dataset, by class DatasetMetaItem.

The method getDatasetMeta(int index) of AbstractChart returns null is chart is not initialized.

/**
 * Looks for the dataset that matches the current index and returns that metadata.
 * 
 * @param index dataset index
 * @return dataset meta data item.
 */
public DatasetMetaItem getDatasetMeta(int index) {
	// checks consistency of chart and datasets
	if (chart != null && data.getDatasets() != null && !data.getDatasets().isEmpty() && index < data.getDatasets().size()) {
		// gets meta data item
		DatasetMetaItem array = new DatasetMetaItem(getChartDatasetMeta(index));
		// returns the metadata
		return array;
	}
	// returns null
	return null;
}

The DatasetMetaItem has got the method isHidden() to know if dataset is hidden or not.

@niekvanderkooy
Copy link
Author

This was my first thought too. However, the isHidden() of DatasetMetaItem does not always work correctly:

This field is only initialised once the visibility is toggled by the user. Before this time, the javascript value is Null, and isHidden on the DatasetMetaItem defaults to false.
However, since we now have the ability to set isHidden on the dataset, it is possible that this default of false is no longer correct: if we set the dataset to hidden, and the user has nog toggled the visibility, then the dataset is not visible while DatasetMetaItem.isHidden() reports false.

This difference is what chartJS solves in the isDatasetVisible function, see https://github.com/chartjs/Chart.js/blob/da3aa68f38b9db25156c3b32c56098f9ca70f4d8/src/core/core.controller.js#L731.
They first check whether the meta value is initialised, and otherwise return the hidden value of the dataset, not the dataset meta.

@stockiNail
Copy link
Contributor

I've seen an issue in CharJS where they explained that hidden is an internal use only.
Unfortunately they didn't document it (renaming in _hidden) and also isDatasetVisible method is not documented yet :(
Furthermore if you see ChartJS sample about a plugin which is labelling the bars, you can find:

// Define a plugin to provide data labels
Chart.plugins.register({
	afterDatasetsDraw: function(chart) {
		var ctx = chart.ctx;
			chart.data.datasets.forEach(function(dataset, i) {
			var meta = chart.getDatasetMeta(i);
			if (!meta.hidden) {
				meta.data.forEach(function(element, index) {
					// Draw the text in black, with the specified font
					ctx.fillStyle = 'rgb(0, 0, 0)';
					var fontSize = 16;
					var fontStyle = 'normal';
					var fontFamily = 'Helvetica Neue';
					ctx.font = Chart.helpers.fontString(fontSize, fontStyle, fontFamily);
					// Just naively convert to string for now
					var dataString = dataset.data[index].toString();
					// Make sure alignment settings are correct
					ctx.textAlign = 'center';
					ctx.textBaseline = 'middle';
					var padding = 5;
					var position = element.tooltipPosition();
					ctx.fillText(dataString, position.x, position.y - (fontSize / 2) - padding);
				});
			}
		});
	}
});

Let me say, sample and documentation should be managed better but I know which effort is needed for those.... and I can understand!!
Nevertheless I'm going to implement the method isDatasetVisible.
As done for all others native method, the chart will expose a wrapper of native method in order to check is the CHARTJS chart is consistent (if not, will return false).

@stockiNail
Copy link
Contributor

@niekvanderkooy I'm gonna add the following methods, currently public in chart:

  • getDatasetAtEvent
  • getVisibleDatasetCount
  • isDatasetVisible

I'll publish it asap

@stockiNail
Copy link
Contributor

@niekvanderkooy We have added and tested 3 methods above mentioned.

See here isDatasetVisible in the master.

@stockiNail
Copy link
Contributor

stockiNail commented Nov 14, 2018

@niekvanderkooy waiting for new release, this is a workaround.
You correctly prepared the code and the trick is org.pepstock.charba.client.items.ChartNode.
Here is a code (tested).

import org.pepstock.charba.client.AbstractChart;
import org.pepstock.charba.client.items.ChartNode;
import org.pepstock.charba.client.items.UndefinedValues;

public final class DatasetHelper {
	
	private static DatasetHelper INSTANCE = new DatasetHelper();
	
	private DatasetHelper() {
	}
	
	public static DatasetHelper get() {
		return INSTANCE;
	}

		/**
	 * Looks for the dataset if it's visible or not, selected by index.
	 * 
	 * @param index dataset index
	 * @return <code>true</code> if dataset is visible otherwise <code>false</code>.
	 */
	public boolean isDatasetVisible(AbstractChart<?, ?> chart, int index) {
		ChartNode node = chart.getChartNode();
		// checks consistency of chart and datasets
		if (node.getId() != UndefinedValues.INTEGER && chart.getData().getDatasets() != null && !chart.getData().getDatasets().isEmpty() && index < chart.getData().getDatasets().size()) {
			// gets if dataset is visible or not
			return isChartDatasetVisible(chart, index);
		}
		// returns false
		return false;
	}
	
	/**
	 * Returns the amount of datasets which are visible
	 * 
	 * @return the amount of datasets which are visible. If chart is not initialized, return {@link org.pepstock.charba.client.items.UndefinedValues.INTEGER}.
	 */
	public int getVisibleDatasetCount(AbstractChart<?, ?> chart) {
		ChartNode node = chart.getChartNode();
		// checks consistency of chart and datasets
		if (node.getId() != UndefinedValues.INTEGER) {
			// gets if dataset is visible or not
			return getChartVisibleDatasetCount(chart);
		}
		// returns false
		return UndefinedValues.INTEGER;
	}

	/**
	 * Gets if the dataset is visible or not, selected by index.
	 * @param datasetIndex dataset index
	 * @return <code>true</code> if dataset is visible otherwise <code>false</code>.
	 */
	private native boolean isChartDatasetVisible(AbstractChart<?, ?> chart, int datasetIndex)/*-{
		return chart.@org.pepstock.charba.client.AbstractChart::chart.isDatasetVisible(datasetIndex);
	}-*/;

	/**
	 * Gets the amount of datasets which are visible
	 * @return the amount of datasets which are visible
	 */
	private native int getChartVisibleDatasetCount(AbstractChart<?, ?> chart)/*-{
		return chart.@org.pepstock.charba.client.AbstractChart::chart.getVisibleDatasetCount();
	}-*/;

}

Hopefully it can help

Nevertheless I'm gonna add a method to AbstractChart, like boolean isInitialized.

@stockiNail
Copy link
Contributor

In the master, isInitialized method.

@stockiNail
Copy link
Contributor

Charba 1.7 released with required methods.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants