Dynamically add graph to charts

Hi everyone,
I would like to know if there is a way to dynamically add graph to charts.
I try to explain. I need to add (and remove) curves from an XY chart by selecting rows of a table.
The data are taken from a text file that is uploaded into the database (as a fileDescriptor) and associated with an entity.
At the moment I can insert a single graph correctly: when I select a row in the table I generate a dataProvider that “fill” the graph defined in the XML.
However I can’t find a way to add more graph if I previously don’t define them in the XML of the screen.
Also in this way number of curves is limited to a number of graphs insert in the chart element.
Some one can help? Thanks in advance

Hi,

A chart can have only one data provider, so in your case, you need to add graph instance to a chart and data to an existing data provider.

In my example, I use ListDataProvider as a data provider and MapDataItem as a data items.

Every time “Add” button is pressed, an instance of Graph is created.


Graph graph = new Graph()
            .setId("graph" + graphId++)
            .setBalloonText("x:[[x]] y:[[y]]")
            .setBullet(BulletType.ROUND)
            .setFillAlphas(0.0)
            .setLineAlpha(0.8)
            .setXField(graphId + "x")
            .setYField(graphId + "y");

where graphId is used to identify data added for this graph. In my example, graphId is simple int value, but you can use UUID of your entity. The same graphId is added for data items belong to this graph.


private DataItem getPointPair(double x, double y, int graphId) {
    MapDataItem dataItem = new MapDataItem();
    dataItem.add(graphId + "x", x);
    dataItem.add(graphId + "y", y);

    return dataItem;
}

The code bellow shows how to add chart graphs dynamically.


<layout expand="xyChart" spacing="true">
	<button caption="Add" invoke="addGraph"></button>
	<chart:xyChart id="xyChart"
				   autoMarginOffset="20"
				   marginBottom="60"
				   marginLeft="64"
				   theme="LIGHT"
				   width="100%">
		<chart:chartCursor></chart:chartCursor>
		<chart:valueAxes>
			<chart:axis axisAlpha="0"
						dashLength="1"
						position="BOTTOM"
						title="X Axis"></chart:axis>
			<chart:axis axisAlpha="0"
						dashLength="1"
						position="LEFT"
						title="Y Axis"></chart:axis>
		</chart:valueAxes>
		<chart:export position="BOTTOM_RIGHT"></chart:export>
	</chart:xyChart>
</layout>

@Inject
private Chart xyChart;

@Override
public void init(Map<String, Object> params) {
	ListDataProvider dataProvider = new ListDataProvider();
	xyChart.getConfiguration().setDataProvider(dataProvider);
}

private int graphId = 0;

public void addGraph() {
	Graph graph = new Graph()
			.setId("graph" + graphId++)
			.setBalloonText("x:[[x]] y:[[y]]")
			.setBullet(BulletType.ROUND)
			.setFillAlphas(0.0)
			.setLineAlpha(0.8)
			.setXField(graphId + "x")
			.setYField(graphId + "y");

	XYChart configuration = (XYChart) xyChart.getConfiguration();
	configuration.addGraphs(graph);

	DataProvider dataProvider = configuration.getDataProvider();

	dataProvider.addItem(getPointPair(1, RandomUtils.nextDouble(), graphId));
	dataProvider.addItem(getPointPair(2, RandomUtils.nextDouble(), graphId));
	dataProvider.addItem(getPointPair(3, RandomUtils.nextDouble(), graphId));
	dataProvider.addItem(getPointPair(4, RandomUtils.nextDouble(), graphId));
	dataProvider.addItem(getPointPair(5, RandomUtils.nextDouble(), graphId));

	xyChart.repaint();
}

private DataItem getPointPair(double x, double y, int graphId) {
	MapDataItem dataItem = new MapDataItem();
	dataItem.add(graphId + "x", x);
	dataItem.add(graphId + "y", y);

	return dataItem;
}

The full sample code available in github

Regards,

Gleb

2 Likes

Thanks a lot, you’ve solved a big issue.
What I was missing was the Graph class and addGraph method XYChart.
In the coming days I try to implement the code in my project.

Thanks again!