How exclude one or two day from jfreechart? I have input date without saturday and chart without saturday, but in axis there all date.
I have all added item on screen. How viewing <= 100 item on screen and if scrolling to right item add more.
UPDATE:
I make CandleChart, used JfreeChart library.
Between 12 and 14 days chart should not be interrupted.
This is string:
One or few day is maybe off-time.
12.10.2012 19:00 1.2951 1.296 1.2947 1.2956
12.10.2012 20:00 1.2956 1.296 1.295 1.2954
**12.10.2012 21:00 1.2955 1.2959 1.2948 1.2949**
**14.10.2012 22:00 1.2952 1.296 1.2948 1.2953**
14.10.2012 23:00 1.2955 1.2955 1.2942 1.2947
This is code:
static TimeSeries t1 = new TimeSeries("");
RegularTimePeriod day = new Day();
RegularTimePeriod hour = new Hour();
private static OHLCDataset createPriceDataset(String FILENAME_SD)
{
OHLCSeries s1 = new OHLCSeries(FILENAME_SD);
if (!Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
}
File sdPath = Environment.getExternalStorageDirectory();
sdPath = new File(sdPath.getAbsolutePath() + "/" + DIR_SD);
File sdFile = new File(sdPath, FILENAME_SD);
try {
BufferedReader in = new BufferedReader(new FileReader(sdFile));
DateFormat df = new SimpleDateFormat("dd.MM.yyyy HH:mm");
String inputLine;
in.readLine();
while ((inputLine = in.readLine()) != null) {
String[] data = inputLine.split("\\s+");
Date date = df.parse(data[0] + " " + data[1]);
double open = Double.parseDouble( data[2] );
double high = Double.parseDouble( data[3] );
double low = Double.parseDouble( data[4] );
double close = Double.parseDouble( data[5] );
// double volume = Double.parseDouble( st.nextToken() );
//double adjClose = Double.parseDouble( st.nextToken() );
s1.add(new Hour(date), open, high, low, close);
t1.add(new Hour(date), open);
}
in.close();
}
catch (Exception e) {
e.printStackTrace();
}
OHLCSeriesCollection dataset = new OHLCSeriesCollection();
dataset.addSeries(s1);
return dataset;
}
Also, diagram zoom depends on how mach string in file. How drawing candles no more than 100 on screen?
This is chart from file with many strings:
This is chart from file with few strings:
If it's particularly candlestick you want to do this with, I do not believe that JFreechart class supports it. You could use Box And Whisker to imitate the behavior while using category based data. For the charts you've shown the axis represents continuous data, categorical axis are for discrete data.
Example code is shown here:
http://www.java2s.com/Code/Java/Chart/JFreeChartBoxAndWhiskerDemo.htm
With that you can choose your own discrete points to be represented on the graph.
If it's for anything other than candlesticks, Graham was right and DefaultCategoryDataset would be more useful:
http://www.jfree.org/jfreechart/api/javadoc/org/jfree/data/category/DefaultCategoryDataset.html
Related
I created a real time chart with JFreechart where the Domain axis is epoch millis. I would like the labels to display HH:MM:SS.
Here is the block of code that I use to load the chart with data. I am very new to Java and any suggestions are very much appreciated.
Thread thread = new Thread(){
public void run() {
try (Scanner scanner = new Scanner(chosenPort.getInputStream())) { // Read Data from Serial Port
int x = 0; // Set data
while(scanner.hasNextLine()) {
long epoch = System.currentTimeMillis();
chart.getXYPlot().getDomainAxis().setRange(epoch - 30000.00, epoch + 1000.00);
try{
String line = scanner.nextLine();
int number = Integer.parseInt(line); //
series.add(epoch,number); // add Data to Chart
p1.repaint();
}catch(Exception e) {}
}
}
}
};
I was using an XYseries Line chart instead of a time series chart. By using JFreeChart chart = ChartFactory.createTimeSeriesChart instead of JFreeChart chart = ChartFactory.createXYLineChart the correct date/time values were interpreted and displayed automatically.
First of all thanks for your help in advance.
I'm writing an investment algorithm and am currently pre-processing CSV historical data. The end goal for this part of the process is to create a symmetrical co-variance matrix of 2k x 2k / 2 (2 million) entries.
The Java class I'm writing takes a folder of CSVs each with 8 bits of information, key ones being Date, Time & Opening stock price. Date & time have been combined into one 'seconds from delta' time measure and opening stock prices remain unchanged. The output CSV contains the above two pieces of information also with a filename index for later referencing.
In order to create the co-variance matrix each stock on the NYSE must have a price value for every time, if values are missing the matrix cannot be properly completed. Due to discrepancies between time entries in the historical training CSV, I have to use a polynomial function to estimate missed values, which then can be fed into the next process in the chain.
My problem sounds fairly simple and should be easy to overcome (I'm probably being a massive idiot). The polynomial package I'm using takes in two arrays of doubles (Double[] x, Double[] y). X pertaining to an array of the 'seconds past delta' time values of a particular stock and Y the corresponding price. When I try to feed these in I'm getting a type error as what I'm actually trying to input are 'java.lang.Double' objects. Can anyone help me with converting an array of the latter to an array of the former?
I realise there is a load of ridiculousness after the main print statement, these are just me tinkering trying to miraculously change the type.
Again thanks for your time, I look forward to your replies!
Please find the relevant method below:
public void main(String filePath) throws IOException {
String index = filePath;
index = index.replace("/Users/louislimon/Desktop/Invest Algorithm/Data/Samples US Stock Data/data-1/5 min/us/nyse stocks/1/", "");
index = index.replace(".us.txt", "");
File fout = new File("/Users/louislimon/Desktop/Invest Algorithm/Data.csv");
FileOutputStream fos = new FileOutputStream(fout);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));
Reader in = new FileReader(filePath);
Iterable<CSVRecord> records;
try {
records = CSVFormat.EXCEL.withSkipHeaderRecord(true).parse(in);
} catch ( IOException ex ) {
System.out.println ( "[ERROR] " + ex );
return;
}
ZoneId zoneId = ZoneId.of("America/New_York");
boolean tmp = true;
Instant firstInstant = null; // Track the baseline against which we calculate the increasing time
ArrayList<Double> timeVals = new ArrayList<Double>();
ArrayList<Double> priceVals = new ArrayList<Double>();
for ( CSVRecord record : records ) {
if(tmp){
tmp = false;
}
else {
//System.out.println(record.toString());
String dateInput = record.get(0);
String timeInput = record.get(1);
Double price = Double.parseDouble(record.get(2));
LocalDate date = LocalDate.parse(dateInput);
LocalTime time = LocalTime.parse(timeInput);
//Double price = Double.parseDouble(priceInput);
LocalDateTime ldt = LocalDateTime.of(date, time);
ZonedDateTime zdt = ldt.atZone(zoneId);
Instant instant = zdt.toInstant(); // Use Instant (moment on the timeline in UTC) for data storage, exchange, serialization, database, etc.
if (null == firstInstant) {
firstInstant = instant; // Capture the first instant.
}
Duration duration = Duration.between(firstInstant, instant);
Long deltaInSeconds = duration.getSeconds();
double doubleDeltaInSeconds = deltaInSeconds.doubleValue();
timeVals.add(doubleDeltaInSeconds);
priceVals.add(price);
//System.out.println("deltaInSeconds: " + deltaInSeconds + " | price: " + price + " | index: " + index);
}
Double [] timeValsArray = timeVals.toArray(new Double[timeVals.size()]);
Double [] priceValsArray = timeVals.toArray(new Double[priceVals.size()]);
Double[] timeFeed = new Double[timeVals.size()];
Double[] priceFeed = new Double[priceVals.size()];
for(int x = 0;x<timeVals.size(); x++) {
timeFeed[x] = new Double (timeValsArray[x].doubleValue());
priceFeed[x] = new Double (priceValsArray[x]);
}
PolynomialFunctionLagrangeForm pflf = new PolynomialFunctionLagrangeForm(timeFeed,priceFeed);
}
According to the documentation, the PolynomialFunctionLagrangeForm constructor takes two double[] arrays, not Double[].
Hence you need to create a raw array and pass that:
...
double[] timeFeed = new double[timeVals.size()];
double[] priceFeed = new double[priceVals.size()];
for(int x = 0; x < timeVals.size(); x++) {
timeFeed[x] = timeValsArray[x].doubleValue();
priceFeed[x] = priceValsArray[x].doubleValue();
}
...
See also How to convert an ArrayList containing Integers to primitive int array? for some alternative ways to convert an ArrayList<T> (where T is a wrapper for a primitive type) to the corresponding raw array T[].
Note that there is also obviously a typo in your code:
Double [] priceValsArray = timeVals.toArray(new Double[priceVals.size()]);
needs to be
Double [] priceValsArray = priceVals.toArray(new Double[priceVals.size()]);
i m using jfreechart to draw a graph about a logger of operations in a computer.
ex:
1:2012/09/39/28 06:55:37 8 S 0x1c0c762 Terminal --geometry=134x35 --display :0.0 --role=Terminal-0x10591b0-16869-1343137248 --show-menubar --show-borders --hide-toolbars --working-directory /home/termier "Terminal", "Terminal" "Terminal - termier#akagi: ~"
2:2012/09/39/28 06:55:41 8 S 0x1600313 /usr/lib/xfce4/notifyd/xfce4-notifyd "xfce4-notifyd", "Xfce4-notifyd" "xfce4-notifyd"
for now , i can draw every point just like (2012/09/39/28 06:55:37,Terminal),scilicet: x-axis is 2012/09/39/28 06:55:37 , Y-axis is: Terminal (i use 1 to present Terminal ,as for other commands just like Terminal... 2:/usr/lib/xfce4/notifyd/xfce4-notifyd ,etc...)
but what i need is draw a block ,like:
terminal 1: _________S||||||
/usr/lib/xfce4/notifyd/xfce4-notifyd2:______________S||||||
com 3: _____S|||||
(S:start ,eg: 2000/12/12 09:22:10 start)
.....
(when the first command end, another one will be start ,i just can get the start, it means that the post command is the end time of the previous command)
but not: 1: S
2: S
3: S
here some codes to you.
private XYDataset createDataset() {
Calendar precal;
Calendar postcal;
this.flags = modelfocus.getListflag();
commands = modelfocus.getListCommand();
DateFormat formatedate = new SimpleDateFormat("yyyy/MM/ww/dd HH:mm:ss");
precal = Calendar.getInstance();
postcal = Calendar.getInstance();
for (int i = 0; i < countCom; i++) {
this.series[i] = new TimeSeries(commands.get(i));
}
for (Focus listTxt : modelfocus.getList()) {
try {
Date d = new Date();
d = formatedate.parse(listTxt.date2String());
System.out.println(d);
precal.setTime(d);
//postcal.setTime();
} catch (ParseException e) {
System.out.println("Can't change this date");
e.printStackTrace();
}
String eachCmd = listTxt.getCommand();
for (int i = 0; i < countCom; i++) {
if (eachCmd == commands.get(i)) {
series[i].addOrUpdate(new Second(precal.getTime()),
flags.get(i));
}
}
}
TimeSeriesCollection dataset = new TimeSeriesCollection();
for (int i = 0; i < countCom; i++) {
dataset.addSeries(this.series[i]);
}
return dataset;
}
Please can someone give help to solve this problem, thank you very much.
As shown in this example, you can change the Shape used to render the values of a time series. A Rectangle is shown below.
r.setSeriesShape(0, new Rectangle(-4, -4, 9, 9));
I'm trying to create a graph for each user that is added into my app. This graph will display the day in this format 21 Dec 2012 on the x-axis and numbers from 30 to 30000. Say this is day 1, the user adds their calorie per hour burn rate and I want that info put into the graph. The next day, I want them to be able to calculate their calorie per hour rate and store that into the graph as well. Sort of like appending it to the graph.
public class Graph extends Activity{
private XYMultipleSeriesDataset mDataset;
private XYMultipleSeriesRenderer mRenderer;
List<double[]> values = new ArrayList<double[]>();
private GraphicalView mChartView;
private TimeSeries time_series;
String gotCal;
Double[] thisDou;
Double convert;
Date date;
// chart container
private LinearLayout layout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
layout = (LinearLayout) findViewById(R.id.chart);
SharedPreferences calStuff = getSharedPreferences("Calories", 0);
if (calStuff != null) {
gotCal = calStuff.getString("This Cal", null);
System.out.println(gotCal);
}
convert = Double.parseDouble(gotCal);
// create dataset and renderer
mDataset = new XYMultipleSeriesDataset();
mRenderer = new XYMultipleSeriesRenderer();
//mRenderer.setAxisTitleTextSize(16);
//mRenderer.setChartTitleTextSize(20);
//mRenderer.setLabelsTextSize(15);
//mRenderer.setLegendTextSize(15);
//mRenderer.setPointSize(3f);
XYSeriesRenderer r = new XYSeriesRenderer();
r.setColor(Color.GREEN);
r.setFillPoints(true);
r.setPointStyle(PointStyle.DIAMOND);
//r.fillPoints(true);
r.setFillBelowLine(true);
mRenderer.addSeriesRenderer(r);
mRenderer.setZoomButtonsVisible(true);
mRenderer.setXTitle("Date");
mRenderer.setYTitle("Calories Burned Per Hour");
//mRenderer.setClickEnabled(true);
r.setDisplayChartValues(true);
mRenderer.setSelectableBuffer(20);
mRenderer.setApplyBackgroundColor(true);
mRenderer.setBackgroundColor(Color.BLACK);
mRenderer.setGridColor(Color.CYAN);
//mRenderer.setChartTitle("LOOOOOL");
//mRenderer.setYLabels(12);
mRenderer.setPanEnabled(true, true);
//mRenderer.setPanEnabled(true);
time_series = new TimeSeries("test");
mDataset.addSeries(time_series);
fillData();
//time_series.add(date, Double.parseDouble(gotCal));
mChartView = ChartFactory.getTimeChartView(this, mDataset, mRenderer,
"dd MMM yyyy");
if (mChartView == null)
mChartView.repaint();
layout.addView(mChartView);
}
private void fillData() {
long value = new Date().getTime() - 3 * TimeChart.DAY;
for (int i = 0; i < gotCal.length(); i += convert) {
//date = new Date(value + i * TimeChart.DAY / 31);
time_series.add(new Date(value + i * TimeChart.DAY / 20), i);
}
}
It only works for one user, so when I try to access the graph from a different user which has different info, there's no graph, why is that? Also, how can I save the graph specifically to that user? Any help is highly appreciated, thank you.
I have a text file input which contains data as below. How can I display data from the text file into specific format?
Monday
Jessy
Walking
20 minutes
Matthew
Run
20 minutes
Karen
Jogging
40 minutes
Jessica
Run
12 minutes
Tuesday
Messia
Walking
10 minutes
Matthew
Run
20 minutes
Pete
Run
10 minutes
Carol
Walking
30 minutes
I want to display data from the text file into this format:
Day Name Type of exercise Time
Monday Jessy Walking 20 minutes
Matthew Run 20 minutes
Karen Jogging 40 minutes
Jessica Run 12 minutes
Tuesday Messia Walking 10 minutes
Matthew Run 20 minutes
Pete Run 10 minutes
Carol Walking 30 minutes
I just threw this together quickly, but what about something like:
static final String[] DAYS =
{ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
public class ActivityEvent
{
public int day;
public String name;
public String typeOfExercise;
public String time;
}
public List loadActivities(String filename) throws IOException
{
List activities = new ArrayList();
FileInputStream fis = new FileInputStream(filename);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
int lastDay = -1;
String line;
while ((line = br.readLine()) != null)
{
line = line.trim();
int day;
for (day = DAYS.length - 1; day >= 0; day--)
{
if (line.equals(DAYS[day]))
{
break;
}
}
String name;
if (day < 0)
{
day = lastDay;
if (lastDay < 0)
{
throw new IOException(filename + " must start with day of week");
}
name = line;
}
else
{
name = br.readLine();
if (name == null)
{
throw new IOException(filename + " expected name, reached end of file");
}
}
String type = br.readLine();
if (type == null)
{
throw new IOException(filename + " expected type of exercise, reached end of file");
}
String time = br.readLine();
if (time != null)
{
throw new IOException(filename + " expected time of exercise, reached end of file");
}
ActivityEvent activity = new ActivityEvent();
activity.day = day;
activity.name = name;
activity.typeOfExercise = type;
activity.time = time;
activities.add(activity);
}
return activities;
}
public void printActivities(List activities)
{
StringBuilder str = new StringBuilder("Day\tName\tType of Exercise\tTime\n");
int numActivities = activities.size();
int lastDay = -1;
for (int index = 0; index < numActivities; index++)
{
ActivityEvent activity = (ActivityEvent)activities.get(index);
if (activity.day != lastDay)
{
str.append(DAYS[activity.day]);
}
str.append('\t');
str.append(activity.name);
str.append('\t');
str.append(activity.typeOfExercise);
str.append('\t');
str.append(activity.time);
str.append('\n');
}
System.out.print(str.toString());
}
And then invoke everything for example:
List activities = loadActivities("somefile.txt");
// Do optional sorting, etc. here.
printActivities(activities);
I would have a look at Java's sprintf() function and it's ability to left/right justify data with specified widths.
Regarding parsing the input:
One issue you will have is that each "record" of data (each row, in the ouput) is not a fixed size.
Some are 3-tuples of name,exercise,time, and others are 4-tuples of day,name,exercise,time
That said, assuming the format you've given is really all there is to it, the issue can be worked around.
After reading a line, you could check for a weekday, and if so assume that's the start of a 4-tuple, and read the next 3 lines.
If it is not a weekday, then assume it is a 3-tuple, and only read the next 2 lines.
If there might be "gaps" in the name, type, or time columns in the output as well, and in different combinations, it gets trickier.
You really need your program to have special knowledge about what values are valid in what columns. Eg, that 'Jessica' is not a valid type of exercise, and 'Jogging' is not a valid name.
Regarding formatting the output
Brian's answer is relevant.
It depends on the language you use. Most languages have a printf-equivalent.
The formatting codes of printf allow you to pad with space, etc.
If you are using Perl (might be well-suited to this task), you can use formats