JFreeChart : How to draw the moving average over a OHLC chart - jfreechart
I am trying to overlay a moving average over an OHLC chart but it does not seem to work.
I provide two critical functions of the code :
private static OHLCDataset createPriceDataset(String filename)
{
OHLCSeries s1 = new OHLCSeries(filename);
try {
BufferedReader in = new BufferedReader(new FileReader(filename));
DateFormat df = new SimpleDateFormat("yyyyMMdd");
String inputLine;
in.readLine();
while ((inputLine = in.readLine()) != null) {
StringTokenizer st = new StringTokenizer(inputLine, ",");
Date date = df.parse( st.nextToken() );
double open = Double.parseDouble( st.nextToken() );
double high = Double.parseDouble( st.nextToken() );
double low = Double.parseDouble( st.nextToken() );
double close = Double.parseDouble( st.nextToken() );
double volume = Double.parseDouble( st.nextToken() );
//double adjClose = Double.parseDouble( st.nextToken() );
s1.add(new Day(date), open, high, low, close);
}
in.close();
}
catch (Exception e) {
e.printStackTrace();
}
OHLCSeriesCollection dataset = new OHLCSeriesCollection();
dataset.addSeries(s1);
return dataset;
}
private static JFreeChart createCombinedChart()
{
OHLCDataset data1 = createPriceDataset(filename);
XYItemRenderer renderer1 = new HighLowRenderer();
renderer1.setBaseToolTipGenerator(new StandardXYToolTipGenerator(StandardXYToolTipGenerator.DEFAULT_TOOL_TIP_FORMAT, new SimpleDateFormat("d-MMM-yyyy"), new DecimalFormat("0.00")));
renderer1.setSeriesPaint(0, Color.blue);
DateAxis domainAxis = new DateAxis("Date");
NumberAxis rangeAxis = new NumberAxis("Price");
rangeAxis.setNumberFormatOverride(new DecimalFormat("$0.00"));
rangeAxis.setAutoRange(true);
rangeAxis.setAutoRangeIncludesZero(false);
XYPlot plot1 = new XYPlot(data1, domainAxis, rangeAxis, renderer1);
plot1.setBackgroundPaint(Color.lightGray);
plot1.setDomainGridlinePaint(Color.white);
plot1.setRangeGridlinePaint(Color.white);
plot1.setRangePannable(true);
//Overlay the Long-Term Trend Indicator
XYDataset dataset3 = MovingAverage.createMovingAverage(data1, "LT", 49.0, 49.0);
plot1.setDataset(1, dataset3);
plot1.setRenderer(1, new StandardXYItemRenderer());
//add a second dataset (volume) and renderer
IntervalXYDataset data2 = createVolumeDataset(filename);
XYBarRenderer renderer2 = new XYBarRenderer();
renderer2.setDrawBarOutline(false);
renderer2.setBaseToolTipGenerator(new StandardXYToolTipGenerator(StandardXYToolTipGenerator.DEFAULT_TOOL_TIP_FORMAT, new SimpleDateFormat("d-MMM-yyyy"), new DecimalFormat("0,000.00")));
renderer2.setSeriesPaint(0, Color.red);
XYPlot plot2 = new XYPlot(data2, null, new NumberAxis("Volume"), renderer2);
plot2.setBackgroundPaint(Color.lightGray);
plot2.setDomainGridlinePaint(Color.white);
plot2.setRangeGridlinePaint(Color.white);
CombinedDomainXYPlot cplot = new CombinedDomainXYPlot(domainAxis);
cplot.add(plot1, 3);
cplot.add(plot2, 2);
cplot.setGap(8.0);
cplot.setDomainGridlinePaint(Color.white);
cplot.setDomainGridlinesVisible(true);
cplot.setDomainPannable(true);
//return the new combined chart
JFreeChart chart = new JFreeChart("Sun Microsystems (SUNW)", JFreeChart.DEFAULT_TITLE_FONT, cplot, false);
ChartUtilities.applyCurrentTheme(chart);
renderer2.setShadowVisible(false);
renderer2.setBarPainter(new StandardXYBarPainter());
return chart;
}
Any ideas?
Thank you.
I've added the following code and it seems to work.
If anybody disagrees on this solution just let me know.
Here it goes :
public class PriceVolumeChart2 extends ApplicationFrame{
final static String filename = "A.txt";
*static TimeSeries t1 = new TimeSeries("49-day moving average");*
/**
* Default constructor
*/
public PriceVolumeChart2(String title)
{
super(title);
JPanel panel = createDemoPanel();
panel.setPreferredSize(new Dimension(500, 270));
setContentPane(panel);
}
//create price dataset
//hard-coded here
private static OHLCDataset createPriceDataset(String filename)
{
//the following data is taken from http://finance.yahoo.com/
//for demo purposes...
OHLCSeries s1 = new OHLCSeries(filename);
try {
BufferedReader in = new BufferedReader(new FileReader(filename));
DateFormat df = new SimpleDateFormat("yyyyMMdd");
String inputLine;
in.readLine();
while ((inputLine = in.readLine()) != null) {
StringTokenizer st = new StringTokenizer(inputLine, ",");
Date date = df.parse( st.nextToken() );
double open = Double.parseDouble( st.nextToken() );
double high = Double.parseDouble( st.nextToken() );
double low = Double.parseDouble( st.nextToken() );
double close = Double.parseDouble( st.nextToken() );
double volume = Double.parseDouble( st.nextToken() );
//double adjClose = Double.parseDouble( st.nextToken() );
s1.add(new Day(date), open, high, low, close);
*t1.add(new Day(date), close);*
}
in.close();
}
catch (Exception e) {
e.printStackTrace();
}
OHLCSeriesCollection dataset = new OHLCSeriesCollection();
dataset.addSeries(s1);
return dataset;
}
//create volume dataset
private static IntervalXYDataset createVolumeDataset(String filename)
{
//create dataset 2...
TimeSeries s1 = new TimeSeries("Volume");
try {
BufferedReader in = new BufferedReader(new FileReader(filename));
DateFormat df = new SimpleDateFormat("yyyyMMdd");
String inputLine;
in.readLine();
while ((inputLine = in.readLine()) != null) {
StringTokenizer st = new StringTokenizer(inputLine, ",");
Date date = df.parse( st.nextToken() );
st.nextToken();
st.nextToken();
st.nextToken();
st.nextToken();
double volume = Double.parseDouble( st.nextToken() );
//double adjClose = Double.parseDouble( st.nextToken() );
s1.add(new Day(date), volume);
}
in.close();
}
catch (Exception e) {
e.printStackTrace();
}
return new TimeSeriesCollection(s1);
}
private static JFreeChart createCombinedChart()
{
OHLCDataset data1 = createPriceDataset(filename);
XYItemRenderer renderer1 = new HighLowRenderer();
renderer1.setBaseToolTipGenerator(new StandardXYToolTipGenerator(
StandardXYToolTipGenerator.DEFAULT_TOOL_TIP_FORMAT,
new SimpleDateFormat("d-MMM-yyyy"), new DecimalFormat("0.00")));
renderer1.setSeriesPaint(0, Color.blue);
DateAxis domainAxis = new DateAxis("Date");
NumberAxis rangeAxis = new NumberAxis("Price");
rangeAxis.setNumberFormatOverride(new DecimalFormat("$0.00"));
rangeAxis.setAutoRange(true);
rangeAxis.setAutoRangeIncludesZero(false);
XYPlot plot1 = new XYPlot(data1, domainAxis, rangeAxis, renderer1);
plot1.setBackgroundPaint(Color.lightGray);
plot1.setDomainGridlinePaint(Color.white);
plot1.setRangeGridlinePaint(Color.white);
plot1.setRangePannable(true);
//Overlay the Long-Term Trend Indicator
*TimeSeries dataset3 = MovingAverage.createMovingAverage(t1, "LT", 49, 49);
TimeSeriesCollection collection = new TimeSeriesCollection();
collection.addSeries(dataset3);
plot1.setDataset(1, collection);*
plot1.setRenderer(1, new StandardXYItemRenderer());
//add a second dataset (volume) and renderer
IntervalXYDataset data2 = createVolumeDataset(filename);
XYBarRenderer renderer2 = new XYBarRenderer();
renderer2.setDrawBarOutline(false);
renderer2.setBaseToolTipGenerator(new StandardXYToolTipGenerator(
StandardXYToolTipGenerator.DEFAULT_TOOL_TIP_FORMAT,
new SimpleDateFormat("d-MMM-yyyy"), new DecimalFormat("0,000.00")));
renderer2.setSeriesPaint(0, Color.red);
XYPlot plot2 = new XYPlot(data2, null, new NumberAxis("Volume"), renderer2);
plot2.setBackgroundPaint(Color.lightGray);
plot2.setDomainGridlinePaint(Color.white);
plot2.setRangeGridlinePaint(Color.white);
CombinedDomainXYPlot cplot = new CombinedDomainXYPlot(domainAxis);
cplot.add(plot1, 3);
cplot.add(plot2, 2);
cplot.setGap(8.0);
cplot.setDomainGridlinePaint(Color.white);
cplot.setDomainGridlinesVisible(true);
cplot.setDomainPannable(true);
//return the new combined chart
JFreeChart chart = new JFreeChart("Sun Microsystems (SUNW)",
JFreeChart.DEFAULT_TITLE_FONT, cplot, false);
ChartUtilities.applyCurrentTheme(chart);
renderer2.setShadowVisible(false);
renderer2.setBarPainter(new StandardXYBarPainter());
return chart;
}
//create a panel
public static JPanel createDemoPanel()
{
JFreeChart chart = createCombinedChart();
return new ChartPanel(chart);
}
public static void main(String[] args) {
// TODO code application logic here
PriceVolumeChart2 demo = new PriceVolumeChart2(
"JFreeChart: CombinedXYPlotDemo1.java (base)");
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
}
//Download data from web
}
Sample data:
20110103,41.56,42.14,41.41,41.88,3572300
20110104,41.99,42.1,41.18,41.49,3588800
20110105,41.28,41.73,41,41.4,3232700
20110106,41.37,41.84,41.21,41.48,3361400
20110107,41.52,41.8,41.04,41.62,2725900
20110110,41.41,42.72,41.3,42.22,3145800
20110111,42.52,43.31,42.38,42.94,3315400
20110112,43.2,43.41,42.96,43.13,2463100
20110113,42.88,43.23,42.87,42.97,1676400
20110114,42.79,43.37,42.76,43.26,2215600
20110117,43.26,43.26,43.26,43.26,0
20110118,43.33,44.45,43.32,44.35,2982300
20110119,44.16,44.29,42.27,42.43,4537200
20110120,41.95,42.58,41.46,42.29,4874700
20110121,42.5,43.26,42.03,42.11,3004500
20110124,42.18,42.79,42.07,42.77,2067400
20110125,42.77,43.52,42.28,42.69,3132700
20110126,42.82,42.97,42.04,42.57,3927300
20110127,42.77,43.09,42.37,42.45,3189600
20110128,42.5,42.52,40.88,40.98,3629800
20110131,41.21,41.83,40.89,41.83,3690900
20110201,42.07,42.7,41.93,42.05,3388200
20110202,41.75,41.91,40.82,41.23,3970700
20110203,40.93,41.18,40.23,40.99,3522700
20110204,41.19,43.13,40.94,42.99,5197700
20110207,43.45,44.66,43.37,44.44,4569800
20110208,44.65,44.71,43.83,44.17,3734500
20110209,44.01,44.17,43.16,43.43,3779300
20110210,43.22,44.01,42.57,44,3275700
20110211,43.77,45.15,43.65,45.02,4436000
20110214,45,45.42,44.72,44.79,3484400
20110215,44.79,45,42.64,42.65,7328000
20110216,42.91,43.6,42.7,43.57,4159800
20110217,43.38,44,43.02,43.92,2621800
20110218,43.78,44.29,43.65,43.92,4390200
20110221,43.92,43.92,43.92,43.92,0
20110222,43.21,43.75,42.39,42.49,4143600
20110223,42.59,42.75,39.94,40.45,7074200
20110224,40.34,41.55,40.18,41.15,4455700
20110225,41.16,42.41,41.13,42.36,4297500
20110228,42.43,42.65,41.36,42.08,3070200
20110301,41.98,42.49,40.65,40.68,4091300
The new code is inside asterisks.
If you believe that there is a more elegant solution , please let me know.
Related
Implementing safe areas with Infinite Container pull to refresh
How can I set the safe area for pull to refresh? I have a form with with an infinite container. I set the IC with safe area ic.setSafeArea(true). When I rotate the screen the safe area is respected(see image 1). If i pull to refresh the safe area is not respected (see image 2). With the below code taken from the InfiniteContainerSample, how can I ensure the safe area is respected after pull to refresh? image 1 public void showForm() { Form hi = new Form("InfiniteContainer", new BorderLayout()); Style s = UIManager.getInstance().getComponentStyle("MultiLine1"); FontImage p = FontImage.createMaterial(FontImage.MATERIAL_PORTRAIT, s); EncodedImage placeholder = EncodedImage.createFromImage(p.scaled(p.getWidth() * 3, p.getHeight() * 3), false); InfiniteContainer ic = new InfiniteContainer() { #Override public Component[] fetchComponents(int index, int amount) { java.util.List<Map<String, Object>> data = fetchPropertyData("Leeds"); MultiButton[] cmps = new MultiButton[data.size()]; for(int iter = 0 ; iter < cmps.length ; iter++) { Map<String, Object> currentListing = data.get(iter); if(currentListing == null) { return null; } String thumb_url = (String)currentListing.get("thumb_url"); String guid = (String)currentListing.get("guid"); String summary = (String)currentListing.get("summary"); cmps[iter] = new MultiButton(summary); cmps[iter].setIcon(URLImage.createToStorage(placeholder, guid, thumb_url)); } return cmps; } }; ic.setUIID("Blue"); ic.setSafeArea(true); ic.addComponent(new Label("This is a test")); hi.add(BorderLayout.CENTER, ic); hi.show(); } int pageNumber = 1; java.util.List<Map<String, Object>> fetchPropertyData(String text) { try { ConnectionRequest r = new ConnectionRequest(); r.setPost(false); r.setUrl("http://api.nestoria.co.uk/api"); r.addArgument("pretty", "0"); r.addArgument("action", "search_listings"); r.addArgument("encoding", "json"); r.addArgument("listing_type", "buy"); r.addArgument("page", "" + pageNumber); pageNumber++; r.addArgument("country", "uk"); r.addArgument("place_name", text); NetworkManager.getInstance().addToQueueAndWait(r); Map<String,Object> result = new JSONParser().parseJSON(new InputStreamReader(new ByteArrayInputStream(r.getResponseData()), "UTF-8")); Map<String, Object> response = (Map<String, Object>)result.get("response"); return (java.util.List<Map<String, Object>>)response.get("listings"); } catch(Exception err) { Log.e(err); return null; } }
Thanks for reporting this. This has been fixed on github. It will be included in the next release on Friday.
JFreeChart XYLineAndShapeRenderer show unwanted vales outside range start and finish
Im build a series graph with jfreechart using XYLineAndShapeRenderer, this series need to show values for each day of a month, then I need that the X axis shows values from 1 to 30 or 1 to 31 (depend of current month). The dataset only have X values from 1 to 30/31, but the resultant graph shows ZERO(before 1) and 31/32 after(30/31). I want to show only 1 to 30/31 on X axis. But I dont have success. Follow shows the code that build dataset and graph and resultante image. How I can show only valid values on X axis in this case ? // build dataset private XYDataset createSampleData() { List<Integer> diario = new ArrayList<>(Arrays.asList(20, 50, 120, 78, 37, 69, 145)); int dSize = diario.size(); int dPos = 0; XYSeries serieD = new XYSeries("Diário"); XYSeries serieA = new XYSeries("Acumulado"); int acumulado = 0; for(int i=1; i < 31; i++) { int valDay = diario.get(dPos++); acumulado += valDay; serieD.add(i, valDay); serieA.add(i, acumulado); if( dPos >= dSize ) { dPos = 0; } } XYSeriesCollection result = new XYSeriesCollection(serieD); result.addSeries(serieA); return result; } private JFreeChart buildSeriesChartBySeriesData(String title, String labelX, String labelY) { NumberAxis xAxis = new NumberAxis(labelX); xAxis.setAutoRangeIncludesZero(false); xAxis.setRangeType(RangeType.POSITIVE); NumberAxis yAxis = new NumberAxis(labelY); yAxis.setAutoRangeIncludesZero(false); yAxis.setRangeType(RangeType.POSITIVE); XYSplineRenderer renderer1 = new XYSplineRenderer(); XYPlot plot = new XYPlot(this.createSampleData(), xAxis, yAxis, renderer1); plot.setDomainGridlinesVisible(true); plot.setDomainZeroBaselineVisible(false); plot.setDomainPannable(false); plot.setBackgroundPaint(new Color(224, 224,235)); plot.setDomainGridlinePaint(Color.white); plot.setRangeGridlinePaint(Color.white); plot.setDomainAxisLocation(AxisLocation.BOTTOM_OR_LEFT); plot.setRangeAxisLocation(AxisLocation.TOP_OR_LEFT); plot.setDomainPannable(false); plot.setRangePannable(false); plot.setDomainZeroBaselineVisible(false); plot.setRangeZeroBaselineVisible(false); renderer1.setSeriesPaint(0, Color.blue); renderer1.setSeriesPaint(1, Color.yellow); plot.setAxisOffset(new RectangleInsets(3, 3, 3, 3)); plot.setDomainCrosshairVisible(true); plot.setRangeCrosshairVisible(true); XYLineAndShapeRenderer localXYLineAndShapeRenderer = (XYLineAndShapeRenderer) plot.getRenderer(); localXYLineAndShapeRenderer.setBaseShapesVisible(true); localXYLineAndShapeRenderer.setBaseShapesFilled(true); localXYLineAndShapeRenderer.setDrawOutlines(true); NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis(); rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); // show item labels: final XYItemRenderer renderer = plot.getRenderer(); ItemLabelPosition position = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER); renderer.setBasePositiveItemLabelPosition(position); final StandardXYItemLabelGenerator generator = new StandardXYItemLabelGenerator(); renderer.setSeriesItemLabelGenerator(0, generator); renderer.setSeriesItemLabelsVisible(0, true); renderer.setSeriesItemLabelGenerator(1, generator); renderer.setSeriesItemLabelsVisible(1, true); JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, true); return chart; } In the next graph, I draw with timeSeries, and the results is the same, showing the last day of previos month and first day of next month, I don not want to show this values. The result that I need is like this image(a sample from chartJs): How I can hide the zero and 31 from result of first top graph ? long time later... ---- after a long time I make the desired graph myself ----- This code generates the right graph: private JFreeChart TimeSeriesChartExample() { XYDataset dataset = createSampleMonthData(); // Create chart JFreeChart chart = ChartFactory.createTimeSeriesChart( "Time Series Chart Example", "Date", "Values", dataset, true, true, false); // Changes background color XYPlot plot = (XYPlot)chart.getPlot(); plot.setBackgroundPaint(new Color(224, 224,235)); XYSplineRenderer renderer1 = new XYSplineRenderer(); renderer1.setSeriesPaint(0, Color.blue); renderer1.setSeriesPaint(1, Color.green); plot.setRenderer(renderer1); plot.setAxisOffset(new RectangleInsets(3, 3, 3, 3)); // show item labels: XYItemRenderer renderer = plot.getRenderer(); ItemLabelPosition position = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER); renderer.setBasePositiveItemLabelPosition(position); final StandardXYItemLabelGenerator generator = new StandardXYItemLabelGenerator(); renderer.setSeriesItemLabelGenerator(0, generator); renderer.setSeriesItemLabelsVisible(0, true); renderer.setSeriesItemLabelGenerator(1, generator); renderer.setSeriesItemLabelsVisible(1, true); DateAxis xAxis = (DateAxis)plot.getDomainAxis(); xAxis.setDateFormatOverride(new SimpleDateFormat("dd/MM/yy")); ValueAxis domainAxis = plot.getDomainAxis(); domainAxis.setVerticalTickLabels(true); return chart; } This is the resultando graph:
The solution is the follow, I put on the question body too: private JFreeChart TimeSeriesChartExample() { XYDataset dataset = createSampleMonthData(); JFreeChart chart = ChartFactory.createTimeSeriesChart( "Time Series Chart Example", "Date", "Values", dataset, true, true, false); // Changes background color XYPlot plot = (XYPlot)chart.getPlot(); plot.setBackgroundPaint(new Color(224, 224,235)); XYSplineRenderer renderer1 = new XYSplineRenderer(); renderer1.setSeriesPaint(0, Color.blue); renderer1.setSeriesPaint(1, Color.green); plot.setRenderer(renderer1); plot.setAxisOffset(new RectangleInsets(3, 3, 3, 3)); XYItemRenderer renderer = plot.getRenderer(); ItemLabelPosition position = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER); renderer.setBasePositiveItemLabelPosition(position); final StandardXYItemLabelGenerator generator = new StandardXYItemLabelGenerator(); renderer.setSeriesItemLabelGenerator(0, generator); renderer.setSeriesItemLabelsVisible(0, true); renderer.setSeriesItemLabelGenerator(1, generator); renderer.setSeriesItemLabelsVisible(1, true); DateAxis xAxis = (DateAxis)plot.getDomainAxis(); xAxis.setDateFormatOverride(new SimpleDateFormat("dd/MM/yy")); ValueAxis domainAxis = plot.getDomainAxis(); domainAxis.setVerticalTickLabels(true); return chart; } This is the result: Code as tested: import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.swing.JFrame; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.DateAxis; import org.jfree.chart.axis.ValueAxis; import org.jfree.chart.labels.ItemLabelAnchor; import org.jfree.chart.labels.ItemLabelPosition; import org.jfree.chart.labels.StandardXYItemLabelGenerator; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.chart.renderer.xy.XYSplineRenderer; import org.jfree.data.xy.XYDataset; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; import org.jfree.ui.RectangleInsets; import org.jfree.ui.TextAnchor; /** * #see https://stackoverflow.com/a/49909020/230513 */ public class ChartTest { private void display() { JFrame f = new JFrame("ChartTest"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.add(new ChartPanel(createTimeSeriesChartExample()){ #Override public Dimension getPreferredSize() { return new Dimension(1000, 400); } }); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } private XYDataset createSampleMonthData() { List<Integer> diario = new ArrayList<>( Arrays.asList(20, 50, 120, 78, 37, 69, 145)); int dSize = diario.size(); int dPos = 0; XYSeries serieD = new XYSeries("Diário"); XYSeries serieA = new XYSeries("Acumulado"); int acumulado = 0; for (int i = 1; i < 31; i++) { int valDay = diario.get(dPos++); acumulado += valDay; serieD.add(i, valDay); serieA.add(i, acumulado); if (dPos >= dSize) { dPos = 0; } } XYSeriesCollection result = new XYSeriesCollection(serieD); result.addSeries(serieA); return result; } private JFreeChart createTimeSeriesChartExample() { XYDataset dataset = createSampleMonthData(); JFreeChart chart = ChartFactory.createTimeSeriesChart( "Time Series Chart Example", "Date", "Values", dataset, true, true, false); // Changes background color XYPlot plot = (XYPlot) chart.getPlot(); plot.setBackgroundPaint(new Color(224, 224, 235)); XYSplineRenderer renderer1 = new XYSplineRenderer(); renderer1.setSeriesPaint(0, Color.blue); renderer1.setSeriesPaint(1, Color.green); plot.setRenderer(renderer1); plot.setAxisOffset(new RectangleInsets(3, 3, 3, 3)); XYItemRenderer renderer = plot.getRenderer(); ItemLabelPosition position = new ItemLabelPosition( ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER); renderer.setBasePositiveItemLabelPosition(position); final StandardXYItemLabelGenerator generator = new StandardXYItemLabelGenerator(); renderer.setSeriesItemLabelGenerator(0, generator); renderer.setSeriesItemLabelsVisible(0, true); renderer.setSeriesItemLabelGenerator(1, generator); renderer.setSeriesItemLabelsVisible(1, true); DateAxis xAxis = (DateAxis) plot.getDomainAxis(); xAxis.setDateFormatOverride(new SimpleDateFormat("dd/MM/yy")); ValueAxis domainAxis = plot.getDomainAxis(); domainAxis.setVerticalTickLabels(true); return chart; } public static void main(String[] args) { EventQueue.invokeLater(new ChartTest()::display); } }
Displaying image from database in iTextSharp document [duplicate]
I try to create a PDF report from a datatable. One of the columns contents image. How can I extract the image from datatable and insert into PDF table? I'm using iTextShap version 5.4.2.0. Here is the code: public void Report(DataTable dt, string output) { Document doc = new Document(PageSize.LETTER, 50, 50, 80, 50); PdfWriter PDFWriter = PdfWriter.GetInstance(doc, new FileStream(output, FileMode.Create)); PDFWriter.ViewerPreferences = PdfWriter.PageModeUseOutlines; iTextSharp.text.Font hel8 = FontFactory.GetFont(BaseFont.HELVETICA, 8); doc.Open(); PdfPTable table = new PdfPTable(dt.Columns.Count); float[] widths = new float[] { 1.2f, 1.2f, 1.2f, 1.2f, 1f, 4f, 1f, 4f }; table.SetWidths(widths); table.WidthPercentage = 100; PdfPCell cell = new PdfPCell(new Phrase("NewCells")); cell.Colspan = dt.Columns.Count; foreach (DataColumn c in dt.Columns) { table.AddCell(new Phrase(c.ColumnName, hel8)); } foreach (DataRow r in dt.Rows) { if (dt.Rows.Count > 0) { table.AddCell(new Phrase(r[0].ToString(), hel8)); table.AddCell(new Phrase(r[1].ToString(), hel8)); table.AddCell(new Phrase(r[2].ToString(), hel8)); table.AddCell(new Phrase(r[3].ToString(), hel8)); table.AddCell(new Phrase(r[4].ToString(), hel8)); table.AddCell(new Phrase(r[5].ToString(), hel8)); byte[] byt = (byte[])r[6]; MemoryStream ms = new MemoryStream(byt); System.Drwaing.Image sdi = System.Drawing.Image.FromStream(ms); Image img = Image.GetInstance(sdi); <-- this is the problem code table.AddCell(img); table.AddCell(new Phrase(r[7].ToString(), hel8)); } } doc.Add(table); } doc.Close(); } Update: #nekno, all of your suggestions are worked. But I still need to correct the casting at line: byte[] byt = (byte[])r[6]; It gave me a casting exception from VS2008. So I added the conversion function (pulled it from stackoverflow): byte[] ImageToByte(System.Drawing.Image img) { byte[] byteArray = new byte[0]; using (MemoryStream stream = new MemoryStream()) { img.Save(stream, System.Drawing.Imaging.ImageFormat.Png); stream.Close(); byteArray = stream.ToArray(); } return byteArray; } And revised the code: byte[] byt = ImageToByte((System.Drawing.Image)dt.Rows[e][6]); Thanks.
What exactly is the problem? What happens when you use your problem code? Try one of the other Image.GetInstance() overloads: You can pass the byte array directly: byte[] byt = (byte[])r[6]; Image img = Image.GetInstance(byt); Or you can pass the Stream: byte[] byt = (byte[])r[6]; MemoryStream ms = new MemoryStream(byt); Image img = Image.GetInstance(ms); Or you can give iTextSharp more info about the image format: byte[] byt = (byte[])r[6]; MemoryStream ms = new MemoryStream(byt); System.Drawing.Image sdi = System.Drawing.Image.FromStream(ms); Image img = Image.GetInstance(sdi, ImageFormat.Png); If your column can be cast to a System.Drawing.Image, then you can use it directly: Image img = Image.GetInstance((System.Drawing.Image)r[6], System.Drawing.Imaging.ImageFormat.Png);
I have suggested steps how shows how to add image into PDF, given below code snippet show how to add logo into your PDF using iTextsharp, follow provided below steps: I have provided link to download "itextsharp" component from given link http://sourceforge.net/projects/itextsharp/ You have to add reference into your application. Next you have to add required namespaces "iTextsharp.text.html", "iTextsharp.text" to consume its best properties. Now you have to add code snippet into your application given at the end, add code snippet under "button click" in code behind. Hope it will work for you !!! protected void btnPDF_Click(object sender, ImageClickEventArgs e) { DataTable dtn = new DataTable(); dtn = GetDataTable(); dtPDF = dtn.Copy(); for (int i = 0; i <= dtn.Rows.Count - 1; i++) { ExportToPdf(dtPDF); } } public void ExportToPdf(DataTable myDataTable) { Document pdfDoc = new Document(PageSize.A4, 10, 10, 10, 10); try { PdfWriter.GetInstance(pdfDoc, System.Web.HttpContext.Current.Response.OutputStream); pdfDoc.Open(); Chunk c = new Chunk("" + System.Web.HttpContext.Current.Session["CompanyName"] + "", FontFactory.GetFont("Verdana", 11)); Paragraph p = new Paragraph(); p.Alignment = Element.ALIGN_CENTER; p.Add(c); pdfDoc.Add(p); string clientLogo = Server.MapPath(".") + "/logo/tpglogo.jpg"; string imageFilePath = Server.MapPath(".") + "/logo/tpglogo.jpg"; iTextSharp.text.Image jpg = iTextSharp.text.Image.GetInstance(imageFilePath); //Resize image depend upon your need jpg.ScaleToFit(80f, 60f); //Give space before image jpg.SpacingBefore = 0f; //Give some space after the image jpg.SpacingAfter = 1f; jpg.Alignment = Element.HEADER; pdfDoc.Add(jpg); Font font8 = FontFactory.GetFont("ARIAL", 7); DataTable dt = myDataTable; if (dt != null) { //Craete instance of the pdf table and set the number of column in that table PdfPTable PdfTable = new PdfPTable(dt.Columns.Count); PdfPCell PdfPCell = null; for (int rows = 0; rows < dt.Rows.Count; rows++) { for (int column = 0; column < dt.Columns.Count; column++) { PdfPCell = new PdfPCell(new Phrase(new Chunk(dt.Rows[rows][column].ToString(), font8))); PdfTable.AddCell(PdfPCell); } } //PdfTable.SpacingBefore = 15f; // Give some space after the text or it may overlap the table pdfDoc.Add(PdfTable); // add pdf table to the document } pdfDoc.Close(); Response.ContentType = "application/pdf"; Response.AddHeader("content-disposition", "attachment; filename= SampleExport.pdf"); System.Web.HttpContext.Current.Response.Write(pdfDoc); Response.Flush(); Response.End(); //HttpContext.Current.ApplicationInstance.CompleteRequest(); } catch (DocumentException de) { System.Web.HttpContext.Current.Response.Write(de.Message); } catch (IOException ioEx) { System.Web.HttpContext.Current.Response.Write(ioEx.Message); } catch (Exception ex) { System.Web.HttpContext.Current.Response.Write(ex.Message); } }
I want to Create and Image handler that will resize the Image and return Images to my application
This is the same question asked before and the answer is also verified but in My Project I am using WebApi 2 and want return image from Ihttpactionresult I have searched and lot and done some code Which I don't know if I am doing right.. I also Looked at ImageReizer but it saves the resized Images in the folder. Idon't want to save the Image. Here is My Controller Action [HttpGet] [Route("GetFile")] public IHttpActionResult GetFile(string filename, int w = 0, int h = 0) { //string filePath = "fdsafsa"; //int width = 0; //var fileStream = File.Open("/ProjectFiles", FileMode.Open); //var content = new StreamContent(fileStream); //content.Headers.ContentType = new MediaTypeHeaderValue("png"); var imageFile = HttpContext.Current.Server.MapPath(#filename); if(File.Exists(imageFile)) { var srcImage = Image.FromFile(imageFile); var newImage = new Bitmap(w, h); var graphics = Graphics.FromImage(newImage); var stream = new MemoryStream(); graphics.SmoothingMode = SmoothingMode.AntiAlias; graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; graphics.DrawImage(srcImage, new Rectangle(0, 0, w, h)); newImage.Save(stream, ImageFormat.Png); //var content = new StreamContent(stream); HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); result.Content = new ByteArrayContent(stream.ToArray()); result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/png"); return Ok(result); } This is the html where I want to render the Image <img src="/api/Public/GetFile?filename=/ProjectFiles/Project_2087/art-therapy-career2_73937984-7e03-4067-91bf-2dd4fc10b328.jpg&w=100&h=100" alt="image" /> How can I show the resized Image dynamically without storing the resize image on the server. I don't want to save the resize Images. I need help soon. Thanks for your help. Another approach ...... [HttpGet] [Route("GetFileStream")] public IHttpActionResult GetFileStream(string filename, int w = 0, int h = 0) { var imagePath = HttpContext.Current.Server.MapPath(#filename); var result = getResizedImage(imagePath, w, h); return Ok(result); } byte[] getResizedImage(String path, int width, int height) { Bitmap imgIn = new Bitmap(path); double y = imgIn.Height; double x = imgIn.Width; double factor = 1; if (width > 0) { factor = width / x; } else if (height > 0) { factor = height / y; } System.IO.MemoryStream outStream = new System.IO.MemoryStream(); Bitmap imgOut = new Bitmap((int)(x * factor), (int)(y * factor)); Graphics g = Graphics.FromImage(imgOut); g.Clear(Color.White); g.DrawImage(imgIn, new Rectangle(0, 0, (int)(factor * x), (int)(factor * y)), new Rectangle(0, 0, (int)x, (int)y), GraphicsUnit.Pixel); imgOut.Save(outStream, getImageFormat(path)); return outStream.ToArray(); } ** This is the Working Code with Mvc ** This is the code I found working for Simple Mvc Application An Action public ActionResult Thumb(string filename = "Azalea.jpg", int w = 0, int h = 0) { string path = Path.Combine(Server.MapPath("~/images2"), filename); //Bitmap bitmap = new Bitmap(filepath); //if (bitmap == null) //{ // return new EmptyResult(); //} //MemoryStream ms = new MemoryStream(); //bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png); Bitmap imgIn = new Bitmap(path); double y = imgIn.Height; double x = imgIn.Width; double factor = 1; if (w > 0) { factor = w / x; } else if (h > 0) { factor = h / y; } System.IO.MemoryStream outStream = new System.IO.MemoryStream(); Bitmap imgOut = new Bitmap((int)(x * factor), (int)(y * factor)); Graphics g = Graphics.FromImage(imgOut); g.Clear(Color.White); g.DrawImage(imgIn, new Rectangle(0, 0, (int)(factor * x), (int)(factor * y)), new Rectangle(0, 0, (int)x, (int)y), GraphicsUnit.Pixel); imgOut.Save(outStream, getImageFormat(path)); outStream.Seek(0, SeekOrigin.Begin); FileStreamResult fileStreamResult = new FileStreamResult(outStream, "image/png"); return fileStreamResult; } In cshtml page <img src="~/Home/Thumb/#Model.ImageName?w=700&h=300" alt="image" /> How to use this With web Api2 ? Answer of My Question after long search.Please Improve this [HttpGet] [Route("GetFileStream")] public IHttpActionResult GetFileStream(string filename, int w = 0, int h = 0) { var imagePath = HttpContext.Current.Server.MapPath(#filename); return new FileResult(imagePath, w, h, "image/jpeg"); } public class FileResult : IHttpActionResult { private readonly string filePath; private readonly string contentType; private readonly int width; private readonly int height; public FileResult(string filePath, int width, int height, string contentType = null) { this.filePath = filePath; this.contentType = contentType; this.width = width; this.height = height; } public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken) { return Task.Run(() => { var result = getResizedImage(filePath, width, height); var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = new ByteArrayContent(result) //Content = new StreamContent(File.OpenRead(filePath)) }; var contentType = this.contentType ?? MimeMapping.GetMimeMapping(Path.GetExtension(filePath)); response.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType); return response; }, cancellationToken); } } static byte[] getResizedImage(String path, int width, int height) { Bitmap imgIn = new Bitmap(path); double y = imgIn.Height; double x = imgIn.Width; double factor = 1; if (width > 0) { factor = width / x; } else if (height > 0) { factor = height / y; } System.IO.MemoryStream outStream = new System.IO.MemoryStream(); Bitmap imgOut = new Bitmap((int)(x * factor), (int)(y * factor)); Graphics g = Graphics.FromImage(imgOut); g.Clear(Color.White); g.DrawImage(imgIn, new Rectangle(0, 0, (int)(factor * x), (int)(factor * y)), new Rectangle(0, 0, (int)x, (int)y), GraphicsUnit.Pixel); imgOut.Save(outStream, getImageFormat(path)); //outStream.Seek(0, SeekOrigin.Begin); //System.Web.Mvc.FileStreamResult fileStreamResult = new System.Web.Mvc.FileStreamResult(outStream, "image/png"); //return fileStreamResult; return outStream.ToArray(); } string getContentType(String path) { switch (Path.GetExtension(path)) { case ".bmp": return "Image/bmp"; case ".gif": return "Image/gif"; case ".jpg": return "Image/jpeg"; case ".png": return "Image/png"; default: break; } return ""; } static ImageFormat getImageFormat(String path) { switch (Path.GetExtension(path)) { case ".bmp": return ImageFormat.Bmp; case ".gif": return ImageFormat.Gif; case ".jpg": return ImageFormat.Jpeg; case ".png": return ImageFormat.Png; default: break; } return ImageFormat.Jpeg; } Please Help in improving this answer, Thanks, Sanuj
You can pass your byteArray to View, then use something like this: Create your image model: public class ImageData { public string Name { get; set; } public byte[] Content { get; set; } . . . } Then in controller assign and return your model to View(): #{ string imageBase = Convert.ToBase64String(Model.ImageContent); string imageSource = string.Format("data:image/gif;base64,{0}", imageBase); } <img src="#imageSource" alt="#Model.ImageName" width="100" height="100" />
Update Jfreechart when update data from Webcam
My jfreeChart comes from frames of a webcam. I pass this frames and it generates a graphic of R, G and B colors of this frame. I want this chart do automatic update as I pass the frames. I've tried everything but nothing seens to work. Any help is welcome. class DaemonThread implements Runnable { protected volatile boolean runnable = false; #Override public void run() { synchronized(this) { while(runnable) { if(webSource.grab()) { try { webSource.retrieve(frame); Imgcodecs.imencode(".bmp", frame, mem); Image im = ImageIO.read(new ByteArrayInputStream(mem.toArray())); buff = (BufferedImage) im; if(contHistograma==0) { h = new Histo(buff); contHistograma++; }else{ h.update(buff); } webcamLabel.setIcon(new ImageIcon(buff)); Graphics g=webcamPanel.getGraphics(); if (g.drawImage(buff, 0, 0, getWidth(), getHeight() -150 , 0, 0, buff.getWidth(), buff.getHeight(), null)) if(runnable == false) { System.out.println("Going to wait()"); this.wait(); } } catch(Exception ex) { System.out.println("Error"); } } } } } } public class Histo{ private ChartFrame lineFrame; private ArrayList<Integer> redArray; private ArrayList<Integer> greenArray; private ArrayList<Integer> blueArray; public Histo(BufferedImage originalImage){ Color c; redArray = new ArrayList<>(); greenArray = new ArrayList<>(); blueArray = new ArrayList<>(); for (int i = 0; i < originalImage.getWidth(null); i++) { for (int j = 0; j < originalImage.getHeight(null); j++) { c = new Color(originalImage.getRGB(i,j)); redArray.add(c.getRed()); greenArray.add(c.getGreen()); blueArray.add(c.getBlue()); } } Collections.sort(redArray); Collections.sort(greenArray); Collections.sort(blueArray); XYSeriesCollection dataset = creatingDataset(redArray, greenArray, blueArray); JFreeChart chart = createChart(dataset); ChartPanel chartPanel = new ChartPanel(chart); lineFrame = new ChartFrame("teste", chart); lineFrame.add(chartPanel); lineFrame.setVisible(true); lineFrame.setSize(600, 450); } public void update(BufferedImage originalImage){ redArray.clear(); greenArray.clear(); blueArray.clear(); Color c; for (int i = 0; i < originalImage.getWidth(null); i++) { for (int j = 0; j < originalImage.getHeight(null); j++) { c = new Color(originalImage.getRGB(i,j)); redArray.add(c.getRed()); greenArray.add(c.getGreen()); blueArray.add(c.getBlue()); } } Collections.sort(redArray); Collections.sort(greenArray); Collections.sort(blueArray); XYSeriesCollection dataset = creatingDataset(redArray, greenArray, blueArray); JFreeChart chart = createChart(dataset); ChartPanel chartPanel = new ChartPanel(chart); lineFrame.removeAll(); lineFrame.add(chartPanel); lineFrame.revalidate(); lineFrame.setLayout(new BorderLayout()); lineFrame.repaint(); } public static XYSeriesCollection creatingDataset(ArrayList<Integer> redArray,ArrayList<Integer> greenArray,ArrayList<Integer> blueArray){ int cont=1, cont2=1, cont3=1; XYSeries series = new XYSeries("Red"); XYSeries series2 = new XYSeries("Green"); XYSeries series3 = new XYSeries("Blue"); for (int i = 0; i < redArray.size()-1; i++) { if(redArray.get(i).intValue() == redArray.get(i+1).intValue()) { cont++; }else{ series.add(redArray.get(i).intValue(), cont); cont=1; } } for (int i = 0; i < greenArray.size()-1; i++) { if(greenArray.get(i).intValue() == greenArray.get(i + 1).intValue()) { cont2++; }else{ series2.add(greenArray.get(i).intValue(), cont2); cont2 = 1; } } for (int i = 0; i < blueArray.size()-1; i++) { if(blueArray.get(i).intValue() == blueArray.get(i+1).intValue()) { cont3++; }else{ series3.add(blueArray.get(i).intValue(), cont3); cont3=1; } } XYSeriesCollection dataset = new XYSeriesCollection(); dataset.addSeries(series); dataset.addSeries(series2); dataset.addSeries(series3); return dataset; } private JFreeChart createChart(final XYDataset dataset) { JFreeChart result = ChartFactory.createXYLineChart("Gráfico XY", "Eixo X", "Eixo Y", dataset, PlotOrientation.VERTICAL, true, true, false); final XYPlot plot = result.getXYPlot(); plot.setBackgroundPaint(new Color(0xffffe0)); plot.setDomainGridlinesVisible(true); plot.setDomainGridlinePaint(Color.lightGray); plot.setRangeGridlinesVisible(true); plot.setRangeGridlinePaint(Color.lightGray); final NumberAxis domainAxis = (NumberAxis) plot.getDomainAxis(); //RANGE EIXO X domainAxis.setRange(0, 260); final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis(); //RANGE EIXO Y rangeAxis.setRange(0, 5000); return result; } }
If someone else have this problem here is the answer: Chartframe can't get rid of chartpanel, so I made Chartpanel a atribute. After that I update my dataset and did this: JFreeChart chart = createChart(dataset); chartPanel.setChart(chart); lineFrame.setLayout(new BorderLayout()); lineFrame.repaint(); Problem solved.