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?

enter image description here

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.

image

addition: think there misunderstanding.

heap size monitor visualvm enter image description here 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. enter image description here

but small data heap size growing on 1.5 gb!

enter image description here

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. enter image description here

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 tablemodel of chartpanel instances; chartrenderer correspondingly 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.

image

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.

profile

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

Popular posts from this blog

java - SSE Emitter : Manage timeouts and complete() -

jquery - uncaught exception: DataTables Editor - remote hosting of code not allowed -

java - How to resolve error - package com.squareup.okhttp3 doesn't exist? -