I'm using the Jfree chart in my struts application. Y-Axis is Over Shipment Pieces and X-Axis is Supplier Code and secondary axis is used for the Over Shipment %. What the problem i faced here is , If the Over Shipment % values all comes to Zero it hide the X-Axis Supplier Value also. How can i overcome to avoid this. I have attached here screen shot for your consideration. Thanks to all to read this question.
I pasted my code here for your clear understanding,
/**
*
* #param response
* #throws IOException
*/
public void writeOccurrenceBasedParetoChart(HttpServletResponse response) throws IOException
{
String METHOD_NAME = "writeOccurrenceBasedParetoChart";
log.entering(CLASS_NAME, METHOD_NAME);
CategoryDataset dataset1 = createDataSetForPercentBasedChart1();
CategoryDataset dataset2 = createDataSetForPercentBasedChart2();
String rangeAxisLabel = "";
String numOfSupplrs = "";
//Behind Schedule "4"
if(searchRatingElement.equalsIgnoreCase("4"))
{
System.out.println("*******************searchRatingElement"+searchRatingElement);
rangeAxisLabel = I18nMessageUtil.getMessage(CommonUtil.getLocale(), "label.reports.wdid.ovrshptpcs");
}
else
{
rangeAxisLabel = I18nMessageUtil.getMessage(CommonUtil.getLocale(), "label.reports.wdid.ovrshptpcs");
}
JFreeChart chart = ChartFactory.createBarChart(
"", // chart title
"", // domain axis label
rangeAxisLabel, // range axis label
dataset1, // data
PlotOrientation.VERTICAL, // orientation
true, // include legend
true, // tooltips?
false // URLs?
);
// NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART...
// set the background color for the chart...
chart.setBackgroundPaint(Color.white);
CategoryPlot plot = (CategoryPlot) chart.getPlot();
plot.setBackgroundPaint(Color.lightGray);
plot.setDataset(1, dataset2);
plot.mapDatasetToRangeAxis(1, 1);
CategoryItemRenderer renderer1 = plot.getRenderer();
renderer1.setSeriesItemLabelGenerator(0,new CategoryItemLabelGenerator() {
public String generateRowLabel(final CategoryDataset arg0, final int arg1) {
// TODO Auto-generated method stub
return null;
}
public String generateLabel(final CategoryDataset dataset1,final int series,final int category) {
String result = null;
//CHAPTER 12. ITEM LABELS 91
final Number value = dataset1.getValue(series, category);
if (value != null) {
final double v = value.doubleValue();
if (v > 0) {
result = value.toString(); // could apply formatting here
}
}
return result;
}
public String generateColumnLabel(final CategoryDataset arg0, final int arg1) {
// TODO Auto-generated method stub
return null;
}
});
renderer1.setSeriesItemLabelsVisible(0,true);
BarRenderer renderer = (BarRenderer) plot.getRenderer();
renderer.setDrawBarOutline(false);
renderer.setSeriesOutlinePaint(0,Color.BLACK);
renderer.setDrawBarOutline(true);
renderer.setMaximumBarWidth(0.02);
renderer.setSeriesPaint(0,new Color(170, 0, 85));
CategoryAxis domainAxis = plot.getDomainAxis();
domainAxis.setCategoryLabelPositions(CategoryLabelPositions.createUpRotationLabelPositions(.6));
domainAxis.setLabelFont(new Font("Helvetica", Font.BOLD, 14));
domainAxis.setTickLabelFont(new Font("Helvetica", Font.BOLD, 14));
//Behind Schedule "4"
if(searchRatingElement.equalsIgnoreCase("4"))
{
System.out.println("||||||||||||||||||||||||||||||||searchRatingElement"+searchRatingElement);
numOfSupplrs = I18nMessageUtil.getMessage(CommonUtil.getLocale(), "label.reports.wdid.bhndschpctforchart");
}
else
{
numOfSupplrs = I18nMessageUtil.getMessage(CommonUtil.getLocale(), "label.reports.wdid.ovrshptpctforchart");
}
ValueAxis axis2 = new NumberAxis(numOfSupplrs);
axis2.setLabelFont(new Font("Helvetica", Font.BOLD, 14));
axis2.setTickLabelFont(new Font("Helvetica", Font.PLAIN, 14));
//if(!this.isValueDataZeros)
//axis2.setRange(0,13);
plot.setRangeAxis(1, axis2);
NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
// if(!this.isNumberDataZeros)
//rangeAxis.setRange(0,90);
//rangeAxis.setTickUnit(new NumberTickUnit(1));
rangeAxis.setLabelFont(new Font("Helvetica", Font.BOLD, 14));
rangeAxis.setTickLabelFont(new Font("Helvetica", Font.PLAIN, 14));
LineAndShapeRenderer renderer2 = new LineAndShapeRenderer();
renderer2.setSeriesPaint(0, Color.BLUE);
/*Start */
renderer2.setSeriesItemLabelGenerator(0,new CategoryItemLabelGenerator() {
public String generateRowLabel(final CategoryDataset arg0, final int arg1) {
// TODO Auto-generated method stub
return null;
}
public String generateLabel(final CategoryDataset dataset1,final int series,final int category) {
String result = null;
//CHAPTER 12. ITEM LABELS 91
final Number value = dataset1.getValue(series, category);
if (value != null) {
final double v = value.doubleValue();
if (v > 0) {
result = value.toString(); // could apply formatting here
}
}
return result;
}
public String generateColumnLabel(final CategoryDataset arg0, final int arg1) {
// TODO Auto-generated method stub
return null;
}
});
renderer2.setSeriesItemLabelsVisible(0,true);
/* End */
plot.setRenderer(1, renderer2);
plot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);
ChartUtilities.writeChartAsPNG(response.getOutputStream(), chart,
1150, 450);
}
/**
*
*/
public DefaultCategoryDataset createDataSetForPercentBasedChart1()
{
String METHOD_NAME = "createDataSetForPercentBasedChart1";
log.entering(CLASS_NAME, METHOD_NAME);
DefaultCategoryDataset dataSetForOccurrenceBasedChart = new DefaultCategoryDataset();
boolean flagForPercentPareto = false;
String occurrenceCountLabelName = null;
try
{
if(paretoReportBasedDataQO != null && paretoReportBasedDataQO.size()>0)
{
//Behind Schedule "4"
if(searchRatingElement.equalsIgnoreCase("4"))
{
occurrenceCountLabelName = I18nMessageUtil.getMessage(CommonUtil.getLocale(), "label.reports.wdid.bhndschpctforchart");
}
else
{
occurrenceCountLabelName = I18nMessageUtil.getMessage(CommonUtil.getLocale(), "label.reports.wdid.ovrshptpcs");
}
if(!flagForPercentPareto)
{
for(int i =0;i<paretoReportBasedDataQO.size();i++)
{
dataSetForOccurrenceBasedChart.addValue(paretoReportBasedDataQO.get(i).getOverShipmentPiecesCount(), occurrenceCountLabelName, paretoReportBasedDataQO.get(i).getSupplierName());
}
}
}
}
catch(Exception exceptionOccurrenceBasedChart)
{
flagForPercentPareto = true;
System.out.println("Exception In createDataSetForPercentBasedChart1 : "+exceptionOccurrenceBasedChart.getMessage());
}
log.exiting(CLASS_NAME, METHOD_NAME);
return dataSetForOccurrenceBasedChart;
}
/**
*
*/
public DefaultCategoryDataset createDataSetForPercentBasedChart2()
{
String METHOD_NAME = "createDataSetForPercentBasedChart2";
log.entering(CLASS_NAME, METHOD_NAME);
DefaultCategoryDataset dataSetForOccurrenceBasedChart = new DefaultCategoryDataset();
boolean flagForPercentPareto = false;
String occurrenceCountLabelName = null;
try
{
if(paretoReportBasedDataQO != null && paretoReportBasedDataQO.size()>0)
{
if(searchRatingElement.equalsIgnoreCase("4"))
{
occurrenceCountLabelName = I18nMessageUtil.getMessage(CommonUtil.getLocale(), "label.reports.wdid.bhndschpctforchart");
}
else
{
occurrenceCountLabelName = I18nMessageUtil.getMessage(CommonUtil.getLocale(), "label.reports.wdid.ovrshptpctforchart");
}
if(!flagForPercentPareto)
{
for(int i =0;i<paretoReportBasedDataQO.size();i++)
{
dataSetForOccurrenceBasedChart.addValue(paretoReportBasedDataQO.get(i).getOverShipmentPercentageCount(), occurrenceCountLabelName, paretoReportBasedDataQO.get(i).getSupplierName());
}
}
}
}
catch(Exception exceptionOccurrenceBasedChart)
{
flagForPercentPareto = true;
System.out.println("Exception In createDataSetForPercentBasedChart2 : "+exceptionOccurrenceBasedChart.getMessage());
}
log.exiting(CLASS_NAME, METHOD_NAME);
return dataSetForOccurrenceBasedChart;
}
What if you put the label in another position?
For example:
renderer.setBasePositiveItemLabelPosition(
new ItemLabelPosition(ItemLabelAnchor.CENTER, TextAnchor.CENTER));
Related
I'm simulating dummy real-time data using DynamicTimeSeriesCollection, like this. During random intervals, the data being passed to the plot should 'dropout' to simulate a network connection loss. At this point, this plot should stop drawing and only start plotting the data after the dropout has subsided.
I subclassed XYLineAndShapeRenderer and overrode the getItemLineVisible() method:
#Override
public boolean getItemLineVisible(int series, int item){
if(offline){
return false;
}else{
return true;
}
}
However when offline is true, all points are still being drawn on the graph.
public class Test extends ApplicationFrame {
private static final String TITLE = "Dynamic Series";
private static final String START = "Start";
private static final String STOP = "Stop";
private static final int COUNT = 1000*60;
private static final int FAST = 1; //1000/FAST = occurrences per second real time
private static final int REALTIME = FAST * 1000;
private static final Random random = new Random();
private static final double threshold = 35;
private double gateStart = ThreadLocalRandom.current().nextInt(0, 101);
private boolean returning = false;
private boolean offline = false;
private Timer timer;
private Calendar startDate;
private static final int simulationSpeed = 1000/FAST;
private final TimeSeries seriesA = new TimeSeries("A");
public Test(final String title) throws ParseException {
super(title);
SimpleDateFormat formatter = new SimpleDateFormat("dd/mm/yyyy HH:mm", Locale.ENGLISH);
PriceParser parser = new PriceParser();
List<List<String>> priceData = parser.parse();
Date date = formatter.parse(priceData.get(0).get(0));
startDate = Calendar.getInstance();
startDate.setTime(date);
Calendar timeBaseStartDate = Calendar.getInstance();
timeBaseStartDate.setTime(startDate.getTime());
timeBaseStartDate.add(Calendar.SECOND, -COUNT);
final TimeSeriesCollection dataset = new TimeSeriesCollection();
dataset.addSeries(this.seriesA);
JFreeChart chart = createChart(dataset);
final JComboBox combo = new JComboBox();
combo.addItem("Fast");
combo.addItem("Real-time");
combo.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if ("Fast".equals(combo.getSelectedItem())) {
timer.setDelay(FAST);
} else {
timer.setDelay(REALTIME);
}
}
});
JFrame frame = new JFrame("Test");
JLabel label = new JLabel("Network connectivity lost.");
this.add(new ChartPanel(chart), BorderLayout.CENTER);
JPanel btnPanel = new JPanel(new FlowLayout());
btnPanel.add(combo);
JPanel test = new JPanel();
test.add(label);
this.add(btnPanel, BorderLayout.SOUTH);
// frame.add(btnPanel);
//frame.add(test);
timer = new Timer(FAST, new ActionListener() {
Date timeToCheck = formatter.parse(priceData.get(0).get(0));
Calendar pauseResume = Calendar.getInstance();
Calendar offlineTime = Calendar.getInstance();
boolean paused = false;
boolean waiting = false;
//boolean offline = false;
double currentPrice;
float[] newData = new float[1];
PopupFactory pf = PopupFactory.getSharedInstance();
Popup popup;
#Override
public void actionPerformed(ActionEvent e) {
Date datasetTime = new Date();
if(offline){
System.out.println("Offline: "+offlineTime.getTime());
System.out.println("Current: "+datasetTime);
if(offlineTime.getTime().compareTo(datasetTime) == 0){
offline = false;
System.out.println("Im no longer offline");
popup.hide();
}
}
if(ThreadLocalRandom.current().nextInt(0, 1001) > 999 && !offline){
offline = true;
offlineTime.setTime(datasetTime);
offlineTime.add(Calendar.SECOND, ThreadLocalRandom.current().nextInt(1, 5)*10);
// dataset.addValue(0, 0, null);
popup = pf.getPopup(btnPanel, label, 900, 300);
popup.show();
}
if(timeToCheck.compareTo(datasetTime) == 0){
currentPrice = Double.valueOf(priceData.get(0).get(1));
paused = currentPrice >= threshold;
priceData.remove(0);
try {
timeToCheck = formatter.parse(priceData.get(0).get(0));
} catch (ParseException ex) {
ex.printStackTrace();
}
}
if(!paused) {
if (Math.round(gateStart) * 10 / 10.0 == 100d) {
returning = true;
} else if (Math.round(gateStart) * 10 / 10.0 == 0) {
returning = false;
}
if (returning) {
gateStart -= 0.1d;
} else {
gateStart += 0.1d;
}
}else{
if(datasetTime.compareTo(pauseResume.getTime()) == 0 && currentPrice < threshold){
paused = false;
waiting = false;
}else{
if(Math.round(gateStart)*10/10.0 == 0 || Math.round(gateStart)*10/10.0 == 100){
if(!waiting){
pauseResume.setTime(datasetTime);
pauseResume.add(Calendar.SECOND, 120);
}
waiting = true;
}else{
if(Math.round(gateStart)*10/10.0 >= 50){
gateStart += 0.1d;
}else if(Math.round(gateStart)*10/10.0 < 50){
gateStart -= 0.1d;
}
}
}
}
newData[0] = (float)gateStart;
seriesA.addOrUpdate(new Second(), gateStart);
}
});
}
private JFreeChart createChart(final XYDataset dataset) {
final JFreeChart result = ChartFactory.createTimeSeriesChart(
TITLE, "Time", "Shearer Position", dataset, true, true, false);
final XYPlot plot = result.getXYPlot();
plot.setDomainZeroBaselineVisible(false);
XYLineAndShapeRendererTest renderer = new XYLineAndShapeRendererTest(true, false);
plot.setRenderer(renderer);
DateAxis domain = (DateAxis)plot.getDomainAxis();
Calendar endDate = Calendar.getInstance();
endDate.setTime(new Date());
endDate.add(Calendar.HOUR_OF_DAY, 12);
System.out.println(new Date());
System.out.println(endDate.getTime());
domain.setRange(new Date(), endDate.getTime());
domain.setTickUnit(new DateTickUnit(DateTickUnitType.HOUR, 1));
domain.setDateFormatOverride(new SimpleDateFormat("HH:mm"));
ValueAxis range = plot.getRangeAxis();
range.setRange(0, 100);
return result;
}
private class XYLineAndShapeRendererTest extends XYLineAndShapeRenderer {
private boolean drawSeriesLineAsPath;
public XYLineAndShapeRendererTest(boolean line, boolean shapes){
super(line, shapes);
}
#Override
public Paint getItemPaint(int row, int col) {
if(!offline){
return super.getItemPaint(row, col);
}else{
return new Color(0, 0, 0);
}
}
}
private void start() {
timer.start();
}
public static void main(final String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
Test demo = null; //pass date in from csv
try {
demo = new Test(TITLE);
} catch (ParseException e) {
e.printStackTrace();
}
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
demo.start();
}
});
}
}
What am I doing wrong?
One approach would be to append an appropriate baseline value when off line. Starting from this example, the range is centered on a value of zero millivolts. The modification below adds zeroes between 60 and 90 milliseconds:
private float[] gaussianData() {
float[] a = new float[COUNT];
for (int i = 0; i < a.length; i++) {
if (i > 60 && i < 90) a[i] = 0;
else a[i] = randomValue();
}
return a;
}
In my instance, a period of offline should effectively stop graphing.
Use the approach suggested here, which uses setMaximumItemAge() to limit the number of displayed records. Add null values, as suggested here, to interrupt the display. Starting from this example, I got this display with these changes:
seriesA.setMaximumItemCount(120);
seriesB.setMaximumItemCount(120);
…
int i;
…
public void addNull() {
this.seriesA.add(new Millisecond(), null);
this.seriesB.add(new Millisecond(), null);
}
#Override
public void actionPerformed(ActionEvent e) {
if (i > 60 && i < 90) {
demo.addNull();
} else {
…
}
i++;
}
It is the current state of my project
I want to change this
this is my code
Blockquote
public class MainActivity extends AppCompatActivity {
LineChart mChart;
private static final float MAX_BP_VALUE = 220f;
private static final float MAX_BT_VALUE = 42f;
private static final float UPPER_LIMIT = 130.0f;
private static final float LOWER_LIMIT = 50.0f;
private static SimpleDateFormat mFormat = new SimpleDateFormat("yyyy:mm:dd");
IAxisValueFormatter xAxisFormatter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFormat.setTimeZone(TimeZone.getDefault());
mChart = (LineChart) findViewById(R.id.chart);
xAxisFormatter = new IAxisValueFormatter() {
public int getDecimalDigits() {
return 0;
}
#Override
public String getFormattedValue(float value, AxisBase axis) {
return mFormat.format(new Date((long) value));
}
};
setupChart();
setupAxes();
setupData();
setLegend();
Button drawButton = (Button) findViewById(R.id.drawButton);
drawButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
LineData data = mChart.getData();
LineDataSet dataset = BPcreateSet();
try {
dataset.addEntry(new Entry(new Long(mFormat.parse("2018:05:11").getTime()).floatValue(), 110));
dataset.addEntry(new Entry(new Long(mFormat.parse("2018:06:13").getTime()).floatValue(), 150));
dataset.addEntry(new Entry(new Long(mFormat.parse("2018:07:15").getTime()).floatValue(), 120));
dataset.addEntry(new Entry(new Long(mFormat.parse("2018:08:17").getTime()).floatValue(), 80));
dataset.addEntry(new Entry(new Long(mFormat.parse("2018:09:18").getTime()).floatValue(), 40));
} catch(Exception e) {
e.printStackTrace();
}
ArrayList<Integer> colorList = new ArrayList<Integer>();
colorList.add(Color.WHITE);
colorList.add(Color.RED);
colorList.add(Color.WHITE);
colorList.add(Color.WHITE);
colorList.add(Color.BLUE);
dataset.setCircleColors(colorList);
data.addDataSet(dataset);
mChart.setData(data);
data.notifyDataChanged();
mChart.notifyDataSetChanged();
mChart.animateX(1000);
}
});
}
private void setupChart() {
mChart.getDescription().setEnabled(false);
mChart.setTouchEnabled(true);
mChart.setPinchZoom(true);
mChart.setScaleEnabled(true);
mChart.setDrawGridBackground(false);
mChart.setBackgroundColor(Color.BLACK);
mChart.setMarker(new XYMarkerView(this, xAxisFormatter));
mChart.setDrawMarkers(true);
}
private void setupAxes() {
XAxis xl = mChart.getXAxis();
xl.setPosition(XAxis.XAxisPosition.BOTTOM);
xl.setTextColor(Color.WHITE);
xl.setDrawGridLines(false);
xl.setAvoidFirstLastClipping(true);
xl.setEnabled(true);
xl.setLabelRotationAngle(-45.0f);
xl.setGranularityEnabled(true);
xl.setGranularity(1.0f/6.0f); // per 10 minutes
xl.setDrawGridLines(true);
xl.setAxisLineWidth(2f);
xl.setAxisLineColor(Color.WHITE);
xl.setValueFormatter(xAxisFormatter);
YAxis leftAxis = mChart.getAxisLeft();
leftAxis.setTextColor(Color.WHITE);
leftAxis.setAxisMaximum(MAX_BP_VALUE);
leftAxis.setAxisMinimum(20f);
leftAxis.setGranularity(20f);
leftAxis.setAxisLineWidth(2f);
leftAxis.setAxisLineColor(Color.WHITE);
leftAxis.setLabelCount(10);
leftAxis.setDrawGridLines(true);
YAxis rightAxis = mChart.getAxisRight();
rightAxis.setTextColor(Color.WHITE);
rightAxis.setAxisMaximum(MAX_BT_VALUE);
rightAxis.setAxisMinimum(32f);
rightAxis.setGranularity(2f);
rightAxis.setAxisLineWidth(2f);
rightAxis.setAxisLineColor(Color.WHITE);
rightAxis.setDrawGridLines(false);
xl.setSpaceMin(50);
LimitLine ul = new LimitLine(UPPER_LIMIT, "Upper Limit");
ul.setLineWidth(2f);
ul.setLabelPosition(LimitLine.LimitLabelPosition.RIGHT_TOP);
ul.setTextSize(10f);
ul.setTextColor(Color.WHITE);
LimitLine ll = new LimitLine(LOWER_LIMIT, "Lower Limit");
ll.setLineColor(Color.BLUE);
ll.setLineWidth(2f);
ll.setLabelPosition(LimitLine.LimitLabelPosition.LEFT_TOP);
ll.setTextSize(10f);
ll.setTextColor(Color.WHITE);
LimitLine llI = new LimitLine(400f, "체온");
llI.setLineColor(Color.BLUE);
llI.setLineWidth(2f);
llI.setLabelPosition(LimitLine.LimitLabelPosition.RIGHT_BOTTOM);
leftAxis.removeAllLimitLines();
leftAxis.addLimitLine(ul);
leftAxis.addLimitLine(ll);
xl.addLimitLine(llI);
leftAxis.setDrawLimitLinesBehindData(true);
}
private void setupData() {
LineData data = new LineData();
data.setValueTextColor(Color.WHITE);
// add empty data
mChart.setData(data);
}
private void setLegend() {
Legend l = mChart.getLegend();
l.setForm(Legend.LegendForm.CIRCLE);
l.setTextColor(Color.WHITE);
}
private LineDataSet BPcreateSet() {
LineDataSet set = new LineDataSet(null, "pulse");
set.setAxisDependency(YAxis.AxisDependency.LEFT);
set.setColors(Color.argb(255, 0, 255, 0));
set.setLineWidth(3f);
set.setCircleRadius(6f);
set.setValueTextColor(Color.WHITE);
set.setValueTextSize(10f);
set.setDrawValues(false);
return set;
}
}
I want to mark the X-axis like the picture above.
Please excuse me that First and last values is empty because I am poor at Photoshop.
Is there a solution?
You can also recommend another library that represents the time value and indicates the value required for the X-axis
first of: I am really having a problem with JFreechart and mainly I really believe that this is my fault because I start using the library without fully understanding how it fully function or use
second of: these are some helpful resource that helped me :
check it out 1
check it out 2
check it out 3
my current state : my problem is in making use of the drawPrimaryLine()
in my already build project so I am still having a problem in connecting the dots
in my way, not in a sequence way
example: if I enter (10,10) and (15,15) and (20,20) and (25,25) in this sequence, this is what I will end up with (the left side without connecting, the right side with connecting)
My problem is:
1 - when drawing a line is showing on the right side, I don't want the line to be generated or created until all of the points are add and the button done has been clicked *show in the most bottom right side
2 - I don't want the showing line to be in a sequence way I want the line to be shown base on some algorithm and not all dots will have or a line will pass through it, only a line will pass in some case.
so, in summary: not all dots will be connected only some based on an algorithm.
this is my code :
public class x_y_2 extends JFrame {
private static final String title = "Connecting The Dots";
private XYSeries added = new XYSeries("Added");
public List ls = new LinkedList<XYSeries>();
private XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
final XYSeriesCollection dataset = new XYSeriesCollection();
private XYPlot plot ;
public x_y_2(String s) {
super(s);
final ChartPanel chartPanel = createDemoPanel();
this.add(chartPanel, BorderLayout.CENTER);
JPanel control = new JPanel();
JLabel label = new JLabel("Enter 'x' value");
JTextField Field_x = new JTextField();
Field_x.setPreferredSize( new Dimension( 100, 24 ));
JLabel label2 = new JLabel("Enter 'y' value");
JTextField Field_y = new JTextField();
JLabel error = new JLabel("Importent*** in case no value is entered,value is set to '1' ");
error.setForeground(Color.RED);
Field_y.setPreferredSize( new Dimension( 100, 24 ));
control.add(label);
control.add(Field_x);
control.add(label2);
control.add(Field_y);
control.add(new JButton(new AbstractAction("Add") {
#Override
public void actionPerformed(ActionEvent e) {
if (Field_x.getText().isEmpty()) {
Field_x.setText("1"); ;
}
if (Field_y.getText().isEmpty()) {
Field_y.setText("1");
}
Double x = Double.parseDouble(Field_x.getText());
Double y = Double.parseDouble(Field_y.getText());
added.add(x,y);
ls.add(added);
Field_x.setText("");
Field_y.setText("");
}
}));
control.add(error);
control.add(new JButton(new AbstractAction("Done..") {
#Override
public void actionPerformed(ActionEvent e) {
label.setVisible(false);
label2.setVisible(false);
Field_x.setVisible(false);
Field_y.setVisible(false);
error.setVisible(false);
PrimaryLine pr = new PrimaryLine(3);
GraphingData graphingdata = new GraphingData(2,4,2,10);
// pr.drawPrimaryLine(state, g2, plot, dataset, pass, series, item, domainAxis, rangeAxis, dataArea);
System.out.println(ls.size());
for (int i = 0 ; i < ls.size() ; i++) {
XYSeries xy = (XYSeries)ls.get(i);
System.out.println(xy.getX(i) +" "+xy.getY(i));
}
}
}));
this.add(control, BorderLayout.SOUTH);
}
private XYDataset createSampleData() {
dataset.addSeries(added);
return dataset;
}
private ChartPanel createDemoPanel() {
JFreeChart jfreechart = ChartFactory.createXYLineChart(
title, "X", "Y", createSampleData(),PlotOrientation.VERTICAL, true, true, false);
plot =jfreechart.getXYPlot();
renderer.setSeriesLinesVisible(0, true);
renderer.setSeriesShapesVisible(0, true);
plot.setRenderer(renderer);
return new ChartPanel(jfreechart);
}}
second class :
public class GraphingData extends JPanel {
double x_st , y_st , x_ed, y_ed = 0;
public Graphics2D g2 ;
public GraphingData(double x_st,double y_st,double x_ed,double y_ed) {
this.x_st = x_st ;
this.y_st = y_st;
this.x_ed = x_ed;
this.y_ed = y_ed;
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
g2.draw(new Line2D.Double(x_st,y_st,x_ed, y_ed));
}
}
Third Class :
public class PrimaryLine extends XYLineAndShapeRenderer {
private final int anchor;
public PrimaryLine(int acnchor) {
this.anchor = acnchor;
}
#Override
protected void drawPrimaryLine(XYItemRendererState state, Graphics2D g2,
XYPlot plot, XYDataset dataset, int pass, int series, int item,
ValueAxis domainAxis, ValueAxis rangeAxis, Rectangle2D dataArea) {
if (item == anchor) {
return;
}
}
public void chart() {
PrimaryLine r = new PrimaryLine(8);
XYPlot plot = new XYPlot(createSampleData(),new NumberAxis("X"), new
NumberAxis("Y"), r);
JFreeChart chart = new JFreeChart(plot);
}
private XYDataset createSampleData() {
XYSeriesCollection xySeriesCollection = new XYSeriesCollection();
XYSeries added = new XYSeries("added");
added.add(4,2);
added.add(2,1);
xySeriesCollection.addSeries(added);
return xySeriesCollection;
}
}
Any kinda of help I would be greatfull for .
I have to build a GPS parser. I need to parse the NMEA string in another thread, which will be parsing a single NMEA string and update chart at 1 Hz. For now I build part of my code, but I parse data in main thread in while loop; my teacher said that is wrong. I was programming some on Java but not in multi-threading aspects. How I could move parsing process and refreshing chart to background thread?
public class MainFrame extends JFrame {
private JButton btnWybPlik;
private JLabel jlDroga;
private JLabel jlPredkosc;
private JLabel jlCzas;
private JPanel mainjpanel;
private JPanel jpMenu;
private JPanel jpTablica;
//private String sciezkaPliku;
private SekwencjaGGA sekGGA = null;
private SekwencjaGGA popSekGGA = null;
private SekwencjaGSA sekGSA;
private SekwencjaGLL sekGLL;
private SekwencjaRMC sekRMC;
private double droga;
private double predkosc;
private XYSeries series1;
private XYSeriesCollection dataset;
public MainFrame() {
droga = 0;
btnWybPlik.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
int result = fileChooser.showOpenDialog(mainjpanel);
if (result == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();
//System.out.println("Selected file: " + selectedFile.getAbsolutePath());
String sciezkaPliku = selectedFile.getAbsolutePath();
wczytaniePliku(sciezkaPliku);
}
}
});
jpTablica = new JPanel();
mainjpanel.add(jpTablica);
this.series1 = new XYSeries("Trasa", false);
final XYSeriesCollection dataset = new XYSeriesCollection(this.series1);
final JFreeChart chart = createChart(dataset);
final ChartPanel chartPanel = new ChartPanel(chart);
jpTablica.add(chartPanel);
}
private void wczytaniePliku(String sciezkaDoPliku) {
try (BufferedReader br = new BufferedReader(new FileReader(sciezkaDoPliku))) {
String line;
//series1.add(53.448, 14.4907);
while ((line = br.readLine()) != null) {
parseLine(line);
}
//series1.add(53.4485, 14.4910);
} catch (IOException e) {
e.printStackTrace();
}
}
private void parseLine(String line) {
String bezSumKont = line.substring(0, line.length() - 3);
List<String> podzSekw = Arrays.asList(bezSumKont.split(","));
if (podzSekw.get(0).equalsIgnoreCase("$GPGGA")) {
if (check(line)) {
if (sekGGA != null)
popSekGGA = sekGGA;
sekGGA = new SekwencjaGGA(podzSekw);
if (popSekGGA != null) {
droga += obliczOdleglosc(popSekGGA, sekGGA);
jlDroga.setText(String.valueOf(droga));
}
series1.add(sekGGA.getWspolzedne().getLongitude(), sekGGA.getWspolzedne().getLatitude());
System.out.println(sekGGA.getWspolzedne().getLatitude() + " " + sekGGA.getWspolzedne().getLongitude());
//System.out.println(series1.getMaxY() + " " + series1.getMinY());
} else {
//TODO: Zlicz błąd
}
}
if (podzSekw.get(0).equalsIgnoreCase("$GPGSA")) {
if (check(line)) {
sekGSA = new SekwencjaGSA(podzSekw);
} else {
//TODO: Zlicz błąd
}
}
if (podzSekw.get(0).equalsIgnoreCase("$GPGLL")) {
if (check(line)) {
sekGLL = new SekwencjaGLL(podzSekw);
} else {
//TODO: Zlicz błąd
}
}
if (podzSekw.get(0).equalsIgnoreCase("$GPRMC")) {
//TODO: Sekwencja RMC (Recommended minimum of data)
if (check(line)) {
sekRMC = new SekwencjaRMC(podzSekw);
} else {
//TODO: Zlicz błąd
}
}
}
private double obliczOdleglosc(SekwencjaGGA pkt1, SekwencjaGGA pkt2) {
double odleglosc = 0;
double earthRadius = 6371000; //meters
double dLat = Math.toRadians(pkt2.getWspolzedne().getLatitude() - pkt1.getWspolzedne().getLatitude());
double dLng = Math.toRadians(pkt2.getWspolzedne().getLongitude() - pkt1.getWspolzedne().getLongitude());
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(Math.toRadians(pkt1.getWspolzedne().getLatitude())) * Math.cos(Math.toRadians(pkt1.getWspolzedne().getLatitude())) *
Math.sin(dLng / 2) * Math.sin(dLng / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
odleglosc = earthRadius * c;
return odleglosc;
}
/**
* Funkcja sprawdzająca sume kontrolną
*
* #param tekst cała linia NMEA
* #return true jeśli się suma kontrolna zgadza
*/
private boolean check(String tekst) {
String suma = tekst.substring(tekst.length() - 2, tekst.length());
tekst = tekst.substring(1, tekst.length() - 3);
int checksum = 0;
for (int i = 0; i < tekst.length(); i++) {
checksum = checksum ^ tekst.charAt(i);
}
if (Integer.parseInt(suma, 16) == checksum) {
return true;
}
return false;
}
private JFreeChart createChart(final XYDataset dataset) { ... }
private void customizeChart(JFreeChart chart) { ... }
public static void main(String[] args) {
JFrame frame = new JFrame("MainFrame");
frame.setContentPane(new MainFrame().mainjpanel);
frame.setPreferredSize(new Dimension(640, 480));
frame.pack();
frame.setVisible(true);
}
To avoid blocking the event dispatch thread, construct an instance of SwingWorker. Collect data in your implementation of doInBackground(), publish() intermediate results, and update the XYSeries in your implementation of process(). The listening chart will update itself in response. A related example that uses jfreechart is seen below and examined here.
I want to compress and store data of real time line graph I tried but not succeeded
public class DTest extends ApplicationFrame {
javax.swing.Timer _timer;
int nPoints = 200;
float[] history;
/** The most recent value added. */
private float lastValue = (float) 100.0;
DynamicTimeSeriesCollection dataset;
JPanel content;
private final ChartPanel chartPanel;
public DTest(final String title) {
super(title);
history = new float[nPoints];
dataset = new DynamicTimeSeriesCollection(
1, nPoints, new Second()//here speed will set
);
dataset.setTimeBase(new Second(0,0,0,1,1,2000));
dataset.addSeries(new float[]{0.0f}, 0, "S1");
System.out.println("Series count = " + dataset.getSeriesCount());
final JFreeChart chart = createChart(dataset);
chartPanel = new ChartPanel(chart);
content = new JPanel(new FlowLayout());
final JButton btn = new JButton("Stop");
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
_timer.stop();
}
});
final JButton btn1 = new JButton("Run");
btn1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// create new dataset and chart, set the new chart in the chartpanel
//createChart(dataset);
_timer.start();
}
});
JComboBox comb = new JComboBox();
comb.addItem("Select");
comb.addItem("Joy Stick");
content.add(chartPanel);//panel for chart
JPanel btnPanel = new JPanel(new FlowLayout());
btnPanel.add(btn);
btnPanel.add(btn1);
btnPanel.add(comb);
Container pane = getContentPane();
pane.setLayout(new BorderLayout());
pane.add(content, BorderLayout.NORTH);
pane.add(btnPanel, BorderLayout.CENTER);
chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
//setContentPane(content);
comb.addActionListener(new ActionListener() {
private float[] float_array;
private int itemCount;
public void actionPerformed(ActionEvent e) {
JComboBox jComb = (JComboBox) e.getSource();
if (jComb.getSelectedItem().equals("Joy Stick")) {
System.out.println("Joy Stick is Pressed");
try {
float_array = new float[1];
float_array[0] = 0;
itemCount = 0;
dataset.appendData(float_array);
dataset.addSeries(new float[]{0.0f}, 0, "S1");
_timer = new javax.swing.Timer(1, new ActionListener() { // 500ms
private int resizes;
private int inserted;
public void actionPerformed(ActionEvent e) {
double factor = 0.90 + 0.2 * Math.random();
lastValue = lastValue * (float) factor;
float_array[0] = lastValue;
System.out.println("lastValue is " + lastValue);
inserted++;
if ( inserted % (resizes+1)==0 )
dataset.appendData(float_array, itemCount++, 1);
history[itemCount] = lastValue;
if (itemCount >= nPoints - 1) {
resizes++;
DynamicTimeSeriesCollection newSet = new DynamicTimeSeriesCollection(1, nPoints, new Second());
newSet.setTimeBase(new Second(0,0,0,2,2,2000));
newSet.addSeries(new float[]{0.0f}, 0, "S1");
itemCount /= 2;
for (int i = 1; i < nPoints; i++) {
history[i / 2] = history[i];
float_array[0]=history[i / 2];
newSet.appendData(float_array, i/2, 1);
history[i] = 0;
}
chartPanel.setChart(createChart(newSet));
dataset = newSet;
chartPanel.repaint();
}
}
});
_timer.setRepeats(true);
_timer.start();
} catch (NullPointerException ne) {
System.out.println("NullPointer Exception" + ne.toString());
} catch (Exception ex) {
ex.printStackTrace();
}
} else { ;
}
}
});
}
private JFreeChart createChart(final XYDataset dataset) {
final JFreeChart result = ChartFactory.createTimeSeriesChart(
"Dynamic Graph", "Time", "Value", dataset, true, true,
false);
final XYPlot plot = result.getXYPlot();
ValueAxis axis = plot.getDomainAxis();
//plot.setRangeAxis(WIDTH, axi)
axis.setAutoRange(true);
//axis.setFixedAutoRange(60.0); // 60 seconds
axis = plot.getRangeAxis();
axis.setRange(-100.0, 200.0);
return result;
}
public static void main(final String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
try {
final DTest demo = new DTest("Dynamic Graph");
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
demo.setVisible(true);
} catch (Exception e) {
}
}
});
}
}
…as the line moves forward, the previous line value should not disappear, but it should begin to compress itself.
The Memory Usage tab of the demo does exactly what you describe.