java - What is the right way to create thumbnail charts? -
i'm trying create chart of thumbnails of data using jscrollpane, encounter performance difficulties. example has 100 thumbnails charts 5000 samples in each one. when i'm trying scroll down , multiple times, scrolling occurs delay, cpu load increasing, application memory usage reaches on 500 mb.
is there way avoid performance problem without reducing data?
import java.awt.color; import java.awt.eventqueue; import java.awt.gridlayout; import java.util.random; import javax.swing.jframe; import javax.swing.jpanel; import javax.swing.jscrollpane; import org.jfree.chart.chartfactory; import org.jfree.chart.chartpanel; import org.jfree.chart.jfreechart; import org.jfree.chart.plot.plotorientation; import org.jfree.chart.plot.thermometerplot; import org.jfree.data.general.defaultvaluedataset; import org.jfree.data.xy.xyseries; import org.jfree.data.xy.xyseriescollection; public class thumbnailchartstest extends jpanel { private static final int w = 200; private static final int h = w; private static final int n = 5000; private static final random random = new random(); private static chartpanel createpane() { final xyseries series = new xyseries("data"); (int = 0; < random.nextint(n) + n; i++) { series.add(i, random.nextgaussian()); } xyseriescollection dataset = new xyseriescollection(series); jfreechart chart = chartfactory.createxylinechart("random", "domain", "range", dataset, plotorientation.vertical, false, false, false); return new chartpanel(chart, w, h, w, h, w, h, false, true, true, true, true, true); } public static void main(final string[] args) { eventqueue.invokelater(new runnable() { @override public void run() { jframe f = new jframe("test"); f.setdefaultcloseoperation(jframe.exit_on_close); jpanel panel = new jpanel(); panel.setlayout(new gridlayout(0, 4)); (int i=0; i<100; i++){ panel.add(createpane()); } jscrollpane scrollpane = new jscrollpane(panel, jscrollpane.vertical_scrollbar_always, jscrollpane.horizontal_scrollbar_never); f.add(scrollpane); f.pack(); f.setvisible(true); } }); } } edit: can't understand 1 thing: why in case memory usage still huge! please @ illustration.

addition: think there misunderstanding.
heap size monitor visualvm
after starting applet heap size 125 mb, it's cool. i'm starting testing: scrolling , resizing multiple times, more , more -- , down, , down, smaller frame , bigger frame. heap size growing on 500 mb! suppose situation isn't normal.
addition #2
real-world example:
my data has size 2 mb , represented in 90 charts(2 series in each one), 1 series contain 3000 elements. i've implemented changing number columns slider. 
but small data heap size growing on 1.5 gb!
this happens after actions, changing number columns e.g. cpu(core 2 duo 2.2ghz) every drawing table takes time 4 sec! big delay it's hard control slider.
update:
i've implemented downsampling data 100 samples per thumbnail chart. it's faster, problem huge heap size still there. on picture 1 above 700mb, , it's not record. i'm frustrated. 
use flyweight pattern render visible charts. approach, used jtable renderers, outlined here , shown in chartrenderer seen below. illustration, dataset recreated each time cell revealed; scroll, resize , switch applications see effect. while such rendering scales tens of thousands of cells, each chart still renders n data points. can limit number of visible cells in implementation of scrollable method, getpreferredscrollableviewportsize(), shown below.
how reduce memory usage small values?
there no general answer, several strategies may prove helpful:
compose charts in program initialization possible, rather @ time rendered; updated example below constructs
tablemodelofchartpanelinstances;chartrenderercorrespondingly simpler.charts having more few thousand points unreadable; consider truncating large datasets , displaying full data in response
listselectionevent, illustrated here.platform activity monitors may misleading; profile verify actual results.
after starting applet it's not big, less 200 mb, after scrolling, resizing etc. memory usage reaches values more 600 mb. why?
a typical profiler view of code below shows moderate usage , expected free/used ratio after scrolling , garbage collection; results may vary.
import java.awt.component; import java.awt.dimension; import java.awt.eventqueue; import java.util.random; import javax.swing.jframe; import javax.swing.jscrollpane; import javax.swing.jtable; import javax.swing.table.defaulttablemodel; import javax.swing.table.tablecellrenderer; import org.jfree.chart.chartfactory; import org.jfree.chart.chartpanel; import org.jfree.chart.jfreechart; import org.jfree.data.xy.xyseries; import org.jfree.data.xy.xyseriescollection; /** * @see https://stackoverflow.com/a/40445144/230513 */ public class charttable { private static final random r = new random(); private static final int n = 5000; private static final int w = 200; private static final int h = w; private void display() { jframe f = new jframe("charttable"); f.setdefaultcloseoperation(jframe.exit_on_close); defaulttablemodel model = new defaulttablemodel( new string[]{"", "", "", ""}, 0) { @override public class<?> getcolumnclass(int columnindex) { return chartpanel.class; } }; (int r = 0; r < 25; r++) { chartpanel[] row = new chartpanel[4]; (int c = 0; c < row.length; c++) { final xyseries series = new xyseries("data"); int n = r.nextint(n); (int = 0; < n; i++) { series.add(i, r.nextgaussian()); } xyseriescollection dataset = new xyseriescollection(series); jfreechart chart = chartfactory.createxylinechart( "random " + series.getitemcount(), "domain", "range", dataset); chartpanel chartpanel = new chartpanel(chart) { @override public dimension getpreferredsize() { return new dimension(w, h); } }; row[c] = chartpanel; } model.addrow(row); } jtable table = new jtable(model) { @override public dimension getpreferredscrollableviewportsize() { return new dimension(4 * w, 2 * h); } }; table.setdefaultrenderer(chartpanel.class, new chartrenderer()); table.setrowheight(w); f.add(new jscrollpane(table)); f.pack(); f.setlocationrelativeto(null); f.setvisible(true); } private static class chartrenderer implements tablecellrenderer { @override public component gettablecellrenderercomponent( jtable table, object value, boolean isselected, boolean hasfocus, int row, int column) { return (chartpanel) value; } } public static void main(string[] args) { eventqueue.invokelater(new charttable()::display); } } 



Comments
Post a Comment