how to display data dynamically in jfreechart - jfreechart

I have created a function that processes some value.
Now, my problem is that the graph i create displays the values generated after ALL the values have been calculated. i want to generate the graph such that the as and when the data is calculated; it must be plotted on the data.
The calculation and the display of data in the graph must appear parallel.
I have generated the graph as:
dataset.addSeries(series1);
dataset = new XYSeriesCollection();
series1 = new XYSeries("% ERROR");
chart = ChartFactory.createXYLineChart("Percent Error", "Number of Records", "% Error", dataset,PlotOrientation.VERTICAL,true, true, true);
chart.setBackgroundPaint(Color.WHITE);
frame = new ChartFrame("Error graph", chart);
frame.pack();
frame.setVisible(true);
The series1 is plotted on the graph.the values in series1 is added on every iteration of the loop which generates some value.
Can it be done using wait and notify? I am not really sure about this functions. Please help

The add() method of XYSeries "Adds a data item to the series and sends a SeriesChangeEvent to all registered listeners." One approach is to invoke add() using javax.swing.Timer, as shown in this example.

If your data are computed within a fix period what about using DinamycTimeSeriesCollection?
They are very usefull.
You can find an example in this question where I managed the problem of having periods multiple of a millisecond.

Related

Devexpress: how to add points to Chart Control at runtime?

i'm trying to build a telemetry software using Winform and Devexpress library. Specifically i'm working on a Line Chart Control and what i would like to do is to configure the chart so that it is able to display a data changing in real time.
The graph is generated reading some external sensors that send informations at a rate of 10 values per second.
This is my code for initialize the chart:
series1 = new Series("test test", ViewType.Line);
chartControl1.Series.Add(series1);
series1.ArgumentScaleType = ScaleType.Numerical;
((LineSeriesView)series1.View).LineMarkerOptions.Kind = MarkerKind.Triangle;
((LineSeriesView)series1.View).LineStyle.DashStyle = DashStyle.Dash;
((XYDiagram)chartControl1.Diagram).EnableAxisXZooming = true;
chartControl1.Legend.Visibility = DefaultBoolean.False;
chartControl1.Titles.Add(new ChartTitle());
chartControl1.Titles[0].Text = "A Line Chart";
chartControl1.Dock = DockStyle.Fill;
And this is the one that add a new point and remove the first point available so that the amount of points in my chart is always the same (after a minimum amount of points is reached) and it keeps updating itself displaying the last X seconds of values and discarding the old values.
series1.Points.RemoveRange(0, 1);
series1.Points.Add(new SeriesPoint(time, value));
...
AxisXRange.SetMinMaxValues(newFirstTime, time);
AxisRange is the following
Range AxisXRange
{
get
{
SwiftPlotDiagram diagram = chartControl1.Diagram as SwiftPlotDiagram;
if (diagram != null)
return diagram.AxisX.VisualRange;
return null;
}
}
**The problem ** is that this code works temporarily. After some seconds, the chart stop working and a big red cross is displayed over it.
Is there something that i'm missing with its configuration?
Do you know any better way to realize my task?
Any help would be appreciated.
Thank you
I think you doing it nearly right. Devexpress has an Article about RealTime-Charts. They doing it the same way but using a timer for updating the data. Maybe this would fix your painting problems.

Create Fatter Candlesticks in JFreeChart

I'm developing an app that displays daily financial data, and have chosen to use JFreeChart. I was able to learn how to create a candlestick chart, but my problem lies in customization.
You see, what I'm aiming for is more along the lines of
While, so far all I've been able to manage is
.
No matter how far I zoom in, the candlesticks do not increase in width.
I'm fairly certain that somehow the thin candlesticks have something to do with being bound to a certain time range.. I've tried to remedy that but am not sure what I'm doing wrong here.
SSCE
public void showStockHistory(OHLCDataset dataset, String stockName) {
JFreeChart candleChart = ChartFactory.createCandlestickChart("History of " + stockName, "Date", "Stock Points", dataset, true);
XYPlot plot = candleChart.getXYPlot();
plot.setDomainPannable(true);
plot.setRangePannable(true);
ValueAxis domain = plot.getDomainAxis();
domain.setAutoRange(true);
NumberAxis range = (NumberAxis)plot.getRangeAxis();
range.setUpperMargin(0.0D);
range.setLowerMargin(0.0D);
range.setAutoRange(true);
range.setAutoRangeIncludesZero(false);
ChartPanel chartPanel = new ChartPanel(candleChart);
chartPanel.setMouseWheelEnabled(true);
chartPanel.setMouseZoomable(true);
getViewport().add(chartPanel);
}
Although my given example seems to have to no differing method calls from the demo in the first picture's code above, it nevertheless only shows thin candlesticks. I assume this to be some kind of bug.
However, I was able to rectify the issue as follows:
getting the renderer for the chart,
casting it to a type of CandlestickRenderer, and
setting its setAutoWidthMethod() method to CandlestickRenderer.WIDTHMETHOD_SMALLEST.
This is how you do it:
JFreeChart candleChart = ChartFactory.createCandlestickChart(
"History of " + stockName, "Date", "Stock Points", dataset, true);
XYPlot plot = candleChart.getXYPlot();
CandlestickRenderer renderer = (CandlestickRenderer) plot.getRenderer();
renderer.setAutoWidthMethod(CandlestickRenderer.WIDTHMETHOD_SMALLEST);

How to store data from SmartGWT ListGrid?

I've been searching for hours but I couldn't find an answer to my question: I've set up a ListGrid similar to the one shown here (Link). Right now I am using a XML-File as data source (default rows) just like in the example. It is also possible to add and delete rows to/from the grid.
Therefore I would like to store every user's data from the grid in a data store (Google Datastore). So I need to read all the rows of the current user as Strings. What would be a good way to do that? I already tried the following, but without success:
ListGrid componentsGrid = new ListGrid();
componentsGrid.setWidth(500);
componentsGrid.setHeight(224);
componentsGrid.setCellHeight(22);
componentsGrid.setDataSource(ComponentsXmlDS.getInstance());
componentsGrid.setAutoFetchData(true);
componentsGrid.setCanEdit(true);
componentsGrid.setModalEditing(true);
componentsGrid.setEditEvent(ListGridEditEvent.CLICK);
componentsGrid.setListEndEditAction(RowEndEditAction.NEXT);
componentsGrid.setAutoSaveEdits(false);
layout.addMember(componentsGrid);
//First try
componentsGrid.fetchData();
logger.log(Level.INFO, "Components: "+ componentsGrid.getResultSet().get(0).getAttribute("componentType"));
//Second try
logger.log(Level.INFO, "Components: "+ componentsGrid.getAllFields());
// Third try
logger.log(Level.INFO, "Components: "+ componentsGrid.getRecords());
Anyone having a hint? Help is greatly appreciated.
If I understand well your requirement you want to read all the rows of the grid and store their data in a db.
I think you can use:
getRecordList() which *Return the underlying data of this DataBoundComponent as a RecordList.
You will be able to iterate inside this list, extract the attribute value you want for every record and store these data in your db.
Or use the getRecords() method as you said and iterate in the array of ListGridRecord obtained.
To iterate through your RecordList you have to transform it to an array, for example with a lot of dummy objects and methods:
RecordList data = MyGrid.getRecordList();
for(Record record : data.toArray()){
MyDataObject obj = new MyDataObject()
obj.setId(record.getAttribute("thId"));
obj.setOne(record.getAttribute("anAttribute"));
obj.setTwo(record.getAttribute("anotherAttribute"));
obj.StoreToDb();
}

Dynamically add forex data points to Shield UI Chart

I need is to dynamically add the points I’ve received from a forex provider to s Shield UI Chart. According to the documentation, there isn’t the possibility for dynamically adding of points At least there is no such method, something like: AddPoint or similar.
How can I still achieve a web page using Shield UI Chart, which to constantly show a couple of exchange rates?
You are right, that there is no addPoints method of the Shield UI Chart. However we can add the incoming data values to an array instead. You might find useful following code:
We need some arrays- as many as we need to show.
var EURUSD = new Array();
var USDCAD = new Array();
var GBPUSD = new Array();
In the body of the function, that will actually display the data we will have the following code:
EURUSD[EURUSD.length] = parseFloat(data.ticks.EURUSD);
USDCAD[USDCAD.length] = parseFloat(data.ticks.USDCAD);
GBPUSD[GBPUSD.length] = parseFloat(data.ticks.GBPUSD);
it will actually put the new data to the designated arrays. You can note, that each time data is received, it has been added to the last index of each array:
EURUSD.length
Since we don’t want our arrays to grow too large, it is good to specify how many points we need to keep. Once that limit is reached, we remove the oldest point:
if (EURUSD.length > 50)
EURUSD = EURUSD.splice(1, 49);
if (USDCAD.length > 50)
USDCAD = USDCAD.splice(1, 49);
if (GBPUSD.length > 50)
GBPUSD = GBPUSD.splice(1, 49);
At the end we need to recreate the chart, referencing the appropriate container:
var containter = $("#EURUSDChart").swidget();
containter.destroy();
and than create the chart again.

JFreeChart - Determine the moment when chart is not visible because of big amount of range axes

I am using JFreeChart library to create Chart. I need to present big amount of data on the same chart. Because of that I have many range axes descriptions.
Unfortunately when there are too many range axes, chart is no longer visible. It is possible to make chart visible by calling this simple lines (Where plot is an XYPlot instance):
int axises = plot.getRangeAxisCount();
for (int i = 0; i < axises; i++) {
plot.getRangeAxis(i).setVisible(false);
}
This simple portion of code hides all RangeAxes. After that code execution, chart does not have any description for range axes but it is visible.
But unfortunately I am unable to figure out how can I determine does the chart is visible or not during the processing time.
Information that is important to me is in:
chartPanel.getChartRenderingInfo().getPlotInfo().getDataArea().getWidth()
But unfortunately I am performing many operations on the chart (for example zoom, move, etc.) and because of that I need to have this information everytime, when state of the chart changes. I am unable to take that information whenever plotChanged() method of the PlotChangeListener interface is called, because there is no plot (this event is not fired). chartChanged() method from ChartChangeListener is fired too early - chartPanel.getChartRenderingInfo().getPlotInfo().getDataArea().getWidth() returns old values. Any ideas?
You can add a ChartProgressListener to the ChartPanel.
chart.addProgressListener(new ChartProgressListener() {
#Override
public void chartProgress(ChartProgressEvent event) {
System.out.println(event.getType() + " "
+ event.getPercent() + " "
+ chartPanel.getChartRenderingInfo()
.getPlotInfo().getDataArea().getWidth());
}
});

Resources